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 N = 2e5 + 10, inf = 0x3f3f3f3f;
using std::make_pair;
using std::pair;
using std::vector;
int n, m, q, p[N], f[N * 2], fa[N * 2][19], mn[N * 2], mx[N * 2], rdfn[N],
    val[N * 2], cnt;
pair<int, pair<int, int> > g[N * 3];
pair<int, int> c[N * 3];
vector<int> v[N * 2];
struct SegmentTree {
  int mx[N * 4], pos[N * 4];
  inline int ls(int k) { return k << 1; }
  inline int rs(int k) { return k << 1 | 1; }
  void up(int k) {
    if (mx[ls(k)] > mx[rs(k)]) {
      pos[k] = pos[ls(k)];
      mx[k] = mx[ls(k)];
    } else {
      pos[k] = pos[rs(k)];
      mx[k] = mx[rs(k)];
    }
  }
  void modify(int k, int pos, int L, int R) {
    if (L == R) {
      mx[k] = 0;
      return;
    }
    int mid(L + R >> 1);
    if (pos <= mid)
      modify(ls(k), pos, L, mid);
    else
      modify(rs(k), pos, mid + 1, R);
    return up(k);
  }
  pair<int, int> query(int k, int L, int R, int nL, int nR) {
    if (nL <= L && R <= nR) {
      return make_pair(mx[k], pos[k]);
    }
    int mid(L + R >> 1);
    pair<int, int> ans(0, 0);
    if (nL <= mid) ans = query(ls(k), L, mid, nL, nR);
    if (mid < nR) ans = std::max(query(rs(k), mid + 1, R, nL, nR), ans);
    return ans;
  }
  void Build(int k, int L, int R) {
    if (L == R) {
      mx[k] = p[rdfn[L]];
      pos[k] = L;
      return;
    }
    int mid(L + R >> 1);
    Build(ls(k), L, mid);
    Build(rs(k), mid + 1, R);
    return up(k);
  }
} SingerCoder;
int find(int x) { return x ^ f[x] ? f[x] = find(f[x]) : x; }
void Dfs(int u) {
  if (u <= n) {
    rdfn[mn[u] = mx[u] = ++cnt] = u;
    return;
  }
  mn[u] = n + 1;
  for (vector<int>::iterator it = v[u].begin(); it != v[u].end(); ++it) {
    Dfs(*it);
    mx[u] = std::max(mx[u], mx[*it]);
    mn[u] = std::min(mn[u], mn[*it]);
  }
}
int main() {
  scanf("%d %d %d", &n, &m, &q);
  for (int i = 1; i <= n; ++i) scanf("%d", p + i);
  for (int i = 1; i <= m; ++i)
    scanf("%d %d", &g[i].second.first, &g[i].second.second);
  for (int i = 1; i <= q; ++i) {
    scanf("%d %d", &c[i].first, &c[i].second);
    if (c[i].first == 2) g[c[i].second].first = inf - i - 1;
  }
  for (int i = 2; i < n; ++i) g[++m] = make_pair(inf, make_pair(1, i));
  std::sort(g + 1, g + 1 + m);
  for (int i = 1; i < 2 * n; ++i) f[i] = i;
  int tot = n;
  for (int i = 1; i <= m; ++i) {
    int _x = find(g[i].second.first), _y = find(g[i].second.second);
    if (_x ^ _y) {
      val[fa[_x][0] = fa[_y][0] = f[_x] = f[_y] = ++tot] = g[i].first;
      v[tot].push_back(_x);
      v[tot].push_back(_y);
    }
  }
  for (int i = 1; i <= 18; ++i) {
    for (int j = 1; j <= tot; ++j) fa[j][i] = fa[fa[j][i - 1]][i - 1];
  }
  Dfs(tot);
  SingerCoder.Build(1, 1, n);
  for (int i = 1; i <= q; ++i) {
    if (c[i].first == 1) {
      int v = c[i].second;
      for (int j = 18; ~j; --j)
        if (fa[v][j] && val[fa[v][j]] < inf - i - 1) v = fa[v][j];
      pair<int, int> ans;
      printf("%d\n", (ans = SingerCoder.query(1, 1, n, mn[v], mx[v])).first);
      SingerCoder.modify(1, ans.second, 1, n);
    }
  }
  return 0;
}
