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;
int n, m, q;
const int N = 2e5 + 1;
const int M = 3e5 + 1;
const int Q = 5e5 + 1;
int val[N * 2];
int e[M][2];
bool u[M];
int qq[Q][2];
int lp[N * 2], rp[N * 2];
int dfso[N * 2];
int tree[N * 4];
int f[N * 2];
int cnt;
int dfscnt;
vector<int> ee[N * 2];
int ufind(int x) {
  if (x != f[x]) f[x] = ufind(f[x]);
  return f[x];
}
void pushup(int p) {
  tree[p] = max(tree[p << 1], tree[p << 1 | 1]);
  return;
}
void build(int l, int r, int p) {
  if (l == r) {
    tree[p] = dfso[l];
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, p << 1);
  build(mid + 1, r, p << 1 | 1);
  pushup(p);
  return;
}
int query(int long long, int rr, int l, int r, int p) {
  if (long long <= l && r <= rr) {
    return tree[p];
  }
  int mid = (l + r) >> 1;
  int ret = 0;
  if (long long <= mid) ret = max(ret, query(long long, rr, l, mid, p << 1));
  if (rr > mid) ret = max(ret, query(long long, rr, mid + 1, r, p << 1 | 1));
  return ret;
}
void update(int x, int l, int r, int p) {
  if (l == r) {
    tree[p] = 0;
    return;
  }
  int mid = (l + r) >> 1;
  if (tree[p << 1] == x) update(x, l, mid, p << 1);
  if (tree[p << 1 | 1] == x) update(x, mid + 1, r, p << 1 | 1);
  pushup(p);
  return;
}
void build_tree(int a, int b) {
  a = ufind(a);
  b = ufind(b);
  if (a == b) return;
  cnt++;
  f[cnt] = cnt;
  val[cnt] = 0;
  ee[cnt].clear();
  f[a] = cnt;
  f[b] = cnt;
  ee[cnt].push_back(a);
  ee[cnt].push_back(b);
  ee[a].push_back(cnt);
  ee[b].push_back(cnt);
  return;
}
void dfs(int p, int pre) {
  dfscnt++;
  lp[p] = dfscnt;
  dfso[dfscnt] = val[p];
  for (auto v : ee[p]) {
    if (v == pre) continue;
    dfs(v, p);
  }
  rp[p] = dfscnt;
  return;
}
int main() {
  std::ios::sync_with_stdio(0);
  std::cin.tie(0);
  while (cin >> n >> m >> q) {
    for (int i = (1); i < (n + 1); i++) {
      cin >> val[i];
      f[i] = i;
      ee[i].clear();
    }
    for (int i = (1); i < (m + 1); i++) {
      cin >> e[i][0] >> e[i][1];
      u[i] = 0;
    }
    for (int i = (1); i < (q + 1); i++) {
      cin >> qq[i][0] >> qq[i][1];
      if (qq[i][0] == 2) u[qq[i][1]] = 1;
    }
    cnt = n;
    for (int i = (1); i < (m + 1); i++) {
      if (u[i] == 0) {
        int a = e[i][0];
        int b = e[i][1];
        build_tree(a, b);
      }
    }
    for (int i = (q + 1) - 1; i >= (1); --i) {
      if (qq[i][0] == 1) {
        qq[i][1] = ufind(qq[i][1]);
      } else {
        int a = e[i][0];
        int b = e[i][1];
        build_tree(a, b);
      }
    }
    cnt++;
    f[cnt] = cnt;
    val[cnt] = 0;
    ee[cnt].clear();
    for (int i = (1); i < (n + 1); i++) {
      int a = i;
      a = ufind(a);
      if (a != cnt) {
        f[a] = cnt;
        ee[a].push_back(cnt);
        ee[cnt].push_back(a);
      }
    }
    dfscnt = 0;
    dfs(cnt, -1);
    build(1, dfscnt, 1);
    for (int i = (1); i < (q + 1); i++) {
      if (qq[i][0] == 1) {
        int ans = query(lp[qq[i][1]], rp[qq[i][1]], 1, dfscnt, 1);
        update(ans, 1, dfscnt, 1);
        cout << ans << '\n';
      }
    }
  }
  return 0;
}
