#include <bits/stdc++.h>   using namespace std;   const int inf = 0x3f3f3f3f;   const int N = 1e6 + 100;   int n, m, q;   struct Qu {     int op, x;   } qu[N];   struct Edge {     int u, v, w;     bool operator<(const Edge& t) const { return w < t.w; }   } edge[N];   struct Max {     int val, pos;     Max() {}     Max(int val, int pos) : val(val), pos(pos) {}     static Max inf() { return Max(-0x3f3f3f3f, 0); }     bool operator<(const Max& t) const { return val < t.val; }   };   struct Node {     int l, r;     Max mmax;   } tree[N << 2];   int a[N], f[N], val[N], dp[N][25], L[N], R[N], id[N], tot;   vector<int> node[N];   void pushup(int k) {     tree[k].mmax = max(tree[k << 1].mmax, tree[k << 1 | 1].mmax);   }   void build(int k, int l, int r) {     tree[k].l = l;     tree[k].r = r;     if (l == r) {       tree[k].mmax.val = a[id[l]];       tree[k].mmax.pos = l;       return;     }     int mid = l + r >> 1;     build(k << 1, l, mid);     build(k << 1 | 1, mid + 1, r);     pushup(k);   }   void update(int k, int pos) {     if (tree[k].l == tree[k].r) {       tree[k].mmax.val = 0;       return;     }     int mid = tree[k].l + tree[k].r >> 1;     if (pos <= mid)       update(k << 1, pos);     else       update(k << 1 | 1, pos);     pushup(k);   }   Max query(int k, int l, int r) {     if (tree[k].l > r || tree[k].r < l) return Max::inf();     if (tree[k].l >= l && tree[k].r <= r) return tree[k].mmax;     return max(query(k << 1, l, r), query(k << 1 | 1, l, r));   }   void dfs(int u, int fa) {     dp[u][0] = fa;     for (int i = 1; i <= 20; i++) dp[u][i] = dp[dp[u][i - 1]][i - 1];     L[u] = ++tot;     id[tot] = u;     for (auto v : node[u]) dfs(v, u);     R[u] = tot;   }   int get_pos(int u, int up) {     for (int i = 20; i >= 0; i--)       if (dp[u][i] != 0 && val[dp[u][i]] <= up) u = dp[u][i];     return u;   }   int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }   int Ex_Kruskal() {     for (int i = 1; i <= n << 1; i++) f[i] = i;     int index = n;     sort(edge + 1, edge + 1 + m);     for (int i = 1; i <= m; i++) {       int xx = find(edge[i].u), yy = find(edge[i].v);       if (xx != yy) {         f[xx] = f[yy] = ++index;         val[index] = edge[i].w;         node[index].push_back(xx);         node[index].push_back(yy);       }     }     int last = 1;     for (int i = 1; i <= n; i++) {       int xx = find(last), yy = find(i);       if (xx != yy) {         f[xx] = f[yy] = ++index;         val[index] = inf;         node[index].push_back(xx);         node[index].push_back(yy);         last = index;       }     }     return index;   }   int main() {     scanf( %d%d%d , &n, &m, &q);     for (int i = 1; i <= n; i++) scanf( %d , a + i);     for (int i = 1; i <= m; i++) {       scanf( %d%d , &edge[i].u, &edge[i].v);       edge[i].w = 0;     }     int val = inf;     for (int i = 1; i <= q; i++) {       scanf( %d%d , &qu[i].op, &qu[i].x);       if (qu[i].op == 2) edge[qu[i].x].w = --val;     }     int root = Ex_Kruskal();     dfs(root, 0);     build(1, 1, root);     val = inf - 1;     for (int i = 1; i <= q; i++) {       if (qu[i].op == 1) {         int x = get_pos(qu[i].x, val);         Max ans = query(1, L[x], R[x]);         printf( %d n , ans.val);         update(1, ans.pos);       } else         val--;     }     return 0;   }