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;
int t, n, m, Q;
int p[maxn + 5];
struct E {
  int u, v;
} e[maxn + 5];
struct Que {
  int typ, x;
} q[maxn + 5];
bool used[maxn + 5];
int tot;
int head[maxn + 5], ek;
struct Edge {
  int to, nxt;
} edge[maxn * 2 + 5];
void readn(int &num) {
  char c = getchar();
  while (c < '0' || c > '9') c = getchar();
  for (num = 0; c >= '0' && c <= '9'; num = num * 10 + c - '0', c = getchar())
    ;
}
void Connect(int u, int v) {
  ek++;
  edge[ek] = Edge{v, head[u]};
  head[u] = ek;
}
namespace Uif {
int f[maxn + 5];
void pre_f() {
  for (int i = 1; i <= n; i++) f[i] = i;
}
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
void uni(int u, int v) {
  int fu = find(u), fv = find(v);
  if (fu == fv) return;
  tot++;
  f[tot] = tot;
  f[fu] = f[fv] = tot;
  Connect(tot, fu);
  Connect(tot, fv);
}
}  // namespace Uif
using namespace Uif;
namespace Segtr {
struct Tr {
  int iv, v;
} tr[maxn * 4 + 5];
Tr mx(Tr ta, Tr tb) { return ta.v > tb.v ? ta : tb; }
void add(int l, int r, int st, int da, int id) {
  if (l == r) {
    tr[id] = Tr{st, da};
    return;
  }
  int mid = (l + r) >> 1;
  if (st <= mid)
    add(l, mid, st, da, id << 1);
  else
    add(mid + 1, r, st, da, id << 1 | 1);
  tr[id] = mx(tr[id << 1], tr[id << 1 | 1]);
}
Tr query(int l, int r, int st, int en, int id) {
  if (st <= l && en >= r) return tr[id];
  int mid = (l + r) >> 1;
  Tr ans = Tr{0, 1 << 31};
  if (st <= mid) ans = mx(ans, query(l, mid, st, en, id << 1));
  if (en > mid) ans = mx(ans, query(mid + 1, r, st, en, id << 1 | 1));
  return ans;
}
}  // namespace Segtr
using namespace Segtr;
int dfn[maxn + 5], l[maxn + 5], r[maxn + 5], dfns;
void dfs(int u) {
  dfn[++dfns] = u;
  l[u] = dfns;
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    dfs(v);
  }
  r[u] = dfns;
}
void init() {
  readn(n);
  readn(m);
  readn(Q);
  for (int i = 1; i <= n; i++) readn(p[i]);
  for (int i = 1; i <= m; i++) {
    readn(e[i].u);
    readn(e[i].v);
  }
  for (int i = 1; i <= Q; i++) {
    readn(q[i].typ);
    readn(q[i].x);
    if (q[i].typ == 2) used[q[i].x] = 1;
  }
  tot = n;
  pre_f();
  for (int i = 1; i <= m; i++)
    if (!used[i]) uni(e[i].u, e[i].v);
  for (int i = Q; i; i--)
    if (q[i].typ == 2)
      uni(e[q[i].x].u, e[q[i].x].v);
    else
      q[i].x = find(q[i].x);
  dfns = 0;
  for (int i = 1; i <= tot; i++)
    if (find(i) == i) dfs(i);
  for (int i = 1; i <= tot; i++) {
    int tmp = i <= n ? p[i] : 0;
    add(1, tot, l[i], tmp, 1);
  }
}
int main() {
  Tr ans;
  init();
  for (int i = 1; i <= Q; i++)
    if (q[i].typ == 1) {
      ans = query(1, tot, l[q[i].x], r[q[i].x], 1);
      printf("%d\n", ans.v);
      add(1, tot, ans.iv, 0, 1);
    }
  return 0;
}
