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 inf = 1e9 + 7;
const long long INF = 1LL << 60;
const long long mod = 1e9 + 7;
const long double eps = 1e-8;
const long double pi = acos(-1.0);
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
long long n, m, q;
vector<long long> p;
vector<pair<long long, long long>> es;
struct UnionFind {
  long long n;
  vector<long long> par;
  vector<set<long long>> nums;
  vector<vector<long long>> add;
  vector<pair<long long, set<long long>>> addp;
  vector<bool> ers;
  UnionFind(long long n_)
      : n(n_), par(n_, -1), nums(n_, set<long long>()), ers(n_ + 1, false) {
    for (long long i = 0; i < n_; i++) {
      nums[i].insert(p[i]);
    }
  }
  long long root(long long x) {
    if (par[x] < 0) return x;
    return root(par[x]);
  }
  void pop() {
    if (add.size()) {
      auto ad = add.back();
      add.pop_back();
      auto adp = addp.back();
      addp.pop_back();
      par[ad[0]] = ad[1], par[ad[2]] = ad[3];
      for (long long z : adp.second) {
        if (n == 96) cout << ad[0] << " " << ad[2] << " " << z << endl;
        if (ers[z]) {
          if (n == 96) cout << "ers" << z << endl;
          if (n != 96) nums[ad[2]].erase(z);
        }
        if (n != 96) nums[ad[0]].erase(z);
      }
    }
  }
  bool merge(long long x, long long y) {
    x = root(x), y = root(y);
    if (x == y) return false;
    if (par[x] > par[y]) swap(x, y);
    add.push_back({x, par[x], y, par[y]});
    set<long long> adp;
    for (long long z : nums[y]) {
      nums[x].insert(z);
      adp.insert(z);
    }
    addp.push_back({x, adp});
    par[x] += par[y];
    par[y] = x;
    return true;
  }
  long long ans(long long x) {
    x = root(x);
    if (nums[x].empty()) {
      return 0;
    }
    auto ite = nums[x].end();
    --ite;
    ers[(*ite)] = true;
    nums[x].erase(*ite);
    return *ite;
  }
};
void solve() {
  cin >> n >> m >> q;
  p.resize(n);
  for (long long i = 0; i < n; i++) {
    cin >> p[i];
  }
  es.resize(m);
  for (long long i = 0; i < m; i++) {
    long long a, b;
    cin >> a >> b;
    --a, --b;
    es[i] = {a, b};
  }
  vector<long long> t(q), v(q, -1), id(q, -1);
  vector<bool> used(m, 0);
  for (long long i = 0; i < q; i++) {
    cin >> t[i];
    if (t[i] == 1) {
      cin >> v[i];
      --v[i];
    } else {
      cin >> id[i];
      --id[i];
      used[id[i]] = 1;
    }
  }
  UnionFind uf(n);
  for (long long i = 0; i < m; i++) {
    if (!used[i]) {
      uf.merge(es[i].first, es[i].second);
    }
  }
  for (long long i = q - 1; i >= 0; i--) {
    if (t[i] == 2) {
      uf.merge(es[id[i]].first, es[id[i]].second);
    }
  }
  for (long long i = 0; i < q; i++) {
    if (t[i] == 1) {
      cout << uf.ans(v[i]) << endl;
    } else {
      uf.pop();
    }
  }
}
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  solve();
  return 0;
}
