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 long long N = 5e5 + 5;
const long long M = 4e6 + 5;
const long long mod = 1e9 + 7;
const long long INF = 0x7f7f7f7f7f7f7f7f;
const int INFi = 0x7f7f7f7f;
int n, m, q, a[N], u[N], v[N], rem[N], X[N], Y[N];
int p[N], sz[N], l[N], r[N], ind[N];
vector<long long> adj[N];
struct NODE {
  int val, ind;
  NODE() : val(), ind() {}
  NODE(int v, int i) : val(v), ind(i) {}
};
NODE tree[4 * N + 8];
NODE combine(NODE a, NODE b) {
  NODE c;
  c.val = max(a.val, b.val);
  if (c.val == a.val)
    c.ind = a.ind;
  else
    c.ind = b.ind;
  return c;
}
void build(int node, int p, int start, int end) {
  if (start == end) {
    tree[node] = NODE(a[adj[p][start - 1]], start);
  } else {
    int mid = (start + end) / 2;
    build(2 * node, p, start, mid);
    build(2 * node + 1, p, mid + 1, end);
    tree[node] = combine(tree[2 * node], tree[2 * node + 1]);
  }
}
void update(int node, int start, int end, int idx) {
  if (start == end) {
    tree[node] = NODE(0, idx);
  } else {
    int mid = (start + end) / 2;
    if (start <= idx and idx <= mid)
      update(2 * node, start, mid, idx);
    else
      update(2 * node + 1, mid + 1, end, idx);
    tree[node] = combine(tree[2 * node], tree[2 * node + 1]);
  }
}
NODE query(int node, int start, int end, int l, int r) {
  if (start > end or start > r or end < l) return NODE();
  if (l <= start and end <= r) return tree[node];
  int mid = (start + end) / 2;
  NODE p1 = query(2 * node, start, mid, l, r);
  NODE p2 = query(2 * node + 1, mid + 1, end, l, r);
  return combine(p1, p2);
}
void make(long long n) {
  for (int i = 1; i <= n; i++) {
    p[i] = i;
    sz[i] = 1;
    adj[i].push_back(i);
  }
}
int find(long long x) { return (p[x] == x) ? x : p[x] = find(p[x]); }
void merge(long long x, long long y) {
  long long a = find(x);
  long long b = find(y);
  if (a != b) {
    if (sz[a] >= sz[b]) swap(a, b);
    p[a] = b;
    sz[b] += sz[a];
    for (auto it : adj[a]) adj[b].push_back(it);
    adj[a].clear();
  }
}
void solve() {
  cin >> n >> m >> q;
  make(n);
  for (int i = 1; i <= n; i++) cin >> a[i];
  for (int i = 1; i <= m; i++) cin >> u[i] >> v[i];
  for (int i = 1; i <= q; i++) {
    cin >> X[i] >> Y[i];
    if (X[i] == 2) rem[Y[i]] = 1;
  }
  for (int i = 1; i <= m; i++) {
    if (rem[i] == 1) continue;
    merge(u[i], v[i]);
  }
  for (int i = q; i >= 1; i--) {
    if (X[i] == 2)
      merge(u[Y[i]], v[Y[i]]);
    else {
      int x = find(Y[i]);
      l[i] = adj[x].front(), r[i] = adj[x].back();
    }
  }
  for (int i = 2; i <= n; i++) merge(1, i);
  int p = find(1);
  for (int i = 0; i < n; i++) ind[adj[p][i]] = i + 1;
  build(1, p, 1, n);
  for (int i = 1; i <= q; i++) {
    if (X[i] == 2) continue;
    NODE c = query(1, 1, n, ind[l[i]], ind[r[i]]);
    if (c.ind) update(1, 1, n, c.ind);
    cout << c.val << "\n";
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << fixed;
  cout << setprecision(15);
  ;
  int test = 1;
  for (int i = 1; i <= test; i++) {
    solve();
  }
}
