#include <bits/stdc++.h>
using namespace std;
int n, F[500007], wartosc[500007], Fat[500007];
bool valid_number[500007], valid_edges[300007], query_node[500007];
int Find(int a) { return (a == Fat[a] ? a : Fat[a] = Find(Fat[a])); }
inline void Union(int a, int b) {
  a = Find(a);
  b = Find(b);
  F[a] = F[b] = ++n;
  Fat[a] = Fat[b] = F[n] = Fat[n] = n;
}
vector<int> G[500007];
int pre[500007], pos[500007], order[500007], nr;
bool visited[500007];
void DFS(int v) {
  visited[v] = 1;
  pre[v] = ++nr;
  order[nr] = v;
  for (auto i : G[v])
    if (!visited[i]) DFS(i);
  pos[v] = nr;
}
int tree[1 << 20], M = 1;
inline void zrob_drzewa() {
  for (int i = 1; i <= n; i++)
    if (F[i] != i) {
      G[i].push_back(F[i]);
      G[F[i]].push_back(i);
    }
  for (int i = 1; i <= n; i++)
    if (F[i] == i) DFS(i);
  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]);
}
void remove_invalid(int v) {
  if (valid_number[tree[v]]) 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;
    } else {
      int j = queries[i].second;
      int a = edges[j].first, b = edges[j].second;
      Union(a, b);
    }
  }
  zrob_drzewa();
  for (int i = 0; i < q; i++) {
    if (queries[i].first == 2) continue;
    int v = Res[i];
    int res = maks(pre[v], pos[v]);
    cout << res << '\n';
    valid_number[res] = false;
    valid_number[0] = true;
  }
}
