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;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<double, double>;
using vpii = vector<pii>;
using vpll = vector<pll>;
using vpdd = vector<pdd>;
template <typename T>
void ckmin(T& a, const T& b) {
  a = min(a, b);
}
template <typename T>
void ckmax(T& a, const T& b) {
  a = max(a, b);
}
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
namespace __input {
template <class T1, class T2>
void re(pair<T1, T2>& p);
template <class T>
void re(vector<T>& a);
template <class T, size_t SZ>
void re(array<T, SZ>& a);
template <class T>
void re(T& x) {
  cin >> x;
}
void re(double& x) {
  string t;
  re(t);
  x = stod(t);
}
template <class Arg, class... Args>
void re(Arg& first, Args&... rest) {
  re(first);
  re(rest...);
}
template <class T1, class T2>
void re(pair<T1, T2>& p) {
  re(p.first, p.second);
}
template <class T>
void re(vector<T>& a) {
  for (int i = 0; i < (int((a).size())); i++) re(a[i]);
}
template <class T, size_t SZ>
void re(array<T, SZ>& a) {
  for (int i = 0; i < (SZ); i++) re(a[i]);
}
}  // namespace __input
using namespace __input;
namespace __output {
template <class T1, class T2>
void pr(const pair<T1, T2>& x);
template <class T, size_t SZ>
void pr(const array<T, SZ>& x);
template <class T>
void pr(const vector<T>& x);
template <class T>
void pr(const set<T>& x);
template <class T1, class T2>
void pr(const map<T1, T2>& x);
template <class T>
void pr(const T& x) {
  cout << x;
}
template <class Arg, class... Args>
void pr(const Arg& first, const Args&... rest) {
  pr(first);
  pr(rest...);
}
template <class T1, class T2>
void pr(const pair<T1, T2>& x) {
  pr("{", x.first, ", ", x.second, "}");
}
template <class T, bool pretty = true>
void prContain(const T& x) {
  if (pretty) pr("{");
  bool fst = 1;
  for (const auto& a : x) pr(!fst ? pretty ? ", " : " " : "", a), fst = 0;
  if (pretty) pr("}");
}
template <class T>
void pc(const T& x) {
  prContain<T, false>(x);
  pr("\n");
}
template <class T, size_t SZ>
void pr(const array<T, SZ>& x) {
  prContain(x);
}
template <class T>
void pr(const vector<T>& x) {
  prContain(x);
}
template <class T>
void pr(const set<T>& x) {
  prContain(x);
}
template <class T1, class T2>
void pr(const map<T1, T2>& x) {
  prContain(x);
}
void ps() { pr("\n"); }
template <class Arg>
void ps(const Arg& first) {
  pr(first);
  ps();
}
template <class Arg, class... Args>
void ps(const Arg& first, const Args&... rest) {
  pr(first, " ");
  ps(rest...);
}
}  // namespace __output
using namespace __output;
namespace __algorithm {
template <typename T>
void dedup(vector<T>& v) {
  sort((v).begin(), (v).end());
  v.erase(unique((v).begin(), (v).end()), v.end());
}
template <typename T>
typename vector<T>::const_iterator find(const vector<T>& v, const T& x) {
  auto it = lower_bound((v).begin(), (v).end(), x);
  return it != v.end() && *it == x ? it : v.end();
}
template <typename T>
size_t index(const vector<T>& v, const T& x) {
  auto it = find(v, x);
  assert(it != v.end() && *it == x);
  return it - v.begin();
}
template <typename T1, typename T2>
typename vector<pair<T1, T2>>::iterator lower_bound(
    const vector<pair<T1, T2>>& v, const T1& x) {
  return lower_bound(
      (v).begin(), (v).end(), x,
      [](pair<T1, T2> a, pair<T1, T2> b) { return a.first < b.first; });
}
template <typename T1, typename T2>
typename vector<pair<T1, T2>>::iterator upper_bound(
    const vector<pair<T1, T2>>& v, const T1& x) {
  return upper_bound(
      (v).begin(), (v).end(), x,
      [](pair<T1, T2> a, pair<T1, T2> b) { return a.first < b.first; });
}
}  // namespace __algorithm
using namespace __algorithm;
struct __monostate {
  friend istream& operator>>(istream& is,
                             const __attribute__((unused)) __monostate& ms) {
    return is;
  }
  friend ostream& operator<<(ostream& os,
                             const __attribute__((unused)) __monostate& ms) {
    return os;
  }
} ms;
namespace __io {
void setIn(string second) { freopen(second.c_str(), "r", stdin); }
void setOut(string second) { freopen(second.c_str(), "w", stdout); }
void setIO(string second = "") {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout << setprecision(15);
  if (int((second).size())) {
    setIn(second + ".in"), setOut(second + ".out");
  }
}
}  // namespace __io
using namespace __io;
struct union_find {
  struct node {
    int par, rnk, size;
    vi elts;
    node(int id = 0) : par(id), rnk(0), size(1), elts({id}) {}
  };
  vector<node> uf;
  union_find(int N = 0) : uf(N) {
    for (int i = 0; i < N; i++) uf[i] = node(i);
  }
  int rep(int i) {
    if (i != uf[i].par) uf[i].par = rep(uf[i].par);
    return uf[i].par;
  }
  bool unio(int a, int b) {
    a = rep(a), b = rep(b);
    if (a == b) return false;
    if (uf[a].size < uf[b].size) {
      swap(a, b);
    }
    uf[b].par = a;
    uf[a].size += uf[b].size;
    if (uf[a].rnk == uf[b].rnk) uf[a].rnk++;
    for (auto& e : uf[b].elts) uf[a].elts.push_back(e);
    return true;
  }
  node& operator[](int i) { return uf[rep(i)]; }
  friend void pr(const union_find& u) {
    pr("{");
    bool first = 1;
    for (int i = 0; i < int((u.uf).size()); i++)
      if (u.uf[i].par == i) {
        if (!first)
          pr(", ");
        else
          first = 0;
        pr("[ ", i, " | rank=", u.uf[i].rnk, " size=", u.uf[i].size, " ]");
      }
    pr("}");
  }
};
int main() {
  setIO();
  int N, M, Q;
  re(N, M, Q);
  vi p(N);
  re(p);
  vi inv_p(N + 1, -1);
  for (int i = 0; i < (N); i++) inv_p[p[i]] = i;
  vpii edges(M);
  re(edges);
  for (auto& e : edges) --e.first, --e.second;
  vpii ops(Q);
  re(ops);
  for (auto& e : ops) --e.second;
  union_find uf(N);
  vb is_deleted(M);
  for (auto& e : ops)
    if (e.first == 2) is_deleted[e.second] = 1;
  for (int e = 0; e < (M); e++)
    if (!is_deleted[e]) uf.unio(edges[e].first, edges[e].second);
  vector<pair<int, vi>> relabel(Q);
  for (int q = (Q)-1; q >= 0; q--) {
    if (ops[q].first == 2) {
      auto [a, b] = edges[ops[q].second];
      a = uf.rep(a);
      b = uf.rep(b);
      if (a != b) {
        if (uf[a].size < uf[b].size) swap(a, b);
        vi relabeled = uf[b].elts;
        relabel[q] = {b, relabeled};
        uf.unio(a, b);
      }
    }
  }
  vi label(N);
  for (int i = 0; i < (N); i++) label[i] = uf.rep(i);
  vector<set<int>> by_label(N);
  for (int i = 0; i < (N); i++) by_label[label[i]].insert(-p[i]);
  for (int q = 0; q < (Q); q++) {
    auto e = ops[q];
    if (e.first == 1) {
      auto& second = by_label[label[e.second]];
      if (second.empty()) {
        ps(0);
      } else {
        int val = -*second.begin();
        p[inv_p[val]] = 0;
        second.erase(second.begin());
        ps(val);
      }
    } else {
      for (auto& node : relabel[q].second) {
        if (p[node]) by_label[label[node]].erase(-p[node]);
        label[node] = relabel[q].first;
        if (p[node]) by_label[label[node]].insert(-p[node]);
      }
    }
  }
  return 0;
}
