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;
const int N(500005);
struct EdgeNode {
  int a, b, w;
} ed[N];
bool cmp(const EdgeNode &a, const EdgeNode &b) { return a.w > b.w; }
int fu[N];
int Find(int x) { return (fu[x] > 0) ? (fu[x] = Find(fu[x])) : (x); }
struct LnkNode {
  int v, nxt;
} edge[N << 1];
int etot, fst[N];
inline void addedge(int u, int v) {
  ++etot;
  edge[etot].v = v;
  edge[etot].nxt = fst[u];
  fst[u] = etot;
  return;
}
int n, m, Q, p[N], op[N], x[N], ncnt, w[N];
int fa[N], dep[N], siz[N], son[N], tp[N], dcnt, dfn[N], rev[N];
void dfs1(int x, int f) {
  dep[fa[x] = f] = x;
  siz[x] = 1;
  for (int i = fst[x]; i; i = edge[i].nxt) {
    int &y = edge[i].v;
    if (y != f) {
      dfs1(y, x);
      siz[x] += siz[y];
      if (siz[son[x]] < siz[y]) son[x] = y;
    }
  }
  return;
}
void dfs2(int x, int t) {
  tp[x] = t;
  rev[dfn[x] = ++dcnt] = x;
  if (son[x]) dfs2(son[x], t);
  for (int i = fst[x]; i; i = edge[i].nxt) {
    int &y = edge[i].v;
    if (y != fa[x] && y != son[x]) dfs2(y, y);
  }
  return;
}
inline int Qry(int x, int i) {
  while (x) {
    if (w[fa[tp[x]]] < i) {
      int l = dfn[tp[x]], r = dfn[x];
      while (l ^ r)
        (w[rev[(l + r) >> 1]] < i) ? (l = ((l + r) >> 1) + 1)
                                   : (r = ((l + r) >> 1));
      return rev[r];
    }
    x = fa[tp[x]];
  }
  return 0;
}
struct SegT {
  int l, r;
  pair<int, int> max;
} t[N << 2];
void Build(int p, int l, int r) {
  t[p].l = l, t[p].r = r;
  if (l == r) return (void)(t[p].max = pair<int, int>(::p[rev[l]], l));
  Build((p << 1), l, (l + r) >> 1);
  Build(((p << 1) | 1), ((l + r) >> 1) + 1, r);
  t[p].max = max(t[(p << 1)].max, t[((p << 1) | 1)].max);
  return;
}
void Modify(int p, int x) {
  if (t[p].l == t[p].r) return (void)(t[p].max = pair<int, int>(0, x));
  Modify(x <= ((t[p].l + t[p].r) >> 1) ? (p << 1) : ((p << 1) | 1), x);
  t[p].max = max(t[(p << 1)].max, t[((p << 1) | 1)].max);
  return;
}
pair<int, int> Query(int p, int l, int r) {
  if (l <= t[p].l && t[p].r <= r) return t[p].max;
  pair<int, int> s(0, 0);
  if (l <= ((t[p].l + t[p].r) >> 1)) s = max(s, Query((p << 1), l, r));
  if (((t[p].l + t[p].r) >> 1) < r) s = max(s, Query(((p << 1) | 1), l, r));
  return s;
}
int main() {
  w[0] = -1;
  scanf("%d%d%d", &n, &m, &Q);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", p + i);
    w[i] = Q;
  }
  for (int i = 1; i <= m; ++i) {
    scanf("%d%d", &ed[i].a, &ed[i].b);
    ed[i].w = Q;
  }
  for (int i = 0; i < Q; ++i) {
    scanf("%d%d", op + i, x + i);
    if (op[i] == 2) ed[x[i]].w = i;
  }
  sort(ed, ed + m, cmp);
  ncnt = n;
  for (int i = 0; i < m; ++i) {
    int fx = Find(ed[i].a), fy = Find(ed[i].b);
    if (fx != fy) {
      fu[fx] = fu[fy] = ++ncnt;
      addedge(ncnt, fx);
      addedge(ncnt, fy);
      w[ncnt] = ed[i].w;
    }
  }
  for (int i = 1; i <= ncnt; ++i)
    if (!fu[i]) dfs1(i, 0), dfs2(i, i);
  Build(1, 1, ncnt);
  for (int i = 0; i < Q; ++i)
    if (op[i] == 1) {
      int t = Qry(x[i], i);
      pair<int, int> p = Query(1, dfn[t], dfn[t] + siz[t] - 1);
      printf("%d\n", p.first);
      Modify(1, p.second);
    }
  return 0;
}
