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;
using ll = long long;
void cmax(int &x, const int &y) { x = x > y ? x : y; }
void cmin(int &x, const int &y) { x = x < y ? x : y; }
template <class T>
istream &operator>>(istream &in, vector<T> &V) {
  for (auto &x : V) in >> x;
  return in;
}
template <class T>
ostream &operator<<(ostream &out, const vector<T> &V) {
  for (auto x : V) out << x << ' ';
  return out;
}
template <class T>
void sort(vector<T> &V) {
  sort(V.begin(), V.end());
}
template <class T>
void reverse(vector<T> &V) {
  reverse(V.begin(), V.end());
}
template <class T>
int SZ(const vector<T> &V) {
  return (int)V.size();
}
void debug() { cerr << "whxorz" << '\n'; }
const int N = 2e5 + 5;
const int M = 3e5 + 5;
const int Q = 5e5 + 5;
int n, m, q;
int _p[N];
int opt[Q], opx[Q];
struct Edge {
  int u, v, w;
  bool operator<(const Edge &rhs) const { return w > rhs.w; }
} edge[M];
const int T = N << 1;
vector<int> g[T];
int fa[T], val[T];
const int K = 19;
int f[T][K];
int find(const int &x) {
  if (x == fa[x])
    return x;
  else
    return fa[x] = find(fa[x]);
}
int sz[T], dfn[T], idx = 0;
void dfs(int u) {
  sz[u] = 1;
  dfn[u] = ++idx;
  for (auto v : g[u])
    if (!dfn[v]) {
      f[v][0] = u;
      dfs(v), sz[u] += sz[v];
    }
}
pair<int, int> s[T << 2];
void up(int p) { s[p] = max(s[p << 1], s[p << 1 | 1]); }
void modify(int l, int r, int p, int x, int v) {
  if (l == r) {
    s[p] = make_pair(_p[v], v);
    return;
  }
  int mid = l + r >> 1;
  if (x <= mid) {
    modify(l, mid, p << 1, x, v);
  } else {
    modify(mid + 1, r, p << 1 | 1, x, v);
  }
  up(p);
}
pair<int, int> query(int ql, int qr, int l, int r, int p) {
  if (ql <= l && r <= qr) {
    return s[p];
  }
  int mid = l + r >> 1;
  if (qr <= mid) {
    return query(ql, qr, l, mid, p << 1);
  } else if (ql > mid) {
    return query(ql, qr, mid + 1, r, p << 1 | 1);
  } else {
    return max(query(ql, qr, l, mid, p << 1),
               query(ql, qr, mid + 1, r, p << 1 | 1));
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> m >> q;
  for (int i = 1; i <= n; i++) {
    cin >> _p[i];
  }
  for (int i = 1; i <= m; i++) {
    int u, v;
    cin >> u >> v;
    edge[i].u = u;
    edge[i].v = v;
    edge[i].w = q + 1;
  }
  for (int i = 1; i <= q; i++) {
    cin >> opt[i] >> opx[i];
  }
  for (int i = 1; i <= q; i++) {
    if (opt[i] == 2) {
      edge[opx[i]].w = i;
    }
  }
  sort(edge + 1, edge + m + 1);
  int tot = n;
  for (int i = 1; i <= n * 2; i++) {
    fa[i] = i;
  }
  for (int i = 1; i <= m; i++) {
    int x = find(edge[i].u), y = find(edge[i].v);
    if (x == y) {
      continue;
    }
    ++tot;
    fa[x] = tot;
    fa[y] = tot;
    g[tot].push_back(x);
    g[tot].push_back(y);
    val[tot] = edge[i].w;
  }
  for (int i = tot; i >= 1; --i)
    if (!dfn[i]) {
      dfs(i);
    }
  for (int j = 1; j < K; j++) {
    for (int i = 1; i <= tot; i++) {
      f[i][j] = f[f[i][j - 1]][j - 1];
    }
  }
  for (int i = 1; i <= n; i++) {
    modify(1, tot, 1, dfn[i], i);
  }
  for (int i = 1; i <= q; i++) {
    if (opt[i] == 2) {
      continue;
    }
    int x = opx[i];
    for (int j = K - 1; j >= 0; --j) {
      if (val[f[x][j]] > i) {
        x = f[x][j];
      }
    }
    auto res = query(dfn[x], dfn[x] + sz[x] - 1, 1, tot, 1);
    int v = res.second;
    cout << _p[v] << '\n';
    _p[v] = 0;
    modify(1, tot, 1, dfn[v], v);
  }
  return 0;
}
