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

// Nurstan Duisengaliev
// ASA KONKRETNO KATAIMASH
// MUKHA KONKRETNO KATAIMASH
// ADIL SEN KATAIABER, TEBE MOZHNO 

/*#pragma GCC target ("avx2")
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimize("O3")*/                   
      
#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp> 
 
#define ll long long
#define all(x) x.begin(), x.end()
#define in insert
#define mp make_pair
#define F first
#define S second
#define ppf pop_front
#define pb push_back
#define ppb pop_back
#define pf push_front
#define pii pair <int, int>
#define boost() ios_base::sync_with_stdio(0), cin.tie(0)
#define sz(x) (int)x.size()
 
using namespace std;
//using namespace __gnu_pbds;

//template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;                         

const int N = (int)1e6 + 123;
const int mod = (int)1e9 + 7;
const ll INF = (ll)1e18 + 1;
int n, m, Q;
int a[N], par[N], boss[N];
pii edge[N], q[N];
bool del[N];
vector <int> g[N];
int get_par (int v) {
	if (par[v] == v) return v;
	return par[v] = get_par (par[v]);
}
void unite_sets (int v, int u) {
	v = get_par (v), u = get_par (u);
	if (v == u) return;
	n ++;
	par[v] = n;
	par[u] = n;
	par[n] = n;
	g[n].pb (v);
	g[n].pb (u);
}
int tin[N], tout[N], timer = 0;
pii d[N];
void build (int v, int l, int r) {
	if (l == r) {
		d[v] = mp (0, l);
		return;
	}	
	int mid = l + r >> 1;
	build (v * 2, l, mid);
	build (v * 2 + 1, mid + 1, r);
	if (d[v * 2].F <= d[v * 2 + 1].F) d[v] = d[v * 2 + 1];
	else d[v] = d[v * 2]; 
}
void update (int v, int l, int r, int pos, int x) {
	if (l == r) {
		d[v].F = x;
		return;
	}
	int mid = l + r >> 1;
	if (pos <= mid) update (v * 2, l, mid, pos, x);
	else update (v * 2 + 1, mid + 1, r, pos, x);
	if (d[v * 2].F <= d[v * 2 + 1].F) d[v] = d[v * 2 + 1];
	else d[v] = d[v * 2];
}
pii get (int v, int l, int r, int nl, int nr) {
	if (nl > r || l > nr) return mp (0, 0);
	if (nl <= l && r <= nr) return d[v];
	int mid = l + r >> 1;
	pii f = get (v * 2, l, mid, nl, nr), s = get (v * 2 + 1, mid + 1, r, nl, nr);
	if (f.F >= s.F) return f;
	else return s;
}
void dfs (int v) {
	tin[v] = ++ timer;
	update (1, 1, n, tin[v], a[v]);
	for (auto to : g[v]) {
		dfs (to);
	}
	tout[v] = timer;
}
void solve () {
	cin >> n >> m >> Q;
	for (int i = 1; i <= n; i ++) {
		cin >> a[i];
		par[i] = i;
	}
	for (int i = 1; i <= m; i ++) {
		cin >> edge[i].F >> edge[i].S;
	}
	for (int i = 1; i <= Q; i ++) {
		int x, y;
		cin >> x >> y;
		q[i] = mp (x, y);
		if (x == 2) {
			del[y] = 1;		
		}
	}
	for (int i = 1; i <= m; i ++) {
		if (!del[i]) unite_sets (edge[i].F, edge[i].S);	
	}
	for (int i = Q; i >= 1; i --) {
		if (q[i].F == 1) {
			boss[i] = par[q[i].S];
		}
		else {
			unite_sets (edge[i].F, edge[i].S);
		}
	}
	build (1, 1, n);
	for (int i = 1; i <= n; i ++) {
		if (par[i] == i) {
			dfs (i);	
		}
	}
	for (int i = 1; i <= Q; i ++) {
		if (q[i].F == 1) {
			pii x = get (1, 1, n, tin[boss[i]], tout[boss[i]]);
			update (1, 1, n, x.S, 0);
			cout << x.F << '\n';
		}
	}	                
}   	
 
main () {
//	freopen (".in", "r", stdin);
//	freopen (".out", "w", stdout);
	boost ();
	int TT = 1;
//    cin >> TT;
	while (TT --) {
		solve ();
	}
	return 0;	
}