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>
#pragma GCC optimize(2)
using namespace std;
inline int read() {
  int x = 0;
  int f = 0;
  char ch = 0;
  while (!isdigit(ch)) {
    f |= (ch == '-') ? 1 : 0;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = (x << 3) + (x << 1) + (ch ^ 48);
    ch = getchar();
  }
  return f ? -x : x;
}
const int maxn = 3e5 + 10;
int aa[maxn], pos[maxn];
int n, m, q;
set<int> sset[maxn];
set<int>::iterator it;
int st1[maxn], st2[maxn];
struct node {
  int to, nxt;
} edge[maxn << 1];
int head[maxn], tot = 0;
inline void add(int u, int v) {
  edge[tot].to = v;
  edge[tot].nxt = head[u];
  head[u] = tot++;
}
int main() {
  n = read();
  m = read();
  q = read();
  for (register int i = 1; i <= n; ++i)
    head[i] = -1, aa[i] = read(), pos[aa[i]] = i, sset[i].insert(aa[i]);
  for (register int i = 1; i <= m; ++i) {
    int u = read();
    int v = read();
    st1[i] = u;
    st2[i] = v;
    sset[u].insert(aa[v]);
    sset[v].insert(aa[u]);
    add(u, v);
    add(v, u);
  }
  while (q--) {
    int typ = read();
    int x = read();
    if (typ == 1) {
      if (sset[x].size()) {
        int u = *(--sset[x].end());
        sset[x].erase(u);
        int p = pos[u];
        if (sset[p].count(u)) sset[p].erase(u);
        for (int i = head[p]; i != -1; i = edge[i].nxt) {
          int v = edge[i].to;
          if (sset[v].count(u)) sset[v].erase(u);
        }
        printf("%d\n", u);
      } else
        printf("0\n");
    } else {
      if (sset[st1[x]].count(aa[st2[x]])) sset[st1[x]].erase(aa[st2[x]]);
      if (sset[st2[x]].count(aa[st1[x]])) sset[st2[x]].erase(aa[st1[x]]);
    }
  }
}
