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;
int F[500007], n, Fat[500007];
bool valid_edges[300007], query_node[500007];
int Find(int a) { return (a == Fat[a] ? a : Fat[a] = Find(Fat[a])); }
void Union(int a, int b) {
  a = Find(a);
  b = Find(b);
  if (!query_node[b]) {
    F[a] = b;
    Fat[a] = b;
  } else if (!query_node[a]) {
    F[b] = a;
    Fat[b] = a;
  } else {
    F[a] = F[b] = ++n;
    Fat[a] = Fat[b] = n;
    F[n] = n;
    Fat[n] = n;
  }
}
vector<int> G[500007];
int poczatek_poddrzewa[500007], koniec_poddrzewa[500007], nr = 0, order[500007];
bool visited[500007];
void DFS(int v) {
  visited[v] = true;
  poczatek_poddrzewa[v] = ++nr;
  order[nr] = v;
  for (auto i : G[v])
    if (!visited[i]) DFS(i);
  koniec_poddrzewa[v] = nr;
}
void zrob_drzewo_find_and_union() {
  for (int i = 1; i <= n; i++)
    if (i != F[i]) {
      G[i].push_back(F[i]);
      G[F[i]].push_back(i);
    }
  for (int i = 1; i <= n; i++)
    if (visited[i] == false && F[i] == i) DFS(i);
}
int wartosc[500007], tree[1 << 20], M = 1;
void zbuduj_drzewo_przedzialowe() {
  while (M < n) M *= 2;
  for (int i = 1; i <= n; i++) tree[i + M - 1] = wartosc[order[i]];
  for (int i = M - 1; i > 0; i--) tree[i] = max(tree[i * 2], tree[i * 2 + 1]);
}
bool valid_number[200007];
void remove_invalid(int v) {
  if (valid_number[tree[v]] == true) return;
  tree[v] = 0;
  if (v >= M) return;
  remove_invalid(v * 2);
  remove_invalid(v * 2 + 1);
  tree[v] = max(tree[v * 2], tree[v * 2 + 1]);
}
int maks(int a, int b, int v = 1, int p = 1, int k = M) {
  if (p > b || k < a) return 0;
  if (p >= a && k <= b) {
    remove_invalid(v);
    return tree[v];
  }
  return max(maks(a, b, v * 2, p, (p + k) / 2),
             maks(a, b, v * 2 + 1, (p + k) / 2 + 1, k));
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int m, q;
  cin >> n >> m >> q;
  n = n;
  for (int i = 1, a; i <= n; i++) {
    cin >> wartosc[i];
    valid_number[wartosc[i]] = true;
    F[i] = i;
    Fat[i] = i;
  }
  vector<pair<int, int>> edges(m + 1);
  for (int i = 1; i <= m; i++) {
    cin >> edges[i].first >> edges[i].second;
    valid_edges[i] = true;
  }
  vector<pair<int, int>> queries(q);
  for (int i = 0; i < q; i++) {
    cin >> queries[i].first >> queries[i].second;
    if (queries[i].first == 2) valid_edges[queries[i].second] = false;
  }
  for (int i = 1; i <= m; i++)
    if (valid_edges[i]) Union(edges[i].first, edges[i].second);
  int Res[q];
  for (int i = q - 1; i >= 0; i--) {
    if (queries[i].first == 1) {
      int v = queries[i].second;
      v = Find(v);
      Res[i] = v;
      query_node[v] = true;
    } else {
      int j = queries[i].second;
      int a = edges[j].first, b = edges[j].second;
      Union(a, b);
    }
  }
  zrob_drzewo_find_and_union();
  zbuduj_drzewo_przedzialowe();
  cout << '\n';
  for (int i = 0; i < q; i++) {
    if (queries[i].first == 2) continue;
    int v = Res[i];
    int res = maks(poczatek_poddrzewa[v], koniec_poddrzewa[v]);
    cout << res << '\n';
    valid_number[res] = false;
    valid_number[0] = true;
  }
}
