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 N = 5 * 1e5 + 100;
int n, m, q, a[N], vi[N], dfn[N], out[N], cnt, tr[N];
int son[N][2], f[N], t[N], fa[N][21];
struct edge {
  int u, v;
} e[N];
struct ask {
  int t, x;
} sh[N * 2];
namespace tree {
struct node {
  int MAX, wh;
} sh[N * 4];
inline void pushup(int x) {
  if (sh[x + x].MAX > sh[x + x + 1].MAX)
    sh[x] = sh[x + x];
  else
    sh[x] = sh[x + x + 1];
}
void build(int x, int l, int r) {
  if (l == r) {
    sh[x].MAX = a[tr[l]];
    sh[x].wh = tr[l];
    return;
  }
  int mid = (l + r) >> 1;
  build(x + x, l, mid);
  build(x + x + 1, mid + 1, r);
  pushup(x);
}
void change(int x, int l, int r, int wh) {
  if (l == r) {
    sh[x].MAX = 0;
    return;
  }
  int mid = (l + r) >> 1;
  if (wh <= mid)
    change(x + x, l, mid, wh);
  else
    change(x + x + 1, mid + 1, r, wh);
  pushup(x);
}
int query(int x, int l, int r, int ll, int rr) {
  if (ll <= l && rr >= r) return sh[x].wh;
  int mid = (l + r) >> 1, ans = -1, wh, id;
  if (ll <= mid) {
    id = query(x + x, l, mid, ll, rr);
    if (ans < a[id]) ans = a[id], wh = id;
  }
  if (rr > mid) {
    id = query(x + x + 1, mid + 1, r, ll, rr);
    if (ans < a[id]) ans = a[id], wh = id;
  }
  return wh;
}
}  // namespace tree
int find(int x) {
  if (f[x] == x) return x;
  return f[x] = find(f[x]);
}
void dfs(int x, int father) {
  fa[x][0] = father;
  if (!son[x][0] && !son[x][1]) {
    out[x] = dfn[x] = ++cnt, tr[cnt] = x;
    return;
  }
  if (son[x][0]) dfs(son[x][0], x);
  if (son[x][1]) dfs(son[x][1], x);
  out[x] = out[son[x][1]];
  dfn[x] = dfn[son[x][0]];
}
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", &e[i].u, &e[i].v);
  for (int i = 1; i <= q; i++) {
    scanf("%d%d", &sh[i].t, &sh[i].x);
    if (sh[i].t == 2) vi[sh[i].x] = 1;
  }
  for (int i = 1; i <= n + m; i++) f[i] = i;
  for (int i = 1; i <= m; i++) {
    if (vi[i]) continue;
    int fax = find(e[i].u), fay = find(e[i].v);
    if (fax == fay) continue;
    f[fax] = f[fay] = n + i;
    son[n + i][0] = fax, son[n + i][1] = fay;
    t[n + i] = q + 1;
  }
  for (int i = q; i >= 1; i--) {
    if (sh[i].t == 1) continue;
    int id = sh[i].x;
    int fax = find(e[id].u), fay = find(e[id].v);
    if (fax == fay) continue;
    f[fax] = f[fay] = n + id;
    son[n + id][0] = fax, son[n + id][1] = fay;
    t[n + id] = i;
  }
  for (int i = 1; i <= n; i++) {
    if (dfn[i]) continue;
    int root = find(i);
    dfs(root, root);
  }
  tree::build(1, 1, n);
  for (int j = 1; j <= 20; j++)
    for (int i = 1; i <= n + m; i++) fa[i][j] = fa[fa[i][j - 1]][j - 1];
  for (int i = 1; i <= q; i++) {
    if (sh[i].t == 2) continue;
    int x = sh[i].x;
    for (int j = 20; j >= 0; j--)
      if (t[fa[x][j]] >= i) x = fa[x][j];
    int wh = tree::query(1, 1, n, dfn[x], out[x]);
    printf("%d\n", a[wh]);
    if (a[wh] == 0) continue;
    a[wh] = 0;
    tree::change(1, 1, n, dfn[wh]);
  }
}
