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;
const int N = 1000050;
const int inf = 0x3f3f3f3f;
const long long llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end() {}
int n, m, Q, p[N], f[N], in[N], out[N], tim, del[N];
vector<int> g[N];
int Find(int x) { return x == f[x] ? x : f[x] = Find(f[x]); }
void Union(int x, int y) {
  int fx = Find(x), fy = Find(y);
  if (fx != fy) {
    ++n;
    f[n] = n, f[fx] = n, f[fy] = n;
    g[n].push_back(fx), g[n].push_back(fy);
  }
}
void dfs_tim(int u, int fa) {
  in[u] = ++tim;
  for (auto v : g[u]) {
    if (v != fa) dfs_tim(v, u);
  }
  out[u] = tim;
}
struct querys {
  int type;
  int val;
} q[N];
struct edges {
  int u, v;
} e[N];
struct segtree {
  int l, r;
  pair<int, int> mx;
} t[N << 2];
inline void pushup(int id) { t[id].mx = max(t[id << 1].mx, t[id << 1 | 1].mx); }
void build(int l, int r, int id) {
  t[id].l = l, t[id].r = r;
  if (l == r) return;
  int mid = (l + r) >> 1;
  build(l, mid, id << 1);
  build(mid + 1, r, id << 1 | 1);
}
void change(int pos, pair<int, int> val, int id) {
  int l = t[id].l, r = t[id].r;
  if (l == r) {
    t[id].mx = val;
    return;
  }
  int mid = (l + r) >> 1;
  if (pos <= mid)
    change(pos, val, id << 1);
  else
    change(pos, val, id << 1 | 1);
  pushup(id);
}
pair<int, int> query(int L, int R, int id) {
  int l = t[id].l, r = t[id].r;
  if (L <= l && R >= r) return t[id].mx;
  int mid = (l + r) >> 1;
  if (R <= mid)
    return query(L, R, id << 1);
  else if (L > mid)
    return query(L, R, id << 1 | 1);
  else
    return max(query(L, mid, id << 1), query(mid + 1, R, id << 1 | 1));
}
inline void solve() {
  scanf("%d%d%d", &n, &m, &Q);
  int nn = n;
  for (int i = 1; i <= n; ++i) scanf("%d", &p[i]), f[i] = i;
  for (int i = 1; i <= m; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    e[i] = (edges){x, y};
  }
  for (int i = 1; i <= Q; ++i) {
    scanf("%d%d", &q[i].type, &q[i].val);
    if (q[i].type == 2) del[q[i].val] = 1;
  }
  for (int i = 1; i <= m; ++i)
    if (del[i] == 0) Union(e[i].u, e[i].v);
  for (int i = Q; i; --i) {
    if (q[i].type == 2)
      Union(e[q[i].val].u, e[q[i].val].v);
    else
      q[i].val = Find(q[i].val);
  }
  for (int i = 1; i <= n; ++i)
    if (Find(i) == i) dfs_tim(i, 0);
  build(1, tim, 1);
  for (int i = 1; i <= nn; ++i) change(in[i], make_pair((p[i]), (i)), 1);
  for (int i = 1; i <= Q; ++i) {
    if (q[i].type == 1) {
      int u = q[i].val;
      pair<int, int> ans = query(in[u], out[u], 1);
      printf("%d\n", ans.first);
      int node = ans.second;
      if (in[node]) change(in[node], make_pair((0), (0)), 1);
    }
  }
}
int main() {
  TIME__START = clock();
  int Test = 1;
  while (Test--) {
    solve();
  }
  TIME__END = clock();
  program_end();
  return 0;
}
