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;
std::mt19937 rnd(
    (int)std::chrono::steady_clock::now().time_since_epoch().count());
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 200000;
const int MAXM = 300000;
const int MAXQ = 500000;
const int MAXLG = 19;
const int MAXS = 4 * MAXN;
struct E {
  int a, b;
};
int n, m, nq;
int val[MAXN];
E e[MAXM];
int qkind[MAXQ], qv[MAXQ], qidx[MAXQ], qans[MAXQ];
int trem[MAXM];
pair<int, int> edgeorder[MAXM];
bool intree[MAXM];
struct UF {
  int n;
  vector<int> par, sz;
  void init(int _n) {
    n = _n;
    par = sz = vector<int>(n);
    for (int i = (0); i < (n); ++i) par[i] = i, sz[i] = 1;
  }
  int find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }
  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y) return false;
    if (sz[x] < sz[y]) swap(x, y);
    par[y] = x, sz[x] += sz[y];
    return true;
  }
};
UF uf;
int root[MAXN];
int par[MAXM + MAXN];
vector<int> ch[MAXM + MAXN];
pair<int, int> up[MAXM + MAXN][MAXLG + 1];
int lid[MAXM + MAXN], rid[MAXM + MAXN], nid;
int who[MAXN];
void dfsid(int at) {
  lid[at] = nid;
  if (at >= m) who[nid] = at - m, ++nid;
  for (int i = (0); i < (((int)(ch[at]).size())); ++i) dfsid(ch[at][i]);
  rid[at] = nid;
}
void printtree(int at, int dep) {
  for (int i = (0); i < (dep); ++i) printf("  ");
  printf("%d\n", at);
  for (int i = (0); i < (((int)(ch[at]).size())); ++i)
    printtree(ch[at][i], dep + 1);
}
int jump(int at, int t) {
  for (int k = MAXLG; k >= 0; --k)
    if (t < up[at][k].second) at = up[at][k].first;
  return at;
}
pair<int, int> sval[MAXS];
void spull(int x) {
  pair<int, int> a = sval[2 * x + 1], b = sval[2 * x + 2];
  sval[x] = a;
  if (b.first > a.first || b.first == a.first && b.second < a.second)
    sval[x] = b;
}
void sinit(int x, int l, int r) {
  if (l == r) {
    sval[x] = make_pair(val[who[l]], l);
  } else {
    int m = l + (r - l) / 2;
    sinit(2 * x + 1, l, m);
    sinit(2 * x + 2, m + 1, r);
    spull(x);
  }
}
void smod(int x, int l, int r, int IDX, int VAL) {
  if (l == r) {
    sval[x] = make_pair(VAL, l);
  } else {
    int m = l + (r - l) / 2;
    if (IDX <= m) smod(2 * x + 1, l, m, IDX, VAL);
    if (m + 1 <= IDX) smod(2 * x + 2, m + 1, r, IDX, VAL);
    spull(x);
  }
}
pair<int, int> sget(int x, int l, int r, int L, int R) {
  if (L <= l && r <= R) {
    return sval[x];
  } else {
    int m = l + (r - l) / 2;
    pair<int, int> ret = make_pair(INT_MIN, -1);
    if (L <= m) {
      pair<int, int> cur = sget(2 * x + 1, l, m, L, R);
      if (cur.first > ret.first ||
          cur.first == ret.first && cur.second < ret.second)
        ret = cur;
    }
    if (m + 1 <= R) {
      pair<int, int> cur = sget(2 * x + 2, m + 1, r, L, R);
      if (cur.first > ret.first ||
          cur.first == ret.first && cur.second < ret.second)
        ret = cur;
    }
    return ret;
  }
}
void solve() {
  for (int i = (0); i < (m); ++i) trem[i] = nq;
  for (int i = (0); i < (nq); ++i)
    if (qkind[i] == 2) trem[qidx[i]] = i;
  for (int i = (0); i < (m); ++i) edgeorder[i] = make_pair(-trem[i], i);
  sort(edgeorder, edgeorder + m);
  uf.init(n);
  for (int i = (0); i < (m); ++i) {
    int id = edgeorder[i].second;
    intree[id] = uf.unite(e[id].a, e[id].b);
  }
  uf.init(n);
  for (int i = (0); i < (m + n); ++i) par[i] = -1;
  for (int i = (0); i < (n); ++i) root[i] = m + i;
  for (int i = (0); i < (m); ++i) {
    int id = edgeorder[i].second;
    if (!intree[id]) continue;
    int x = uf.find(e[id].a), y = uf.find(e[id].b);
    assert(x != y);
    ch[id].push_back(root[x]);
    ch[id].push_back(root[y]);
    par[root[x]] = par[root[y]] = id;
    assert(uf.unite(x, y));
    root[uf.find(x)] = id;
  }
  for (int i = (0); i < (m + n); ++i)
    up[i][0] =
        par[i] == -1 ? make_pair(i, nq) : make_pair(par[i], trem[par[i]]);
  for (int k = (0); k < (MAXLG); ++k)
    for (int i = (0); i < (m + n); ++i)
      up[i][k + 1] =
          make_pair(up[up[i][k].first][k].first,
                    min(up[i][k].second, up[up[i][k].first]->second));
  nid = 0;
  for (int i = (0); i < (m + n); ++i)
    if (par[i] == -1) dfsid(i);
  assert(nid == n);
  sinit(0, 0, n - 1);
  for (int i = (0); i < (nq); ++i)
    if (qkind[i] == 1) {
      int at = jump(m + qv[i], i);
      assert(lid[at] < rid[at]);
      pair<int, int> cur = sget(0, 0, n - 1, lid[at], rid[at] - 1);
      qans[i] = cur.first;
      smod(0, 0, n - 1, cur.second, 0);
    }
}
void run() {
  scanf("%d%d%d", &n, &m, &nq);
  for (int i = (0); i < (n); ++i) scanf("%d", &val[i]);
  for (int i = (0); i < (m); ++i)
    scanf("%d%d", &e[i].a, &e[i].b), --e[i].a, --e[i].b;
  for (int i = (0); i < (nq); ++i) {
    scanf("%d", &qkind[i]);
    if (qkind[i] == 1) scanf("%d", &qv[i]), --qv[i];
    if (qkind[i] == 2) scanf("%d", &qidx[i]), --qidx[i];
  }
  solve();
  for (int i = (0); i < (nq); ++i)
    if (qkind[i] == 1) printf("%d\n", qans[i]);
}
int main() {
  run();
  return 0;
}
