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 NMAX = 2e5;
const int MMAX = 3e5;
const int QMAX = 5e5;
int n, N, M, Q;
int p[NMAX + 2];
pair<int, int> edges[MMAX + 2];
set<int> edgesSet;
struct Query {
  int type, x;
};
Query qr[QMAX + MMAX + 2];
int dad[NMAX + MMAX + 2], boss[QMAX + 2];
vector<int> g[NMAX + MMAX + 2];
int Root(int node) {
  if (node == dad[node]) return node;
  return dad[node] = Root(dad[node]);
}
void join(int p, int q) {
  p = Root(p);
  q = Root(q);
  if (p != q) {
    ++N;
    dad[p] = N;
    dad[q] = N;
    g[N].push_back(p);
    g[N].push_back(q);
  }
}
bool vis[NMAX + MMAX + 2];
vector<int> eulerTour;
int lf[NMAX + MMAX + 2], rg[NMAX + MMAX + 2];
void dfs(int node) {
  vis[node] = true;
  eulerTour.push_back(node);
  lf[node] = (int)eulerTour.size();
  for (auto it : g[node]) dfs(it);
  rg[node] = (int)eulerTour.size();
}
struct Aint {
  int v[4 * (NMAX + MMAX)];
  int p[4 * (NMAX + MMAX)];
  void Update(int node, int st, int dr, int pos, int val) {
    if (st == dr) {
      v[node] = val;
      p[node] = pos;
      return;
    }
    int mid = (st + dr) >> 1;
    if (pos <= mid)
      Update(2 * node, st, mid, pos, val);
    else
      Update(2 * node + 1, mid + 1, dr, pos, val);
    if (v[2 * node] > v[2 * node + 1])
      v[node] = v[2 * node], p[node] = p[2 * node];
    else
      v[node] = v[2 * node + 1], p[node] = p[2 * node + 1];
  }
  pair<int, int> Query(int node, int st, int dr, int l, int r) {
    if (l <= st && dr <= r) return {v[node], p[node]};
    if (r < st || dr < l) return {-1, -1};
    int mid = (st + dr) >> 1;
    pair<int, int> a1 = Query(2 * node, st, mid, l, r);
    pair<int, int> a2 = Query(2 * node + 1, mid + 1, dr, l, r);
    if (a1.first > a2.first) return a1;
    return a2;
  }
};
Aint aint;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> M >> Q;
  for (int i = 1; i <= n; i++) cin >> p[i];
  N = n;
  for (int i = 1; i <= M; i++) {
    int x, y;
    cin >> x >> y;
    edges[i] = {x, y};
    edgesSet.insert(i);
  }
  for (int i = 1; i <= Q; i++) {
    int t, x;
    cin >> t >> x;
    qr[i] = {t, x};
    if (t == 2) edgesSet.erase(x);
  }
  while (!edgesSet.empty()) {
    int edg = *edgesSet.begin();
    edgesSet.erase(edg);
    qr[++Q] = {2, edg};
  }
  for (int i = 1; i <= N + M; i++) dad[i] = i;
  for (int i = Q; i >= 1; i--) {
    if (qr[i].type == 2) {
      int edg = qr[i].x;
      join(edges[edg].first, edges[edg].second);
    } else
      boss[i] = Root(qr[i].x);
  }
  for (int i = N; i >= 1; i--)
    if (!vis[i]) dfs(i);
  for (int i = 1; i <= n; i++) aint.Update(1, 1, N, lf[i], p[i]);
  for (int i = 1; i <= Q; i++) {
    if (qr[i].type == 2) continue;
    pair<int, int> res = aint.Query(1, 1, N, lf[boss[i]], rg[boss[i]]);
    cout << res.first << '\n';
    aint.Update(1, 1, N, res.second, 0);
  }
  return 0;
}
