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>
template <class T>
struct DisjointSetUnionWithData {
  using MergeFunc = std::function<void(T &, T &)>;
  std::vector<int> parent, sizes;
  std::vector<T> data;
  MergeFunc mergeFunc;
  DisjointSetUnionWithData(int size, MergeFunc mergeFunc, T defaultValue = T())
      : mergeFunc(mergeFunc),
        parent(size + 1),
        sizes(size + 1),
        data(size + 1, defaultValue) {
    for (int i = 0; i <= size; i++) {
      parent[i] = i;
      sizes[i] = 1;
    }
  }
  int findParent(int x) {
    if (x != parent[x]) {
      parent[x] = findParent(parent[x]);
    }
    return parent[x];
  }
  void merge(int a, int b) {
    int pa = findParent(a);
    int pb = findParent(b);
    if (pa == pb) return;
    if (sizes[pa] < sizes[pb]) std::swap(pa, pb);
    parent[pb] = parent[pa];
    sizes[pa] += sizes[pb];
    mergeFunc(data[a], data[b]);
  }
  T &getData(int x) { return data[findParent(x)]; }
  int getSize(int x) { return sizes[findParent(x)]; }
};
struct Group {
  std::vector<int> p;
};
struct Op {
  std::vector<int> values = std::vector<int>(0);
};
struct Edge {
  int a, b;
};
struct Query {
  int type, value;
};
using DSU = DisjointSetUnionWithData<Group>;
const int MAXN = 200005;
const int MAXM = 300005;
const int MAXQ = 500005;
int n, m, q;
int p[MAXN];
Op splits[MAXQ];
Edge edges[MAXM];
Query queries[MAXQ];
bool usedEdge[MAXM] = {};
std::vector<std::set<int>> sets;
int setIndices[MAXN];
int main() {
  scanf("%d %d %d", &n, &m, &q);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &p[i]);
  }
  DSU dsu(n, [](Group &g1, Group &g2) {
    if (g1.p.size() > g2.p.size()) {
      std::swap(g1.p, g2.p);
    }
    for (auto &v : g1.p) {
      g2.p.push_back(v);
    }
    g1.p.clear();
  });
  for (int i = 1; i <= n; i++) {
    dsu.getData(i).p.push_back(p[i]);
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    edges[i].a = p[a];
    edges[i].b = p[b];
  }
  for (int i = 0; i < q; i++) {
    Query &q = queries[i];
    scanf("%d %d", &q.type, &q.value);
    if (q.type == 2) {
      q.value--;
      usedEdge[q.value] = 1;
    } else {
      q.value = p[q.value];
    }
  }
  for (int i = 0; i < m; i++) {
    if (!usedEdge[i]) {
      Edge &e = edges[i];
      dsu.merge(e.a, e.b);
    }
  }
  for (int i = q - 1; i >= 0; i--) {
    Query &q = queries[i];
    if (q.type == 2) {
      Edge &e = edges[q.value];
      int p1 = dsu.findParent(e.a);
      int p2 = dsu.findParent(e.b);
      if (p1 == p2) continue;
      int s1 = dsu.getSize(p1);
      int s2 = dsu.getSize(p2);
      if (s1 > s2) {
        std::swap(s1, s2);
        std::swap(p1, p2);
      }
      auto &g = dsu.getData(p1);
      for (int v : g.p) {
        splits[i].values.push_back(v);
      }
      dsu.merge(p1, p2);
    }
  }
  for (int i = 1; i <= n; i++) {
    setIndices[p[i]] = sets.size();
    sets.push_back({});
    sets.back().insert(p[i]);
  }
  for (int i = 0; i < m; i++) {
    Edge &e = edges[i];
    int ix1 = setIndices[e.a];
    int ix2 = setIndices[e.b];
    if (ix1 == ix2) continue;
    if (sets[ix1].size() > sets[ix2].size()) {
      std::swap(ix1, ix2);
    }
    for (int v : sets[ix1]) {
      setIndices[v] = ix2;
    }
    sets[ix2].insert(sets[ix1].begin(), sets[ix1].end());
    sets[ix1].clear();
  }
  for (int i = 0; i < q; i++) {
    Query &q = queries[i];
    if (q.type == 1) {
      int ix = setIndices[q.value];
      auto it = std::prev(sets[ix].end());
      int v = *it;
      printf("%d\n", v);
      sets[ix].erase(it);
      sets[ix].insert(0);
    } else {
      if (splits[i].values.empty()) continue;
      Edge &e = edges[q.value];
      int ix = setIndices[e.a];
      std::set<int> set;
      set.insert(splits[i].values.begin(), splits[i].values.end());
      for (int v : splits[i].values) {
        setIndices[v] = sets.size();
        sets[ix].erase(v);
      }
      sets.push_back(set);
    }
  }
  return 0;
}
