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;
long long mod = 1000000007;
long long inf = 1LL << 50;
const int N = 500000;
vector<int> tree;
vector<int> ranks;
vector<int> graph[N];
pair<int, int> range[N];
vector<int> traverse;
struct segTreeMax {
  vector<pair<int, int> > tree;
  int len;
  segTreeMax(const vector<int> &input, int l) {
    tree = vector<pair<int, int> >(2 * (int)pow(2, ceil(log2(l))) - 1);
    len = l;
    constructTree(0, len - 1, 0, input);
  }
  void constructTree(int low, int high, int pos, const vector<int> &input) {
    if (low == high) {
      tree[pos] = {input[low], low};
      return;
    }
    int mid = (low + high) / 2;
    constructTree(low, mid, pos * 2 + 1, input);
    constructTree(mid + 1, high, pos * 2 + 2, input);
    tree[pos] = max(tree[pos * 2 + 2], tree[pos * 2 + 1]);
  }
  pair<int, int> query(int low, int high) {
    return rangeMax(low, high, 0, len - 1, 0);
  }
  pair<int, int> rangeMax(int qlow, int qhigh, int low, int high, int pos) {
    if (qlow <= low && qhigh >= high) {
      return tree[pos];
    }
    if (qlow > high || low > qhigh) {
      return {-2147483648, 0};
    }
    int mid = (low + high) / 2;
    return max(rangeMax(qlow, qhigh, low, mid, pos * 2 + 1),
               rangeMax(qlow, qhigh, mid + 1, high, pos * 2 + 2));
  }
  void update(int pos, int newVal) { update(pos, 0, len - 1, 0, newVal); }
  void update(int i, int low, int high, int pos, int newVal) {
    if (i > high || low > i) {
      return;
    }
    if (low != high) {
      int mid = (low + high) / 2;
      update(i, low, mid, pos * 2 + 1, newVal);
      update(i, mid + 1, high, pos * 2 + 2, newVal);
      tree[pos] = max(tree[pos * 2 + 1], tree[pos * 2 + 2]);
    } else {
      tree[pos].first = newVal;
    }
  }
};
int find(int x) {
  while (x != tree[x]) {
    x = tree[x];
  }
  return x;
}
void link(int x, int y) {
  if (ranks[x] > ranks[y]) {
    tree[y] = x;
  } else {
    tree[x] = y;
    if (ranks[x] == ranks[y]) {
      ranks[y]++;
    }
  }
}
int arr[N];
pair<int, int> edges[N];
pair<int, int> queries[N];
int ans[N];
vector<int> pq[N];
vector<pair<int, int> > events[N];
bool off[N];
void dfs(int curr) {
  range[curr].first = traverse.size();
  traverse.push_back(arr[curr]);
  for (int i : graph[curr]) {
    dfs(i);
  }
  range[curr].second = traverse.size() - 1;
}
void recurse(int curr, segTreeMax &st) {
  int itr = events[curr].size() - 1;
  for (int i : pq[curr]) {
  }
  for (int i = pq[curr].size() - 1; i >= 0; i--) {
    while (itr >= 0 && events[curr][itr].first < pq[curr][i]) {
      recurse(events[curr][itr].second, st);
      itr--;
    }
    pair<int, int> query = st.query(range[curr].first, range[curr].second);
    ans[pq[curr][i]] = query.first;
    st.update(query.second, 0);
  }
  while (itr >= 0) {
    recurse(events[curr][itr].second, st);
    itr--;
  }
  for (int i = range[curr].first; i <= range[i].second; i++) {
    st.update(i, 0);
  }
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin.exceptions(cin.failbit);
  int n, m, q;
  cin >> n >> m >> q;
  for (int i = 0; i < n; i++) {
    cin >> arr[i + 1];
  }
  for (int i = 0; i < m; i++) {
    cin >> edges[i].first >> edges[i].second;
  }
  for (int i = 0; i < q; i++) {
    int a;
    cin >> a;
    if (a == 1) {
      queries[i].first = -1;
      cin >> queries[i].second;
    } else {
      cin >> queries[i].first;
      queries[i].first--;
      off[queries[i].first] = true;
      queries[i] = edges[queries[i].first];
    }
  }
  tree.resize(n + 1);
  ranks.resize(n + 1);
  for (int i = 0; i <= n; i++) {
    tree[i] = i;
  }
  for (int i = 0; i < m; i++) {
    if (!off[i]) {
      int a = find(edges[i].first);
      int b = find(edges[i].second);
      if (a != b) {
        link(a, b);
        if (tree[a] == b) {
          graph[b].push_back(a);
        } else {
          graph[a].push_back(b);
        }
      }
    }
  }
  for (int i = q - 1; i >= 0; i--) {
    if (queries[i].first != -1) {
      int x = find(queries[i].first);
      int y = find(queries[i].second);
      if (x != y) {
        link(x, y);
        if (tree[x] == y) {
          events[y].push_back({i, x});
          graph[y].push_back(x);
        } else {
          events[x].push_back({i, y});
          graph[x].push_back(y);
        }
      }
    } else {
      pq[find(queries[i].second)].push_back(i);
    }
  }
  for (int i = 1; i <= n; i++) {
    if (tree[i] == i) {
      graph[0].push_back(i);
    }
  }
  dfs(0);
  segTreeMax st(traverse, n + 1);
  for (int i : graph[0]) {
    recurse(i, st);
  }
  for (int i = 0; i < q; i++) {
    if (queries[i].first == -1) {
      cout << ans[i] << "\n";
    }
  }
}
