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;
template <typename T>
inline int len(const T &a) {
  return a.size();
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m, q;
  cin >> n >> m >> q;
  vector<int> p(n);
  for (auto &i : p) {
    cin >> i;
  }
  vector<int> parent(n, -1), sz(n, 1);
  vector<pair<int, int>> history;
  vector<set<pair<int, int>>> numbers(n);
  vector<vector<int>> where(n), compo(n);
  for (int i = 0; i < n; ++i) {
    numbers[i].insert({p[i], i});
    where[i].push_back(i);
    compo[i].push_back(i);
  }
  auto root = [&](int v) {
    while (parent[v] != -1) {
      v = parent[v];
    }
    return v;
  };
  auto unite = [&](int v, int u) {
    v = root(v), u = root(u);
    if (v == u) {
      return;
    }
    if (sz[u] > sz[v]) {
      swap(u, v);
    }
    history.push_back({v, u});
    for (auto &val : numbers[u]) {
      numbers[v].insert(val);
    }
    for (auto &x : compo[u]) {
      where[x].push_back(v);
      compo[v].push_back(x);
    }
    sz[v] += sz[u];
    parent[u] = v;
  };
  auto rollback = [&]() {
    assert(!history.empty());
    int v = history.back().first, u = history.back().second;
    sz[v] -= sz[u];
    parent[u] = -1;
    for (auto &val : numbers[u]) {
      numbers[v].erase(val);
    }
    for (auto &x : compo[u]) {
      compo[v].pop_back();
      where[x].pop_back();
    }
    history.pop_back();
  };
  auto query = [&](int v) {
    v = root(v);
    auto best = *numbers[v].rbegin();
    for (auto &roots : where[best.second]) {
      numbers[roots].erase(best);
      numbers[roots].insert({0, best.second});
    }
    return best.first;
  };
  vector<pair<int, int>> edges(m);
  for (int i = 0; i < m; ++i) {
    cin >> edges[i].first >> edges[i].second;
    edges[i].first--;
    edges[i].second--;
  }
  vector<pair<int, int>> qs(q);
  vector<bool> emark(m);
  for (int i = 0; i < q; ++i) {
    cin >> qs[i].first >> qs[i].second;
    qs[i].second--;
    if (qs[i].first == 2) {
      emark[qs[i].second] = true;
    }
  }
  for (int i = 0; i < m; ++i) {
    if (!emark[i]) {
      unite(edges[i].first, edges[i].second);
    }
  }
  for (int i = q - 1; i >= 0; --i) {
    if (qs[i].first == 2) {
      int e = qs[i].second;
      unite(edges[e].first, edges[e].second);
    }
  }
  for (int i = 0; i < q; ++i) {
    if (qs[i].first == 1) {
      cout << query(qs[i].second) << '\n';
    } else {
      rollback();
    }
  }
  return 0;
}
