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 maxn = 2e5 + 5;
int readint() {
  int x = 0, f = 1;
  char s = getchar();
  while (s < '0' || s > '9') {
    if (s == '-') f = -1;
    (s = getchar());
  }
  while (s >= '0' && s <= '9') {
    x = (x << 3) + (x << 1) + (s ^ 48);
    (s = getchar());
  }
  return x * f;
}
struct edge {
  int nxt, v;
  edge(){};
  edge(int V, int N) {
    v = V;
    nxt = N;
  }
} e[maxn << 3];
int head[maxn << 2], edge_cnt = -1;
void addedge(int u, int v) {
  e[++edge_cnt] = edge(v, head[u]);
  head[u] = edge_cnt;
  e[++edge_cnt] = edge(u, head[v]);
  head[v] = edge_cnt;
}
int a[maxn << 2];
struct zz {
  int u, v;
} s[maxn << 1];
struct Query {
  int op, id, belong;
} query[maxn << 2];
bool vis[maxn << 1];
int fa[maxn << 2];
int dfn[maxn << 2], rdfn[maxn << 2], dfn_en[maxn << 2], dfn_cnt;
int findset(int x) {
  if (fa[x] != x) fa[x] = findset(fa[x]);
  return fa[x];
}
void dfs(int u, int pre) {
  dfn[u] = ++dfn_cnt;
  rdfn[dfn_cnt] = u;
  for (int i = head[u]; ~i; i = e[i].nxt) {
    int v = e[i].v;
    if (v == pre) continue;
    dfs(v, u);
  }
  dfn_en[u] = dfn_cnt;
}
int maxx[maxn << 4], ind[maxn << 4];
void pushup(int x) {
  if (maxx[x << 1] > maxx[x << 1 | 1])
    maxx[x] = maxx[x << 1], ind[x] = ind[x << 1];
  else
    maxx[x] = maxx[x << 1 | 1], ind[x] = ind[x << 1 | 1];
}
void build(int x, int l, int r) {
  if (l == r) {
    maxx[x] = a[rdfn[l]];
    ind[x] = l;
    return;
  }
  int mid = (l + r) >> 1;
  build(x << 1, l, mid);
  build(x << 1 | 1, mid + 1, r);
  pushup(x);
}
void modify(int x, int l, int r, int goal) {
  if (goal == l && l == r) {
    maxx[x] = 0;
    return;
  }
  int mid = (l + r) >> 1;
  if (goal <= mid)
    modify(x << 1, l, mid, goal);
  else
    modify(x << 1 | 1, mid + 1, r, goal);
  pushup(x);
}
pair<int, int> ask(int x, int l, int r, int goal_l, int goal_r) {
  if (goal_l <= l && goal_r >= r) return make_pair(maxx[x], ind[x]);
  int mid = (l + r) >> 1;
  pair<int, int> res;
  if (goal_l <= mid) res = max(res, ask(x << 1, l, mid, goal_l, goal_r));
  if (goal_r > mid) res = max(res, ask(x << 1 | 1, mid + 1, r, goal_l, goal_r));
  return res;
}
int main() {
  memset(head, -1, sizeof(head));
  int n = readint(), m = readint(), q = readint();
  for (int i = 1; i <= n; i++) {
    a[i] = readint();
  }
  for (int i = 1; i <= m; i++) s[i].u = readint(), s[i].v = readint();
  for (int i = 1; i <= q; i++) {
    query[i].op = readint(), query[i].id = readint();
    if (query[i].op == 2) vis[query[i].id] = 1;
  }
  for (int i = 1; i <= n + q; i++) fa[i] = i;
  for (int i = 1; i <= m; i++) {
    if (vis[i]) continue;
    int u = s[i].u, v = s[i].v;
    int fu = findset(u), fv = findset(v);
    if (fu == fv) continue;
    fa[fu] = fv;
    addedge(u, v);
  }
  for (int i = q; i; i--) {
    if (query[i].op == 2) {
      int id = query[i].id;
      int u = s[id].u, v = s[id].v;
      int fu = findset(u), fv = findset(v);
      if (fu == fv) continue;
      n++;
      fa[fu] = n;
      fa[fv] = n;
      addedge(n, fu);
      addedge(n, fv);
    } else
      query[i].belong = findset(query[i].id);
  }
  for (int i = 1; i <= n; i++)
    if (!dfn[i]) {
      dfs(findset(i), 0);
    }
  build(1, 1, dfn_cnt);
  for (int i = 1; i <= q; i++) {
    if (query[i].op == 1) {
      pair<int, int> ans =
          ask(1, 1, dfn_cnt, dfn[query[i].belong], dfn_en[query[i].belong]);
      if (ans.first > 0) modify(1, 1, dfn_cnt, ans.second);
      printf("%d\n", ans.first);
    }
  }
  return 0;
}
