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 mxn = 1e5 + 5;
const int inf = 1e9;
int p[mxn];
int L[mxn], R[mxn];
bool usd[mxn];
int tp[mxn], id[mxn];
struct reachability_tree {
  int parent[mxn];
  int sz[mxn];
  int in[mxn], out[mxn], id[mxn];
  int pc[mxn];
  vector<int> g[mxn];
  vector<int> w[mxn];
  int T = 0;
  void init(int n) {
    for (int i = 1; i <= n; i++) {
      parent[i] = i;
      sz[i] = 1;
    }
  }
  int findrep(int u) { return parent[u] == u ? u : findrep(parent[u]); }
  void unite(int u, int v, int cst) {
    u = findrep(u);
    v = findrep(v);
    if (u == v) return;
    if (sz[u] > sz[v]) swap(u, v);
    parent[u] = v;
    sz[v] += sz[u];
    g[v].push_back(u);
    w[v].push_back(cst);
    pc[u] = cst;
  }
  void dfs(int u) {
    in[u] = ++T;
    id[T] = u;
    for (int v : g[u]) {
      dfs(v);
    }
    out[u] = T;
  }
  pair<int, int> range(int u, int tm) {
    while (parent[u] != u && pc[u] >= tm) u = parent[u];
    int p = upper_bound(w[u].begin(), w[u].end(), tm,
                        [](int a, int b) { return a > b; }) -
            w[u].begin();
    if (p == 0) {
      return {in[u], in[u]};
    }
    int v = g[u][p - 1];
    return {in[u], out[v]};
  }
} rt;
struct segtree {
  pair<int, int> tree[4 * mxn];
  void update(int node, int b, int e, int p, int v) {
    if (e < p || b > p) return;
    if (b == e) {
      tree[node] = {v, b};
      return;
    }
    int mid = b + e >> 1;
    int left = node << 1;
    int right = left | 1;
    update(left, b, mid, p, v);
    update(right, mid + 1, e, p, v);
    tree[node] = max(tree[left], tree[right]);
  }
  pair<int, int> query(int node, int b, int e, int l, int r) {
    if (b > l || e < r) return {0, 0};
    if (b >= l && e <= r) return tree[node];
    int mid = b + e >> 1;
    int left = node << 1;
    int right = left | 1;
    return max(query(left, b, mid, l, r), query(right, mid + 1, e, l, r));
  }
} st;
int main() {
  int n, m, q;
  cin >> n >> m >> q;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &p[i]);
  }
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &L[i], &R[i]);
  }
  for (int i = 1; i <= q; i++) {
    scanf("%d %d", &tp[i], &id[i]);
    if (tp[i] == 2) usd[id[i]] = true;
  }
  rt.init(n);
  for (int i = 1; i <= m; i++) {
    if (!usd[i]) rt.unite(L[i], R[i], inf);
  }
  for (int i = q; i > 0; i--) {
    if (tp[i] == 2) rt.unite(L[i], R[i], i);
  }
  for (int i = 1; i <= n; i++)
    if (rt.findrep(i) == i) rt.dfs(i);
  for (int i = 1; i <= n; i++) {
    st.update(1, 1, n, rt.id[i], p[i]);
  }
  bool dn[mxn];
  for (int i = 1; i <= q; i++) {
    if (tp[i] == 1) {
      pair<int, int> rg = rt.range(id[i], i);
      pair<int, int> x = st.query(1, 1, n, rg.first, rg.second);
      if (x.first == 0) {
        printf("0\n");
      } else {
        printf("%d\n", x.first);
        if (dn[x.second]) continue;
        st.update(1, 1, n, x.second, 0);
      }
    }
  }
}
