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>
namespace atcoder {
namespace internal {
int ceil_pow2(int n) {
  int x = 0;
  while ((1U << x) < (unsigned int)(n)) x++;
  return x;
}
int bsf(unsigned int n) { return __builtin_ctz(n); }
}  // namespace internal
}  // namespace atcoder
namespace atcoder {
template <class S, S (*op)(S, S), S (*e)()>
struct segtree {
 public:
  segtree() : segtree(0) {}
  segtree(int n) : segtree(std::vector<S>(n, e())) {}
  segtree(const std::vector<S>& v) : _n(int(v.size())) {
    log = internal::ceil_pow2(_n);
    size = 1 << log;
    d = std::vector<S>(2 * size, e());
    for (int i = 0; i < _n; i++) d[size + i] = v[i];
    for (int i = size - 1; i >= 1; i--) {
      update(i);
    }
  }
  void set(int p, S x) {
    assert(0 <= p && p < _n);
    p += size;
    d[p] = x;
    for (int i = 1; i <= log; i++) update(p >> i);
  }
  S get(int p) {
    assert(0 <= p && p < _n);
    return d[p + size];
  }
  S prod(int l, int r) {
    assert(0 <= l && l <= r && r <= _n);
    S sml = e(), smr = e();
    l += size;
    r += size;
    while (l < r) {
      if (l & 1) sml = op(sml, d[l++]);
      if (r & 1) smr = op(d[--r], smr);
      l >>= 1;
      r >>= 1;
    }
    return op(sml, smr);
  }
  S all_prod() { return d[1]; }
  template <bool (*f)(S)>
  int max_right(int l) {
    return max_right(l, [](S x) { return f(x); });
  }
  template <class F>
  int max_right(int l, F f) {
    assert(0 <= l && l <= _n);
    assert(f(e()));
    if (l == _n) return _n;
    l += size;
    S sm = e();
    do {
      while (l % 2 == 0) l >>= 1;
      if (!f(op(sm, d[l]))) {
        while (l < size) {
          l = (2 * l);
          if (f(op(sm, d[l]))) {
            sm = op(sm, d[l]);
            l++;
          }
        }
        return l - size;
      }
      sm = op(sm, d[l]);
      l++;
    } while ((l & -l) != l);
    return _n;
  }
  template <bool (*f)(S)>
  int min_left(int r) {
    return min_left(r, [](S x) { return f(x); });
  }
  template <class F>
  int min_left(int r, F f) {
    assert(0 <= r && r <= _n);
    assert(f(e()));
    if (r == 0) return 0;
    r += size;
    S sm = e();
    do {
      r--;
      while (r > 1 && (r % 2)) r >>= 1;
      if (!f(op(d[r], sm))) {
        while (r < size) {
          r = (2 * r + 1);
          if (f(op(d[r], sm))) {
            sm = op(d[r], sm);
            r--;
          }
        }
        return r + 1 - size;
      }
      sm = op(d[r], sm);
    } while ((r & -r) != r);
    return 0;
  }

 private:
  int _n, size, log;
  std::vector<S> d;
  void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};
}  // namespace atcoder
using namespace std;
using namespace atcoder;
const long long INF = 2e18;
const long long fact_table = 3200008;
priority_queue<long long> pql;
priority_queue<pair<long long, long long>> pqp;
priority_queue<long long, vector<long long>, greater<long long>> pqls;
priority_queue<pair<long long, long long>, vector<pair<long long, long long>>,
               greater<pair<long long, long long>>>
    pqps;
long long dx[8] = {1, 0, -1, 0, 1, 1, -1, -1};
long long dy[8] = {0, 1, 0, -1, 1, -1, -1, 1};
const long long mod = 998244353ll;
long long mypow(long long a, long long b, long long m = mod) {
  long long x = 1;
  while (b) {
    while (!(b & 1)) {
      (a *= a) %= m;
      b >>= 1;
    }
    (x *= a) %= m;
    b--;
  }
  return x;
}
vector<long long> readvec(long long read) {
  vector<long long> res(read);
  for (int i = 0; i < read; i++) {
    cin >> res[i];
  }
  return res;
}
void YES(bool cond) {
  if (cond) {
    cout << "YES" << endl;
    ;
  } else {
    cout << "NO" << endl;
    ;
  }
  return;
}
void Yes(bool cond) {
  if (cond) {
    cout << "Yes" << endl;
    ;
  } else {
    cout << "No" << endl;
    ;
  }
  return;
}
void line() {
  cout << "--------------------" << endl;
  ;
  return;
}
pair<long long, long long> edges[300005], query[500005];
bool multicase = false;
bool WillDelete[300005];
bool marked[500005];
vector<long long> G[800005];
long long parent[800005];
long long lef[800005], righ[800005];
long long bossnode;
struct S {
  long long v, id;
};
S op(S l, S r) {
  if (l.v > r.v) {
    return (S){l.v, l.id};
  } else {
    return (S){r.v, r.id};
  }
}
S e() { return (S){0, -1}; }
void add_edge(int v, int u) {
  G[v].push_back(u);
  G[u].push_back(v);
  return;
}
long long findd(int v) {
  if (parent[v] == v) {
    return v;
  } else {
    return parent[v] = findd(parent[v]);
  }
}
void merge(int v, int u, bool newboss) {
  v = findd(v);
  u = findd(u);
  if (v == u) return;
  if (!newboss) {
    parent[v] = u;
    add_edge(u, v);
  } else {
    parent[v] = bossnode;
    parent[u] = bossnode;
    parent[bossnode] = bossnode;
    add_edge(u, bossnode);
    add_edge(v, bossnode);
    bossnode++;
  }
}
void dfs(long long v, long long p, int& idx) {
  lef[v] = idx++;
  for (auto u : G[v]) {
    if (u != p) dfs(u, v, idx);
  }
  righ[v] = idx;
}
void init(long long n) {
  for (int i = 0; i <= n; i++) {
    parent[i] = i;
  }
  return;
}
void solve() {
  long long n, m, q;
  cin >> n >> m >> q;
  init(n);
  bossnode = n + 1;
  vector<long long> po(n);
  for (int i = 0; i < n; i++) {
    cin >> po[i];
  }
  for (int i = 0; i < m; i++) {
    long long a, b;
    cin >> a >> b;
    edges[i].first = a, edges[i].second = b;
  }
  for (int i = 0; i < q; i++) {
    long long type, num;
    cin >> type >> num;
    query[i].first = type, query[i].second = num;
    if (type == 2) {
      WillDelete[num - 1] = true;
    }
  }
  for (int i = 0; i < m; i++) {
    if (WillDelete[i]) continue;
    merge(edges[i].first, edges[i].second, false);
  }
  vector<long long> nodes;
  for (int i = q - 1; i >= 0; i--) {
    long long type = query[i].first;
    if (type == 1) {
      long long node = query[i].second;
      long long p = findd(node);
      nodes.push_back(p);
    } else {
      long long idx = query[i].second - 1;
      int v = edges[idx].first, u = edges[idx].second;
      merge(u, v, true);
    }
  }
  reverse(nodes.begin(), nodes.end());
  int id = 0;
  for (int i = 1; i < bossnode; i++) {
    if (marked[findd(i)]) continue;
    marked[findd(i)] = true;
    dfs(findd(i), -1, id);
  }
  for (int i = 1; i <= n; i++) {
  }
  segtree<S, op, e> seg(800000);
  for (int i = 1; i <= n; i++) {
    seg.set(lef[i], (S){po[i - 1], lef[i]});
  }
  for (auto v : nodes) {
    auto ans = seg.prod(lef[v], righ[v]);
    if (ans.v > 0) seg.set(ans.id, (S){0, ans.id});
    cout << ans.v << endl;
    ;
  }
  return;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  long long q, testcase = 1;
  if (multicase) {
    cin >> q;
  } else {
    q = 1;
  }
  while (q--) {
    solve();
    testcase++;
  }
  return 0;
}
