#include <bits/stdc++.h>
using namespace std;
vector<int> snm, nodes_rank;
vector<pair<int, int>> tree;
pair<int, int> get_max(int v, int vl, int vr, int l, int r) {
  if (l <= vl && r >= vr) return tree[v];
  if (l >= vr || r <= vl) return make_pair(-1, -1);
  auto mid = (vl + vr) / 2;
  auto x1 = get_max(2 * v + 1, vl, mid, l, r);
  auto x2 = get_max(2 * v + 2, mid, vr, l, r);
  if (x1.first > x2.first) return x1;
  return x2;
}
void update(int v, int vl, int vr, int pos, int val) {
  if (vl + 1 == vr) {
    tree[v].first = val;
    tree[v].second = pos;
    return;
  }
  auto mid = (vl + vr) / 2;
  if (pos < mid) {
    update(2 * v + 1, vl, mid, pos, val);
  } else {
    update(2 * v + 2, mid, vr, pos, val);
  }
  auto x1 = tree[2 * v + 1], x2 = tree[2 * v + 2];
  if (x1.first > x2.first)
    tree[v] = x1;
  else
    tree[v] = x2;
}
int get_parent(int v) {
  if (snm[v] == -1) return v;
  snm[v] = get_parent(snm[v]);
  return snm[v];
}
int uni(int p1, int p2) {
  if (nodes_rank[p1] < nodes_rank[p2]) swap(p1, p2);
  snm[p2] = p1;
  if (nodes_rank[p1] == nodes_rank[p2]) nodes_rank[p1]++;
  return p1;
}
int n;
vector<int> euler_tour;
vector<pair<int, int>> first_last;
vector<bool> dfs_used;
vector<vector<int>> graph;
void dfs(int v) {
  if (dfs_used[v]) return;
  dfs_used[v] = true;
  euler_tour.push_back(v);
  first_last[v].first = euler_tour.size() - 1;
  first_last[v].second = euler_tour.size() - 1;
  for (auto&& to : graph[v]) {
    dfs(to);
  }
  if (v >= n) {
    euler_tour.push_back(v);
    first_last[v].second = euler_tour.size() - 1;
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int m, q;
  cin >> n >> m >> q;
  vector<long long> p(n), parent;
  graph.resize(n);
  nodes_rank.resize(n, 0);
  snm.resize(n, -1);
  for (int i = 0; i < n; i++) cin >> p[i];
  vector<bool> used(m, false);
  vector<pair<long long, long long>> 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>> queries(q);
  for (int i = 0; i < q; i++) {
    cin >> queries[i].first >> queries[i].second;
    queries[i].second--;
    if (queries[i].first == 2) used[queries[i].second] = true;
  }
  for (int i = 0; i < m; i++)
    if (!used[i]) queries.push_back(make_pair(2, i));
  parent.resize(queries.size(), -1);
  for (int i = queries.size() - 1; i >= 0; i--) {
    if (queries[i].first == 2) {
      auto [from, to] = edges[queries[i].second];
      auto pfrom = get_parent(from);
      auto pto = get_parent(to);
      if (pfrom != pto) {
        snm.emplace_back(-1);
        nodes_rank.emplace_back(0);
        graph.emplace_back();
        auto vertex = snm.size() - 1;
        snm[uni(pfrom, pto)] = vertex;
        graph[pto].push_back(vertex);
        graph[vertex].push_back(pto);
        graph[pfrom].push_back(vertex);
        graph[vertex].push_back(pfrom);
      }
    } else {
      parent[i] = get_parent(queries[i].second);
    }
  }
  dfs_used.resize(snm.size(), false);
  first_last.resize(snm.size());
  for (int i = 0; i < snm.size(); i++) {
    if (!dfs_used[i] && snm[i] == -1) dfs(i);
  }
  tree.resize(4 * euler_tour.size(), make_pair(-1, -1));
  vector<int> cost(euler_tour.size());
  for (int i = 0; i < euler_tour.size(); i++) {
    if (euler_tour[i] < n) {
      cost[i] = p[euler_tour[i]];
    } else {
      cost[i] = 0;
    }
    update(0, 0, euler_tour.size(), i, cost[i]);
  }
  for (int i = 0; i < queries.size(); i++) {
    if (queries[i].first == 1) {
      auto [second, e] = first_last[parent[i]];
      auto x = get_max(0, 0, euler_tour.size(), second, e + 1);
      cout << x.first << endl;
      update(0, 0, euler_tour.size(), x.second, 0);
    }
  }
  return 0;
}
