#include <bits/stdc++.h>
using namespace std;
const int64_t M1 = 998244353;
const int64_t M2 = 1000000007;
mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());
vector<vector<int64_t>> node(600001);
vector<int64_t> root(600001), in(600001), out(600001), a;
int64_t n, time_stamp = 0;
int64_t get_root(int64_t u) {
  return (u == root[u] ? u : (root[u] = get_root(root[u])));
}
void merge(int64_t u, int64_t v) {
  u = get_root(u);
  v = get_root(v);
  if (u == v) return;
  root[n] = n;
  root[u] = n;
  root[v] = n;
  node[n].push_back(u);
  node[n].push_back(v);
  a.push_back(0);
  n++;
}
class seg_tree {
  int64_t n;
  vector<tuple<int64_t, int64_t>> tree;

 public:
  seg_tree(int64_t _n) : n(_n) {
    tree.resize(4 * n + 11, tuple<int64_t, int64_t>(0, 0));
  }
  void upd(int64_t n, int64_t s, int64_t e, int64_t i,
           tuple<int64_t, int64_t> x) {
    if (s == e) {
      tree[n] = x;
    } else {
      int64_t m = (s + e) >> 1;
      if (i <= m) {
        upd(n << 1, s, m, i, x);
      } else {
        upd(n << 1 | 1, m + 1, e, i, x);
      }
      tree[n] = max(tree[n << 1], tree[n << 1 | 1]);
    }
  }
  void upd(int64_t i, tuple<int64_t, int64_t> x) {
    if (i < 1 || i > n) return;
    upd(1, 1, n, i, x);
  }
  tuple<int64_t, int64_t> get_sum(int64_t n, int64_t s, int64_t e, int64_t l,
                                  int64_t r) {
    if (s > e || s > r || e < l) return tuple<int64_t, int64_t>(0, 0);
    if (l <= s && e <= r) return tree[n];
    int64_t m = (s + e) >> 1;
    return max(get_sum(n << 1, s, m, l, r),
               get_sum(n << 1 | 1, m + 1, e, l, r));
  }
  tuple<int64_t, int64_t> get_sum(int64_t l, int64_t r) {
    if (l > r) {
      return tuple<int64_t, int64_t>(0, 0);
    } else {
      return get_sum(1, 1, n, l, r);
    }
  }
};
void dfs(int64_t u) {
  in[u] = ++time_stamp;
  for (int64_t v : node[u]) dfs(v);
  out[u] = time_stamp;
}
void solve() {
  int64_t m, q;
  cin >> n >> m >> q;
  vector<int64_t> good(m, 1), ty(q), ui(q);
  a.resize(n);
  vector<tuple<int64_t, int64_t>> edges;
  for (int64_t &i : a) cin >> i;
  for (int64_t i = 0; i < m; i++) {
    int64_t u, v;
    cin >> u >> v;
    edges.push_back({--u, --v});
  }
  for (int64_t i = 0; i < q; i++) {
    cin >> ty[i] >> ui[i];
    ui[i]--;
    if (ty[i] == 2) {
      good[ui[i]] = 0;
    }
  }
  for (int64_t i = 0; i < n; i++) root[i] = i;
  for (int64_t i = 0; i < m; i++) {
    if (good[i]) {
      merge(get<0>(edges[i]), get<1>(edges[i]));
    }
  }
  for (int64_t i = q - 1; ~i; --i) {
    if (ty[i] == 2) {
      merge(get<0>(edges[ui[i]]), get<1>(edges[ui[i]]));
    } else {
      ui[i] = get_root(ui[i]);
    }
  }
  for (int64_t i = 0; i < n; i++) {
    if (i == get_root(i)) dfs(i);
  }
  seg_tree tree(time_stamp);
  for (int64_t i = 0; i < n; i++) {
    tree.upd(in[i], tuple<int64_t, int64_t>(a[i], in[i]));
  }
  for (int64_t i = 0; i < q; i++) {
    int64_t u, v;
    if (ty[i] == 1) {
      tie(u, v) = tree.get_sum(in[ui[i]], out[ui[i]]);
      cout << u << "\n";
      tree.upd(v, tuple<int64_t, int64_t>(0, 0));
    }
  }
}
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  solve();
}
