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 = 1e6 + 33, INF = 0x3f3f3f3f;
struct node {
  int l, r, mx;
} t[N];
int val[N];
void pushup(int k) {
  t[k].mx = (val[t[k << 1].mx] > val[t[k << 1 | 1].mx] ? t[k << 1].mx
                                                       : t[k << 1 | 1].mx);
}
void build(int k, int l, int r) {
  t[k].l = l;
  t[k].r = r;
  if (l == r) {
    t[k].mx = l;
    return;
  }
  int mid = l + r >> 1;
  build(k << 1, l, mid);
  build(k << 1 | 1, mid + 1, r);
  pushup(k);
}
void del(int k, int ps) {
  if (t[k].l > ps || t[k].r < ps) return;
  if (t[k].l == t[k].r) {
    t[k].mx = 0;
    return;
  }
  del(k << 1, ps);
  del(k << 1 | 1, ps);
  pushup(k);
}
int query(int k, int l, int r) {
  if (t[k].l > r || t[k].r < l) return 0;
  if (t[k].l >= l && t[k].r <= r) return t[k].mx;
  int as1 = query(k << 1, l, r), as2 = query(k << 1 | 1, l, r);
  return (val[as1] > val[as2] ? as1 : as2);
}
int tot, rt;
int fir[N], nxt[N], to[N], up[N], num[N];
int ff[400503][19];
void addedge(int x, int f, int z) {
  nxt[++tot] = fir[f];
  fir[f] = tot;
  to[tot] = x;
  ff[x][0] = f;
  up[x] = z;
}
int in[N], out[N];
int n;
int ccc;
void Dfs(int x) {
  for (int i = 1; i <= 18; ++i) ff[x][i] = ff[ff[x][i - 1]][i - 1];
  if (x <= n) {
    in[x] = ++ccc;
    num[ccc] = x;
  } else
    in[x] = ccc + 1;
  for (int e = fir[x]; e; e = nxt[e]) {
    Dfs(to[e]);
  }
  out[x] = ccc;
}
int query(int x, int tim) {
  for (int i = 18; i >= 0; --i) {
    if (up[ff[x][i]] > tim) x = ff[x][i];
  }
  if (up[x] > tim) x = ff[x][0];
  int haha = query(1, in[x], out[x]);
  del(1, haha);
  return val[haha];
}
int re() {
  int i = 0, f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = -1;
  for (; isdigit(c); c = getchar()) i = (i << 3) + (i << 1) + c - '0';
  return i * f;
}
struct E {
  int x, y, z;
  bool operator<(const E &e) const { return z > e.z; }
} edge[N];
int a[N];
struct Q {
  int x, tim;
} que[N];
int fa[N];
int getfa(int x) { return x == fa[x] ? x : fa[x] = getfa(fa[x]); }
bool vis[N];
int main() {
  n = re();
  int m = re(), q = re();
  for (int i = 1; i <= n; ++i) a[i] = re();
  for (int i = 1; i <= m; ++i) {
    edge[i].x = re(), edge[i].y = re(), edge[i].z = q + 1;
  }
  int cnt = 0;
  for (int i = 1; i <= q; ++i) {
    int opt = re(), x = re();
    if (opt == 1) {
      ++cnt;
      que[cnt].x = x;
      que[cnt].tim = i;
    } else {
      edge[x].z = i;
    }
  }
  sort(edge + 1, edge + m + 1);
  for (int i = 1; i < N; ++i) fa[i] = i;
  int sm = n;
  for (int i = 1; i <= m; ++i) {
    int x = getfa(edge[i].x), y = getfa(edge[i].y);
    if (x == y) continue;
    ++sm;
    addedge(x, sm, edge[i].z);
    addedge(y, sm, edge[i].z);
    fa[x] = sm;
    fa[y] = sm;
  }
  for (int i = 1; i <= n; ++i) {
    int rt = getfa(i);
    if (vis[rt]) continue;
    vis[rt] = true;
    Dfs(rt);
  }
  for (int i = 1; i <= n; ++i) val[i] = a[num[i]];
  build(1, 1, n);
  for (int i = 1; i <= cnt; ++i) {
    cout << query(que[i].x, que[i].tim) << endl;
  }
}
