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;
template <typename T>
void read(T &X) {
  X = 0;
  char C = getchar();
  T Sig = 1;
  for (; !isdigit(C); C = getchar())
    if (C == '-') Sig = -1;
  for (; isdigit(C); C = getchar()) X = (X << 3) + (X << 1) + C - '0';
  X *= Sig;
}
template <typename T>
void write(T x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  T y = 0;
  int wei = 0;
  while (x > 9) {
    y = y * 10 + x % 10;
    x /= 10;
    ++wei;
  }
  putchar(x + 48);
  while (wei--) {
    putchar(y % 10 + 48);
    y /= 10;
  }
}
int n, m, q;
int w[400010 + 300010];
int pos[400010 + 300010];
struct rec {
  int u, v;
  bool flag;
  void rd() {
    read(u);
    read(v);
    flag = true;
    return;
  }
};
rec r[300010];
struct ques {
  int op, x;
  void rd() {
    read(op);
    read(x);
    return;
  }
};
ques que[500010];
void get_data() {
  read(n);
  read(m);
  read(q);
  for (int i = 1; i <= n; i++) read(w[i]);
  for (int i = 1; i <= m; i++) r[i].rd();
  for (int i = 1; i <= q; i++) que[i].rd();
  return;
}
int f[400010 + 300010];
int what[400010 + 300010];
int cnt;
int par(int x) {
  while (x ^ f[x]) x = f[x] = f[f[x]];
  return x;
}
void merge(int x, int y) {
  f[par(x)] = par(y);
  return;
}
struct side {
  int v, last;
  void get(int x, int y) {
    v = x;
    last = y;
    return;
  }
};
int len;
side c[400010 + 300010];
int head[400010 + 300010];
int pt[400010 + 300010];
int fa[400010 + 300010][25];
int h[400010 + 300010];
bool vis[400010 + 300010];
int tmp;
int lst[400010 + 300010];
int lef[400010 + 300010];
int rig[400010 + 300010];
void put(int x, int y) {
  c[++len].get(y, head[x]);
  head[x] = len;
  return;
}
void dfs(int p) {
  lst[++tmp] = p;
  lef[p] = tmp;
  vis[p] = true;
  for (int i = head[p]; i; i = c[i].last)
    if (!vis[c[i].v]) {
      fa[c[i].v][0] = p;
      for (int j = 1; fa[c[i].v][j - 1]; j++, h[c[i].v]++)
        fa[c[i].v][j] = fa[fa[c[i].v][j - 1]][j - 1];
      dfs(c[i].v);
    }
  rig[p] = tmp;
  return;
}
void prepare() {
  for (int i = 1; i <= q; i++)
    if (que[i].op == 2) r[que[i].x].flag = false;
  for (int i = 1; i <= n; i++) f[i] = i;
  for (int i = 1; i <= m; i++)
    if (r[i].flag) merge(r[i].u, r[i].v);
  cnt = n;
  for (int i = 1; i <= n; i++) {
    if (!what[par(i)]) {
      what[par(i)] = ++cnt;
      pt[cnt] = q + 1;
      f[cnt] = cnt;
    }
    put(what[par(i)], i);
  }
  for (int i = 1; i <= n; i++)
    if (f[i] == i) merge(i, what[i]);
  for (int i = q; i; i--)
    if (que[i].op == 2) {
      int u = par(r[que[i].x].u), v = par(r[que[i].x].v);
      if (u != v) {
        pt[++cnt] = i;
        f[cnt] = cnt;
        put(cnt, u);
        put(cnt, v);
        merge(u, cnt);
        merge(v, cnt);
      }
    }
  for (int i = 1; i <= cnt; i++) h[i] = -1;
  for (int i = 1; i <= cnt; i++)
    if (f[i] == i) dfs(i);
  for (int i = 1; i <= n; i++) pos[w[i]] = i;
  return;
}
struct Segment_Tree {
  struct node {
    int lef, rig, v;
  };
  node tr[(400010 + 300010) << 2];
  void pushup(int i) {
    tr[i].v = max(tr[i << 1].v, tr[i << 1 | 1].v);
    return;
  }
  void build(int i, int L, int R) {
    tr[i].lef = L;
    tr[i].rig = R;
    if (L == R) {
      tr[i].v = w[lst[L]];
      return;
    }
    int mid = (L + R) >> 1;
    build(i << 1, L, mid);
    build(i << 1 | 1, mid + 1, R);
    pushup(i);
    return;
  }
  void change(int i, int idx) {
    if (tr[i].lef == tr[i].rig) {
      tr[i].v = 0;
      return;
    }
    if (idx <= tr[i << 1].rig)
      change(i << 1, idx);
    else
      change(i << 1 | 1, idx);
    pushup(i);
    return;
  }
  int query(int i, int L, int R) {
    if (L <= tr[i].lef && tr[i].rig <= R) return tr[i].v;
    int res = 0;
    if (L <= tr[i << 1].rig) res = query(i << 1, L, R);
    if (R >= tr[i << 1 | 1].lef) res = max(res, query(i << 1 | 1, L, R));
    return res;
  }
};
Segment_Tree tree;
int jmp(int id, int x) {
  for (int i = h[id]; i >= 0; i--)
    if (fa[id][i] && pt[fa[id][i]] > x) id = fa[id][i];
  return id;
}
void count() {
  tree.build(1, 1, cnt);
  for (int i = 1; i <= q; i++)
    if (que[i].op == 1) {
      int o = jmp(que[i].x, i);
      int where = pos[tree.query(1, lef[o], rig[o])];
      write(w[where]);
      putchar('\n');
      if (where) tree.change(1, lef[where]);
      w[where] = 0;
    }
  return;
}
int main() {
  get_data();
  prepare();
  count();
  return 0;
}
