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;
inline int read() {
  int w = 0, x = 0;
  char c = getchar();
  while (!isdigit(c)) w |= c == '-', c = getchar();
  while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar();
  return w ? -x : x;
}
namespace star {
const int maxn = 2e5, maxm = 3e5, maxq = 5e5 + 10;
int n, m, Q, hd[maxn], nxt[maxn], ed[maxn], pre[maxn], fa[maxn], a[maxn],
    rk[maxn], dfn[maxn];
struct edge {
  int u, v, t;
  inline bool operator<(const edge &zp) const { return t < zp.t; }
} e[maxm];
struct query {
  int op, x, l, r;
} q[maxq];
struct SegmentTree {
  int val[maxn << 2], id[maxn << 2];
  inline void pushup(const int &ro) {
    if (val[(ro << 1)] >= val[(ro << 1 | 1)])
      val[ro] = val[(ro << 1)], id[ro] = id[(ro << 1)];
    else
      val[ro] = val[(ro << 1 | 1)], id[ro] = id[(ro << 1 | 1)];
  }
  void build(const int &ro = 1, const int &l = 1, const int &r = n) {
    if (l == r) return val[ro] = a[rk[l]], id[ro] = l, void();
    build((ro << 1), l, ((l + r) >> 1)),
        build((ro << 1 | 1), ((l + r) >> 1) + 1, r);
    pushup(ro);
  }
  pair<int, int> query(const int &x, const int &y, const int &ro = 1,
                       const int &l = 1, const int &r = n) {
    if (l == x and r == y) return make_pair(val[ro], id[ro]);
    if (y <= ((l + r) >> 1))
      return query(x, y, (ro << 1), l, ((l + r) >> 1));
    else if (x > ((l + r) >> 1))
      return query(x, y, (ro << 1 | 1), ((l + r) >> 1) + 1, r);
    return max(
        query(x, ((l + r) >> 1), (ro << 1), l, ((l + r) >> 1)),
        query(((l + r) >> 1) + 1, y, (ro << 1 | 1), ((l + r) >> 1) + 1, r));
  }
  void update(const int &x, const int &ro = 1, const int &l = 1,
              const int &r = n) {
    if (l == r) return val[ro] = 0, void();
    (x <= ((l + r) >> 1)) ? update(x, (ro << 1), l, ((l + r) >> 1))
                          : update(x, (ro << 1 | 1), ((l + r) >> 1) + 1, r);
    pushup(ro);
  }
} T;
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
inline void work() {
  n = read(), m = read(), Q = read();
  for (int i = 1; i <= n; i++) a[i] = read(), fa[i] = hd[i] = ed[i] = i;
  for (int i = 1; i <= m; i++) e[i].u = read(), e[i].v = read(), e[i].t = Q + 1;
  for (int i = 1; i <= Q; i++) q[i].op = read() - 1, q[i].x = read();
  for (int i = 1; i <= Q; i++)
    if (q[i].op) e[q[i].x].t = i;
  sort(e + 1, e + 1 + m);
  int tmp = Q;
  for (int i = m; i; i--) {
    for (; tmp >= e[i].t; tmp--) {
      if (q[tmp].op) continue;
      int x = find(q[tmp].x);
      q[tmp].l = hd[x], q[tmp].r = ed[x];
    }
    int x = find(e[i].u), y = find(e[i].v);
    if (x == y) continue;
    nxt[ed[x]] = hd[y];
    pre[hd[y]] = ed[x];
    fa[x] = y, hd[y] = hd[x];
  }
  for (; tmp; tmp--) {
    if (q[tmp].op) continue;
    int x = find(q[tmp].x);
    q[tmp].l = hd[x], q[tmp].r = ed[x];
  }
  for (int i = 1; i <= n; i++)
    if (!pre[i])
      for (int j = i; j; j = nxt[j]) rk[dfn[j] = ++dfn[0]] = j;
  T.build();
  for (int i = 1; i <= Q; i++) {
    if (q[i].op) continue;
    pair<int, int> res = T.query(dfn[q[i].l], dfn[q[i].r]);
    printf("%d\n", res.first);
    T.update(res.second);
  }
}
}  // namespace star
signed main() {
  star::work();
  return 0;
}
