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 = 2e5;
const int MAXM = 3e5;
const int MAXQ = 5e5;
int N, M, Q, p[MAXN], st[MAXN], par[MAXN], sz[MAXN], dist[MAXN];
pair<int, int> edges[MAXM], queries[MAXQ], t[4 * MAXN];
bool del[MAXM], useful[MAXM];
vector<pair<int, int> > moves;
int getIndex(int p) {
  if (par[p] != p) {
    return getIndex(par[p]) + dist[p];
  }
  return dist[p];
}
int find(int p) {
  while (p != par[p]) p = par[p];
  return p;
}
bool merge(int p, int q) {
  int rootP = find(p);
  int rootQ = find(q);
  if (rootP == rootQ) {
    return false;
  }
  if (sz[rootP] < sz[rootQ]) {
    par[rootP] = rootQ;
    dist[rootP] += sz[rootQ];
    sz[rootQ] += sz[rootP];
    moves.push_back(make_pair(rootQ, rootP));
  } else {
    par[rootQ] = rootP;
    dist[rootQ] += sz[rootP];
    sz[rootP] += sz[rootQ];
    moves.push_back(make_pair(rootP, rootQ));
  }
  return true;
}
void undo() {
  pair<int, int> act = moves.back();
  moves.pop_back();
  par[act.second] = act.second;
  sz[act.first] -= sz[act.second];
}
void update(int v, int tl, int tr, int index, int val) {
  if (tl == tr) {
    t[v] = make_pair(val, tl);
  } else {
    int tm = (tl + tr) / 2;
    if (index <= tm)
      update(2 * v, tl, tm, index, val);
    else
      update(2 * v + 1, tm + 1, tr, index, val);
    t[v] = max(t[2 * v], t[2 * v + 1]);
  }
}
pair<int, int> getMx(int v, int tl, int tr, int l, int r) {
  if (l > r) return make_pair(0, -1);
  if (tl == l && tr == r) return t[v];
  int tm = (tl + tr) / 2;
  return max(getMx(2 * v, tl, tm, l, min(r, tm)),
             getMx(2 * v + 1, tm + 1, tr, max(l, tm + 1), r));
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> N >> M >> Q;
  for (int i = 0; i < N; i++) {
    cin >> p[i];
  }
  for (int i = 0; i < N; i++) {
    sz[i] = 1;
    par[i] = i;
    dist[i] = 0;
  }
  for (int i = 0; i < M; i++) {
    cin >> edges[i].first >> edges[i].second;
    edges[i].first--;
    edges[i].second--;
  }
  for (int i = 0; i < Q; i++) {
    cin >> queries[i].first >> queries[i].second;
    queries[i].second--;
    if (queries[i].first == 2) {
      del[queries[i].second] = true;
    }
  }
  for (int i = 0; i < M; i++) {
    if (!del[i]) {
      merge(edges[i].first, edges[i].second);
    }
  }
  for (int i = Q - 1; i >= 0; i--) {
    if (queries[i].first == 2) {
      useful[queries[i].second] = merge(edges[queries[i].second].first,
                                        edges[queries[i].second].second);
    }
  }
  int c = 0;
  for (int i = 1; i < N; i++) {
    c += merge(0, i);
  }
  for (int i = 0; i < N; i++) {
    st[i] = getIndex(i);
    update(1, 0, N - 1, st[i], p[i]);
  }
  while (c != 0) {
    undo();
    c--;
  }
  for (int i = 0; i < Q; i++) {
    if (queries[i].first == 1) {
      int r = find(queries[i].second);
      pair<int, int> ans = getMx(1, 0, N - 1, st[r], st[r] + sz[r] - 1);
      cout << ans.first << "\n";
      if (ans.first != 0) update(1, 0, N - 1, ans.second, 0);
    } else if (useful[queries[i].second]) {
      undo();
    }
  }
}
