//#pragma GCC optimize("Ofast,unroll-loops") #ifdef LOCAL #include "debug.h" #else #include #include #include #define debug(x...) #endif using namespace std; //#define int ll typedef long long ll; typedef long double ld; typedef pair pii; #define sz(x) int((x).size()) template using ordered_set = __gnu_pbds::tree , __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>; #ifdef ONLINE_JUDGE mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); #else mt19937 rng(1000 - 7); #endif const int N = 2e5 + 10; //const ll MOD = 998244353; const ll MOD = 1e9 + 7; const ld eps = 5e-8; const pii dir[] = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } }; int n, m, q; int a[N], id[N]; vector g[N]; struct Tree { struct Node { Node *l = nullptr; Node *r = nullptr; int tl, tr, sum = 0; Node(int tl, int tr) : tl(tl), tr(tr) {} ~Node() { delete l; delete r; } }; Node *root = nullptr; Tree() {} Tree(int n) { root = new Node(0, n - 1); } void update(Node *u, int pos, int val) { if (u->tl == u->tr) { u->sum = val; } else { int tm = (u->tl + u->tr) / 2; if (pos <= tm) { if (!u->l) u->l = new Node(u->tl, tm); update(u->l, pos, val); } else { if (!u->r) u->r = new Node(tm + 1, u->tr); update(u->r, pos, val); } u->sum = ((u->l ? u->l->sum : 0) + (u->r ? u->r->sum : 0)); if (u->sum == 0) { delete u; } } } int get(Node *u) { if (u->tl == u->tr) { return (u->sum ? -1 : u->tl); } else { if (!u->r) { return u->tr; } if (u->r->sum < u->r->tr - u->r->tl + 1) { return get(u->r); } else if (u->l) { return get(u->l); } else { return (u->tl + u->tr) / 2; } } } }; int best[N]; Tree tree[N]; vector aa; inline int f(int i) { if (best[i] == -1) { return 0; } int j = aa[best[i]].second; if (i != aa.back().second && j != aa.back().second) { return a[i] + a[j] + aa.back().first; } else if (i != aa[n - 2].second && j != aa[n - 2].second) { return a[i] + a[j] + aa[n - 2].first; } else { return a[i] + a[j] + aa[n - 3].first; } } struct TreeMin { int t[4 * N]; void build(int v, int l, int r) { if (l == r) { t[v] = f(l); } else { int m = (l + r) / 2; build(2 * v, l, m); build(2 * v + 1, m + 1, r); t[v] = max(t[2 * v], t[2 * v + 1]); } } void update(int v, int l, int r, int pos) { if (l == r) { t[v] = f(l); } else { int m = (l + r) / 2; if (pos <= m) { update(2 * v, l, m, pos); } else { update(2 * v + 1, m + 1, r, pos); } t[v] = max(t[2 * v], t[2 * v + 1]); } } int get() { return t[1]; } } treemin; signed main() { #ifdef LOCAL freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); #endif cout << fixed << setprecision(9); ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> n >> m >> q; for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0, u, v; i < m; i++) { cin >> u >> v; u--, v--; g[u].push_back(v); g[v].push_back(u); } aa.resize(n); for (int i = 0; i < n; i++) { aa[i] = { a[i], i }; } sort(aa.begin(), aa.end()); for (int i = 0; i < n; i++) { id[aa[i].second] = i; } for (int i = 0; i < n; i++) { tree[i] = Tree(n); tree[i].update(tree[i].root, id[i], 1); for (int j : g[i]) { tree[i].update(tree[i].root, id[j], 1); } best[i] = tree[i].get(tree[i].root); } treemin.build(1, 0, n - 1); while (q--) { int type, u, v; cin >> type >> u >> v; type = 1 ^ (type - 1); u--, v--; tree[u].update(tree[u].root, id[v], type); tree[v].update(tree[v].root, id[u], type); best[u] = tree[u].get(tree[u].root); best[v] = tree[v].get(tree[v].root); treemin.update(1, 0, n - 1, u); treemin.update(1, 0, n - 1, v); cout << treemin.get() << "\n"; } return 0; }