#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T sqr(T x) {
  return x * x;
}
const double EPS = 1e-9;
const int INF = 1000 * 1000 * 1000;
const long long LINF = INF * 1ll * INF;
const double DINF = 1e200;
const double PI = 3.1415926535897932384626433832795l;
int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
long long gcdex(long long a, long long b, long long &x, long long &y) {
  if (!a) {
    x = 0, y = 1;
    return b;
  }
  long long k = b / a;
  long long g = gcdex(b - k * a, a, y, x);
  x -= k * y;
  return g;
}
long long inv(long long a, long long m) {
  assert(m > 1);
  long long x, y, g;
  g = gcdex(a, m, x, y);
  return (x % (m / g) + m / g) % m / g;
}
long long crt(long long a1, long long m1, long long a2, long long m2) {
  long long a = (a2 - a1 % m2 + m2) % m2;
  long long x, y, g;
  g = gcdex(m1, m2, x, y);
  if (a % g) return -1;
  long long m = m1 / g * m2;
  assert(x + m2 >= 0);
  x = a / g * (x + m2) % m2;
  long long r = (a1 + x * m1) % m;
  assert(r % m1 == a1 && r % m2 == a2);
  return r;
}
long long powmod(long long a, long long p, long long m) {
  assert(p >= 0);
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
bool isprime(long long a) {
  if (a <= 1) return false;
  for (long long i = 2; i * i <= a; ++i) {
    if (a % i == 0) return false;
  }
  return true;
}
long long sqrtup(long long a) {
  if (!a) return 0;
  long long x = max(0ll, (long long)sqrt((double)a));
  while (x * x >= a) --x;
  while ((x + 1) * (x + 1) < a) ++x;
  return x + 1;
}
long long isqrt(long long a) {
  if (a <= 0) {
    assert(!a);
    return 0;
  }
  long long x = (long long)sqrt((double)a);
  while (sqr(x + 1) <= a) ++x;
  while (x * x > a) --x;
  return x;
}
long long sgn(long long x) { return x < 0 ? -1 : x > 0 ? 1 : 0; }
double randf() {
  double m = RAND_MAX + 1.;
  return (((rand() + .5) / m + rand()) / m + rand()) / m;
}
int rand30() {
  assert(RAND_MAX >= (1 << 15) - 1);
  return (
      int)((((uint32_t)rand()) * (1u + (uint32_t)RAND_MAX) + (uint32_t)rand()) &
           ((1u << 30) - 1));
}
template <class T>
void smin(T &a, T b) {
  a = min(a, b);
}
template <class T>
void smax(T &a, T b) {
  a = max(a, b);
}
template <class T>
ostream &operator<<(ostream &s, const vector<T> &v);
template <class A, class B>
ostream &operator<<(ostream &s, const pair<A, B> &p);
template <class K, class V>
ostream &operator<<(ostream &s, const map<K, V> &m);
template <class T>
ostream &operator<<(ostream &s, const set<T> &m);
template <class T, size_t N>
ostream &operator<<(ostream &s, const array<T, N> &a);
template <class... T>
ostream &operator<<(ostream &s, const tuple<T...> &t);
template <class T>
ostream &operator<<(ostream &s, const vector<T> &v) {
  s << '[';
  for (int i = 0; i < (((int)(v).size())); ++i) {
    if (i) s << ',';
    s << v[i];
  }
  s << ']';
  return s;
}
template <class A, class B>
ostream &operator<<(ostream &s, const pair<A, B> &p) {
  s << "(" << p.first << "," << p.second << ")";
  return s;
}
template <class K, class V>
ostream &operator<<(ostream &s, const map<K, V> &m) {
  s << "{";
  bool f = false;
  for (const auto &it : m) {
    if (f) s << ",";
    f = true;
    s << it.first << ": " << it.second;
  }
  s << "}";
  return s;
}
template <class T>
ostream &operator<<(ostream &s, const set<T> &m) {
  s << "{";
  bool f = false;
  for (const auto &it : m) {
    if (f) s << ",";
    f = true;
    s << it;
  }
  s << "}";
  return s;
}
template <class T>
ostream &operator<<(ostream &s, const multiset<T> &m) {
  s << "{";
  bool f = false;
  for (const auto &it : m) {
    if (f) s << ",";
    f = true;
    s << it;
  }
  s << "}";
  return s;
}
template <class T, class V, class C>
ostream &operator<<(ostream &s, const priority_queue<T, V, C> &q) {
  auto a = q;
  s << "{";
  bool f = false;
  while (!a.empty()) {
    if (f) s << ",";
    f = true;
    s << a.top();
    a.pop();
  }
  return s << "}";
}
template <class T, size_t N>
ostream &operator<<(ostream &s, const array<T, N> &a) {
  s << '[';
  for (int i = 0; i < (((int)(a).size())); ++i) {
    if (i) s << ',';
    s << a[i];
  }
  s << ']';
  return s;
}
template <class T>
ostream &operator<<(ostream &s, const deque<T> &a) {
  s << '[';
  for (int i = 0; i < (((int)(a).size())); ++i) {
    if (i) s << ',';
    s << a[i];
  }
  s << ']';
  return s;
}
template <size_t n, class... T>
struct put1 {
  static ostream &put(ostream &s, const tuple<T...> &t) {
    s << get<sizeof...(T) - n>(t);
    if (n > 1) s << ',';
    return put1<n - 1, T...>::put(s, t);
  }
};
template <class... T>
struct put1<0, T...> {
  static ostream &put(ostream &s, const tuple<T...> &t) { return s; }
};
template <class... T>
ostream &operator<<(ostream &s, const tuple<T...> &t) {
  s << "(";
  put1<sizeof...(T), T...>::put(s, t);
  s << ")";
  return s;
}
ostream &put3(ostream &s, const char *, bool) { return s; }
template <class U, class... T>
ostream &put3(ostream &s, const char *f, bool fs, U &&u, T &&...t) {
  while (*f == ' ') ++f;
  if (!fs) s << ", ";
  auto nf = f;
  int d = 0;
  while (*nf && (*nf != ',' || d)) {
    if (*nf == '(')
      ++d;
    else if (*nf == ')')
      --d;
    ++nf;
  }
  auto nf2 = nf;
  while (nf2 > f && *(nf2 - 1) == ' ') --nf;
  fs = *f == '"';
  if (!fs) {
    s.write(f, nf2 - f);
    s << "=";
  };
  s << u;
  if (fs) s << ' ';
  if (*nf) ++nf;
  return put3(s, nf, fs, forward<T>(t)...);
}
mt19937 mtrng;
struct comp {
  vector<int> V;
  vector<pair<int, int>> E;
};
struct tree {
  vector<pair<int, int>> T;
  tree(int n) : T(n * 4) {}
  void init(int a, int b, int k, const vector<int> &A) {
    if (b == a + 1) {
      T[k] = make_pair(A[a], a);
      return;
    }
    int c = (a + b) / 2;
    init(a, c, k * 2 + 1, A);
    init(c, b, k * 2 + 2, A);
    T[k] = max(T[k * 2 + 1], T[k * 2 + 2]);
  }
  pair<int, int> getmax(int l, int r, int a, int b, int k) {
    if (l >= b || r <= a) return make_pair(0, -1);
    if (l <= a && r >= b) return T[k];
    int c = (a + b) / 2;
    return max(getmax(l, r, a, c, k * 2 + 1), getmax(l, r, c, b, k * 2 + 2));
  }
  void setv(int p, int v, int a, int b, int k) {
    if (b == a + 1) {
      T[k] = make_pair(v, p);
      return;
    }
    int c = (a + b) / 2;
    if (p < c)
      setv(p, v, a, c, k * 2 + 1);
    else
      setv(p, v, c, b, k * 2 + 2);
    T[k] = max(T[k * 2 + 1], T[k * 2 + 2]);
  }
};
int main(int argc, char **argv) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.precision(20);
  srand(35964);
  mtrng.seed(765674737);
  int n, m, tc;
  cin >> n >> m >> tc;
  vector<int> P;
  P.resize(n);
  for (int i = 0; i < (n); ++i) cin >> P[i];
  vector<pair<pair<int, int>, int>> E(m);
  for (int i = 0; i < (m); ++i) {
    cin >> E[i].first.first >> E[i].first.second;
    --E[i].first.first;
    --E[i].first.second;
  }
  vector<pair<int, int>> Q(tc);
  for (int i = 0; i < (tc); ++i) {
    cin >> Q[i].first >> Q[i].second;
    --Q[i].second;
    if (Q[i].first == 2) E[Q[i].second].second = 1;
  }
  vector<int> v2c(n);
  vector<comp> cs(n);
  for (int i = 0; i < (n); ++i) {
    v2c[i] = i;
    cs[i].V.push_back(i);
  }
  auto mer = [&](int a, int b, int q) {
    if (a == b) return;
    if (((int)(cs[a].V).size()) < ((int)(cs[b].V).size())) swap(a, b);
    for (pair<int, int> x : cs[b].E)
      cs[a].E.push_back(make_pair(x.first, x.second + ((int)(cs[a].V).size())));
    if (q != -1) cs[a].E.push_back(make_pair(q, ((int)(cs[a].V).size())));
    for (int v : cs[b].V) {
      v2c[v] = a;
      cs[a].V.push_back(v);
    }
    cs[b].V.clear();
    cs[b].E.clear();
  };
  for (auto e : E) {
    if (e.second) continue;
    mer(v2c[e.first.first], v2c[e.first.second], -1);
  }
  for (int q = tc - 1; q >= 0; --q) {
    if (Q[q].first != 2) continue;
    pair<int, int> e = E[Q[q].second].first;
    int a = v2c[e.first], b = v2c[e.second];
    mer(a, b, q);
  }
  set<int> B;
  vector<int> v2i(n);
  vector<int> i2v;
  vector<pair<int, int>> ev;
  B.insert(0);
  for (comp &c : cs) {
    if (!((int)(c.V).size())) continue;
    for (pair<int, int> e : c.E)
      ev.push_back(make_pair(e.first, e.second + ((int)(i2v).size())));
    for (int v : c.V) {
      v2i[v] = ((int)(i2v).size());
      i2v.push_back(v);
    }
    B.insert(((int)(i2v).size()));
  }
  assert(((int)(i2v).size()) == n);
  sort((ev).begin(), (ev).end());
  tree T(n);
  vector<int> A(n);
  for (int i = 0; i < (n); ++i) A[i] = P[i2v[i]];
  T.init(0, n, 0, A);
  int ei = 0;
  for (int q = 0; q < (tc); ++q) {
    if (Q[q].first == 1) {
      int i = v2i[Q[q].second];
      auto it = B.upper_bound(i);
      int b = *it;
      --it;
      int a = *it;
      pair<int, int> t = T.getmax(a, b, 0, n, 0);
      T.setv(t.second, 0, 0, n, 0);
      cout << t.first << '\n';
    } else if (ei < ((int)(ev).size()) && ev[ei].first == q) {
      B.insert(ev[ei].second);
      ++ei;
    }
  }
  return 0;
}
