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;
struct node {
  long long val, id;
  node(long long _val = 0, long long _id = 0) : val(_val), id(_id) {}
};
node oper(node a, node b) {
  if (a.val > b.val) return a;
  return b;
}
template <int N>
struct Seg {
  int n = N;
  vector<node> s;
  void build() {
    for (int i = n - 1; i > 0; i--) {
      s[i] = oper(s[i << 1], s[i << 1 | 1]);
    }
  }
  Seg() {
    n = N;
    s = vector<node>(2 * n);
    build();
  }
  void upd(int pos, node val) {
    for (s[pos += n] = val; pos > 1; pos >>= 1)
      s[pos >> 1] = oper(s[pos], s[pos ^ 1]);
  }
  node qry(int l, int r) {
    node ans;
    for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if (l & 1) ans = oper(ans, s[l++]);
      if (r & 1) ans = oper(ans, s[--r]);
    }
    return ans;
  }
};
template <int N, bool IN_EDGES>
struct HLD {
  int t;
  vector<int> g[N];
  int pai[N], sz[N], d[N];
  int root[N], pos[N];
  void ae(int a, int b) { g[a].push_back(b), g[b].push_back(a); }
  void dfsSz(int no) {
    if (~pai[no]) g[no].erase(find((g[no]).begin(), (g[no]).end(), pai[no]));
    sz[no] = 1;
    for (auto &it : g[no]) {
      pai[it] = no;
      d[it] = d[no] + 1;
      dfsSz(it);
      sz[no] += sz[it];
      if (sz[it] > sz[g[no][0]]) swap(it, g[no][0]);
    }
  }
  void dfsHld(int no) {
    pos[no] = t++;
    for (auto &it : g[no]) {
      root[it] = (it == g[no][0] ? root[no] : it);
      dfsHld(it);
    }
  }
  void init(int nor) {
    root[nor] = d[nor] = t = 0;
    pai[nor] = -1;
    dfsSz(nor);
    dfsHld(nor);
  }
  Seg<N> tree;
  void changeNode(int v, node val) { tree.upd(pos[v], val); }
  long long querySubtree(int v) {
    node ans = tree.qry(pos[v] + IN_EDGES, pos[v] + sz[v]);
    if (ans.val) {
      changeNode(ans.id, node(0, ans.id));
    }
    return ans.val;
  }
};
const int N = 4e5 + 10;
int tempo[N];
namespace lca_space {
int nlog;
int n;
vector<int> *g;
int pai[N], dist[N];
int st[N][25];
void dfs(int no, int from, int dac) {
  dist[no] = dac;
  for (auto it : g[no]) {
    if (it == from) continue;
    pai[it] = no;
    dfs(it, no, dac + 1);
  }
}
void make(vector<int> _g[N], int _n, int vr) {
  g = _g;
  n = _n;
  int root = vr;
  pai[root] = -1;
  dfs(root, -1, 0);
  nlog = 1;
  while ((1 << nlog) < n) nlog++;
  assert(nlog < 25);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < nlog + 1; j++) st[i][j] = -1;
  for (int i = 0; i < n; i++) st[i][0] = pai[i];
  for (int j = 1; j <= nlog; j++) {
    for (int i = 0; i < n; i++) {
      int ant_pai = st[i][j - 1];
      if (ant_pai != -1) st[i][j] = st[ant_pai][j - 1];
    }
  }
}
int lca(int v, int tt) {
  assert(tempo[v] >= tt);
  for (int i = nlog; i >= 0; i--) {
    if (st[v][i] != -1 and tempo[st[v][i]] >= tt) v = st[v][i];
  }
  return v;
}
};  // namespace lca_space
HLD<N, false> hld;
vector<int> g[N];
void add_edge(int u, int v) {
  g[u].push_back(v);
  g[v].push_back(u);
  hld.ae(u, v);
}
int id_nn;
int pai[N];
int rep(int u) { return pai[u] < 0 ? u : pai[u] = rep(pai[u]); }
void merge(int u, int v, int tt) {
  u = rep(u), v = rep(v);
  if (u != v) {
    pai[u] = id_nn;
    pai[v] = id_nn;
    add_edge(id_nn, u), add_edge(id_nn, v);
    tempo[id_nn] = tt;
    id_nn++;
  }
}
int val[N];
int idq_edge[N];
vector<pair<int, int>> qry, edges;
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, m, q;
  cin >> n >> m >> q;
  id_nn = n;
  for (int i = 0; i < n; i++) tempo[i] = q;
  for (int i = 0; i < N; i++) pai[i] = -1;
  for (int i = 0; i < n; i++) cin >> val[i];
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    edges.emplace_back(a, b);
    idq_edge[i] = q;
  }
  for (int i = 0; i < q; i++) {
    int a, b;
    cin >> a >> b;
    b--;
    if (a == 2) {
      idq_edge[b] = i;
    }
    qry.emplace_back(a, b);
  }
  vector<tuple<int, int, int>> edge_q;
  for (int i = 0; i < m; i++) {
    int a, b;
    tie(a, b) = edges[i];
    edge_q.emplace_back(idq_edge[i], a, b);
  }
  sort((edge_q).begin(), (edge_q).end());
  reverse((edge_q).begin(), (edge_q).end());
  for (auto &[idq, a, b] : edge_q) {
    merge(a, b, idq);
  }
  for (int i = 1; i < n; i++) {
    merge(0, i, -1);
  }
  cerr << "id_nn"
       << " = " << id_nn << endl;
  for (int i = 0; i < id_nn; i++)
    cerr << "tempo[i]"
         << " = " << tempo[i] << endl;
  hld.init(id_nn - 1);
  for (int i = 0; i < n; i++) hld.changeNode(i, node(val[i], i));
  lca_space::make(g, id_nn, id_nn - 1);
  for (int i = 0; i < id_nn; i++) {
    cerr << "i"
         << " = " << i << endl;
    cerr << "g[i]"
         << " = ";
    for (auto it : g[i]) cout << it << ", ";
    cout << endl;
  }
  for (int i = 0; i < n; i++)
    cerr << "val[i]"
         << " = " << val[i] << endl;
  for (int i = 0; i < id_nn; i++)
    cerr << "tempo[i]"
         << " = " << tempo[i] << endl;
  for (int i = 0; i < (int)(qry.size()); i++) {
    int tipo, no;
    tie(tipo, no) = qry[i];
    if (tipo == 1) {
      cerr << "i"
           << " = " << i << endl;
      cerr << "no"
           << " = " << no << endl;
      int pp = lca_space::lca(no, i);
      cerr << "pp"
           << " = " << pp << endl;
      cout << hld.querySubtree(pp) << "\n";
    }
  }
}
