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 MAX = 4e5 + 9;
int n, p[MAX / 2], idx[MAX], node[(int)5e5 + 9];
vector<int> adj[MAX];
pair<int, int> qu[(int)5e5 + 9], edges[(int)3e5 + 9];
bool vis[(int)3e5 + 9];
int par[MAX];
int dfsCnt, euler[MAX], rangeStart[MAX], rangeEnd[MAX];
int tree[(MAX << 2)];
int FindSet(int node) {
  if (par[node] == node) {
    return node;
  }
  return par[node] = FindSet(par[node]);
}
void MergeNodes(int u, int v) {
  int parU = FindSet(u), parV = FindSet(v);
  ++n;
  adj[n].push_back(parU);
  adj[n].push_back(parV);
  par[parU] = par[parV] = n;
}
void Initialize() {
  for (int i = 1; i < MAX; ++i) {
    par[i] = i;
  }
}
void DFS(int cur, int parent = -1) {
  vis[cur] = 1;
  ++dfsCnt;
  (cur <= n ? euler[dfsCnt] = p[cur] : euler[dfsCnt] = 0);
  rangeStart[cur] = dfsCnt;
  for (int i = 0; i < adj[cur].size(); ++i) {
    int child = adj[cur][i];
    if (child != parent) {
      DFS(child, cur);
    }
  }
  rangeEnd[cur] = dfsCnt;
}
void Build(int low, int high, int pos) {
  if (low == high) {
    tree[pos] = euler[low];
    return;
  }
  int mid = ((low + high) >> 1);
  Build(low, mid, (pos << 1));
  Build(mid + 1, high, (pos << 1 | 1));
  tree[pos] = max(tree[(pos << 1)], tree[(pos << 1 | 1)]);
}
int Query(int low, int high, int pos, int L, int R) {
  if (L > high || R < low) {
    return 0;
  }
  if (L <= low && R >= high) {
    return tree[pos];
  }
  int mid = ((low + high) >> 1);
  return max(Query(low, mid, (pos << 1), L, R),
             Query(mid + 1, high, (pos << 1 | 1), L, R));
}
void Update(int low, int high, int pos, int index) {
  if (low == high) {
    tree[pos] = 0;
    return;
  }
  int mid = ((low + high) >> 1);
  if (index <= mid)
    Update(low, mid, (pos << 1), index);
  else
    Update(mid + 1, high, (pos << 1 | 1), index);
  tree[pos] = max(tree[(pos << 1)], tree[(pos << 1 | 1)]);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int m, q;
  cin >> n >> m >> q;
  for (int i = 1; i <= n; ++i) {
    cin >> p[i];
    idx[p[i]] = i;
  }
  for (int i = 1; i <= m; ++i) {
    cin >> edges[i].first >> edges[i].second;
  }
  for (int i = 1; i <= q; ++i) {
    cin >> qu[i].first >> qu[i].second;
    if (qu[i].first == 2) {
      vis[qu[i].second] = 1;
    }
  }
  Initialize();
  for (int i = 1; i <= m; ++i) {
    if (!vis[i]) {
      MergeNodes(edges[i].first, edges[i].second);
    }
  }
  for (int i = q; i >= 1; --i) {
    if (qu[i].first == 1) {
      node[i] = FindSet(qu[i].second);
    } else {
      MergeNodes(edges[qu[i].second].first, edges[qu[i].second].second);
    }
  }
  for (int i = 1; i <= n; ++i) {
    vis[i] = 0;
  }
  DFS(n);
  Build(1, dfsCnt, 1);
  for (int i = 1; i <= q; ++i) {
    if (qu[i].first == 1) {
      int ans = Query(1, dfsCnt, 1, rangeStart[node[i]], rangeEnd[node[i]]);
      cout << ans << "\n";
      if (ans) {
        Update(1, dfsCnt, 1, rangeStart[idx[ans]]);
      }
    }
  }
  return 0;
}
