9 5 14
7 1 4 8 5 2 6 9 3
2 8
1 6
5 7
1 3
3 9
1 5
1 8
1 5
1 4
1 8
1 3
1 5
1 5
1 7
1 7
2 3
1 2
1 1
1 2
 6 5 8
1 2 6 3 4 5
2 4
1 3
1 6
3 5
2 5
1 1
1 4
1 1
2 1
2 5
2 2
2 3
1 4
 2 1 3
1 2
1 2
1 1
1 1
1 1

6
9
5
8
1
7
0
0
0
0
0
4
0
 6
5
4
3
 2
1
0

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e5 + 7;
struct edge {
  int x, y, flag;
  edge() {}
  edge(int xx, int yy) {
    x = xx;
    y = yy;
    flag = 0;
  }
};
edge edges[MAXN];
int n, m, q;
bool mrk[MAXN];
int v[MAXN], tp[MAXN], z[MAXN], pai[MAXN], aux[MAXN],
    t = 0, ent[MAXN], sai[MAXN], tree[4 * MAXN], node[MAXN];
vector<int> G[MAXN];
int raiz(int u) { return (u == pai[u]) ? u : pai[u] = raiz(pai[u]); }
void join(int u, int w) {
  pai[u] = w;
  G[w].push_back(u);
}
void dfs(int u) {
  t++;
  ent[u] = t;
  node[t] = u;
  for (int viz : G[u]) {
    dfs(viz);
  }
  sai[u] = t;
}
void upt(int idx, int l, int r, int pos, int val) {
  if (l == r) {
    tree[idx] = val;
    return;
  }
  if (pos <= (l + r) / 2)
    upt(2 * idx, l, (l + r) / 2, pos, val);
  else
    upt(2 * idx + 1, (l + r) / 2 + 1, r, pos, val);
  if (v[tree[2 * idx]] > v[tree[2 * idx + 1]])
    tree[idx] = tree[2 * idx];
  else
    tree[idx] = tree[2 * idx + 1];
}
int query(int idx, int l, int r, int ql, int qr) {
  if (r < ql || l > qr) return 0;
  if (l >= ql && r <= qr) return tree[idx];
  int esq = query(2 * idx, l, (l + r) / 2, ql, qr);
  int dir = query(2 * idx + 1, (l + r) / 2 + 1, r, ql, qr);
  if (v[esq] > v[dir]) return esq;
  return dir;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cin >> n >> m >> q;
  for (int i = 1; i <= n; i++) {
    cin >> v[i];
    pai[i] = i;
  }
  for (int i = 1; i <= m; i++) {
    int xi, yi;
    cin >> xi >> yi;
    edges[i] = edge(xi, yi);
  }
  for (int i = 1; i <= q; i++) {
    cin >> tp[i] >> z[i];
    if (tp[i] == 2) edges[z[i]].flag = 1;
  }
  for (int i = 1; i <= m; i++) {
    if (edges[i].flag == 0) {
      q++;
      tp[q] = 2;
      z[q] = i;
    }
  }
  for (int i = q; i >= 1; i--) {
    if (tp[i] == 1) {
      aux[i] = raiz(z[i]);
    } else {
      int rx = raiz(edges[z[i]].x);
      int ry = raiz(edges[z[i]].y);
      if (rx != ry) {
        join(rx, ry);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    int ii = raiz(i);
    if (mrk[ii]) continue;
    mrk[ii] = true;
    dfs(ii);
  }
  for (int i = 1; i <= t; i++) {
    upt(1, 1, t, i, node[i]);
  }
  for (int i = 1; i <= q; i++) {
    if (tp[i] == 2) continue;
    int rep = aux[i];
    int u = query(1, 1, t, ent[rep], sai[rep]);
    cout << v[u] << endl;
    upt(1, 1, t, ent[u], 0);
  }
}
