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 = 500010;
inline int read() {
  int n = 0, f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -f;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    n = 10 * n + (c ^ '0');
    c = getchar();
  }
  return f * n;
}
int n, m, q;
int val[MAXN], pos[MAXN], dsu[MAXN];
pair<int, int> edge[MAXN], ask[MAXN];
bool del[MAXN];
vector<int> E[MAXN];
int in[MAXN], out[MAXN], total;
int find(int u) {
  if (dsu[u] == u) return u;
  return dsu[u] = find(dsu[u]);
}
void merge(int u, int v) {
  int fu = find(u);
  int fv = find(v);
  if (fu == fv) return;
  n = n + 1;
  dsu[fu] = dsu[fv] = dsu[n] = n;
  E[n].push_back(fu);
  E[n].push_back(fv);
}
void dfs(int u, int f) {
  in[u] = ++total;
  for (int i = 0; i < E[u].size(); i++) {
    int v = E[u][i];
    if (in[v]) continue;
    dfs(v, u);
  }
  out[u] = total;
}
struct SegTree {
  int l, r, v;
} node[4 * MAXN];
void build(int i, int l, int r) {
  node[i].l = l, node[i].r = r;
  if (l == r) return;
  int m = l + r >> 1;
  build(i << 1, l, m);
  build(i << 1 | 1, m + 1, r);
}
void update(int i, int k, int v) {
  if (node[i].l == node[i].r) {
    node[i].v = v;
    return;
  }
  int m = node[i].l + node[i].r >> 1;
  if (k <= m)
    update(i << 1, k, v);
  else
    update(i << 1 | 1, k, v);
  node[i].v = max(node[i << 1].v, node[i << 1 | 1].v);
}
int query(int i, int l, int r) {
  if (node[i].l == l && node[i].r == r) return node[i].v;
  int m = node[i].l + node[i].r >> 1;
  if (r <= m) return query(i << 1, l, r);
  if (l > m) return query(i << 1 | 1, l, r);
  return max(query(i << 1, l, m), query(i << 1 | 1, m + 1, r));
}
int main() {
  n = read(), m = read(), q = read();
  for (int i = 1; i <= n; i++) {
    val[i] = read();
    pos[val[i]] = dsu[i] = i;
  }
  for (int i = 1; i <= m; i++) {
    edge[i].first = read();
    edge[i].second = read();
  }
  for (int i = 1; i <= q; i++) {
    ask[i].first = read();
    ask[i].second = read();
    if (ask[i].first == 2) {
      del[ask[i].second] = 1;
    }
  }
  for (int i = 1; i <= m; i++) {
    if (del[i]) continue;
    merge(edge[i].first, edge[i].second);
  }
  for (int i = q; i >= 1; i--) {
    if (ask[i].first == 1) {
      ask[i].second = find(ask[i].second);
    } else {
      int k = ask[i].second;
      merge(edge[k].first, edge[k].second);
    }
  }
  for (int i = 1; i <= n; i++) {
    if (dsu[i] == i) {
      dfs(i, -1);
    }
  }
  build(1, 1, n);
  for (int i = 1; i <= n; i++) {
    update(1, in[i], val[i]);
  }
  for (int i = 1; i <= q; i++) {
    if (ask[i].first == 1) {
      int u = ask[i].second;
      int ans = query(1, in[u], out[u]);
      printf("%d\n", ans);
      if (ans != 0) update(1, in[pos[ans]], 0);
    }
  }
  return 0;
}
