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;
void Freopen() {
  freopen(
      "title"
      ".in",
      "r", stdin);
  freopen(
      "title"
      ".out",
      "w", stdout);
}
int read() {
  int g = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || '9' < ch) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while ('0' <= ch && ch <= '9') {
    g = g * 10 + ch - '0';
    ch = getchar();
  }
  return g * f;
}
const int N = 5e5 + 5;
int n, m, q, st[N][20], f[N], L[N], R[N], sign, id[N], d[N], a[N], vis[N],
    rt[N], cnt;
vector<pair<int, int> > G[N];
struct node {
  int x, y, w;
} e[N];
struct solve {
  int op, x;
} sol[N];
int get(int x) { return f[x] == x ? x : f[x] = get(f[x]); }
void kruskal() {
  sort(e + 1, e + m + 1, [](node a, node b) { return a.w > b.w; });
  for (int i = (1); i <= (n); i++) f[i] = i;
  for (int i = (1); i <= (m); i++) {
    int x = e[i].x, y = e[i].y, w = e[i].w;
    if (get(x) == get(y)) continue;
    n++;
    f[n] = n;
    G[n].push_back(pair<int, int>(get(x), w));
    G[n].push_back(pair<int, int>(get(y), w));
    f[get(x)] = n;
    f[get(y)] = n;
  }
}
void dfs(int x, int fa) {
  L[x] = ++sign;
  id[sign] = x;
  st[x][0] = fa;
  for (int i = (1); i <= (19); i++)
    if (st[x][i - 1])
      st[x][i] = st[st[x][i - 1]][i - 1];
    else
      break;
  for (auto y : G[x]) {
    d[y.first] = y.second;
    dfs(y.first, x);
  }
  R[x] = sign;
}
struct Seg {
  int maxn[N << 2];
  void up(int v) {
    if (a[maxn[v << 1]] > a[maxn[v << 1 | 1]])
      maxn[v] = maxn[v << 1];
    else
      maxn[v] = maxn[v << 1 | 1];
  }
  void build(int v, int l, int r) {
    if (l == r) return maxn[v] = id[l], void();
    int mid = l + r >> 1;
    build(v << 1, l, mid), build(v << 1 | 1, mid + 1, r);
    up(v);
  }
  void change(int v, int l, int r, int q) {
    if (l == r) return void();
    int mid = l + r >> 1;
    q <= mid ? change(v << 1, l, mid, q) : change(v << 1 | 1, mid + 1, r, q);
    up(v);
  }
  int query(int v, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) return maxn[v];
    int mid = l + r >> 1, re = 0;
    if (ql <= mid) {
      int ret = query(v << 1, l, mid, ql, qr);
      if (a[ret] > a[re]) re = ret;
    }
    if (qr > mid) {
      int ret = query(v << 1 | 1, mid + 1, r, ql, qr);
      if (a[ret] > a[re]) re = ret;
    }
    return re;
  }
} seg;
int climb(int x, int t) {
  for (int i = (19); i >= (0); i--)
    if (d[st[x][i]] >= t) x = st[x][i];
  if (d[x] >= t) x = st[x][0];
  return x;
}
signed main() {
  n = read(), m = read(), q = read();
  for (int i = (1); i <= (n); i++) a[i] = read();
  for (int i = (1); i <= (m); i++) {
    int x = read(), y = read();
    e[i] = node{x, y, q};
  }
  for (int i = (1); i <= (q); i++) {
    int op = read(), x = read();
    sol[i] = solve{op, x};
    if (op == 2) e[x].w = i - 1;
  }
  kruskal();
  for (int i = (1); i <= (n); i++)
    if (!vis[get(i)]) vis[get(i)] = 1, rt[++cnt] = get(i);
  for (int i = (1); i <= (cnt); i++) d[rt[i]] = 0, dfs(rt[i], 0);
  seg.build(1, 1, n);
  for (int i = (1); i <= (q); i++) {
    int op = sol[i].op, x = sol[i].x;
    if (op == 1) {
      int anc = climb(x, i);
      int p = seg.query(1, 1, n, L[anc], R[anc]);
      cout << a[p] << '\n';
      a[p] = 0;
      seg.change(1, 1, n, L[p]);
    }
  }
  return signed();
}
