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 kN = 5e5 + 10;
vector<int> g[kN];
int n, m, q, N;
struct Query {
  int type, x;
} que[kN];
int top[kN];
int val[kN];
int p[kN];
int Find(int x) { return p[x] == x ? x : p[x] = Find(p[x]); }
int in[kN], out[kN], dfs_clock;
int euler[kN];
bool cut[kN];
void Dfs(int u, int fa = 0) {
  in[u] = ++dfs_clock;
  euler[dfs_clock] = u;
  for (int v : g[u])
    if (v != fa) Dfs(v, u);
  out[u] = dfs_clock;
}
int seg[kN << 2], pos[kN << 2];
bool on_top[kN];
void push_up(int o) {
  seg[o] = max(seg[(o << 1)], seg[(o << 1 | 1)]);
  if (seg[(o << 1)] > seg[(o << 1 | 1)])
    pos[o] = pos[(o << 1)];
  else
    pos[o] = pos[(o << 1 | 1)];
}
void Build(int l = 1, int r = N, int o = 1) {
  if (l == r) {
    seg[o] = val[euler[l]];
    pos[o] = l;
    return;
  }
  int m = (l + r) >> 1;
  Build(l, m, (o << 1)), Build(m + 1, r, (o << 1 | 1));
  push_up(o);
}
void Update(int pos, int x, int l = 1, int r = N, int o = 1) {
  if (l == r) {
    seg[o] = x;
    return;
  }
  int m = (l + r) >> 1;
  if (pos <= m)
    Update(pos, x, l, m, (o << 1));
  else
    Update(pos, x, m + 1, r, (o << 1 | 1));
  push_up(o);
}
pair<int, int> Query(int ql, int qr, int l = 1, int r = N, int o = 1) {
  if (ql > r || qr < l) return {-1, -1};
  if (ql <= l && r <= qr) return {seg[o], pos[o]};
  int m = (l + r) >> 1;
  return max(Query(ql, qr, l, m, (o << 1)),
             Query(ql, qr, m + 1, r, (o << 1 | 1)));
}
int main() {
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 1; i <= n; i++) scanf("%d", &val[i]);
  vector<pair<int, int> > edges(m + 1);
  for (int i = 1; i <= m; i++) scanf("%d%d", &edges[i].first, &edges[i].second);
  for (int i = 1; i <= q; i++) scanf("%d%d", &que[i].type, &que[i].x);
  N = n;
  for (int i = 1; i <= 2 * n; i++) p[i] = i;
  for (int i = 1; i <= n; i++) on_top[i] = 1;
  for (int i = 1; i <= q; i++) {
    auto [type, u] = que[i];
    if (type == 2) cut[u] = 1;
  }
  for (int i = 1; i <= m; i++) {
    if (!cut[i]) {
      auto [a, b] = edges[i];
      N++;
      p[a] = N, p[b] = N;
      on_top[a] = on_top[b] = 0;
      on_top[N] = 1;
      g[N].push_back(a), g[N].push_back(b);
    }
  }
  for (int i = q; i >= 1; i--) {
    auto [type, u] = que[i];
    if (que[i].type == 1) {
      top[i] = Find(u);
    } else {
      auto [a, b] = edges[u];
      a = Find(a), b = Find(b);
      if (a == b) continue;
      N++;
      p[a] = N, p[b] = N;
      on_top[a] = on_top[b] = 0;
      on_top[N] = 1;
      g[N].push_back(a), g[N].push_back(b);
    }
  }
  N++;
  for (int i = 1; i < N; i++)
    if (on_top[i]) g[N].push_back(i);
  Dfs(N);
  Build();
  for (int i = 1; i <= q; i++)
    if (que[i].type == 1) {
      int x = top[i];
      auto [v, id] = Query(in[x], out[x]);
      printf("%d\n", v);
      Update(id, 0);
    }
  return 0;
}
