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;
struct dsu {
  std::vector<int> p;
  int n;
  dsu(int N) {
    n = N;
    p.resize(n);
    iota(p.begin(), p.end(), 0);
  }
  inline int getparent(int i) {
    return ((p[i] == i) ? i : (p[i] = getparent(p[i])));
  }
  bool unite(int x, int y) {
    x = getparent(x);
    y = getparent(y);
    if (x != y) {
      p[x] = y;
      return true;
    }
    return false;
  }
};
struct segtree {
  int treesize;
  vector<pair<int, int> > values;
  pair<int, int> IDENTITY_ELEMENT;
  inline void makeSINGLE(pair<int, int> &t, long long int a, int index) {
    t = {a, index};
  }
  inline void merge(pair<int, int> &ans, pair<int, int> &i1,
                    pair<int, int> &i2) {
    ans = i1.first > i2.first ? i1 : i2;
  }
  void build(vector<long long int> &a, int curr, int l, int r) {
    if (l == r) {
      if (l < (int)a.size()) {
        makeSINGLE(values[curr], a[l], l);
      }
      return;
    }
    int mid = (l + r) / 2;
    build(a, 2 * curr + 1, l, mid);
    build(a, 2 * curr + 2, mid + 1, r);
    merge(values[curr], values[2 * curr + 1], values[2 * curr + 2]);
  }
  segtree(int n, pair<int, int> identity) {
    treesize = 1;
    IDENTITY_ELEMENT = identity;
    while (treesize < n) {
      treesize *= 2;
    }
    values.assign(2 * treesize, IDENTITY_ELEMENT);
  }
  segtree(int n, pair<int, int> identity, vector<long long int> &a) {
    treesize = 1;
    IDENTITY_ELEMENT = identity;
    while (treesize < n) {
      treesize *= 2;
    }
    values.assign(2 * treesize, IDENTITY_ELEMENT);
    build(a, 0, 0, treesize - 1);
  }
  void set(int i, pair<int, int> &newval, int curr, int l, int r) {
    if (l == r) {
      values[curr] = newval;
      return;
    }
    int mid = (l + r) / 2;
    (i <= mid) ? set(i, newval, 2 * curr + 1, l, mid)
               : set(i, newval, 2 * curr + 2, mid + 1, r);
    merge(values[curr], values[2 * curr + 1], values[2 * curr + 2]);
  }
  inline void set(int i, long long int val) {
    pair<int, int> newval;
    makeSINGLE(newval, val, i);
    set(i, newval, 0, 0, treesize - 1);
  }
  void segmentval(pair<int, int> &ans, int ql, int qr, int curr, int l, int r) {
    if (l > qr || ql > r) {
      return;
    }
    if (l >= ql && r <= qr) {
      merge(ans, ans, values[curr]);
      return;
    }
    int mid = (l + r) / 2;
    segmentval(ans, ql, qr, 2 * curr + 1, l, mid);
    segmentval(ans, ql, qr, 2 * curr + 2, mid + 1, r);
  }
  inline pair<int, int> segmentval(int ql, int qr) {
    pair<int, int> ans = IDENTITY_ELEMENT;
    segmentval(ans, ql, qr, 0, 0, treesize - 1);
    return ans;
  }
};
int main() {
  ios_base ::sync_with_stdio(0);
  cin.tie(0);
  int n, m, q;
  cin >> n >> m >> q;
  std::vector<int> eds(m);
  std::vector<int> ede(m);
  vector<int> vals(n);
  for (long long int i = 0; i < n; i++) cin >> vals[i];
  for (long long int i = 0; i < m; i++) {
    cin >> eds[i] >> ede[i];
    eds[i]--;
    ede[i]--;
  }
  std::vector<int> op(q);
  vector<int> num(q);
  for (int i = 0; i < q; i++) {
    cin >> op[i] >> num[i];
    num[i]--;
  }
  vector<int> mark(m, 0);
  for (int i = 0; i < q; i++) {
    if (op[i] == 2) {
      mark[num[i]] = true;
    }
  }
  dsu s(n);
  vector<int> st(n);
  vector<int> end(n);
  vector<int> nxt(n, -1);
  iota(st.begin(), st.end(), 0);
  iota(end.begin(), end.end(), 0);
  for (int i = 0; i < m; i++) {
    if (!mark[i]) {
      int t1 = s.getparent(eds[i]);
      int t2 = s.getparent(ede[i]);
      if (t1 != t2) {
        s.unite(t1, t2);
        nxt[end[t1]] = st[t2];
        st[t2] = st[t1];
      }
    }
  }
  vector<pair<int, int> > que(q);
  for (int i = q - 1; i > -1; i--) {
    if (op[i] == 2) {
      int t1 = s.getparent(eds[num[i]]);
      int t2 = s.getparent(ede[num[i]]);
      if (t1 != t2) {
        s.unite(t1, t2);
        nxt[end[t1]] = st[t2];
        st[t2] = st[t1];
      }
    } else {
      int par = s.getparent(num[i]);
      que[i].first = st[par];
      que[i].second = end[par];
    }
  }
  vector<int> seq;
  for (int i = 0; i < n; i++) {
    if (s.p[i] == i) {
      int cur = st[i];
      while (1) {
        seq.push_back(cur);
        if (cur == end[i]) break;
        cur = nxt[cur];
      }
    }
  }
  vector<int> inv_seq(n);
  vector<long long int> arr(n);
  for (int i = 0; i < n; i++) {
    inv_seq[seq[i]] = i;
    arr[i] = vals[seq[i]];
  }
  pair<int, int> identity = {INT_MIN, -1};
  segtree tree(n, identity, arr);
  for (int i = 0; i < q; i++) {
    if (op[i] == 1) {
      pair<int, int> ans =
          tree.segmentval(inv_seq[que[i].first], inv_seq[que[i].second]);
      cout << ans.first << "\n";
      tree.set(ans.second, 0);
    }
  }
}
