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>
const int maxm = 1e6 + 100;
struct node {
  int u, v;
} edge[maxm];
struct Node {
  int opt, x;
} query[maxm];
int head[maxm], to[maxm * 2], net[maxm * 2], mat[maxm], cnt, tot;
bool used[maxm];
int val[maxm], dfn[maxm], pos[maxm], siz[maxm], fa[maxm];
int n, m, q;
inline void addedge(int u, int v) {
  to[++cnt] = v, net[cnt] = head[u], head[u] = cnt;
}
struct Pos {
  int maxi, id;
} st[maxm * 4];
inline Pos merge(Pos x1, Pos x2) {
  if (x1.maxi > x2.maxi)
    return x1;
  else
    return x2;
}
inline void pushup(int o) { st[o] = merge(st[(o << 1)], st[(o << 1) | 1]); }
void build(int o, int l, int r) {
  if (l >= r) {
    st[o] = (Pos){val[dfn[l]], l};
    return;
  }
  int mid = (l + r) >> 1;
  build((o << 1), l, mid), build((o << 1) | 1, mid + 1, r);
  pushup(o);
}
void change(int o, int l, int r, int ind) {
  if (l >= r) {
    st[o].maxi = 0;
    return;
  }
  int mid = (l + r) >> 1;
  ind <= mid ? change((o << 1), l, mid, ind)
             : change((o << 1) | 1, mid + 1, r, ind);
  pushup(o);
}
Pos ask(int o, int l, int r, int ql, int qr) {
  if (ql > r || qr < l) return (Pos){-1, -1};
  if (ql <= l && r <= qr) return st[o];
  int mid = (l + r) >> 1;
  return merge(ask((o << 1), l, mid, ql, qr),
               ask((o << 1) | 1, mid + 1, r, ql, qr));
}
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void dfs(int x) {
  pos[x] = ++tot, dfn[tot] = x, siz[x] = 1;
  for (int i = head[x]; i; i = net[i]) {
    dfs(to[i]);
    siz[x] += siz[to[i]];
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 1; i <= n; i++) scanf("%d", &val[i]);
  for (int i = 1; i <= m; i++) scanf("%d%d", &edge[i].u, &edge[i].v);
  for (int i = 1; i <= q; i++) {
    scanf("%d%d", &query[i].opt, &query[i].x);
    if (query[i].opt == 2) used[query[i].x] = 1;
  }
  for (int i = 1; i <= n + m; i++) fa[i] = i;
  for (int i = 1; i <= m; i++)
    if (!used[i]) {
      int fa1 = find(edge[i].u), fa2 = find(edge[i].v);
      if (fa1 == fa2) continue;
      fa[fa1] = fa2;
      addedge(fa2, fa1);
    }
  for (int i = q; i >= 1; i--) {
    if (query[i].opt == 2) {
      int fa1 = find(edge[query[i].x].u), fa2 = find(edge[query[i].x].v);
      if (fa1 == fa2) continue;
      n++;
      fa[fa1] = n, fa[fa2] = n;
      addedge(n, fa1), addedge(n, fa2);
    } else
      mat[i] = find(query[i].x);
  }
  for (int i = 1; i <= n; i++)
    if (!pos[i]) dfs(find(i));
  build(1, 1, tot);
  for (int i = 1; i <= q; i++)
    if (query[i].opt == 1) {
      Pos ans = ask(1, 1, tot, pos[mat[i]], pos[mat[i]] + siz[mat[i]] - 1);
      if (ans.maxi) change(1, 1, tot, ans.id);
      printf("%d\n", ans.maxi);
    }
  return 0;
}
