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 N = 2e5 + 5;
int n, m, q, p[2 * N];
vector<int> g[N];
int inb[2 * N], st[2 * N], en[2 * N], ti;
struct Query {
  int x, y;
};
int uf[2 * N];
void init() { memset(uf, -1, sizeof(uf)); }
int last;
int find(int x) { return uf[x] < 0 ? x : uf[x] = find(uf[x]); }
bool join(int x, int y) {
  x = find(x), y = find(y);
  if (x == y) return false;
  uf[x] = uf[y] = last;
  g[last].push_back(x);
  g[last].push_back(y);
  inb[y] = 1, inb[x] = 1;
  last++;
  return true;
}
void dfs(int x) {
  st[x] = ti++;
  for (auto v : g[x]) dfs(v);
  en[x] = ti;
}
struct STree {
  vector<pair<int, int> > st;
  int n;
  STree(int n) : st(4 * n + 5, {0, -1}), n(n) {}
  void upd(int k, int s, int e, int p, pair<int, int> v) {
    if (s + 1 == e) {
      st[k] = v;
      return;
    }
    int m = (s + e) / 2;
    if (p < m)
      upd(2 * k, s, m, p, v);
    else
      upd(2 * k + 1, m, e, p, v);
    st[k] = max(st[2 * k], st[2 * k + 1]);
  }
  pair<int, int> query(int k, int s, int e, int a, int b) {
    if (s >= b || e <= a) return {0, -1};
    if (s >= a && e <= b) return st[k];
    int m = (s + e) / 2;
    return max(query(2 * k, s, m, a, b), query(2 * k + 1, m, e, a, b));
  }
  void upd(int p, pair<int, int> v) { upd(1, 0, n, p, v); }
  pair<int, int> query(int a, int b) { return query(1, 0, n, a, b); }
};
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> q;
  for (int i = 0; i < n; i++) cin >> p[i];
  vector<pair<int, int> > edges;
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    edges.push_back({x, y});
  }
  vector<Query> queries;
  bool deleted[m];
  for (int i = 0; i < q; i++) {
    int x, y;
    cin >> x >> y;
    y--;
    queries.push_back({x, y});
    if (x == 2) deleted[y] = 1;
  }
  init();
  last = n;
  for (int i = 0; i < m; i++)
    if (!deleted[i]) join(edges[i].first, edges[i].second);
  for (int i = q - 1; i >= 0; i--) {
    if (queries[i].x == 1)
      queries[i].y = find(queries[i].y);
    else
      join(edges[queries[i].y].first, edges[queries[i].y].second);
  }
  for (int i = 0; i < last; i++)
    if (!inb[i]) dfs(i);
  STree rmq(last);
  for (int i = 0; i < last; i++) rmq.upd(st[i], {p[i], i});
  for (int i = 0; i < q; i++)
    if (queries[i].x == 1) {
      int k = queries[i].y;
      auto r = rmq.query(st[k], en[k]);
      rmq.upd(st[r.second], {0, r.second});
      cout << r.first << '\n';
    }
  return 0;
}
