#include <bits/stdc++.h>
using namespace std;
int const maxn = 400003;
int n = 0, m = 0, q = 0, cPoint = 0;
int p[maxn];
struct Edge {
  int u, e;
  int id;
};
Edge E[maxn];
int deleteTime[maxn];
inline bool operator<(Edge const &lhs, Edge const &rhs) {
  return deleteTime[lhs.id] > deleteTime[rhs.id];
}
int opt[500003], Sec[500003];
int head[maxn], nxt[maxn], to[maxn], cnt = 0;
inline void insert(int u, int e) {
  nxt[++cnt] = head[u];
  head[u] = cnt;
  to[cnt] = e;
}
int fath[maxn];
inline int find(int x) { return fath[x] == x ? x : fath[x] = find(fath[x]); }
int ti[maxn];
void CreateTheTree() {
  std::sort(E + 1, E + m + 1);
  for (int i = 1; i <= 2 * n; ++i) fath[i] = i;
  cPoint = n;
  for (int i = 1; i <= m; ++i) {
    if (find(E[i].u) == find(E[i].e)) continue;
    ++cPoint;
    ti[cPoint] = deleteTime[E[i].id];
    insert(cPoint, find(E[i].u));
    insert(cPoint, find(E[i].e));
    fath[find(E[i].u)] = cPoint;
    fath[find(E[i].e)] = cPoint;
  }
}
int fa[20][maxn], Ldfn[maxn], Rdfn[maxn];
int dfn[maxn], idfn[maxn];
void dfs(int x, int f) {
  fa[0][x] = f;
  for (int j = 1; j <= 18; ++j) fa[j][x] = fa[j - 1][fa[j - 1][x]];
  if (x <= n) {
    Ldfn[x] = Rdfn[x] = dfn[x] = ++dfn[0];
    idfn[dfn[x]] = x;
    return;
  }
  Ldfn[x] = cPoint + 1, Rdfn[x] = 0;
  for (int i = head[x]; i; i = nxt[i]) {
    dfs(to[i], x);
    Ldfn[x] = std::min(Ldfn[x], Ldfn[to[i]]);
    Rdfn[x] = std::max(Rdfn[x], Rdfn[to[i]]);
  }
}
struct MX {
  int v, pos;
};
MX operator|(MX const &lhs, MX const &rhs) { return lhs.v > rhs.v ? lhs : rhs; }
MX mx[maxn << 2];
void CreateSeg(int po, int L, int R) {
  if (L == R) {
    mx[po].v = p[idfn[L]];
    mx[po].pos = idfn[L];
    return;
  }
  int mid = (L + R) >> 1;
  CreateSeg(po << 1, L, mid);
  CreateSeg(po << 1 | 1, mid + 1, R);
  mx[po] = mx[po << 1] | mx[po << 1 | 1];
}
void Modify(int po, int L, int R, int x) {
  if (L == R) {
    mx[po].v = p[idfn[L]];
    return;
  }
  int mid = (L + R) >> 1;
  if (x <= mid)
    Modify(po << 1, L, mid, x);
  else
    Modify(po << 1 | 1, mid + 1, R, x);
  mx[po] = mx[po << 1] | mx[po << 1 | 1];
}
MX query(int po, int L, int R, int l, int r) {
  if (l <= L && R <= r) return mx[po];
  int mid = (L + R) >> 1;
  if (r <= mid)
    return query(po << 1, L, mid, l, r);
  else if (l > mid)
    return query(po << 1 | 1, mid + 1, R, l, r);
  else
    return query(po << 1, L, mid, l, r) | query(po << 1 | 1, mid + 1, R, l, r);
}
int jump(int x, int time) {
  for (int j = 18; ~j; --j)
    if (ti[fa[j][x]] > time) x = fa[j][x];
  return x;
}
int main() {
  scanf("%d %d %d", &n, &m, &q);
  for (int i = 1; i <= n; ++i) scanf("%d", p + i);
  for (int i = 1; i <= m; ++i) {
    scanf("%d %d", &E[i].u, &E[i].e);
    E[i].id = i;
    deleteTime[i] = q + 1;
  }
  for (int i = 1; i <= q; ++i) {
    scanf("%d %d", opt + i, Sec + i);
    if (opt[i] == 2) deleteTime[Sec[i]] = i;
  }
  CreateTheTree();
  for (int i = 1; i <= cPoint; ++i)
    if (fath[i] == i) dfs(i, 0);
  CreateSeg(1, 1, n);
  for (int i = 1; i <= q; ++i)
    if (opt[i] == 1) {
      int x = jump(Sec[i], i);
      MX res = query(1, 1, n, Ldfn[x], Rdfn[x]);
      printf("%d\n", res.v);
      if (res.v != 0) {
        p[res.pos] = 0;
        Modify(1, 1, n, dfn[res.pos]);
      }
    }
  return 0;
}
