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;
#pragma GCC optimize("Ofast", "unroll-loops", "omit-frame-pointer", "inline")
const int maxn = 500010;
const int mod = 1000000007;
const long double eps = 1e-9;
const int inf = ((1ll << 31ll) - 1ll);
const int INF = 1ll + mod + mod;
const long double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int qpow(int b, int e) {
  if (!e) return 1;
  if (e & 1) return qpow(b, e - 1) * b % mod;
  int pwur = qpow(b, e >> 1);
  return pwur * pwur % mod;
}
int modinv(int x) { return qpow(x, mod - 2); }
struct node {
  int val, lazy, l, r;
};
int n, tl[maxn], tr[maxn], par[maxn], ran[maxn], cnt, m, q, pt[maxn], lv[maxn],
    a[maxn], id[maxn], ind[maxn], tpid[maxn], used[maxn];
vector<int> vnod[maxn], g[maxn];
vector<node> st[maxn];
pair<pair<int, int>, pair<int, int> > edge[maxn];
pair<int, pair<int, int> > nedges[maxn];
pair<int, int> edges[maxn];
pair<int, int> queries[maxn];
int find_(int x) { return (par[x] == x) ? (x) : (find_(par[x])); }
void union_(int u, int v, int id) {
  int a = find_(u), b = find_(v);
  if (a == b) return;
  if (ran[a] < ran[b]) {
    swap(a, b);
    swap(u, v);
  }
  par[b] = a;
  ran[a] += ran[b];
  g[u].push_back(v);
  g[v].push_back(u);
  nedges[id].second.first = u;
  nedges[id].second.second = v;
  used[id] = 1;
}
void dfs(int u, int p) {
  tl[u] = tr[u] = ++cnt;
  vnod[u].push_back(tl[u]);
  for (auto v : g[u]) {
    if (v == p) continue;
    lv[v] = lv[u] + 1;
    pt[v] = u;
    dfs(v, u);
    tr[u] = max(tr[u], tr[v]);
    for (auto i : vnod[v]) vnod[u].push_back(i);
  }
}
void lazyp(int sgt, int nod, int l, int r) {
  st[sgt][nod].val = st[sgt][nod].lazy;
  if (l != -1 || r != -1) {
    st[sgt][l].lazy = st[sgt][nod].lazy;
    st[sgt][r].lazy = st[sgt][nod].lazy;
  }
  st[sgt][nod].lazy = 0;
}
void build(int SgT, int nod, int l, int r) {
  if (l == r) {
    st[SgT][nod].val = a[tpid[vnod[SgT][l]]];
    return;
  }
  int mi = (l + r) >> 1;
  st[SgT].push_back({0, 0, -1, -1});
  st[SgT][nod].l = (int)st[SgT].size() - 1;
  build(SgT, st[SgT][nod].l, l, mi);
  st[SgT].push_back({0, 0, -1, -1});
  st[SgT][nod].r = (int)st[SgT].size() - 1;
  build(SgT, st[SgT][nod].r, mi + 1, r);
  st[SgT][nod].val =
      max(st[SgT][st[SgT][nod].l].val, st[SgT][st[SgT][nod].r].val);
}
void update(int sgt, int nod, int l, int r, int x, int y, int val) {
  if (st[sgt][nod].lazy) lazyp(sgt, nod, st[sgt][nod].l, st[sgt][nod].r);
  if (l > y || r < x) return;
  if (l >= x && r <= y) {
    st[sgt][nod].lazy = val;
    lazyp(sgt, nod, st[sgt][nod].l, st[sgt][nod].r);
    return;
  }
  int mi = (l + r) >> 1;
  update(sgt, st[sgt][nod].l, l, mi, x, y, val);
  update(sgt, st[sgt][nod].r, mi + 1, r, x, y, val);
  st[sgt][nod].val =
      max(st[sgt][st[sgt][nod].l].val, st[sgt][st[sgt][nod].r].val);
}
int query(int sgt, int nod, int l, int r, int x, int y) {
  if (st[sgt][nod].lazy) lazyp(sgt, nod, st[sgt][nod].l, st[sgt][nod].r);
  if (l > y || r < x) return 0;
  if (l >= x && r <= y) return st[sgt][nod].val;
  int mi = (l + r) >> 1;
  int aa = query(sgt, st[sgt][nod].l, l, mi, x, y);
  int bb = query(sgt, st[sgt][nod].r, mi + 1, r, x, y);
  return max(aa, bb);
}
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.setf(ios::fixed);
  cout.precision(0);
  srand(time(NULL));
  cin >> n >> m >> q;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    id[a[i]] = i;
  }
  for (int i = 1; i <= m; i++) {
    cin >> edge[i].second.first >> edge[i].second.second;
    edge[i].first.first = mod;
    edge[i].first.second = i;
  }
  for (int i = 1; i <= q; i++) {
    cin >> queries[i].first >> queries[i].second;
    if (queries[i].first == 2) {
      edge[queries[i].second].first.first = i;
    }
  }
  for (int i = 1; i <= m; i++)
    nedges[i] = {edge[i].first.first,
                 {edge[i].second.first, edge[i].second.second}};
  sort(edge + 1, edge + m + 1);
  reverse(edge + 1, edge + m + 1);
  for (int i = 1; i <= n; i++) {
    ran[i] = i;
    par[i] = i;
  }
  for (int i = 1; i <= m; i++) {
    union_(edge[i].second.first, edge[i].second.second, edge[i].first.second);
  }
  for (int i = 1; i <= n; i++) {
    if (!tl[i]) {
      lv[i] = 1;
      dfs(i, i);
    }
    tpid[tl[i]] = i;
  }
  for (int i = 1; i <= n; i++) {
    if (lv[i] == 1) {
      st[i].push_back({0, 0, -1, -1});
      build(i, 0, 0, (int)vnod[i].size() - 1);
    }
  }
  for (int i = 1; i <= m; i++) {
    if (used[i]) {
      if (lv[nedges[i].second.first] + 1 == lv[nedges[i].second.second]) {
        ind[nedges[i].second.second] = nedges[i].first;
      }
      if (lv[nedges[i].second.second] + 1 == lv[nedges[i].second.first]) {
        ind[nedges[i].second.first] = nedges[i].first;
      }
    }
  }
  for (int i = 1; i <= q; i++) {
    if (queries[i].first == 1) {
      int u = queries[i].second;
      while (ind[u] >= i && pt[u] > 0) u = pt[u];
      int qt =
          query(u, 0, 0, (int)vnod[u].size() - 1, 0, (int)vnod[u].size() - 1);
      cout << qt << '\n';
      a[id[qt]] = 0;
      int nid = lower_bound(vnod[u].begin(), vnod[u].end(), tl[id[qt]]) -
                vnod[u].begin();
      update(u, 0, 0, (int)vnod[u].size() - 1, nid, nid, 0);
    }
    if (queries[i].first == 2) {
      int u = nedges[queries[i].second].second.first;
      int v = nedges[queries[i].second].second.second;
      if (lv[u] > lv[v]) swap(u, v);
      if (lv[u] + 1 != lv[v]) continue;
      while (ind[u] >= i && pt[u] > 0) u = pt[u];
      int nid =
          lower_bound(vnod[u].begin(), vnod[u].end(), tl[v]) - vnod[u].begin();
      int nid2 = lower_bound(vnod[u].begin(), vnod[u].end(), tr[v] + 1) -
                 vnod[u].begin();
      update(u, 0, 0, (int)vnod[u].size() - 1, nid, nid2 - 1, 0);
      st[v].push_back({0, 0, -1 - 1});
      build(v, 0, 0, (int)vnod[v].size() - 1);
    }
  }
  return 0;
}
