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

/**
 🍪 the_hyp0cr1t3
 🍪 30.11.2020 11:51:47
**/
#ifdef W
#include "k_II.h"
#else
#include <bits/stdc++.h>
using namespace std;
#endif
#define pb emplace_back
#define sz(x) int(x.size())
#define all(x) x.begin(), x.end()
auto chmax = [](auto& A, auto&& B) { return B > A? A = B, true : false; };
auto chmin = [](auto& A, auto&& B) { return B < A? A = B, true : false; };

const int64_t DESPACITO = 2e18;
const int INF = 2e9, MOD = 1e9+7;
const int N = 2e5 + 5;

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int i, n, m, Q;
    cin >> n >> m >> Q;
    vector<int> p(n+1, -1);
    for(i = 0; i < n; i++)
        cin >> p[i];
    
    vector<pair<int, int>> edges(m);
    for(i = 0; i < m; i++) {
        cin >> edges[i].first >> edges[i].second;
        --edges[i].first; --edges[i].second;
    }
    
    vector<bool> used(m);
    vector<pair<int, int>> queries, merges;
    queries.reserve(Q); merges.reserve(m);
    for(i = 0; i < Q; i++) {
        int t, x; cin >> t >> x; --x;
        if(t == 1) {
            queries.pb(x, i);
        } else {
            merges.pb(x, i);
            used[x] = true;
        }
    }

    for(i = 0; i < m; i++)
        if(!used[i]) merges.pb(i, Q);

    vector<int> par(n, -1), delta(n);
    auto get_par = [&](int A) -> array<int, 2> {
        int val = delta[A];
        while(par[A] >= 0) {
            A = par[A];
            val += delta[A];
        } return {A, val};
    };
    
    vector<tuple<int*, int, int>> magic;
    magic.reserve(3*m);

    auto merge = [&](int A, int B, int idx) {
        A = get_par(A)[0]; B = get_par(B)[0];
        if(A == B) return false;
        if(-par[A] < -par[B]) swap(A, B);
        magic.pb(&par[A], par[A], idx);
        magic.pb(&par[B], par[B], idx);
        magic.pb(&delta[B], delta[B], idx);
        delta[B] += -par[A];
        par[A] += par[B]; par[B] = A;
        return true;
    };


    while(!merges.empty()) {
        auto [x, t] = merges.back(); merges.pop_back();
        merge(edges[x].first, edges[x].second, t);
    }

    int cur = 0;
    for(i = 0; i < n; i++) {
        if(get_par(i)[0] == i) assert(!delta[i]);
        if(!delta[i]) {
            delta[i] += cur;
            cur += -par[i];
        }
    }

    vector<int> idx(n);
    for(i = 0; i < n; i++)
        idx[i] = get_par(i)[1];

    vector<int> seg(2*n);
    for(i = 0; i < n; i++)
        seg[idx[i]+n] = i;

    for(i = n-1; i; i--) {
        seg[i] = p[seg[i<<1]] > p[seg[i<<1|1]]?
                        seg[i<<1] : seg[i<<1|1];
    }

    auto query = [&](int l, int r) {
        int best = n;
        for(l += n, r += n; l < r; l >>= 1, r >>= 1) {
            if(l&1) {
                if(p[best] < p[seg[l]])
                    best = seg[l];
                l++;
            }
            if(r&1) {
                --r;
                if(p[best] < p[seg[r]])
                    best = seg[r];
            }
        } return best;
    };

    auto update = [&](int pos, int val) {
        for(p[pos] = val, pos += n; pos >>= 1;)
            seg[pos] = p[seg[pos<<1]] > p[seg[pos<<1|1]]?
                            seg[pos<<1] : seg[pos<<1|1];
    };

    for(auto& [x, t]: queries) {
        while(!magic.empty()) {
            auto& [p, val, q] = magic.back();
            if(q > t) break;
            *p = val; magic.pop_back();
        }
        int pp = get_par(x)[0];
        int l = idx[pp], r = l + -par[pp];
        int pos = query(l, r);
        // if(n == 96) cout << t << ' ';
        cout << p[pos] << '\n';
        update(pos, 0);
    }

} // ~W