#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
#define pii pair<int,int>
#define pll pair<ll,ll>
#define el '\n'
#define pb push_back
const int maxN = 2e5 + 5;
const int maxM = 2e5 + 5;
int n, m, query_count;
ll a[maxN];
struct Edge {
int u, v;
} dsc[maxM];
struct Query {
int type;
int id; // for type 1
int u; // for type 2
ll val; // for type 2 (new value)
ll old_val; // for type 2 (value before update)
};
Query q[maxN];
bool deleted_bridge[maxM];
int parent_node[maxN];
ll comp_sum[maxN];
multiset<ll> comp_multiset;
int find_root(int i) {
if (parent_node[i] == i)
return i;
return parent_node[i] = find_root(parent_node[i]);
}
void union_sets(int u, int v) {
int root_u = find_root(u);
int root_v = find_root(v);
if (root_u != root_v) {
comp_multiset.erase(comp_multiset.find(comp_sum[root_u]));
comp_multiset.erase(comp_multiset.find(comp_sum[root_v]));
parent_node[root_u] = root_v;
comp_sum[root_v] += comp_sum[root_u];
comp_multiset.insert(comp_sum[root_v]);
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
if (!(cin >> n >> m >> query_count)) return 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= m; i++) {
cin >> dsc[i].u >> dsc[i].v;
}
for (int i = 1; i <= query_count; i++) {
cin >> q[i].type;
if (q[i].type == 1) {
cin >> q[i].id;
deleted_bridge[q[i].id] = true;
} else if (q[i].type == 2) {
cin >> q[i].u >> q[i].val;
}
}
vector<ll> curr_a(n + 1);
for (int i = 1; i <= n; i++) curr_a[i] = a[i];
for (int i = 1; i <= query_count; i++) {
if (q[i].type == 2) {
q[i].old_val = curr_a[q[i].u];
curr_a[q[i].u] = q[i].val;
}
}
for (int i = 1; i <= n; i++) {
parent_node[i] = i;
comp_sum[i] = curr_a[i];
}
for (int i = 1; i <= m; i++) {
if (!deleted_bridge[i]) {
int root_u = find_root(dsc[i].u);
int root_v = find_root(dsc[i].v);
if (root_u != root_v) {
parent_node[root_u] = root_v;
comp_sum[root_v] += comp_sum[root_u];
}
}
}
for (int i = 1; i <= n; i++) {
if (parent_node[i] == i) {
comp_multiset.insert(comp_sum[i]);
}
}
vector<ll> answers;
for (int i = query_count; i >= 1; i--) {
if (q[i].type == 3) {
answers.push_back(*comp_multiset.rbegin());
} else if (q[i].type == 2) {
int u = q[i].u;
ll old_val = q[i].old_val;
ll new_val = q[i].val;
int root = find_root(u);
comp_multiset.erase(comp_multiset.find(comp_sum[root]));
curr_a[u] = old_val;
comp_sum[root] += (old_val - new_val);
comp_multiset.insert(comp_sum[root]);
} else if (q[i].type == 1) {
int id = q[i].id;
union_sets(dsc[id].u, dsc[id].v);
}
}
for (int i = (int)answers.size() - 1; i >= 0; i--) {
cout << answers[i] << el;
}
return 0;
}