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 INF = 0x3f3f3f3f;
const double eps = 1e-8;
const int maxn = 2e6 + 5;
const int maxm = 5e5 + 5;
const int maxp = 5e5 + 5;
inline long long read() {
  long long ans = 0;
  char ch = getchar(), las = ' ';
  while (!isdigit(ch)) las = ch, ch = getchar();
  while (isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
  if (las == '-') ans = -ans;
  return ans;
}
inline void write(long long x) {
  if (x < 0) x = -x, putchar('-');
  if (x >= 10) write(x / 10);
  putchar(x % 10 + '0');
}
inline void MYFILE() {
  freopen(".in", "r", stdin);
  freopen(".out", "w", stdout);
}
int n, m, op, a[maxn];
pair<int, int> E[maxm], Op[maxp];
struct Edge {
  int nxt, to;
} e[maxn];
int head[maxn], ecnt = -1;
inline void addEdge(int x, int y) {
  e[++ecnt] = (Edge){head[x], y};
  head[x] = ecnt;
}
bool visE[maxm];
int p[maxn], cnt = 0;
inline int Find(int x) { return x == p[x] ? x : p[x] = Find(p[x]); }
inline void merge(int x, int y) {
  int px = Find(x), py = Find(y);
  if (px == py) return;
  ++cnt;
  p[px] = p[py] = cnt;
  addEdge(cnt, px), addEdge(cnt, py);
}
inline void init() {
  memset(head, -1, sizeof(head)), cnt = n;
  for (int i = 1; i < maxn; ++i) p[i] = i;
  for (int i = 1; i <= op; ++i)
    if (Op[i].first == 2) visE[Op[i].second] = 1;
  for (int i = 1; i <= m; ++i)
    if (!visE[i]) merge(E[i].first, E[i].second);
}
bool vis[maxn];
int cnt2 = 0, d[maxn], pos[maxn], siz[maxn];
inline void dfs(int now) {
  siz[now] = vis[now] = 1, d[++cnt2] = now, pos[now] = cnt2;
  for (int i = head[now], v; ~i && (v = e[i].to); i = e[i].nxt)
    dfs(v), siz[now] += siz[v];
}
int l[maxn << 1], r[maxn << 1];
pair<int, int> Max[maxn << 1];
inline void build(int L, int R, int now) {
  l[now] = L, r[now] = R;
  if (L == R) {
    Max[now] = make_pair(a[d[L]], L);
    return;
  }
  int mid = (L + R) >> 1;
  build(L, mid, now << 1), build(mid + 1, R, now << 1 | 1);
  Max[now] = max(Max[now << 1], Max[now << 1 | 1]);
}
inline void update(int x, int now) {
  if (l[now] == r[now]) {
    Max[now] = make_pair(0, l[now]);
    return;
  }
  int mid = (l[now] + r[now]) >> 1;
  if (x <= mid)
    update(x, now << 1);
  else
    update(x, now << 1 | 1);
  Max[now] = max(Max[now << 1], Max[now << 1 | 1]);
}
inline pair<int, int> query(int L, int R, int now) {
  if (l[now] == L && r[now] == R) return Max[now];
  int mid = (l[now] + r[now]) >> 1;
  if (R <= mid)
    return query(L, R, now << 1);
  else if (L > mid)
    return query(L, R, now << 1 | 1);
  else
    return max(query(L, mid, now << 1), query(mid + 1, R, now << 1 | 1));
}
int ans[maxp];
inline void work() {
  for (int i = op; i; --i) {
    if (Op[i].first == 1)
      ans[i] = Find(Op[i].second);
    else
      merge(E[Op[i].second].first, E[Op[i].second].second);
  }
  for (int i = 1; i <= cnt; ++i)
    if (p[i] == i && !vis[i]) dfs(i);
  build(1, cnt2, 1);
  for (int i = 1; i <= op; ++i) {
    if (Op[i].first == 1) {
      int x = ans[i];
      pair<int, int> tp = query(pos[x], pos[x] + siz[x] - 1, 1);
      write(tp.first), puts("");
      update(tp.second, 1);
    }
  }
}
int main() {
  n = read(), m = read(), op = read();
  for (int i = 1; i <= n; ++i) a[i] = read();
  for (int i = 1; i <= m; ++i) E[i].first = read(), E[i].second = read();
  for (int i = 1; i <= op; ++i) Op[i].first = read(), Op[i].second = read();
  init(), work();
  return 0;
}
