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>
inline void ckmax(T& x, T y) {
  x = (y > x ? y : x);
}
template <typename T>
inline void ckmin(T& x, T y) {
  x = (y < x ? y : x);
}
inline int read() {
  char ch = getchar();
  int s = 0, f = 1;
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while ('0' <= ch && ch <= '9') {
    s = s * 10 + ch - '0';
    ch = getchar();
  }
  return f * s;
}
const int maxn = 2e5 + 7;
const int maxm = 3e5 + 7;
const int maxq = 5e5 + 7;
int p[maxn], tim[2 * maxn];
struct edge {
  int next, to;
} e[maxm];
int cnt1 = 0;
int tree[maxn * 2];
inline int makeNode(int t = 0) {
  ++cnt1;
  tree[cnt1] = t;
  return cnt1;
}
struct node {
  int u, v;
} tmpEdge[maxm], sortEdge[maxm];
struct que {
  int opt;
  int index;
} query[maxq];
int cnt = 0;
int head[maxn * 2];
bool initEdge[maxm];
inline void addEdge(int u, int v) {
  e[++cnt].to = v;
  e[cnt].next = head[u];
  head[u] = cnt;
}
int fa[maxn * 2];
int getFa(int u) {
  if (fa[u] == u)
    return u;
  else
    return fa[u] = getFa(fa[u]);
}
const int LOG = 18;
int anc[maxn * 2][LOG + 1];
int mi_dfn[maxn * 2], mx_dfn[maxn * 2], rev[maxn * 2];
int dfns = 0;
void dfs(int u) {
  for (int i = 1; i <= LOG; i++) anc[u][i] = anc[anc[u][i - 1]][i - 1];
  bool isLeaf = 1;
  mi_dfn[u] = maxq;
  for (int i = head[u]; i; i = e[i].next) {
    int v = e[i].to;
    isLeaf = 0;
    anc[v][0] = u;
    dfs(v);
    mi_dfn[u] = min(mi_dfn[u], mi_dfn[v]);
    mx_dfn[u] = max(mx_dfn[u], mx_dfn[v]);
  }
  if (isLeaf) {
    rev[++dfns] = u;
    mi_dfn[u] = mx_dfn[u] = dfns;
  }
}
int mx[maxn * 4 + 5], mx_pos[maxn * 4 + 5];
void push_up(int p) {
  if (mx[p << 1] > mx[p << 1 | 1]) {
    mx[p] = mx[p << 1];
    mx_pos[p] = mx_pos[p << 1];
  } else {
    mx[p] = mx[p << 1 | 1];
    mx_pos[p] = mx_pos[p << 1 | 1];
  }
}
void build(int P, int l, int r) {
  if (l == r) {
    mx[P] = p[rev[l]];
    mx_pos[P] = l;
    return;
  }
  int mid = (l + r) >> 1;
  build(P << 1, l, mid);
  build(P << 1 | 1, mid + 1, r);
  push_up(P);
}
void point_modify(int p, int l, int r, int pos) {
  if (l == r) {
    mx[p] = 0;
    return;
  }
  int mid = (l + r) >> 1;
  if (pos <= mid) {
    point_modify(p << 1, l, mid, pos);
  } else {
    point_modify(p << 1 | 1, mid + 1, r, pos);
  }
  push_up(p);
}
pair<int, int> quer(int p, int l, int r, int ql, int qr) {
  if (ql <= l && qr >= r) {
    return make_pair(mx[p], mx_pos[p]);
  }
  int mid = (l + r) >> 1;
  pair<int, int> res = make_pair(0, 0);
  if (ql <= mid) {
    res = quer(p << 1, l, mid, ql, qr);
  }
  if (qr > mid) {
    ckmax(res, quer(p << 1 | 1, mid + 1, r, ql, qr));
  }
  return res;
}
int getAnc(int u, int t) {
  for (int i = LOG; i >= 0; i--) {
    if (anc[u][i] && tree[anc[u][i]] <= t) {
      u = anc[u][i];
    }
  }
  return u;
}
int main() {
  int n = read();
  int m = read(), q = read();
  for (int i = 1; i <= n; i++) {
    p[i] = read();
    makeNode();
  }
  for (int i = 1; i <= m; i++) {
    tmpEdge[i].u = read();
    tmpEdge[i].v = read();
    initEdge[i] = 1;
  }
  for (int i = 1; i <= q; i++) {
    query[i].opt = read();
    query[i].index = read();
    if (query[i].opt == 2) initEdge[query[i].index] = 0;
  }
  for (int i = 1; i <= 2 * n; i++) fa[i] = i;
  int m1 = 0;
  for (int i = 1; i <= m; i++) {
    if (initEdge[i]) {
      sortEdge[++m1] = tmpEdge[i];
    }
  }
  for (int i = q; i >= 1; i--) {
    if (query[i].opt == 2) {
      sortEdge[++m1] = tmpEdge[query[i].index];
    } else
      tim[i] = m1;
  }
  for (int i = 1; i <= m1; i++) {
    int u = getFa(sortEdge[i].u);
    int v = getFa(sortEdge[i].v);
    if (u == v) continue;
    makeNode(i);
    addEdge(cnt1, u);
    addEdge(cnt1, v);
    fa[u] = fa[v] = cnt1;
  }
  for (int i = 1; i <= cnt1; i++) {
    if (getFa(i) == (i)) dfs(i);
  }
  build(1, 1, n);
  for (int i = 1; i <= q; i++) {
    if (query[i].opt == 1) {
      int u = query[i].index;
      int v = getAnc(u, tim[i]);
      pair<int, int> qres = quer(1, 1, n, mi_dfn[v], mx_dfn[v]);
      printf("%d\n", qres.first);
      point_modify(1, 1, n, qres.second);
    }
  }
  return 0;
}
