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 = 5e5 + 5;
const int B = 25;
vector<int> vc[N];
int dfn[N], seq[N], anc[N][B + 1], out[N];
int idc;
void dfs(int u) {
  dfn[u] = ++idc;
  seq[idc] = u;
  for (int i = 1; i <= B; i++) anc[u][i] = anc[anc[u][i - 1]][i - 1];
  for (auto v : vc[u]) {
    anc[v][0] = u;
    dfs(v);
  }
  out[u] = idc;
}
struct nod {
  int val, pos;
} tree[N << 2];
int a[N];
nod max(nod a, nod b) {
  if (a.val > b.val) return a;
  if (a.val < b.val) return b;
  return seq[a.pos] < seq[b.pos] ? a : b;
}
void upda(const int &o) { tree[o] = max(tree[o << 1], tree[o << 1 | 1]); }
void build(int o, int l, int r) {
  if (l == r) {
    tree[o].val = a[seq[l]];
    tree[o].pos = l;
    return;
  }
  int mid = (l + r) >> 1;
  build(o << 1, l, mid);
  build(o << 1 | 1, mid + 1, r);
  upda(o);
}
void modify(int o, int l, int r, int pos) {
  if (l == r) {
    tree[o].val = 0;
    return;
  }
  int mid = (l + r) >> 1;
  if (pos <= mid) modify(o << 1, l, mid, pos);
  if (pos > mid) modify(o << 1 | 1, mid + 1, r, pos);
  upda(o);
}
nod query(int o, int l, int r, int L, int R) {
  if (L <= l && r <= R) return tree[o];
  int mid = (l + r) >> 1;
  nod ans;
  ans.val = 0;
  ans.pos = l;
  if (L <= mid) ans = max(ans, query(o << 1, l, mid, L, R));
  if (R > mid) ans = max(ans, query(o << 1 | 1, mid + 1, r, L, R));
  return ans;
}
int n, m, q, xx, yy, fx, fy, tot;
int ssiz[N], f[N], tim[N];
struct bian {
  int fr, to;
} e[N];
struct RW {
  int opt, id;
} rw[N];
bool ban[N];
int find(int x) {
  if (x == f[x]) return x;
  return f[x] = find(f[x]);
}
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", &xx, &yy);
    e[i].fr = xx;
    e[i].to = yy;
  }
  for (int i = 1; i <= q; i++) {
    scanf("%d%d", &xx, &yy);
    rw[i].opt = xx;
    rw[i].id = yy;
    if (rw[i].opt == 2) ban[rw[i].id] = 1;
  }
  for (int i = 1; i <= n * 2; i++) {
    f[i] = i;
    ssiz[i] = (i <= n);
  }
  for (int i = 1; i <= m; i++) {
    if (ban[i]) continue;
    fx = find(e[i].fr);
    fy = find(e[i].to);
    if (fx == fy) continue;
    f[fx] = fy;
    ssiz[fy] += ssiz[fx];
  }
  tot = n;
  for (int i = 1; i <= n; i++) {
    if (ssiz[find(i)] == 1) continue;
    if (find(i) == i) {
      f[i] = ++tot;
      tim[tot] = q + 1;
    }
  }
  for (int i = 1; i <= n; i++) {
    if (find(i) == i) continue;
    vc[find(i)].push_back(i);
  }
  for (int i = q; i >= 1; i--) {
    if (rw[i].opt == 1) continue;
    fx = find(e[rw[i].id].fr);
    fy = find(e[rw[i].id].to);
    if (fx == fy) continue;
    ++tot;
    f[fx] = f[fy] = tot;
    vc[tot].push_back(fx);
    vc[tot].push_back(fy);
    tim[tot] = i;
  }
  for (int i = 1; i <= 2 * n; i++) {
    if (find(i) == i) {
      dfs(i);
    }
  }
  build(1, 1, idc);
  for (int i = 1; i <= q; i++) {
    if (rw[i].opt == 2) continue;
    int u = rw[i].id;
    for (int j = B; j >= 0; j--) {
      if (tim[anc[u][j]] >= i) u = anc[u][j];
    }
    nod tmp = query(1, 1, idc, dfn[u], out[u]);
    modify(1, 1, idc, tmp.pos);
    printf("%d\n", tmp.val);
  }
  return 0;
}
