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>
const int MAX_N = 200000;
const int MAX_M = 300000;
const int MAX_Q = 500000;
int p[1 + MAX_N];
struct Edge {
  int a, b;
  int life, id;
} edges[1 + MAX_M];
struct Operation {
  int type, v;
} ops[1 + MAX_Q];
struct DSU {
  int sef, rank;
  std::set<int> nodes;
} dsu[1 + MAX_N];
int myfind(int nod) {
  if (dsu[nod].sef == nod) return nod;
  return myfind(dsu[nod].sef);
}
struct SetMovement {
  int a, b, c;
};
std::vector<SetMovement> sethistory;
std::vector<std::pair<int *, int>> history;
std::pair<int, int> gettimestamp() {
  return {sethistory.size(), history.size()};
}
void undo(std::pair<int, int> timestamp) {
  while (history.size() > timestamp.second) {
    *history.back().first = history.back().second;
    history.pop_back();
  }
  while (sethistory.size() > timestamp.first) {
    SetMovement x = sethistory.back();
    sethistory.pop_back();
    std::set<int>::iterator it = dsu[x.b].nodes.find(x.c);
    if (it != dsu[x.b].nodes.end()) {
      dsu[x.a].nodes.insert(x.c);
      dsu[x.b].nodes.erase(x.c);
    }
  }
}
void modify(int *pnt, int val) {
  history.push_back({pnt, *pnt});
  *pnt = val;
}
void persistentsetmove(int a, int b, int c) {
  dsu[b].nodes.insert(c);
  sethistory.push_back({a, b, c});
}
void myunion(int a, int b) {
  int sa = myfind(a), sb = myfind(b);
  if (sa != sb) {
    if (dsu[sa].rank > dsu[sb].rank) {
      std::swap(a, b);
      std::swap(sa, sb);
    }
    modify(&dsu[sa].sef, sb);
    modify(&dsu[sb].rank, dsu[sa].rank + dsu[sb].rank);
    for (auto it : dsu[sa].nodes) {
      persistentsetmove(sa, sb, it);
    }
    dsu[sa].nodes.clear();
  }
}
std::pair<int, int> edge_timestamp[1 + MAX_M];
bool cmp(Edge a, Edge b) { return a.life > b.life; }
int main() {
  int n, m, q;
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 1; i <= n; ++i) {
    int x;
    scanf("%d", &x);
    p[i] = x;
    dsu[i] = {i, 1};
    dsu[i].nodes.insert(i);
  }
  for (int i = 1; i <= m; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    edges[i] = {p[x], p[y], MAX_Q + 1, i};
  }
  for (int i = 1; i <= q; ++i) {
    scanf("%d%d", &ops[i].type, &ops[i].v);
    if (ops[i].type == 1)
      ops[i].v = p[ops[i].v];
    else {
      edges[ops[i].v].life = i;
    }
  }
  std::sort(edges + 1, edges + 1 + m, cmp);
  for (int i = 1; i <= m; ++i) {
    edge_timestamp[edges[i].id] = gettimestamp();
    myunion(edges[i].a, edges[i].b);
  }
  for (int i = 1; i <= q; ++i) {
    if (ops[i].type == 1) {
      int x = ops[i].v, sx = myfind(x);
      if (dsu[sx].nodes.empty())
        printf("0\n");
      else {
        int res = *dsu[sx].nodes.rbegin();
        printf("%d\n", res);
        dsu[sx].nodes.erase(res);
      }
    } else {
      undo(edge_timestamp[ops[i].v]);
    }
  }
  return 0;
}
