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 inline read() {
  int num = 0, neg = 1;
  char c = getchar();
  while (!isdigit(c)) {
    if (c == '-') neg = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    num = (num << 3) + (num << 1) + c - '0';
    c = getchar();
  }
  return num * neg;
}
const int maxn = 500010, mod = 998244353;
int n, m, q, p[maxn], cnt, fa[maxn], tot;
struct Q {
  int t, x;
} a[maxn];
struct Edge {
  int u, v, w;
} edge[maxn];
bool cmp(Edge x, Edge y) { return x.w > y.w; }
int Find(int x) { return fa[x] == x ? x : fa[x] = Find(fa[x]); }
vector<int> G[maxn];
int val[maxn];
void kruskal() {
  for (int i = 1; i <= 2 * n; i++) fa[i] = i;
  tot = n;
  for (int i = 1; i <= m; i++) {
    int x = Find(edge[i].u), y = Find(edge[i].v);
    if (x != y) {
      ++tot;
      fa[x] = fa[y] = tot;
      val[tot] = edge[i].w;
      G[tot].push_back(x);
      G[tot].push_back(y);
    }
  }
  ++tot;
  for (int i = 1; i < tot; i++)
    if (fa[i] == i) G[tot].push_back(i);
}
int dfn[maxn], c, rev[maxn], L[maxn], R[maxn], jmp[maxn][21], dep[maxn];
void dfs(int x) {
  for (int i = 1; i <= 20; i++) jmp[x][i] = jmp[jmp[x][i - 1]][i - 1];
  if (!G[x].size()) {
    dfn[x] = ++c;
    rev[c] = x;
    L[x] = c;
    R[x] = c;
    return;
  }
  L[x] = 2147483647;
  R[x] = 0;
  for (int i = 0; i < G[x].size(); i++) {
    int v = G[x][i];
    dep[v] = dep[x] + 1;
    jmp[v][0] = x;
    dfs(v);
    L[x] = min(L[x], L[v]);
    R[x] = max(R[x], R[v]);
  }
}
int sum[maxn << 2], pos[maxn << 2];
void pushup(int x) {
  if (sum[(x << 1)] > sum[(x << 1 | 1)])
    pos[x] = pos[(x << 1)];
  else
    pos[x] = pos[(x << 1 | 1)];
  sum[x] = max(sum[(x << 1)], sum[(x << 1 | 1)]);
}
void update(int x, int l, int r, int P, int k) {
  if (l == r) {
    sum[x] = k;
    pos[x] = rev[l];
    return;
  }
  int mid = l + r >> 1;
  if (mid >= P) update((x << 1), l, mid, P, k);
  if (mid < P) update((x << 1 | 1), mid + 1, r, P, k);
  pushup(x);
}
int Query(int x, int l, int r, int L, int R) {
  if (l >= L && r <= R) return pos[x];
  int mid = l + r >> 1, posl = 0, posr = 0, ans = 0;
  if (mid >= L) posl = Query((x << 1), l, mid, L, R);
  if (mid < R) posr = Query((x << 1 | 1), mid + 1, r, L, R);
  if (p[posl] >= p[ans]) ans = posl;
  if (p[posr] >= p[ans]) ans = posr;
  return ans;
}
int main() {
  n = read();
  m = read();
  q = read();
  for (int i = 1; i <= n; i++) p[i] = read();
  for (int i = 1; i <= m; i++) {
    int x = read(), y = read();
    edge[i].u = x;
    edge[i].v = y;
    edge[i].w = 2147483647;
  }
  for (int i = 1; i <= q; i++) {
    int op = read(), x = read();
    if (op == 1) {
      a[++cnt].t = i;
      a[cnt].x = x;
    } else
      edge[x].w = i;
  }
  sort(edge + 1, edge + m + 1, cmp);
  kruskal();
  dep[tot] = 1;
  dfs(tot);
  for (int i = 1; i <= n; i++) update(1, 1, n, dfn[i], p[i]);
  for (int i = 1; i <= cnt; i++) {
    int now = a[i].x;
    for (int j = 20; j >= 0; j--)
      if (val[jmp[now][j]] >= a[i].t) now = jmp[now][j];
    int ans = Query(1, 1, n, L[now], R[now]);
    printf("%d\n", p[ans]);
    p[ans] = 0;
    update(1, 1, n, dfn[ans], p[ans]);
  }
  return 0;
}
