#include <bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimization("O3")
#pragma GCC optimization("unroll-loops")
using namespace std;
using ll = long long;
using ld = long double;
const ll MOD = 1000000007;
const ll root = 62;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll binpow(ll a, ll b) {
  ll res = 1;
  while (b) {
    if (b & 1) res = (res * a) % MOD;
    a = (a * a) % MOD;
    b >>= 1;
  }
  return res;
}
ll modInv(ll a) { return binpow(a, MOD - 2); }
const double PI = acos(-1);
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const int NINF = 0xc0c0c0c0;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const ll NINFLL = 0xc0c0c0c0c0c0c0c0;
int arr[200001];
int bck[200001];
pair<int, int> edges[300001];
vector<pair<int, int> > qs;
bool anti[300001];
int alive[600001];
int dsu[600001];
int par[600001][20];
int tin[600001], tout[600001];
vector<int> adj[600001];
int cnt = 0;
int node;
int n, m, q;
int find(int a) { return a == dsu[a] ? a : dsu[a] = find(dsu[a]); }
bool merge(int a, int b) {
  a = find(a);
  b = find(b);
  if (a == b) return false;
  dsu[a] = node;
  dsu[b] = node;
  par[a][0] = node;
  par[b][0] = node;
  adj[node].push_back(a);
  adj[node].push_back(b);
  return true;
}
void dfs(int u) {
  tin[u] = cnt++;
  for (int v : adj[u]) {
    dfs(v);
  }
  tout[u] = cnt++;
}
int sgmax[4000001];
void upd(int p, int val) {
  for (sgmax[p += cnt] = val; p > 1; p >>= 1)
    sgmax[p >> 1] = max(sgmax[p], sgmax[p ^ 1]);
}
void init() {
  for (auto i = (0); i < (n); ++i) {
    if (i < n) {
      upd(tin[i], arr[i]);
      upd(tout[i], arr[i]);
    }
  }
}
int qmax(int l, int r) {
  r++;
  int res = 0;
  for (l += cnt, r += cnt; l < r; l >>= 1, r >>= 1) {
    if (l & 1) res = max(res, sgmax[l++]);
    if (r & 1) res = max(res, sgmax[--r]);
  }
  if (res) {
    upd(tin[bck[res]], 0);
    upd(tout[bck[res]], 0);
  }
  return res;
}
int main() {
  mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
  cin.tie(0)->sync_with_stdio(0);
  cin >> n >> m >> q;
  node = n;
  for (auto i = (0); i < (600001); ++i) {
    dsu[i] = i;
    par[i][0] = i;
  }
  for (auto i = (0); i < (n); ++i) {
    cin >> arr[i];
    bck[arr[i]] = i;
  }
  for (auto i = (0); i < (m); ++i) {
    cin >> edges[i].first >> edges[i].second;
    edges[i].first--;
    edges[i].second--;
  }
  qs.resize(q);
  for (auto i = (0); i < (q); ++i) {
    cin >> qs[i].first >> qs[i].second;
    qs[i].second--;
    if (qs[i].first == 2) {
      anti[qs[i].second] = true;
    }
  }
  for (auto i = (0); i < (m); ++i) {
    if (!anti[i]) {
      qs.push_back({2, i});
    }
  }
  reverse(qs.begin(), qs.end());
  for (auto i = (0); i < (qs.size()); ++i) {
    if (qs[i].first == 2) {
      if (merge(edges[qs[i].second].first, edges[qs[i].second].second)) {
        alive[node++] = qs.size() - i - 1;
      }
    }
  }
  reverse(qs.begin(), qs.end());
  for (auto i = (0); i < (node); ++i) {
    if (find(i) == i) {
      dfs(i);
    }
  }
  for (auto i = (node)-1; i >= (0); --i) {
    for (auto lg = (1); lg < (20); ++lg) {
      par[i][lg] = par[par[i][lg - 1]][lg - 1];
    }
  }
  init();
  for (auto i = (0); i < (qs.size()); ++i) {
    if (qs[i].first == 1) {
      int tp = qs[i].second;
      for (auto lg = (20) - 1; lg >= (0); --lg) {
        if (alive[par[tp][lg]] > i) tp = par[tp][lg];
      }
      cout << qmax(tin[tp], tout[tp]) << "\n";
    }
  }
  return 0;
}
