#include<bits/stdc++.h>
using namespace std;

const int MN = 200010;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * MN, 1e9);
    }
    void upd(int x, int v, int l, int r, int n) {
        if(x < l || r < x) return;
        if(l == r) {
            tree[n] = v;
            return;
        }
        int m = (l + r)>>1;
        upd(x, v, l, m, 2*n);
        upd(x, v, m + 1, r, 2*n + 1);
        tree[n] = min(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 1e9;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return min(L, R);
    }
} bit;

int N, M, Q;
vector<int> adj[MN], U, V;
int W[MN];
int cut[MN], tin[MN], invt[MN], bck[MN], id[MN], timer, bcnt;
stack<int> stk;

void dfs0(int u, int fe) {
    tin[u] = timer++;
    bck[u] = tin[u];

    int ccnt = 0;
    for(int i = 0; i < adj[u].size(); i++) {
        int e = adj[u][i];
        int v = U[e] + V[e] - u;
        if(e == fe) continue;
        if(tin[v] == -1) {
            stk.push(e);
            dfs0(v, e);
            bck[u] = min(bck[u], bck[v]);
            ccnt++;

            if(tin[u] <= bck[v]) {
                cut[u] = 1;
                while(1) {
                    int t = stk.top(); stk.pop();
                    id[t] = bcnt;
                    if(t == e) break;
                }
                bcnt++;
            }
        }
        else {
            if(tin[v] < tin[u]) stk.push(e);
            bck[u] = min(bck[u], tin[v]);
        }
    }
    if(fe == -1) cut[u] = ccnt > 1;
}

vector<int> badj[MN];
int root[MN], par[MN], sz[MN], fa[20][MN], dep[MN], head[MN], cid[MN], ccnt;

int lca(int a, int b) {
    if(dep[a] < dep[b]) swap(a, b);
    int diff = dep[a] - dep[b];
    for(int i = 0; i < 20; i++) if(diff & (1 << i)) a = fa[i][a];
    if(a == b) return a;
    for(int i = 20; i--;) {
        if(fa[i][a] != fa[i][b]) {
            a = fa[i][a];
            b = fa[i][b];
        }
    }
    return fa[0][a];
}

void dfs1(int u, int p) {
    fa[0][u] = p;
    for(int i = 1; i < 20; i++) {
        int t = fa[i - 1][u];
        if(t == -1) break;
        fa[i][u] = fa[i - 1][t];
    }
    sz[u] = 1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
    }
}

void dfs2(int u, int p) {
    tin[u] = timer++;

    int mx = -1, big = -1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        if(mx < sz[v]) {
            mx = sz[v], big = v;
        }
    }

    if(big != -1) {
        cid[big] = ccnt;
        dfs2(big, u);
    }
    ccnt++;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p || v == big) continue;
        cid[v] = ccnt;
        head[ccnt] = v;
        dfs2(v, u);
    }
}

multiset<int> st[MN];

void add(int x, int v) {
    st[x].insert(v);
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}
void rem(int x, int v) {
    st[x].erase(st[x].find(v));
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}

int query(int u, int p) {
    int h = head[ cid[u] ];
    if(dep[h] <= dep[p]) return bit.quer(tin[h] + dep[p] - dep[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1);
    else return min(query(par[h], p), bit.quer(tin[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1));
}

int main() {
    scanf("%d %d %d", &N, &M, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &W[i]);
    }

    for(int i = 0; i < M; i++) {
        int a, b; scanf("%d %d", &a, &b);
        a--; b--;

        adj[a].push_back(i);
        adj[b].push_back(i);
        U.push_back(a);
        V.push_back(b);
    }

    memset(fa, -1, sizeof(fa));
    memset(tin, -1, sizeof(tin));
    dfs0(0, -1);
    for(int i = 0; i < N; i++) invt[tin[i]] = i;

    memset(par, -1, sizeof(par));
    for(int i = 0; i < bcnt; i++) root[i] = 1e9;
    for(int i = 0; i < M; i++) {
        root[ id[i] ] = min(root[ id[i] ], tin[ U[i] ]);
        root[ id[i] ] = min(root[ id[i] ], tin[ V[i] ]);
    }

    for(int u = 0; u < N; u++) {
        par[u] = N + u;
        badj[ par[u] ].push_back(u);

        for(int i = 0; i < adj[u].size(); i++) {
            int e = adj[u][i];

            if(root[ id[e] ] != tin[u]) {
                par[N + u] = invt[ root[ id[e] ] ];
                badj[ par[N + u] ].push_back(N + u);
            }
        }
    }
    /*
    cout << "id : ";
    for(int i = 0; i < M; i++) {
        cout << id[i] << ' ';
    }
    cout << endl;

    cout << "par : ";
    for(int i = 0; i < N; i++) {
        cout << par[i] << ' ';
    }
    cout << endl;
    //*/

    int R = -1;
    for(int i = 0; i < 2 * N; i++) if(par[i] == -1) R = i;
    dfs1(R, -1);

    memset(tin, -1, sizeof(tin));
    timer = 0;
    head[0] = R;
    dfs2(R, -1);

    bit.init();
    for(int i = 0; i < N; i++) {
        int p = par[i];

        add(tin[i], W[i]);
        if(p != -1) add(tin[p], W[i]);
    }

    for(int i = 0; i < Q; i++) {
        char t; scanf("\n%c", &t);

        if(t == 'C') {
            int a, w; scanf("%d %d", &a, &w);
            a--;

            int p = par[a];

            rem(tin[a], W[a]);
            if(p != -1) rem(tin[p], W[a]);
            W[a] = w;
            add(tin[a], W[a]);
            if(p != -1) add(tin[p], W[a]);
        }
        if(t == 'A') {
            int a, b; scanf("%d %d", &a, &b);
            a--; b--;

            int x = lca(a, b);
            printf("%d\n", min(query(a, x), query(b, x)));
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 200010;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * MN, 1e9);
    }
    void upd(int x, int v, int l, int r, int n) {
        if(x < l || r < x) return;
        if(l == r) {
            tree[n] = v;
            return;
        }
        int m = (l + r)>>1;
        upd(x, v, l, m, 2*n);
        upd(x, v, m + 1, r, 2*n + 1);
        tree[n] = min(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 1e9;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return min(L, R);
    }
} bit;

int N, M, Q;
vector<int> adj[MN], U, V;
int W[MN];
int cut[MN], tin[MN], invt[MN], bck[MN], id[MN], timer, bcnt;
stack<int> stk;

void dfs0(int u, int fe) {
    tin[u] = timer++;
    bck[u] = tin[u];

    int ccnt = 0;
    for(int i = 0; i < adj[u].size(); i++) {
        int e = adj[u][i];
        int v = U[e] + V[e] - u;
        if(e == fe) continue;
        if(tin[v] == -1) {
            stk.push(e);
            dfs0(v, e);
            bck[u] = min(bck[u], bck[v]);
            ccnt++;

            if(tin[u] <= bck[v]) {
                cut[u] = 1;
                while(1) {
                    int t = stk.top(); stk.pop();
                    id[t] = bcnt;
                    if(t == e) break;
                }
                bcnt++;
            }
        }
        else {
            if(tin[v] < tin[u]) stk.push(e);
            bck[u] = min(bck[u], tin[v]);
        }
    }
    if(fe == -1) cut[u] = ccnt > 1;
}

vector<int> badj[MN];
int root[MN], par[MN], sz[MN], fa[20][MN], dep[MN], head[MN], cid[MN], ccnt;

int lca(int a, int b) {
    if(dep[a] < dep[b]) swap(a, b);
    int diff = dep[a] - dep[b];
    for(int i = 0; i < 20; i++) if(diff & (1 << i)) a = fa[i][a];
    if(a == b) return a;
    for(int i = 20; i--;) {
        if(fa[i][a] != fa[i][b]) {
            a = fa[i][a];
            b = fa[i][b];
        }
    }
    return fa[0][a];
}

void dfs1(int u, int p) {
    fa[0][u] = p;
    for(int i = 1; i < 20; i++) {
        int t = fa[i - 1][u];
        if(t == -1) break;
        fa[i][u] = fa[i - 1][t];
    }
    sz[u] = 1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
    }
}

void dfs2(int u, int p) {
    tin[u] = timer++;

    int mx = -1, big = -1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        if(mx < sz[v]) {
            mx = sz[v], big = v;
        }
    }

    if(big != -1) {
        cid[big] = ccnt;
        dfs2(big, u);
    }
    ccnt++;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p || v == big) continue;
        cid[v] = ccnt;
        head[ccnt] = v;
        dfs2(v, u);
    }
}

multiset<int> st[MN];

void add(int x, int v) {
    st[x].insert(v);
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}
void rem(int x, int v) {
    st[x].erase(st[x].find(v));
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}

int query(int u, int p) {
    int h = head[ cid[u] ];
    if(dep[h] <= dep[p]) return bit.quer(tin[h] + dep[p] - dep[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1);
    else return min(query(par[h], p), bit.quer(tin[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1));
}

int main() {
    scanf("%d %d %d", &N, &M, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &W[i]);
    }

    for(int i = 0; i < M; i++) {
        int a, b; scanf("%d %d", &a, &b);
        a--; b--;

        adj[a].push_back(i);
        adj[b].push_back(i);
        U.push_back(a);
        V.push_back(b);
    }

    memset(fa, -1, sizeof(fa));
    memset(tin, -1, sizeof(tin));
    dfs0(0, -1);
    for(int i = 0; i < N; i++) invt[tin[i]] = i;

    memset(par, -1, sizeof(par));
    for(int i = 0; i < bcnt; i++) root[i] = 1e9;
    for(int i = 0; i < M; i++) {
        root[ id[i] ] = min(root[ id[i] ], tin[ U[i] ]);
        root[ id[i] ] = min(root[ id[i] ], tin[ V[i] ]);
    }

    for(int u = 0; u < N; u++) {
        for(int i = 0; i < adj[u].size(); i++) {
            int e = adj[u][i];

            if(root[ id[e] ] != tin[u]) {
                par[u] = N + id[e];
                badj[ par[u] ].push_back(u);
            }
            else {
                par[ N + id[e] ] = u;
                badj[ par[ N + id[e] ] ].push_back(N + id[e]);
            }
        }
    }
    /*
    cout << "id : ";
    for(int i = 0; i < M; i++) {
        cout << id[i] << ' ';
    }
    cout << endl;

    cout << "par : ";
    for(int i = 0; i < N + bcnt; i++) {
        cout << par[i] << ' ';
    }
    cout << endl;
    //*/

    int R = -1;
    for(int i = 0; i < N + bcnt; i++) if(par[i] == -1) R = i;
    dfs1(R, -1);

    memset(tin, -1, sizeof(tin));
    timer = 0;
    head[0] = R;
    dfs2(R, -1);

    bit.init();
    for(int i = 0; i < N; i++) {
        int p = par[i];

        add(tin[i], W[i]);
        if(p != -1) add(tin[p], W[i]);
    }

    for(int i = 0; i < Q; i++) {
        char t; scanf("\n%c", &t);

        if(t == 'C') {
            int a, w; scanf("%d %d", &a, &w);
            a--;

            int p = par[a];

            rem(tin[a], W[a]);
            if(p != -1) rem(tin[p], W[a]);
            W[a] = w;
            add(tin[a], W[a]);
            if(p != -1) add(tin[p], W[a]);
        }
        if(t == 'A') {
            int a, b; scanf("%d %d", &a, &b);
            a--; b--;

            int x = lca(a, b);
            int ans = min(query(a, x), query(b, x));
            if(N <= x) ans = min(ans, *st[ par[x] ].begin());
            printf("%d\n", ans);
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 200010;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * MN, 1e9);
    }
    void upd(int x, int v, int l, int r, int n) {
        if(x < l || r < x) return;
        if(l == r) {
            tree[n] = v;
            return;
        }
        int m = (l + r)>>1;
        upd(x, v, l, m, 2*n);
        upd(x, v, m + 1, r, 2*n + 1);
        tree[n] = min(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 1e9;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return min(L, R);
    }
} bit;

int N, M, Q;
vector<int> adj[MN], U, V;
int W[MN];
int cut[MN], tin[MN], invt[MN], bck[MN], id[MN], timer, bcnt;
stack<int> stk;

void dfs0(int u, int fe) {
    tin[u] = timer++;
    bck[u] = tin[u];

    int ccnt = 0;
    for(int i = 0; i < adj[u].size(); i++) {
        int e = adj[u][i];
        int v = U[e] + V[e] - u;
        if(e == fe) continue;
        if(tin[v] == -1) {
            stk.push(e);
            dfs0(v, e);
            bck[u] = min(bck[u], bck[v]);
            ccnt++;

            if(tin[u] <= bck[v]) {
                cut[u] = 1;
                while(1) {
                    int t = stk.top(); stk.pop();
                    id[t] = bcnt;
                    if(t == e) break;
                }
                bcnt++;
            }
        }
        else {
            if(tin[v] < tin[u]) stk.push(e);
            bck[u] = min(bck[u], tin[v]);
        }
    }
    if(fe == -1) cut[u] = ccnt > 1;
}

vector<int> badj[MN];
int root[MN], par[MN], sz[MN], fa[20][MN], dep[MN], head[MN];

int lca(int a, int b) {
    if(dep[a] < dep[b]) swap(a, b);
    int diff = dep[a] - dep[b];
    for(int i = 0; i < 20; i++) if(diff & (1 << i)) a = fa[i][a];
    if(a == b) return a;
    for(int i = 20; i--;) {
        if(fa[i][a] != fa[i][b]) {
            a = fa[i][a];
            b = fa[i][b];
        }
    }
    return fa[0][a];
}

void dfs1(int u, int p) {
    fa[0][u] = p;
    for(int i = 1; i < 20; i++) {
        int t = fa[i - 1][u];
        if(t == -1) break;
        fa[i][u] = fa[i - 1][t];
    }
    sz[u] = 1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
    }
}

void dfs2(int u, int p) {
    tin[u] = timer++;

    int mx = -1, big = -1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        if(mx < sz[v]) {
            mx = sz[v], big = v;
        }
    }

    if(big != -1) {
        head[big] = head[u];
        dfs2(big, u);
    }
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p || v == big) continue;
        head[v] = v;
        dfs2(v, u);
    }
}

multiset<int> st[MN];

void add(int x, int v) {
    st[x].insert(v);
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}
void rem(int x, int v) {
    st[x].erase(st[x].find(v));
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}

int query(int u, int p) {
    int h = head[u];
    if(dep[h] <= dep[p]) return bit.quer(tin[h] + dep[p] - dep[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1);
    else return min(query(par[h], p), bit.quer(tin[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1));
}

int main() {
    scanf("%d %d %d", &N, &M, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &W[i]);
    }

    for(int i = 0; i < M; i++) {
        int a, b; scanf("%d %d", &a, &b);
        a--; b--;

        adj[a].push_back(i);
        adj[b].push_back(i);
        U.push_back(a);
        V.push_back(b);
    }

    memset(tin, -1, sizeof(tin));
    dfs0(0, -1);
    for(int i = 0; i < N; i++) invt[tin[i]] = i;

    memset(par, -1, sizeof(par));
    for(int i = 0; i < bcnt; i++) root[i] = 1e9;
    for(int i = 0; i < M; i++) {
        root[ id[i] ] = min(root[ id[i] ], tin[ U[i] ]);
        root[ id[i] ] = min(root[ id[i] ], tin[ V[i] ]);
    }

    for(int u = 0; u < N; u++) {
        for(int i = 0; i < adj[u].size(); i++) {
            int e = adj[u][i];

            if(root[ id[e] ] != tin[u]) {
                par[u] = N + id[e];
                badj[ par[u] ].push_back(u);
            }
            else {
                par[ N + id[e] ] = u;
                badj[u].push_back(N + id[e]);
            }
        }
    }
    for(int i = 0; i < N + bcnt; i++) {
        badj[i].resize(unique(badj[i].begin(), badj[i].end()) - badj[i].begin());
    }

    /*
    cout << "id : ";
    for(int i = 0; i < M; i++) {
        cout << id[i] << ' ';
    }
    cout << endl;

    cout << "par : ";
    for(int i = 0; i < N + bcnt; i++) {
        cout << par[i] << ' ';
    }
    cout << endl;
    //*/

    memset(fa, -1, sizeof(fa));
    int R = -1;
    for(int i = 0; i < N + bcnt; i++) if(par[i] == -1) R = i;
    dfs1(R, -1);

    memset(tin, -1, sizeof(tin));
    timer = 0;
    head[R] = R;
    dfs2(R, -1);

    bit.init();
    for(int i = 0; i < N; i++) {
        int p = par[i];

        add(tin[i], W[i]);
        if(p != -1) add(tin[p], W[i]);
    }

    for(int i = 0; i < Q; i++) {
        char t; scanf("\n%c", &t);

        if(t == 'C') {
            int a, w; scanf("%d %d", &a, &w);
            a--;

            int p = par[a];

            rem(tin[a], W[a]);
            if(p != -1) rem(tin[p], W[a]);
            W[a] = w;
            add(tin[a], W[a]);
            if(p != -1) add(tin[p], W[a]);
        }
        if(t == 'A') {
            int a, b; scanf("%d %d", &a, &b);
            a--; b--;

            int x = lca(a, b);
            int ans = min(query(a, x), query(b, x));
            if(N <= x && par[x] != -1 && st[ tin[ par[x] ] ].size()) ans = min(ans, *st[ tin[ par[x] ] ].begin());
            printf("%d\n", ans);
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 200010;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * MN, 1e9);
    }
    void upd(int x, int v, int l, int r, int n) {
        if(x < l || r < x) return;
        if(l == r) {
            tree[n] = v;
            return;
        }
        int m = (l + r)>>1;
        upd(x, v, l, m, 2*n);
        upd(x, v, m + 1, r, 2*n + 1);
        tree[n] = min(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 1e9;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return min(L, R);
    }
} bit;

int N, M, Q;
vector<int> adj[MN], U, V;
int W[MN];
int cut[MN], tin[MN], invt[MN], bck[MN], id[MN], timer, bcnt;
stack<int> stk;

void dfs0(int u, int fe) {
    tin[u] = timer++;
    bck[u] = tin[u];

    int ccnt = 0;
    for(int i = 0; i < adj[u].size(); i++) {
        int e = adj[u][i];
        int v = U[e] + V[e] - u;
        if(e == fe) continue;
        if(tin[v] == -1) {
            stk.push(e);
            dfs0(v, e);
            bck[u] = min(bck[u], bck[v]);
            ccnt++;

            if(tin[u] <= bck[v]) {
                cut[u] = 1;
                while(1) {
                    int t = stk.top(); stk.pop();
                    id[t] = bcnt;
                    if(t == e) break;
                }
                bcnt++;
            }
        }
        else {
            if(tin[v] < tin[u]) stk.push(e);
            bck[u] = min(bck[u], tin[v]);
        }
    }
    if(fe == -1) cut[u] = ccnt > 1;
}

vector<int> badj[MN];
int root[MN], par[MN], sz[MN], fa[20][MN], dep[MN], head[MN];

int lca(int a, int b) {
    if(dep[a] < dep[b]) swap(a, b);
    int diff = dep[a] - dep[b];
    for(int i = 0; i < 20; i++) if(diff & (1 << i)) a = fa[i][a];
    if(a == b) return a;
    for(int i = 20; i--;) {
        if(fa[i][a] != fa[i][b]) {
            a = fa[i][a];
            b = fa[i][b];
        }
    }
    return fa[0][a];
}

void dfs1(int u, int p) {
    fa[0][u] = p;
    for(int i = 1; i < 20; i++) {
        int t = fa[i - 1][u];
        if(t == -1) break;
        fa[i][u] = fa[i - 1][t];
    }
    sz[u] = 1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
    }
}

void dfs2(int u, int p) {
    tin[u] = timer++;

    int mx = -1, big = -1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        if(mx < sz[v]) {
            mx = sz[v], big = v;
        }
    }

    if(big != -1) {
        head[big] = head[u];
        dfs2(big, u);
    }
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p || v == big) continue;
        head[v] = v;
        dfs2(v, u);
    }
}

multiset<int> st[MN];

void add(int x, int v) {
    st[x].insert(v);
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}
void rem(int x, int v) {
    st[x].erase(st[x].find(v));
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}

int query(int u, int p) {
    int h = head[u];
    if(dep[h] <= dep[p]) return bit.quer(tin[h] + dep[p] - dep[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1);
    else return min(query(par[h], p), bit.quer(tin[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1));
}

int main() {
    scanf("%d %d %d", &N, &M, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &W[i]);
    }

    for(int i = 0; i < M; i++) {
        int a, b; scanf("%d %d", &a, &b);
        a--; b--;

        adj[a].push_back(i);
        adj[b].push_back(i);
        U.push_back(a);
        V.push_back(b);
    }

    if(N > 60000) {
        cout << "here\n";
    }

    memset(tin, -1, sizeof(tin));
    dfs0(0, -1);
    for(int i = 0; i < N; i++) invt[tin[i]] = i;

    memset(par, -1, sizeof(par));
    for(int i = 0; i < bcnt; i++) root[i] = 1e9;
    for(int i = 0; i < M; i++) {
        root[ id[i] ] = min(root[ id[i] ], tin[ U[i] ]);
        root[ id[i] ] = min(root[ id[i] ], tin[ V[i] ]);
    }

    if(N > 60000) {
        cout << "here\n";
    }

    for(int u = 0; u < N; u++) {
        for(int i = 0; i < adj[u].size(); i++) {
            int e = adj[u][i];

            if(root[ id[e] ] != tin[u]) {
                par[u] = N + id[e];
                badj[ par[u] ].push_back(u);
            }
            else {
                par[ N + id[e] ] = u;
                badj[ par[ N + id[e] ] ].push_back(N + id[e]);
            }
        }
    }
    /*
    cout << "id : ";
    for(int i = 0; i < M; i++) {
        cout << id[i] << ' ';
    }
    cout << endl;

    cout << "par : ";
    for(int i = 0; i < N + bcnt; i++) {
        cout << par[i] << ' ';
    }
    cout << endl;
    //*/

    memset(fa, -1, sizeof(fa));
    int R = -1;
    for(int i = 0; i < N + bcnt; i++) if(par[i] == -1) R = i;
    dfs1(R, -1);

    memset(tin, -1, sizeof(tin));
    timer = 0;
    head[0] = R;
    dfs2(R, -1);

    if(N > 60000) {
        cout << "here\n";
    }

    bit.init();
    for(int i = 0; i < N; i++) {
        int p = par[i];

        add(tin[i], W[i]);
        if(p != -1) add(tin[p], W[i]);
    }

    for(int i = 0; i < Q; i++) {
        char t; scanf("\n%c", &t);

        if(t == 'C') {
            int a, w; scanf("%d %d", &a, &w);
            a--;

            int p = par[a];

            rem(tin[a], W[a]);
            if(p != -1) rem(tin[p], W[a]);
            W[a] = w;
            add(tin[a], W[a]);
            if(p != -1) add(tin[p], W[a]);
        }
        if(t == 'A') {
            int a, b; scanf("%d %d", &a, &b);
            a--; b--;

            int x = lca(a, b);
            int ans = min(query(a, x), query(b, x));
            if(N <= x && par[x] != -1 && st[ tin[ par[x] ] ].size()) ans = min(ans, *st[ tin[ par[x] ] ].begin());
            printf("%d\n", ans);
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 200010;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * MN, 1e9);
    }
    void upd(int x, int v, int l, int r, int n) {
        if(x < l || r < x) return;
        if(l == r) {
            tree[n] = v;
            return;
        }
        int m = (l + r)>>1;
        upd(x, v, l, m, 2*n);
        upd(x, v, m + 1, r, 2*n + 1);
        tree[n] = min(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 1e9;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return min(L, R);
    }
} bit;

int N, M, Q;
vector<int> adj[MN], U, V;
int W[MN];
int cut[MN], tin[MN], invt[MN], bck[MN], id[MN], timer, bcnt;
stack<int> stk;

void dfs0(int u, int fe) {
    tin[u] = timer++;
    bck[u] = tin[u];

    int ccnt = 0;
    for(int i = 0; i < adj[u].size(); i++) {
        int e = adj[u][i];
        int v = U[e] + V[e] - u;
        if(e == fe) continue;
        if(tin[v] == -1) {
            stk.push(e);
            dfs0(v, e);
            bck[u] = min(bck[u], bck[v]);
            ccnt++;

            if(tin[u] <= bck[v]) {
                cut[u] = 1;
                while(1) {
                    int t = stk.top(); stk.pop();
                    id[t] = bcnt;
                    if(t == e) break;
                }
                bcnt++;
            }
        }
        else {
            if(tin[v] < tin[u]) stk.push(e);
            bck[u] = min(bck[u], tin[v]);
        }
    }
    if(fe == -1) cut[u] = ccnt > 1;
}

vector<int> badj[MN];
int root[MN], par[MN], sz[MN], fa[20][MN], dep[MN], head[MN];

int lca(int a, int b) {
    if(dep[a] < dep[b]) swap(a, b);
    int diff = dep[a] - dep[b];
    for(int i = 0; i < 20; i++) if(diff & (1 << i)) a = fa[i][a];
    if(a == b) return a;
    for(int i = 20; i--;) {
        if(fa[i][a] != fa[i][b]) {
            a = fa[i][a];
            b = fa[i][b];
        }
    }
    return fa[0][a];
}

void dfs1(int u, int p) {
    fa[0][u] = p;
    for(int i = 1; i < 20; i++) {
        int t = fa[i - 1][u];
        if(t == -1) break;
        fa[i][u] = fa[i - 1][t];
    }
    sz[u] = 1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
    }
}

void dfs2(int u, int p) {
    tin[u] = timer++;

    int mx = -1, big = -1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        if(mx < sz[v]) {
            mx = sz[v], big = v;
        }
    }

    if(big != -1) {
        head[big] = head[u];
        dfs2(big, u);
    }
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p || v == big) continue;
        head[v] = v;
        dfs2(v, u);
    }
}

multiset<int> st[MN];

void add(int x, int v) {
    st[x].insert(v);
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}
void rem(int x, int v) {
    st[x].erase(st[x].find(v));
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}

int query(int u, int p) {
    int h = head[u];
    if(dep[h] <= dep[p]) return bit.quer(tin[h] + dep[p] - dep[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1);
    else return min(query(par[h], p), bit.quer(tin[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1));
}

int main() {
    scanf("%d %d %d", &N, &M, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &W[i]);
    }

    for(int i = 0; i < M; i++) {
        int a, b; scanf("%d %d", &a, &b);
        a--; b--;

        adj[a].push_back(i);
        adj[b].push_back(i);
        U.push_back(a);
        V.push_back(b);
    }

    memset(fa, -1, sizeof(fa));
    memset(tin, -1, sizeof(tin));
    dfs0(0, -1);
    for(int i = 0; i < N; i++) invt[tin[i]] = i;

    memset(par, -1, sizeof(par));
    for(int i = 0; i < bcnt; i++) root[i] = 1e9;
    for(int i = 0; i < M; i++) {
        root[ id[i] ] = min(root[ id[i] ], tin[ U[i] ]);
        root[ id[i] ] = min(root[ id[i] ], tin[ V[i] ]);
    }

    for(int u = 0; u < N; u++) {
        for(int i = 0; i < adj[u].size(); i++) {
            int e = adj[u][i];

            if(root[ id[e] ] != tin[u]) {
                par[u] = N + id[e];
                badj[ par[u] ].push_back(u);
            }
            else {
                par[ N + id[e] ] = u;
                badj[ par[ N + id[e] ] ].push_back(N + id[e]);
            }
        }
    }
    /*
    cout << "id : ";
    for(int i = 0; i < M; i++) {
        cout << id[i] << ' ';
    }
    cout << endl;

    cout << "par : ";
    for(int i = 0; i < N + bcnt; i++) {
        cout << par[i] << ' ';
    }
    cout << endl;
    //*/

    int R = -1;
    for(int i = 0; i < N + bcnt; i++) if(par[i] == -1) R = i;
    dfs1(R, -1);

    memset(tin, -1, sizeof(tin));
    timer = 0;
    head[0] = R;
    dfs2(R, -1);

    if(N == 66601) {
        cout << "here\n";
    }

    bit.init();
    for(int i = 0; i < N; i++) {
        int p = par[i];

        add(tin[i], W[i]);
        if(p != -1) add(tin[p], W[i]);
    }

    for(int i = 0; i < Q; i++) {
        char t; scanf("\n%c", &t);

        if(t == 'C') {
            int a, w; scanf("%d %d", &a, &w);
            a--;

            int p = par[a];

            rem(tin[a], W[a]);
            if(p != -1) rem(tin[p], W[a]);
            W[a] = w;
            add(tin[a], W[a]);
            if(p != -1) add(tin[p], W[a]);
        }
        if(t == 'A') {
            int a, b; scanf("%d %d", &a, &b);
            a--; b--;

            int x = lca(a, b);
            int ans = min(query(a, x), query(b, x));
            if(N <= x) ans = min(ans, *st[ tin[ par[x] ] ].begin());
            printf("%d\n", ans);
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 100010;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * MN, 1e9);
    }
    void upd(int x, int v, int l, int r, int n) {
        if(x < l || r < x) return;
        if(l == r) {
            tree[n] = v;
            return;
        }
        int m = (l + r)>>1;
        upd(x, v, l, m, 2*n);
        upd(x, v, m + 1, r, 2*n + 1);
        tree[n] = min(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 1e9;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return min(L, R);
    }
} bit;

int N, M, Q;
vector<int> adj[MN], U, V;
int W[MN];
int cut[MN], tin[MN], invt[MN], bck[MN], id[MN], timer, bcnt;
stack<int> stk;

void dfs0(int u, int fe) {
    tin[u] = timer++;
    bck[u] = tin[u];

    int ccnt = 0;
    for(int i = 0; i < adj[u].size(); i++) {
        int e = adj[u][i];
        int v = U[e] + V[e] - u;
        if(e == fe) continue;
        if(tin[v] == -1) {
            stk.push(e);
            dfs0(v, e);
            bck[u] = min(bck[u], bck[v]);
            ccnt++;

            if(tin[u] <= bck[v]) {
                cut[u] = 1;
                while(1) {
                    int t = stk.top(); stk.pop();
                    id[t] = bcnt;
                    if(t == e) break;
                }
                bcnt++;
            }
        }
        else {
            if(tin[v] < tin[u]) stk.push(e);
            bck[u] = min(bck[u], tin[v]);
        }
    }
    if(fe == -1) cut[u] = ccnt > 1;
}

vector<int> badj[MN];
int root[MN], par[MN], sz[MN], fa[20][MN], dep[MN], head[MN], cid[MN], ccnt;

int lca(int a, int b) {
    if(dep[a] < dep[b]) swap(a, b);
    int diff = dep[a] - dep[b];
    for(int i = 0; i < 20; i++) if(diff & (1 << i)) a = fa[i][a];
    if(a == b) return a;
    for(int i = 20; i--;) {
        if(fa[i][a] != fa[i][b]) {
            a = fa[i][a];
            b = fa[i][b];
        }
    }
    return fa[0][a];
}

void dfs1(int u, int p) {
    fa[0][u] = p;
    for(int i = 1; i < 20; i++) {
        int t = fa[i - 1][u];
        if(t == -1) break;
        fa[i][u] = fa[i - 1][t];
    }
    sz[u] = 1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
    }
}

void dfs2(int u, int p) {
    tin[u] = timer++;

    int mx = -1, big = -1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        if(mx < sz[v]) {
            mx = sz[v], big = v;
        }
    }

    if(big != -1) {
        cid[big] = ccnt;
        dfs2(big, u);
    }
    ccnt++;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p || v == big) continue;
        cid[v] = ccnt;
        head[ccnt] = v;
        dfs2(v, u);
    }
}

multiset<int> st[MN];

void add(int x, int v) {
    st[x].insert(v);
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}
void rem(int x, int v) {
    st[x].erase(st[x].find(v));
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}

int query(int u, int p) {
    int h = head[ cid[u] ];
    if(dep[h] <= dep[p]) return bit.quer(tin[h] + dep[p] - dep[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1);
    else return min(query(par[h], p), bit.quer(tin[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1));
}

int main() {
    scanf("%d %d %d", &N, &M, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &W[i]);
    }

    for(int i = 0; i < M; i++) {
        int a, b; scanf("%d %d", &a, &b);
        a--; b--;

        adj[a].push_back(i);
        adj[b].push_back(i);
        U.push_back(a);
        V.push_back(b);
    }

    memset(fa, -1, sizeof(fa));
    memset(tin, -1, sizeof(tin));
    dfs0(0, -1);
    for(int i = 0; i < N; i++) invt[tin[i]] = i;

    memset(par, -1, sizeof(par));
    for(int i = 0; i < bcnt; i++) root[i] = 1e9;
    for(int i = 0; i < M; i++) {
        root[ id[i] ] = min(root[ id[i] ], tin[ U[i] ]);
        root[ id[i] ] = min(root[ id[i] ], tin[ V[i] ]);
    }

    for(int u = 0; u < N; u++) {
        for(int i = 0; i < adj[u].size(); i++) {
            int e = adj[u][i];

            if(root[ id[e] ] != tin[u]) {
                par[u] = invt[ root[ id[e] ] ];
                badj[ par[u] ].push_back(u);
            }
        }
    }
    /*
    cout << "id : ";
    for(int i = 0; i < M; i++) {
        cout << id[i] << ' ';
    }
    cout << endl;

    cout << "par : ";
    for(int i = 0; i < N; i++) {
        cout << par[i] << ' ';
    }
    cout << endl;
    //*/

    int R = -1;
    for(int i = 0; i < N; i++) if(par[i] == -1) R = i;
    dfs1(R, -1);

    memset(tin, -1, sizeof(tin));
    timer = 0;
    head[0] = R;
    dfs2(R, -1);

    bit.init();
    for(int i = 0; i < N; i++) {
        int p = par[i];

        add(tin[i], W[i]);
        if(p != -1) add(tin[p], W[i]);
    }

    for(int i = 0; i < Q; i++) {
        char t; scanf("\n%c", &t);

        if(t == 'C') {
            int a, w; scanf("%d %d", &a, &w);
            a--;

            int p = par[a];

            rem(tin[a], W[a]);
            if(p != -1) rem(tin[p], W[a]);
            W[a] = w;
            add(tin[a], W[a]);
            if(p != -1) add(tin[p], W[a]);
        }
        if(t == 'A') {
            int a, b; scanf("%d %d", &a, &b);
            a--; b--;

            int x = lca(a, b);
            printf("%d\n", min(query(a, x), query(b, x)));
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 200010;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * MN, 1e9);
    }
    void upd(int x, int v, int l, int r, int n) {
        if(x < l || r < x) return;
        if(l == r) {
            tree[n] = v;
            return;
        }
        int m = (l + r)>>1;
        upd(x, v, l, m, 2*n);
        upd(x, v, m + 1, r, 2*n + 1);
        tree[n] = min(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 1e9;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return min(L, R);
    }
} bit;

int N, M, Q;
vector<int> adj[MN], U, V;
int W[MN];
int cut[MN], tin[MN], invt[MN], bck[MN], id[MN], timer, bcnt;
stack<int> stk;

void dfs0(int u, int fe) {
    tin[u] = timer++;
    bck[u] = tin[u];

    int ccnt = 0;
    for(int i = 0; i < adj[u].size(); i++) {
        int e = adj[u][i];
        int v = U[e] + V[e] - u;
        if(e == fe) continue;
        if(tin[v] == -1) {
            stk.push(e);
            dfs0(v, e);
            bck[u] = min(bck[u], bck[v]);
            ccnt++;

            if(tin[u] <= bck[v]) {
                cut[u] = 1;
                while(1) {
                    int t = stk.top(); stk.pop();
                    id[t] = bcnt;
                    if(t == e) break;
                }
                bcnt++;
            }
        }
        else {
            if(tin[v] < tin[u]) stk.push(e);
            bck[u] = min(bck[u], tin[v]);
        }
    }
    if(fe == -1) cut[u] = ccnt > 1;
}

vector<int> badj[MN];
int root[MN], par[MN], sz[MN], fa[20][MN], dep[MN], head[MN], cid[MN], ccnt;

int lca(int a, int b) {
    if(dep[a] < dep[b]) swap(a, b);
    int diff = dep[a] - dep[b];
    for(int i = 0; i < 20; i++) if(diff & (1 << i)) a = fa[i][a];
    if(a == b) return a;
    for(int i = 20; i--;) {
        if(fa[i][a] != fa[i][b]) {
            a = fa[i][a];
            b = fa[i][b];
        }
    }
    return fa[0][a];
}

void dfs1(int u, int p) {
    fa[0][u] = p;
    for(int i = 1; i < 20; i++) {
        int t = fa[i - 1][u];
        if(t == -1) break;
        fa[i][u] = fa[i - 1][t];
    }
    sz[u] = 1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
    }
}

void dfs2(int u, int p) {
    tin[u] = timer++;

    int mx = -1, big = -1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        if(mx < sz[v]) {
            mx = sz[v], big = v;
        }
    }

    if(big != -1) {
        cid[big] = ccnt;
        dfs2(big, u);
    }
    ccnt++;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p || v == big) continue;
        cid[v] = ccnt;
        head[ccnt] = v;
        dfs2(v, u);
    }
}

multiset<int> st[MN];

void add(int x, int v) {
    st[x].insert(v);
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}
void rem(int x, int v) {
    st[x].erase(st[x].find(v));
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}

int query(int u, int p) {
    int h = head[ cid[u] ];
    if(dep[h] <= dep[p]) return bit.quer(tin[h] + dep[p] - dep[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1);
    else return min(query(par[h], p), bit.quer(tin[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1));
}

int main() {
    scanf("%d %d %d", &N, &M, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &W[i]);
    }

    for(int i = 0; i < M; i++) {
        int a, b; scanf("%d %d", &a, &b);
        a--; b--;

        adj[a].push_back(i);
        adj[b].push_back(i);
        U.push_back(a);
        V.push_back(b);
    }

    memset(fa, -1, sizeof(fa));
    memset(tin, -1, sizeof(tin));
    dfs0(0, -1);
    for(int i = 0; i < N; i++) invt[tin[i]] = i;

    memset(par, -1, sizeof(par));
    for(int i = 0; i < bcnt; i++) root[i] = 1e9;
    for(int i = 0; i < M; i++) {
        root[ id[i] ] = min(root[ id[i] ], tin[ U[i] ]);
        root[ id[i] ] = min(root[ id[i] ], tin[ V[i] ]);
    }

    for(int u = 0; u < N; u++) {
        for(int i = 0; i < adj[u].size(); i++) {
            int e = adj[u][i];

            if(root[ id[e] ] != tin[u]) {
                par[u] = N + id[e];
                badj[ par[u] ].push_back(u);
            }
            else {
                par[ N + id[e] ] = u;
                badj[ par[ N + id[e] ] ].push_back(N + id[e]);
            }
        }
    }
    /*
    cout << "id : ";
    for(int i = 0; i < M; i++) {
        cout << id[i] << ' ';
    }
    cout << endl;

    cout << "par : ";
    for(int i = 0; i < N + bcnt; i++) {
        cout << par[i] << ' ';
    }
    cout << endl;
    //*/

    int R = -1;
    for(int i = 0; i < N + bcnt; i++) if(par[i] == -1) R = i;
    dfs1(R, -1);

    memset(tin, -1, sizeof(tin));
    timer = 0;
    head[0] = R;
    dfs2(R, -1);

    bit.init();
    for(int i = 0; i < N; i++) {
        int p = par[i];

        add(tin[i], W[i]);
        if(p != -1) add(tin[p], W[i]);
    }

    for(int i = 0; i < Q; i++) {
        char t; scanf("\n%c", &t);

        if(t == 'C') {
            int a, w; scanf("%d %d", &a, &w);
            a--;

            int p = par[a];

            rem(tin[a], W[a]);
            if(p != -1) rem(tin[p], W[a]);
            W[a] = w;
            add(tin[a], W[a]);
            if(p != -1) add(tin[p], W[a]);
        }
        if(t == 'A') {
            int a, b; scanf("%d %d", &a, &b);
            a--; b--;

            int x = lca(a, b);
            int ans = min(query(a, x), query(b, x));
            if(N <= x) ans = min(ans, *st[ tin[ par[x] ] ].begin());
            printf("%d\n", ans);
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 200010;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * MN, 1e9);
    }
    void upd(int x, int v, int l, int r, int n) {
        if(x < l || r < x) return;
        if(l == r) {
            tree[n] = v;
            return;
        }
        int m = (l + r)>>1;
        upd(x, v, l, m, 2*n);
        upd(x, v, m + 1, r, 2*n + 1);
        tree[n] = min(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 1e9;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return min(L, R);
    }
} bit;

int N, M, Q;
vector<int> adj[MN], U, V;
int W[MN];
int cut[MN], tin[MN], invt[MN], bck[MN], id[MN], timer, bcnt;
stack<int> stk;

void dfs0(int u, int fe) {
    tin[u] = timer++;
    bck[u] = tin[u];

    int ccnt = 0;
    for(int i = 0; i < adj[u].size(); i++) {
        int e = adj[u][i];
        int v = U[e] + V[e] - u;
        if(e == fe) continue;
        if(tin[v] == -1) {
            stk.push(e);
            dfs0(v, e);
            bck[u] = min(bck[u], bck[v]);
            ccnt++;

            if(tin[u] <= bck[v]) {
                cut[u] = 1;
                while(1) {
                    int t = stk.top(); stk.pop();
                    id[t] = bcnt;
                    if(t == e) break;
                }
                bcnt++;
            }
        }
        else {
            if(tin[v] < tin[u]) stk.push(e);
            bck[u] = min(bck[u], tin[v]);
        }
    }
    if(fe == -1) cut[u] = ccnt > 1;
}

vector<int> badj[MN];
int root[MN], par[MN], sz[MN], fa[20][MN], dep[MN], head[MN];

int lca(int a, int b) {
    if(dep[a] < dep[b]) swap(a, b);
    int diff = dep[a] - dep[b];
    for(int i = 0; i < 20; i++) if(diff & (1 << i)) a = fa[i][a];
    if(a == b) return a;
    for(int i = 20; i--;) {
        if(fa[i][a] != fa[i][b]) {
            a = fa[i][a];
            b = fa[i][b];
        }
    }
    return fa[0][a];
}

void dfs1(int u, int p) {
    fa[0][u] = p;
    for(int i = 1; i < 20; i++) {
        int t = fa[i - 1][u];
        if(t == -1) break;
        fa[i][u] = fa[i - 1][t];
    }
    sz[u] = 1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
    }
}

void dfs2(int u, int p) {
    tin[u] = timer++;

    int mx = -1, big = -1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        if(mx < sz[v]) {
            mx = sz[v], big = v;
        }
    }

    if(big != -1) {
        head[big] = head[u];
        dfs2(big, u);
    }
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p || v == big) continue;
        head[v] = v;
        dfs2(v, u);
    }
}

multiset<int> st[MN];

void add(int x, int v) {
    st[x].insert(v);
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}
void rem(int x, int v) {
    st[x].erase(st[x].find(v));
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}

int query(int u, int p) {
    int h = head[u];
    if(dep[h] <= dep[p]) return bit.quer(tin[h] + dep[p] - dep[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1);
    else return min(query(par[h], p), bit.quer(tin[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1));
}

int main() {
    scanf("%d %d %d", &N, &M, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &W[i]);
    }

    for(int i = 0; i < M; i++) {
        int a, b; scanf("%d %d", &a, &b);
        a--; b--;

        adj[a].push_back(i);
        adj[b].push_back(i);
        U.push_back(a);
        V.push_back(b);
    }

    memset(fa, -1, sizeof(fa));
    memset(tin, -1, sizeof(tin));
    dfs0(0, -1);
    for(int i = 0; i < N; i++) invt[tin[i]] = i;

    memset(par, -1, sizeof(par));
    for(int i = 0; i < bcnt; i++) root[i] = 1e9;
    for(int i = 0; i < M; i++) {
        root[ id[i] ] = min(root[ id[i] ], tin[ U[i] ]);
        root[ id[i] ] = min(root[ id[i] ], tin[ V[i] ]);
    }

    for(int u = 0; u < N; u++) {
        for(int i = 0; i < adj[u].size(); i++) {
            int e = adj[u][i];

            if(root[ id[e] ] != tin[u]) {
                par[u] = N + id[e];
                badj[ par[u] ].push_back(u);
            }
            else {
                par[ N + id[e] ] = u;
                badj[ par[ N + id[e] ] ].push_back(N + id[e]);
            }
        }
    }
    /*
    cout << "id : ";
    for(int i = 0; i < M; i++) {
        cout << id[i] << ' ';
    }
    cout << endl;

    cout << "par : ";
    for(int i = 0; i < N + bcnt; i++) {
        cout << par[i] << ' ';
    }
    cout << endl;
    //*/

    int R = -1;
    for(int i = 0; i < N + bcnt; i++) if(par[i] == -1) R = i;
    dfs1(R, -1);

    memset(tin, -1, sizeof(tin));
    timer = 0;
    head[0] = R;
    dfs2(R, -1);

    bit.init();
    for(int i = 0; i < N; i++) {
        int p = par[i];

        add(tin[i], W[i]);
        if(p != -1) add(tin[p], W[i]);
    }

    for(int i = 0; i < Q; i++) {
        char t; scanf("\n%c", &t);

        if(t == 'C') {
            int a, w; scanf("%d %d", &a, &w);
            a--;

            int p = par[a];

            rem(tin[a], W[a]);
            if(p != -1) rem(tin[p], W[a]);
            W[a] = w;
            add(tin[a], W[a]);
            if(p != -1) add(tin[p], W[a]);
        }
        if(t == 'A') {
            int a, b; scanf("%d %d", &a, &b);
            a--; b--;

            int x = lca(a, b);
            int ans = min(query(a, x), query(b, x));
            if(N <= x) ans = min(ans, *st[ tin[ par[x] ] ].begin());
            printf("%d\n", ans);
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 200010;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * MN, 1e9);
    }
    void upd(int x, int v, int l, int r, int n) {
        if(x < l || r < x) return;
        if(l == r) {
            tree[n] = v;
            return;
        }
        int m = (l + r)>>1;
        upd(x, v, l, m, 2*n);
        upd(x, v, m + 1, r, 2*n + 1);
        tree[n] = min(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 1e9;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return min(L, R);
    }
} bit;

int N, M, Q;
vector<int> adj[MN], U, V;
int W[MN];
int cut[MN], tin[MN], invt[MN], bck[MN], id[MN], timer, bcnt;
stack<int> stk;

void dfs0(int u, int fe) {
    tin[u] = timer++;
    bck[u] = tin[u];

    int ccnt = 0;
    for(int i = 0; i < adj[u].size(); i++) {
        int e = adj[u][i];
        int v = U[e] + V[e] - u;
        if(e == fe) continue;
        if(tin[v] == -1) {
            stk.push(e);
            dfs0(v, e);
            bck[u] = min(bck[u], bck[v]);
            ccnt++;

            if(tin[u] <= bck[v]) {
                cut[u] = 1;
                while(1) {
                    int t = stk.top(); stk.pop();
                    id[t] = bcnt;
                    if(t == e) break;
                }
                bcnt++;
            }
        }
        else {
            if(tin[v] < tin[u]) stk.push(e);
            bck[u] = min(bck[u], tin[v]);
        }
    }
    if(fe == -1) cut[u] = ccnt > 1;
}

vector<int> badj[MN];
int root[MN], par[MN], sz[MN], fa[20][MN], dep[MN], head[MN];

int lca(int a, int b) {
    if(dep[a] < dep[b]) swap(a, b);
    int diff = dep[a] - dep[b];
    for(int i = 0; i < 20; i++) if(diff & (1 << i)) a = fa[i][a];
    if(a == b) return a;
    for(int i = 20; i--;) {
        if(fa[i][a] != fa[i][b]) {
            a = fa[i][a];
            b = fa[i][b];
        }
    }
    return fa[0][a];
}

void dfs1(int u, int p) {
    fa[0][u] = p;
    for(int i = 1; i < 20; i++) {
        int t = fa[i - 1][u];
        if(t == -1) break;
        fa[i][u] = fa[i - 1][t];
    }
    sz[u] = 1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
    }
}

void dfs2(int u, int p) {
    tin[u] = timer++;

    int mx = -1, big = -1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        if(mx < sz[v]) {
            mx = sz[v], big = v;
        }
    }

    if(big != -1) {
        head[big] = head[u];
        dfs2(big, u);
    }
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p || v == big) continue;
        head[v] = v;
        dfs2(v, u);
    }
}

multiset<int> st[MN];

void add(int x, int v) {
    st[x].insert(v);
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}
void rem(int x, int v) {
    st[x].erase(st[x].find(v));
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}

int query(int u, int p) {
    int h = head[u];
    if(dep[h] <= dep[p]) return bit.quer(tin[h] + dep[p] - dep[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1);
    else return min(query(par[h], p), bit.quer(tin[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1));
}

int main() {
    scanf("%d %d %d", &N, &M, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &W[i]);
    }

    for(int i = 0; i < M; i++) {
        int a, b; scanf("%d %d", &a, &b);
        a--; b--;

        adj[a].push_back(i);
        adj[b].push_back(i);
        U.push_back(a);
        V.push_back(b);
    }

    memset(tin, -1, sizeof(tin));
    dfs0(0, -1);
    for(int i = 0; i < N; i++) invt[tin[i]] = i;

    if(N > 60000) {
        cout << "here\n";
        return 0;
    }

    memset(par, -1, sizeof(par));
    for(int i = 0; i < bcnt; i++) root[i] = 1e9;
    for(int i = 0; i < M; i++) {
        root[ id[i] ] = min(root[ id[i] ], tin[ U[i] ]);
        root[ id[i] ] = min(root[ id[i] ], tin[ V[i] ]);
    }

    for(int u = 0; u < N; u++) {
        for(int i = 0; i < adj[u].size(); i++) {
            int e = adj[u][i];

            if(root[ id[e] ] != tin[u]) {
                par[u] = N + id[e];
                badj[ par[u] ].push_back(u);
            }
            else {
                par[ N + id[e] ] = u;
                badj[u].push_back(N + id[e]);
            }
        }
    }
    /*
    cout << "id : ";
    for(int i = 0; i < M; i++) {
        cout << id[i] << ' ';
    }
    cout << endl;

    cout << "par : ";
    for(int i = 0; i < N + bcnt; i++) {
        cout << par[i] << ' ';
    }
    cout << endl;
    //*/

    memset(fa, -1, sizeof(fa));
    int R = -1;
    for(int i = 0; i < N + bcnt; i++) if(par[i] == -1) R = i;
    dfs1(R, -1);

    memset(tin, -1, sizeof(tin));
    timer = 0;
    head[R] = R;
    dfs2(R, -1);

    bit.init();
    for(int i = 0; i < N; i++) {
        int p = par[i];

        add(tin[i], W[i]);
        if(p != -1) add(tin[p], W[i]);
    }

    for(int i = 0; i < Q; i++) {
        char t; scanf("\n%c", &t);

        if(t == 'C') {
            int a, w; scanf("%d %d", &a, &w);
            a--;

            int p = par[a];

            rem(tin[a], W[a]);
            if(p != -1) rem(tin[p], W[a]);
            W[a] = w;
            add(tin[a], W[a]);
            if(p != -1) add(tin[p], W[a]);
        }
        if(t == 'A') {
            int a, b; scanf("%d %d", &a, &b);
            a--; b--;

            int x = lca(a, b);
            int ans = min(query(a, x), query(b, x));
            if(N <= x && par[x] != -1 && st[ tin[ par[x] ] ].size()) ans = min(ans, *st[ tin[ par[x] ] ].begin());
            printf("%d\n", ans);
        }
    }
}


#include<bits/stdc++.h>
using namespace std;

const int MN = 200010;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * MN, 1e9);
    }
    void upd(int x, int v, int l, int r, int n) {
        if(x < l || r < x) return;
        if(l == r) {
            tree[n] = v;
            return;
        }
        int m = (l + r)>>1;
        upd(x, v, l, m, 2*n);
        upd(x, v, m + 1, r, 2*n + 1);
        tree[n] = min(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 1e9;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return min(L, R);
    }
} bit;

int N, M, Q;
vector<int> adj[MN], U, V;
int W[MN];
int cut[MN], tin[MN], invt[MN], bck[MN], id[MN], timer, bcnt;
stack<int> stk;

void dfs0(int u, int fe) {
    tin[u] = timer++;
    bck[u] = tin[u];

    int ccnt = 0;
    for(int i = 0; i < adj[u].size(); i++) {
        int e = adj[u][i];
        int v = U[e] + V[e] - u;
        if(e == fe) continue;
        if(tin[v] == -1) {
            stk.push(e);
            dfs0(v, e);
            bck[u] = min(bck[u], bck[v]);
            ccnt++;

            if(tin[u] <= bck[v]) {
                cut[u] = 1;
                while(1) {
                    int t = stk.top(); stk.pop();
                    id[t] = bcnt;
                    if(t == e) break;
                }
                bcnt++;
            }
        }
        else {
            if(tin[v] < tin[u]) stk.push(e);
            bck[u] = min(bck[u], tin[v]);
        }
    }
    if(fe == -1) cut[u] = ccnt > 1;
}

vector<int> badj[MN];
int root[MN], par[MN], sz[MN], fa[20][MN], dep[MN], head[MN];

int lca(int a, int b) {
    if(dep[a] < dep[b]) swap(a, b);
    int diff = dep[a] - dep[b];
    for(int i = 0; i < 20; i++) if(diff & (1 << i)) a = fa[i][a];
    if(a == b) return a;
    for(int i = 20; i--;) {
        if(fa[i][a] != fa[i][b]) {
            a = fa[i][a];
            b = fa[i][b];
        }
    }
    return fa[0][a];
}

void dfs1(int u, int p) {
    fa[0][u] = p;
    for(int i = 1; i < 20; i++) {
        int t = fa[i - 1][u];
        if(t == -1) break;
        fa[i][u] = fa[i - 1][t];
    }
    sz[u] = 1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
    }
}

void dfs2(int u, int p) {
    tin[u] = timer++;

    int mx = -1, big = -1;
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p) continue;
        if(mx < sz[v]) {
            mx = sz[v], big = v;
        }
    }

    if(big != -1) {
        head[big] = head[u];
        dfs2(big, u);
    }
    for(int i = 0; i < badj[u].size(); i++) {
        int v = badj[u][i];
        if(v == p || v == big) continue;
        head[v] = v;
        dfs2(v, u);
    }
}

multiset<int> st[MN];

void add(int x, int v) {
    st[x].insert(v);
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}
void rem(int x, int v) {
    st[x].erase(st[x].find(v));
    int mn = *st[x].begin();
    bit.upd(x, mn, 0, MN - 1, 1);
}

int query(int u, int p) {
    int h = head[u];
    if(dep[h] <= dep[p]) return bit.quer(tin[h] + dep[p] - dep[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1);
    else return min(query(par[h], p), bit.quer(tin[h], tin[h] + dep[u] - dep[h], 0, MN - 1, 1));
}

int main() {
    scanf("%d %d %d", &N, &M, &Q);

    for(int i = 0; i < N; i++) {
        scanf("%d", &W[i]);
    }

    for(int i = 0; i < M; i++) {
        int a, b; scanf("%d %d", &a, &b);
        a--; b--;

        adj[a].push_back(i);
        adj[b].push_back(i);
        U.push_back(a);
        V.push_back(b);
    }

    memset(fa, -1, sizeof(fa));
    memset(tin, -1, sizeof(tin));
    dfs0(0, -1);
    for(int i = 0; i < N; i++) invt[tin[i]] = i;

    memset(par, -1, sizeof(par));
    for(int i = 0; i < bcnt; i++) root[i] = 1e9;
    for(int i = 0; i < M; i++) {
        root[ id[i] ] = min(root[ id[i] ], tin[ U[i] ]);
        root[ id[i] ] = min(root[ id[i] ], tin[ V[i] ]);
    }

    for(int u = 0; u < N; u++) {
        for(int i = 0; i < adj[u].size(); i++) {
            int e = adj[u][i];

            if(root[ id[e] ] != tin[u]) {
                par[u] = N + id[e];
                badj[ par[u] ].push_back(u);
            }
            else {
                par[ N + id[e] ] = u;
                badj[ par[ N + id[e] ] ].push_back(N + id[e]);
            }
        }
    }
    /*
    cout << "id : ";
    for(int i = 0; i < M; i++) {
        cout << id[i] << ' ';
    }
    cout << endl;

    cout << "par : ";
    for(int i = 0; i < N + bcnt; i++) {
        cout << par[i] << ' ';
    }
    cout << endl;
    //*/

    int R = -1;
    for(int i = 0; i < N + bcnt; i++) if(par[i] == -1) R = i;
    dfs1(R, -1);

    memset(tin, -1, sizeof(tin));
    timer = 0;
    head[0] = R;
    dfs2(R, -1);

    bit.init();
    for(int i = 0; i < N; i++) {
        int p = par[i];

        add(tin[i], W[i]);
        if(p != -1) add(tin[p], W[i]);
    }

    for(int i = 0; i < Q; i++) {
        char t; scanf("\n%c", &t);

        if(t == 'C') {
            int a, w; scanf("%d %d", &a, &w);
            a--;

            int p = par[a];

            rem(tin[a], W[a]);
            if(p != -1) rem(tin[p], W[a]);
            W[a] = w;
            add(tin[a], W[a]);
            if(p != -1) add(tin[p], W[a]);
        }
        if(t == 'A') {
            int a, b; scanf("%d %d", &a, &b);
            a--; b--;

            int x = lca(a, b);
            int ans = min(query(a, x), query(b, x));
            if(N <= x && par[x] != -1 && st[ tin[ par[x] ] ].size()) ans = min(ans, *st[ tin[ par[x] ] ].begin());
            printf("%d\n", ans);
        }
    }
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include <bits/stdc++.h>
using namespace std;

# define P pair<int, int>

typedef multiset<int>::iterator Si;
typedef long long LL;

namespace {
    template <typename T> inline void read(T &x) {
        x = 0; T f = 1; char c = getchar();
        for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
        for(; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
        x = x * f;
    }
}

const int N = 1E5 + 50, INF = 1e9;
const int M = N << 1;

int Ecnt = 1, tot, n, m, Q, idx, first[N], nex[N << 1], arr[N << 1];
int top, dfn[N], low[N], a[N << 1];
char opt[1];
multiset<int> nb[N << 1];
stack<P> st;

namespace gragh {

    # define ls rt << 1
    # define rs ls | 1

    set<P> check;
    int Ecnt, first[M], nex[M << 1], arr[M << 1], dep[M], ws[M], size[M], fa[M];
    int cnt, top[M], s[M], t[M << 2], id[M];
    inline void Add(int u, int v) {
        nex[++Ecnt] = first[u], first[u] = Ecnt, arr[Ecnt] = v;
    }
    inline void insert(int u, int v) {
        if(check.count(P(u, v))) return ;
        // cout << u << ' ' << v << '\n';
        Add(u, v), Add(v, u);
        check.insert(P(u, v)), check.insert(P(v, u));
    }
    void dfs1(int u, int f) {
        ws[u] = -1, dep[u] = dep[f] + 1, size[u] = 1, fa[u] = f;
        if(u > n) a[u] = INF;
        for(int i = first[u], v; i; i = nex[i]) {
            v = arr[i]; if(v == f) continue;
            dfs1(v, u);
            size[u] += size[v];
            if(u > n) {
                a[u] = min(a[u], a[v]);
                nb[u].insert(a[v]);
            }
            if(ws[u] < 0 || size[ws[u]] < size[v]) ws[u] = v;
        }
    }
    void dfs2(int u, int topf) {
        top[u] = topf, id[u] = ++cnt;
        if(ws[u] > 0) dfs2(ws[u], topf);
        for(int i = first[u], v; i; i = nex[i]) {
            v = arr[i];
            if(v == fa[u] || v == ws[u]) continue;
            dfs2(v, v);
        }
    }
    void Build(int rt, int l, int r) {
        if(l == r) return (void) (t[rt] = s[l]);
        int mid = (l + r) >> 1;
        Build(ls, l, mid), Build(rs, mid + 1, r);
        t[rt] = min(t[ls], t[rs]);
    }
    void update(int rt, int Left, int Right, int x, int num) {
        if(Left > x || Right < x) return ;
        if(Left >= x && Right <= x) return (void) (t[rt] = num);
        int mid = (Left + Right) >> 1;
        update(ls, Left, mid, x, num), update(rs, mid + 1, Right, x, num);
        t[rt] = min(t[ls], t[rs]);
    }
    int Q(int rt, int Left, int Right, int l, int r) {
        if(Left > r || Right < l) return INF;
        if(Left >= l && Right <= r) return t[rt];
        int mid = (Left + Right) >> 1;
        return min(Q(ls, Left, mid, l, r), Q(rs, mid + 1, Right, l, r));
    }
    // in here tot equals n
    void init() {
        dfs1(1, 0);
        dfs2(1, 1);
        // for(int i = 1; i <= tot; i++) printf("id[%d] = %d\n", i, id[i]);
        for(int i = 1; i <= tot; i++) s[id[i]] = a[i];
        // for(int i = 1; i <= tot; i++) cout << s[i] << ' ';
        // puts("");
        Build(1, 1, tot);
    }
    int query(int x, int y) {
        int res = INF;
        for(; top[x] != top[y]; ) {
            if(dep[top[x]] < dep[top[y]]) swap(x, y);
            // cout << "l = " << top[x] << " r = " << x << '\n';
            res = min(res, Q(1, 1, tot, id[top[x]], id[x]));
            x = fa[top[x]];
        }
        if(id[x] > id[y]) res = min(res, Q(1, 1, tot, id[y], id[x]));
        else {
            res = min(res, Q(1, 1, tot, id[x], id[y]));
            swap(x, y);
        }
        // cout << x << ' ' << y << ' ' << res << '\n';
        if(y > n) res = min(res, a[fa[y]]);
        return res;
    }
}

inline void add(int u, int v) {
    nex[++Ecnt] = first[u], first[u] = Ecnt, arr[Ecnt] = v;
}
void tarjan(int u, int fa) {
    dfn[u] = low[u] = ++idx;
    for(int i = first[u], v; i; i = nex[i]) {
        if((i ^ 1) == fa) continue;
        v = arr[i];
        if(!dfn[v]) {
            st.push(P(u, v));
            tarjan(v, i), low[u] = min(low[u], low[v]);
            if(dfn[u] <= low[v]) {
                ++tot;
                while(1) {
                    P p = st.top(); st.pop();
                    gragh::insert(p.first, tot);
                    gragh::insert(p.second, tot);
                    if(p.first == u || p.second == u) break;
                }
            }
        }
        else low[u] = min(low[u], dfn[v]);
    }
}
int main() {
    read(n), read(m), read(Q);
    tot = n;
    for(int i = 1; i <= n; i++) read(a[i]);
    for(int i = 1, u, v; i <= m; i++) {
        read(u), read(v);
        add(u, v), add(v, u);
    }
    tarjan(1, 0);
    gragh::init();
    for(int i = 1, x, y; i <= Q; i++) {
        scanf("%s", opt); read(x), read(y);

        if(opt[0] != 'C')  printf("%d\n", gragh::query(x, y));
        else {
            if(gragh::fa[x]) {
                Si it = nb[gragh::fa[x]].find(a[x]);
                nb[gragh::fa[x]].erase(it);
                nb[gragh::fa[x]].insert(y);
                gragh::update(1, 1, tot, gragh::id[gragh::fa[x]], (*nb[gragh::fa[x]].begin()));
            }
            gragh::update(1, 1, tot, gragh::id[x], y);
            a[x] = y;
        }
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace {
    template <typename T> inline void read(T &x) {
        x = 0; T f = 1; char c = getchar();
        for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
        for(; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
        x = x * f;
    }
}
# define P pair<int, int>

const int N = 1E5 + 50, INF = 1e9;
const int M = N << 1;

int Ecnt = 1, tot, n, m, Q, idx, first[N], nex[N << 1], arr[N << 1];
int top, dfn[N], low[N], a[N << 1];
char opt[1];
set<int> nb[N << 1];
stack<P> st;

namespace gragh {

	# define ls rt << 1
	# define rs ls | 1

	set<P> check;
	int Ecnt, first[M], nex[M << 1], arr[M << 1], dep[M], ws[M], size[M], fa[M];
	int cnt, top[M], s[M], t[M << 2], id[M];
	inline void Add(int u, int v) {
		nex[++Ecnt] = first[u], first[u] = Ecnt, arr[Ecnt] = v;
	}
	inline void insert(int u, int v) {
		if(check.count(P(u, v))) return ;
		// cout << u << ' ' << v << '\n';
		Add(u, v), Add(v, u);
		check.insert(P(u, v)), check.insert(P(v, u));
	}
	void dfs1(int u, int f) {
		ws[u] = -1, dep[u] = dep[f] + 1, size[u] = 1, fa[u] = f;
		if(u > n) a[u] = INF;
		for(int i = first[u], v; i; i = nex[i]) {
			v = arr[i]; if(v == f) continue;
			dfs1(v, u);
			size[u] += size[v];
			if(u > n) {
				a[u] = min(a[u], a[v]);
				nb[u].insert(a[v]);
			}
			if(ws[u] < 0 || size[ws[u]] < size[v]) ws[u] = v;
		}
	}
	void dfs2(int u, int topf) {
		top[u] = topf, id[u] = ++cnt;
		if(ws[u] > 0) dfs2(ws[u], topf);
		for(int i = first[u], v; i; i = nex[i]) {
			v = arr[i];
			if(v == fa[u] || v == ws[u]) continue;
			dfs2(v, v);
		}
	}
	void Build(int rt, int l, int r) {
		if(l == r) return (void) (t[rt] = s[l]);
		int mid = (l + r) >> 1;
		Build(ls, l, mid), Build(rs, mid + 1, r);
		t[rt] = min(t[ls], t[rs]);
	}
	void update(int rt, int Left, int Right, int x, int num) {
		if(Left > x || Right < x) return ;
		if(Left >= x && Right <= x) return (void) (t[rt] = num);
		int mid = (Left + Right) >> 1;
		update(ls, Left, mid, x, num), update(rs, mid + 1, Right, x, num);
		t[rt] = min(t[ls], t[rs]);
	}
	int Q(int rt, int Left, int Right, int l, int r) {
		if(Left > r || Right < l) return INF;
		if(Left >= l && Right <= r) return t[rt];
		int mid = (Left + Right) >> 1;
		return min(Q(ls, Left, mid, l, r), Q(rs, mid + 1, Right, l, r));
	}
	// in here tot equals n
	void init() {
		dfs1(1, 0), dfs2(1, 1);
		// for(int i = 1; i <= tot; i++) printf("id[%d] = %d\n", i, id[i]);
		for(int i = 1; i <= tot; i++) s[id[i]] = a[i];
		// for(int i = 1; i <= tot; i++) cout << s[i] << ' ';
		// puts("");
		Build(1, 1, tot);
	}
	int query(int x, int y) {
		int res = INF;
		for(; top[x] != top[y]; ) {
			if(dep[top[x]] < dep[top[y]]) swap(x, y);
			// cout << "l = " << top[x] << " r = " << x << '\n';
			res = min(res, Q(1, 1, tot, id[top[x]], id[x]));
			x = fa[top[x]];
		}
		if(id[x] > id[y]) res = min(res, Q(1, 1, tot, id[y], id[x]));
		else {
			res = min(res, Q(1, 1, tot, id[x], id[y]));
			swap(x, y);
		}
		// cout << x << ' ' << y << ' ' << res << '\n';
		if(y > n) res = min(res, a[fa[y]]);
		return res;
	}
}

inline void add(int u, int v) {
    nex[++Ecnt] = first[u], first[u] = Ecnt, arr[Ecnt] = v;
}
void tarjan(int u, int fa) {
    dfn[u] = low[u] = ++idx;
    for(int i = first[u], v; i; i = nex[i]) {
        if((i ^ 1) == fa) continue;
        v = arr[i];
        if(!dfn[v]) {
        	st.push(P(u, v));
        	tarjan(v, i), low[u] = min(low[u], low[v]);
        	if(dfn[u] <= low[v]) {
        		++tot;
        		while(1) {
        			P p = st.top(); st.pop();
        			gragh::insert(p.first, tot);
        			gragh::insert(p.second, tot);
        			if(p.first == u || p.second == u) break;
        		}
        	}
        }
        else low[u] = min(low[u], dfn[v]);
    }
}
int main() {
    read(n), read(m), read(Q);
    tot = n;
    for(int i = 1; i <= n; i++) read(a[i]);
    for(int i = 1, u, v; i <= m; i++) {
        read(u), read(v);
        add(u, v), add(v, u);
    }
    tarjan(1, 0);
    gragh::init();
    for(int i = 1, x, y; i <= Q; i++) {
    	scanf("%s", opt); read(x), read(y);

 		if(opt[0] != 'C')  printf("%d\n", gragh::query(x, y));
 		else {
 			if(gragh::fa[x]) {
 				nb[gragh::fa[x]].erase(nb[gragh::fa[x]].find(a[x]));
 				nb[gragh::fa[x]].insert(y);
 				gragh::update(1, 1, tot, gragh::id[gragh::fa[x]], (*nb[gragh::fa[x]].begin()));
 			}
 			gragh::update(1, 1, tot, gragh::id[x], y);
 			a[x] = y;
 		}
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int Inf=0x7fffffff;
int head[1000005],nxt[2000005],to[2000005],shu1,shu2,n,m,q;
int in[1000005],val[1000005],tot,dfn[1000005],low[1000005];
int dfs_num,stk[1000005],top[1000005],cnt,size[1000005],son[1000005];
int father[1000005],all,depth[1000005],Top,que[1000005];
vector <int> vec[1000005];
char cha;
multiset <int> s[1000005];
struct node
{
	node *ls,*rs;
	int mina;
	void update(){mina=min(ls->mina,rs->mina);}
}pool[4000005],*tail=pool,*root;
void add(int x,int y)
{
	to[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
void tarjan(int x)
{
	dfn[x]=low[x]=++dfs_num;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=to[i];
		if(!dfn[y])
		{
			stk[++Top]=y;
			tarjan(y);
			low[x]=min(low[x],low[y]);
			if(low[y]>=dfn[x])
			{
				cnt++;
				while(1)
				{
					int now=stk[Top--];
					vec[cnt].push_back(now);vec[now].push_back(cnt);
					if(now==y) break;
				}
				vec[cnt].push_back(x);vec[x].push_back(cnt);
			}
		}
		else low[x]=min(low[x],dfn[y]);
	}
}
void dfs1(int x,int fa)
{
	size[x]=1;father[x]=fa;
	for(auto y : vec[x])
	{
		if(y==fa) continue;
		depth[y]=depth[x]+1;
		if(x>n) s[x].insert(val[y]);
		dfs1(y,x);
		size[x]+=size[y];
		if(size[y]>size[son[x]]) son[x]=y;
	}
	if(x>n) val[x]=*s[x].begin();
}
void dfs2(int x,int fa,int up)
{
	in[x]=++all;que[all]=x;top[x]=up;
	if(son[x]) dfs2(son[x],x,up);
	for(auto y : vec[x])
	{
		if(y==fa||y==son[x]) continue;
		dfs2(y,x,y);
	}
}
void build(node *&nd,int l,int r)
{
	nd=tail++;
	if(l==r) {nd->mina=val[que[l]];return;}
	int mid=l+r>>1;
	build(nd->ls,l,mid);build(nd->rs,mid+1,r);
	nd->update();
}
void modify(node *&nd,int l,int r,int pos,int delta)
{
	if(l==r){nd->mina=delta;return;}
	int mid=l+r>>1;
	if(pos<=mid) modify(nd->ls,l,mid,pos,delta);
	else modify(nd->rs,mid+1,r,pos,delta);
	nd->update();
}
int query(node *nd,int l,int r,int L,int R)
{
	if(l>=L&&r<=R){return nd->mina;}
	int mid=l+r>>1,ans=Inf;
	if(mid>=L) ans=min(ans,query(nd->ls,l,mid,L,R));
	if(mid<R) ans=min(ans,query(nd->rs,mid+1,r,L,R));
	return ans;
}
int query(int x,int y)
{
	int ans=Inf;
	while(top[x]!=top[y])
	{
		if(depth[top[x]]<depth[top[y]]) swap(x,y);
		ans=min(ans,query(root,1,cnt,in[top[x]],in[x]));x=father[top[x]];
	}
	int lca;
	if(depth[x]>depth[y]) ans=min(ans,query(root,1,cnt,in[y],in[x])),lca=y;
	else ans=min(ans,query(root,1,cnt,in[x],in[y])),lca=x;
	if(lca>n) ans=min(ans,val[father[lca]]);
	return ans;
}
int main()
{
	cin>>n>>m>>q;cnt=n;
	for(int i=1;i<=n;i++) scanf("%d",&val[i]);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&shu1,&shu2);
		add(shu1,shu2);add(shu2,shu1);
	}
	tarjan(1);depth[1]=1;
	dfs1(1,0);dfs2(1,0,1);
	build(root,1,cnt);
	for(int i=1;i<=q;i++)
	{
		scanf("\n%c %d %d",&cha,&shu1,&shu2);
		if(cha=='C')
		{
			if(father[shu1]>n)
			{
				auto it=s[father[shu1]].lower_bound(val[shu1]);
				s[father[shu1]].erase(it);s[father[shu1]].insert(shu2);val[father[shu1]]=*s[father[shu1]].begin();modify(root,1,cnt,in[father[shu1]],*s[father[shu1]].begin());
			}
			val[shu1]=shu2;modify(root,1,cnt,in[shu1],shu2);
		}
		else printf("%d\n",query(shu1,shu2));
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read(){
	register int res=0;
	register char c=getchar(),f=1;
	while(c<48||c>57){if(c=='-')f=0;c=getchar();}
	while(c>=48&&c<=57)res=(res<<3)+(res<<1)+(c&15),c=getchar();
	return f?res:-res;
}
inline char getc(){
	register char c=getchar();
	while(c<65||c>90)c=getchar();
	return c;
}

const int N=1e5+5,M=2e5+5,inf=1e9;
int n,m,q,a[N];
vector<int> G[N],T[M];
int dfn[M],low[N],sta[N],tp=0,tot=0,totv;
multiset<int> c[M];
void dfs(int u,int fa){
	sta[++tp]=u,dfn[u]=low[u]=++tot;
	for(auto v:G[u])if(v!=fa){
		if(!dfn[v]){
			dfs(v,u);
			low[u]=min(low[u],low[v]);
			if(low[v]>=dfn[u]){
				T[u].push_back(++totv);
				int z;
				do{
					z=sta[tp--];
					T[totv].push_back(z);
					c[totv].insert(a[z]);
				}while(z!=v);
				a[totv]=c[totv].empty()?inf:*c[totv].begin();
			}
		}
		else low[u]=min(low[u],dfn[v]);
	}
}

int fa[M],sz[M],son[M],dep[M],val[M],top[M];
void dfs1(int u){
	sz[u]=1;
	for(auto v:T[u])if(v!=fa[u]){
		fa[v]=u,dep[v]=dep[u]+1;
		dfs1(v),sz[u]+=sz[v];
		if(sz[son[u]]<sz[v])son[u]=v;
	}
}
void dfs2(int u,int tp){
	dfn[u]=++tot,top[u]=tp;
	val[tot]=a[u];
	if(son[u])dfs2(son[u],tp);
	for(auto v:T[u])if(v!=fa[u]&&v!=son[u])
		dfs2(v,v);
}

#define lc (x<<1)
#define rc (x<<1|1)
#define mid ((l+r)>>1)
int mn[M*4];
void build(int x,int l,int r){
	if(l==r){mn[x]=val[l];return;}
	build(lc,l,mid),build(rc,mid+1,r);
	mn[x]=min(mn[lc],mn[rc]);
}
void update(int x,int l,int r,int pos,int val){
	if(l==r){mn[x]=val;return;}
	if(pos<=mid)update(lc,l,mid,pos,val);
	else update(rc,mid+1,r,pos,val);
	mn[x]=min(mn[lc],mn[rc]);
}
int query(int x,int l,int r,int le,int ri){
	if(l==le&&r==ri)return mn[x];
	int res=inf;
	if(le<=mid)res=min(res,query(lc,l,mid,le,min(mid,ri)));
	if(ri>mid)res=min(res,query(rc,mid+1,r,max(mid+1,le),ri));
	return res;
}

int op,x,y;
int main(){
	n=read(),m=read(),q=read();
	for(int i=1;i<=n;++i)a[i]=read();
	for(int i=1;i<=m;++i){
		x=read(),y=read();
		G[x].push_back(y);
		G[y].push_back(x);
	}
	totv=n,tot=0,dfs(1,0);
	memset(dfn+1,0,sizeof(int)*n);
	tot=0,dfs1(1),dfs2(1,1);
	build(1,1,totv);
	while(q--){
		op=getc(),x=read(),y=read();
		if(op=='C'){
			update(1,1,totv,dfn[x],y);
			if(fa[x]){
				c[fa[x]].erase(c[fa[x]].find(a[x]));
				if(c[fa[x]].empty()||y<*c[fa[x]].begin())
					update(1,1,totv,dfn[fa[x]],y);
				c[fa[x]].insert(a[x]=y);
			}
		}
		else{
			int res=inf;
			while(top[x]!=top[y]){
				if(dep[top[x]]<dep[top[y]])swap(x,y);
				res=min(res,query(1,1,totv,dfn[top[x]],dfn[x]));
				x=fa[top[x]];
			}
			if(dep[x]>dep[y])swap(x,y);
			res=min(res,query(1,1,totv,dfn[x],dfn[y]));
			if(x>n)res=min(res,a[fa[x]]);
			printf("%d\n",res);
		}
	}
}


#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#include <cstdio>//sprintf islower isupper
#include <cstdlib>//malloc  exit strcat itoa system("cls")
#include <iostream>//pair
#include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin);
#include <bitset>
//#include <map>
//#include<unordered_map>
#include <vector>
#include <stack>
#include <set>
#include <string.h>//strstr substr strcat
#include <string>
#include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
#include <cmath>
#include <deque>
#include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
#include <vector>//emplace_back
//#include <math.h>
#include <cassert>
#include <iomanip>
//#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
#include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
//******************
clock_t __START,__END;
double __TOTALTIME;
void _MS(){__START=clock();}
void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
//***********************
#define rint register int
#define fo(a,b,c) for(rint a=b;a<=c;++a)
#define fr(a,b,c) for(rint a=b;a>=c;--a)
#define mem(a,b) memset(a,b,sizeof(a))
#define pr printf
#define sc scanf
#define ls rt<<1
#define rs rt<<1|1
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef unsigned long long ull;
typedef long long ll;
typedef double db;
const db E=2.718281828;
const db PI=acos(-1.0);
const ll INF=(1LL<<60);
const int inf=(1<<30);
const db ESP=1e-9;
const int mod=(int)1e9+7;
const int N=(int)2e5+10;

int n,m,q;
class LINK
{
public:
	struct EDGE
	{
		int to,next;
	}edge[N<<1];
	int etot;
	int head[N];
	void Init(int n)
	{
		etot=0;
		for(int i=0;i<=n;++i)
			head[i]=0;
	}
	void add(int from,int to)
	{
		++etot;
		edge[etot].to=to;
		edge[etot].next=head[from];
		head[from]=etot;
	}//for(int i=head[u];i;i=edge[i].next)
}G,T;

multiset<int>mset[N];
int a[N];
class TARJAN
{
public:
	int deep,dfn[N],low[N],fa[N];
	int sccn;
	bool in[N];
	void build(int u,int v)
	{
		++sccn;
		for(int i=v;i!=fa[u];i=fa[i])
		{
			T.add(i,sccn);
			T.add(sccn,i);
		}
	}
	void Tarjan(int u)
	{
		dfn[u]=++deep;
		low[u]=deep;
		in[u]=true;
		for(int i=G.head[u];i;i=G.edge[i].next)
		{
			int to=G.edge[i].to;
			if(!dfn[to])
			{
				fa[to]=u;
				Tarjan(to);
				low[u]=min(low[u],low[to]);
			}
			else if(in[to])
				low[u]=min(low[u],low[to]);
			if(low[to]>dfn[u])T.add(u,to),T.add(to,u);//添加桥边
		}
		for(int i=G.head[u];i;i=G.edge[i].next)
		{
			int to=G.edge[i].to;
			if(fa[to]!=u&&dfn[u]<dfn[to])
				build(u,to);
		}
	}
	void dfs(int u,int f)
	{
		for(int i=T.head[u];i;i=T.edge[i].next)
		{
			int to=T.edge[i].to;
			if(to==f)continue;
			if(u>n)mset[u].insert(a[to]);
			dfs(to,u);
		}
		if(u>n)a[u]=*mset[u].begin();
	}
}Taj;

class TREECUT;
class SEG//线段树部分
{
public:
//	TREECUT xx;
	int min_[N];
	void up(int rt)
	{
		min_[rt]=min(min_[ls],min_[rs]);
	}
	void Build(int l,int r,int rt,TREECUT &TREE)
	{
		min_[rt]=inf;
		if(l==r)
		{
			min_[rt]=a[TREE.real[l]];
			return;
		}
		int mid=(l+r)>>1;

		Build(l,mid,rt<<1,TREE);
		Build(mid+1,r,rt<<1|1,TREE);
		up(rt);
	}
	void update_dot(int pos,int val,int l,int r,int rt)
	{
		if(pos>r||pos<l)return;
		if(l==r)
		{
			min_[rt]=val;
			return;
		}

		int mid=(l+r)>>1;
		if(pos<=mid)
			update_dot(pos,val,l,mid,rt<<1);
		else
			update_dot(pos,val,mid+1,r,rt<<1|1);
		up(rt);
	}
	int Query(int L,int R,int l,int r,int rt)//查询区间和
	{
		if(L>R)return inf;
		if(L<=l&&r<=R)return min_[rt];
		int mid=(l+r)>>1;
		int ans=inf;
		if(L<=mid) ans=min(Query(L,R,l,mid,rt<<1),ans);
		if(R> mid) ans=min(Query(L,R,mid+1,r,rt<<1|1),ans);
		return ans;
	}
}Seg;

int LCA;
class TREECUT//树链剖分
{
public:
	int DFN;
	int f[N],d[N],sz[N],hson[N],top[N],dfn[N],real[N];
	void dfs1(int u,int fa,int deep)
	{
		sz[u]=1;
		d[u]=deep;
		f[u]=fa;
		for(int i=T.head[u];i;i=T.edge[i].next)
		{
			int to=T.edge[i].to;
			if(to==fa)continue;
			dfs1(to,u,deep+1);
			sz[u]+=sz[to];
			if(sz[to]>sz[hson[u]])hson[u]=to;
		}
	}
	void dfs2(int u,int t)
	{
		top[u]=t;
		dfn[u]=++DFN;
		real[DFN]=u;
		if(!hson[u])return;
		dfs2(hson[u],t);
		for(int i=T.head[u];i;i=T.edge[i].next)
		{
			int to=T.edge[i].to;
			if(to==f[u]||to==hson[u])continue;
			dfs2(to,to);
		}
	}
	int get_min(int x,int y)
	{
		int ans=inf,fx=top[x],fy=top[y];
		while(fx!=fy)//两点不在同一条重链
		{
			if(d[fx]>=d[fy])
			{
				ans=min(ans,Seg.Query(dfn[fx],dfn[x],1,Taj.sccn,1));
				x=f[fx],fx=top[x];
			}
			else
			{
				ans=min(ans,Seg.Query(dfn[fy],dfn[y],1,Taj.sccn,1));
				y=f[fy],fy=top[y];
			}
		}
		if(dfn[x]<=dfn[y])
			ans=min(ans,Seg.Query(dfn[x],dfn[y],1,Taj.sccn,1)),LCA=x;
		else
			ans=min(ans,Seg.Query(dfn[y],dfn[x],1,Taj.sccn,1)),LCA=y;
		return ans;
	}
}TREE;

signed main()
{
	sc("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;++i)sc("%d",&a[i]);
	for(int i=1;i<=m;++i)
	{
		int u,v;
		sc("%d%d",&u,&v);
		G.add(u,v);
		G.add(v,u);
	}
	Taj.sccn=n;
	Taj.Tarjan(1);
	Taj.dfs(1,0);
	TREE.dfs1(1,0,1);
	TREE.dfs2(1,1);
	Seg.Build(1,Taj.sccn,1,TREE);
	for(int i=1;i<=q;++i)
	{
		char temp[5];
		int x,y;
		sc("%s%d%d",temp,&x,&y);
		if(temp[0]=='A')
		{
			int ans=TREE.get_min(x,y);
//			TREE.get_min(x,y);
//			if(LCA>n)
//			{
//				int pre=a[TREE.f[LCA]];
//				mset[LCA].erase(mset[LCA].find(pre));
//				mset[LCA].insert(a[TREE.f[LCA]]);
//				Seg.update_dot(TREE.dfn[LCA],*mset[LCA].begin(),1,Taj.sccn,1);
//				a[LCA]=*mset[LCA].begin();
//			}
			if(LCA>n)
				ans=min(ans,a[TREE.f[LCA]]);
			pr("%d\n",ans);
		}
		else
		{
			int fa=TREE.f[x];
			if(fa>n)
			{
				int pre=a[x];
				mset[fa].erase(mset[fa].find(pre));
				mset[fa].insert(y);
				Seg.update_dot(TREE.dfn[fa],*mset[fa].begin(),1,Taj.sccn,1);
				a[fa]=*mset[fa].begin();
			}
			a[x]=y;
			Seg.update_dot(TREE.dfn[x],y,1,Taj.sccn,1);
		}
	}
	return 0;
}

/**************************************************************************************/


#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#include <cstdio>//sprintf islower isupper
#include <cstdlib>//malloc  exit strcat itoa system("cls")
#include <iostream>//pair
#include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin);
#include <bitset>
//#include <map>
//#include<unordered_map>
#include <vector>
#include <stack>
#include <set>
#include <string.h>//strstr substr strcat
#include <string>
#include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
#include <cmath>
#include <deque>
#include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
#include <vector>//emplace_back
//#include <math.h>
#include <cassert>
#include <iomanip>
//#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
#include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
//******************
clock_t __START,__END;
double __TOTALTIME;
void _MS(){__START=clock();}
void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
//***********************
#define rint register int
#define fo(a,b,c) for(rint a=b;a<=c;++a)
#define fr(a,b,c) for(rint a=b;a>=c;--a)
#define mem(a,b) memset(a,b,sizeof(a))
#define pr printf
#define sc scanf
#define ls rt<<1
#define rs rt<<1|1
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef unsigned long long ull;
typedef long long ll;
typedef double db;
const db E=2.718281828;
const db PI=acos(-1.0);
const ll INF=(1LL<<60);
const int inf=(1<<30);
const db ESP=1e-9;
const int mod=(int)1e9+7;
const int N=(int)1000+10;

int n,m,q;
class LINK
{
public:
	struct EDGE
	{
		int to,next;
	}edge[N<<1];
	int etot;
	int head[N];
	void Init(int n)
	{
		etot=0;
		for(int i=0;i<=n;++i)
			head[i]=0;
	}
	void add(int from,int to)
	{
		++etot;
		edge[etot].to=to;
		edge[etot].next=head[from];
		head[from]=etot;
	}//for(int i=head[u];i;i=edge[i].next)
}G,T;

multiset<int>mset[100010];
int a[N];
class TARJAN
{
public:
	int deep,dfn[N],low[N],fa[N];
	int sccn;
	bool in[N];
	void build(int u,int v)
	{
		++sccn;
		for(int i=v;i!=fa[u];i=fa[i])
		{
			T.add(i,sccn);
			T.add(sccn,i);
		}
	}
	void Tarjan(int u)
	{
		dfn[u]=++deep;
		low[u]=deep;
		in[u]=true;
		for(int i=G.head[u];i;i=G.edge[i].next)
		{
			int to=G.edge[i].to;
			if(!dfn[to])
			{
				fa[to]=u;
				Tarjan(to);
				low[u]=min(low[u],low[to]);
			}
			else if(in[to])
				low[u]=min(low[u],low[to]);
			if(low[to]>dfn[u])T.add(u,to),T.add(to,u);//添加桥边
		}
		for(int i=G.head[u];i;i=G.edge[i].next)
		{
			int to=G.edge[i].to;
			if(fa[to]!=u&&dfn[u]<dfn[to])
				build(u,to);
		}
	}
	void dfs(int u,int f)
	{
		for(int i=T.head[u];i;i=T.edge[i].next)
		{
			int to=T.edge[i].to;
			if(to==f)continue;
			if(u>n)mset[u].insert(a[to]);
			dfs(to,u);
		}
		if(u>n)a[u]=*mset[u].begin();
	}
}Taj;

int Query(int L,int R,int l,int r,int rt);//查询区间和

int LCA;
class TREECUT//树链剖分
{
public:
	int DFN;
	int f[N],d[N],sz[N],hson[N],top[N],dfn[N],real[N];
	void dfs1(int u,int fa,int deep)
	{
		sz[u]=1;
		d[u]=deep;
		f[u]=fa;
		for(int i=T.head[u];i;i=T.edge[i].next)
		{
			int to=T.edge[i].to;
			if(to==fa)continue;
			dfs1(to,u,deep+1);
			sz[u]+=sz[to];
			if(sz[to]>sz[hson[u]])hson[u]=to;
		}
	}
	void dfs2(int u,int t)
	{
		top[u]=t;
		dfn[u]=++DFN;
		real[DFN]=u;
		if(!hson[u])return;
		dfs2(hson[u],t);
		for(int i=T.head[u];i;i=T.edge[i].next)
		{
			int to=T.edge[i].to;
			if(to==f[u]||to==hson[u])continue;
			dfs2(to,to);
		}
	}
	int get_min(int x,int y)
	{
		int ans=inf,fx=top[x],fy=top[y];
		while(fx!=fy)//两点不在同一条重链
		{
			if(d[fx]>=d[fy])
			{
				ans=min(ans,Query(dfn[fx],dfn[x],1,Taj.sccn,1));
				x=f[fx],fx=top[x];
			}
			else
			{
				ans=min(ans,Query(dfn[fy],dfn[y],1,Taj.sccn,1));
				y=f[fy],fy=top[y];
			}
		}
		if(dfn[x]<=dfn[y])
			ans=min(ans,Query(dfn[x],dfn[y],1,Taj.sccn,1)),LCA=x;
		else
			ans=min(ans,Query(dfn[y],dfn[x],1,Taj.sccn,1)),LCA=y;
		return ans;
	}
}TREE;

int min_[N<<2];
void up(int rt)
{
	min_[rt]=min(min_[ls],min_[rs]);
}
void Build(int l,int r,int rt)
{
	min_[rt]=inf;
	if(l==r)
	{
		min_[rt]=a[TREE.real[l]];
		return;
	}
	int mid=(l+r)>>1;

	Build(l,mid,rt<<1);
	Build(mid+1,r,rt<<1|1);
	up(rt);
}
void update_dot(int pos,int val,int l,int r,int rt)
{
	if(pos>r||pos<l)return;
	if(l==r)
	{
		min_[rt]=val;
		return;
	}

	int mid=(l+r)>>1;
	if(pos<=mid)
		update_dot(pos,val,l,mid,rt<<1);
	else
		update_dot(pos,val,mid+1,r,rt<<1|1);
	up(rt);
}
int Query(int L,int R,int l,int r,int rt)//查询区间和
{
	if(L>R)return inf;
	if(L<=l&&r<=R)return min_[rt];
	int mid=(l+r)>>1;
	int ans=inf;
	if(L<=mid) ans=min(Query(L,R,l,mid,rt<<1),ans);
	if(R> mid) ans=min(Query(L,R,mid+1,r,rt<<1|1),ans);
	return ans;
}

signed main()
{
	sc("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;++i)sc("%d",&a[i]);
	for(int i=1;i<=m;++i)
	{
		int u,v;
		sc("%d%d",&u,&v);
		G.add(u,v);
		G.add(v,u);
	}
	Taj.sccn=n;
	Taj.Tarjan(1);
	Taj.dfs(1,0);
	TREE.dfs1(1,0,1);
	TREE.dfs2(1,1);
	Build(1,Taj.sccn,1);
	for(int i=1;i<=q;++i)
	{
		char temp[5];
		int x,y;
		sc("%s%d%d",temp,&x,&y);
		if(temp[0]=='A')
		{
			int ans=TREE.get_min(x,y);
//			TREE.get_min(x,y);
//			if(LCA>n)
//			{
//				int pre=a[TREE.f[LCA]];
//				mset[LCA].erase(mset[LCA].find(pre));
//				mset[LCA].insert(a[TREE.f[LCA]]);
//				update_dot(TREE.dfn[LCA],*mset[LCA].begin(),1,Taj.sccn,1);
//				a[LCA]=*mset[LCA].begin();
//			}
			if(LCA>n)
				ans=min(ans,a[TREE.f[LCA]]);
			pr("%d\n",ans);
		}
		else
		{
			int fa=TREE.f[x];
			if(fa>n)
			{
				int pre=a[x];
				mset[fa].erase(mset[fa].find(pre));
				mset[fa].insert(y);
				update_dot(TREE.dfn[fa],*mset[fa].begin(),1,Taj.sccn,1);
				a[fa]=*mset[fa].begin();
			}
			a[x]=y;
			update_dot(TREE.dfn[x],y,1,Taj.sccn,1);
		}
	}
	return 0;
}

/**************************************************************************************/


#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#include <cstdio>//sprintf islower isupper
#include <cstdlib>//malloc  exit strcat itoa system("cls")
#include <iostream>//pair
#include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin);
#include <bitset>
//#include <map>
//#include<unordered_map>
#include <vector>
#include <stack>
#include <set>
#include <string.h>//strstr substr strcat
#include <string>
#include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
#include <cmath>
#include <deque>
#include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
#include <vector>//emplace_back
//#include <math.h>
#include <cassert>
#include <iomanip>
//#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
#include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
//******************
clock_t __START,__END;
double __TOTALTIME;
void _MS(){__START=clock();}
void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
//***********************
#define rint register int
#define fo(a,b,c) for(rint a=b;a<=c;++a)
#define fr(a,b,c) for(rint a=b;a>=c;--a)
#define mem(a,b) memset(a,b,sizeof(a))
#define pr printf
#define sc scanf
#define ls rt<<1
#define rs rt<<1|1
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef unsigned long long ull;
typedef long long ll;
typedef double db;
const db E=2.718281828;
const db PI=acos(-1.0);
const ll INF=(1LL<<60);
const int inf=(1<<30);
const db ESP=1e-9;
const int mod=(int)1e9+7;
const int N=(int)2e5+10;

int n,m,q;
class LINK
{
public:
	struct EDGE
	{
		int to,next;
	}edge[N<<1];
	int etot;
	int head[N];
	void Init(int n)
	{
		etot=0;
		for(int i=0;i<=n;++i)
			head[i]=0;
	}
	void add(int from,int to)
	{
		++etot;
		edge[etot].to=to;
		edge[etot].next=head[from];
		head[from]=etot;
	}//for(int i=head[u];i;i=edge[i].next)
}G,T;

multiset<int>mset[N];
int a[N];
class TARJAN
{
public:
	int deep,dfn[N],low[N],fa[N];
	int sccn;
	bool in[N];
	void build(int u,int v)
	{
		++sccn;
		for(int i=v;i!=fa[u];i=fa[i])
		{
			T.add(i,sccn);
			T.add(sccn,i);
		}
	}
	void Tarjan(int u)
	{
		dfn[u]=++deep;
		low[u]=deep;
		in[u]=true;
		for(int i=G.head[u];i;i=G.edge[i].next)
		{
			int to=G.edge[i].to;
			if(!dfn[to])
			{
				fa[to]=u;
				Tarjan(to);
				low[u]=min(low[u],low[to]);
			}
			else if(in[to])
				low[u]=min(low[u],low[to]);
			if(low[to]>dfn[u])T.add(u,to),T.add(to,u);//添加桥边
		}
		for(int i=G.head[u];i;i=G.edge[i].next)
		{
			int to=G.edge[i].to;
			if(fa[to]!=u&&dfn[u]<dfn[to])
				build(u,to);
		}
	}
	void dfs(int u,int f)
	{
		for(int i=T.head[u];i;i=T.edge[i].next)
		{
			int to=T.edge[i].to;
			if(to==f)continue;
			if(u>n)mset[u].insert(a[to]);
			dfs(to,u);
		}
		if(u>n)a[u]=*mset[u].begin();
	}
}Taj;

int Query(int L,int R,int l,int r,int rt);//查询区间和

int LCA;
class TREECUT//树链剖分
{
public:
	int DFN;
	int f[N],d[N],sz[N],hson[N],top[N],dfn[N],real[N];
	void dfs1(int u,int fa,int deep)
	{
		sz[u]=1;
		d[u]=deep;
		f[u]=fa;
		for(int i=T.head[u];i;i=T.edge[i].next)
		{
			int to=T.edge[i].to;
			if(to==fa)continue;
			dfs1(to,u,deep+1);
			sz[u]+=sz[to];
			if(sz[to]>sz[hson[u]])hson[u]=to;
		}
	}
	void dfs2(int u,int t)
	{
		top[u]=t;
		dfn[u]=++DFN;
		real[DFN]=u;
		if(!hson[u])return;
		dfs2(hson[u],t);
		for(int i=T.head[u];i;i=T.edge[i].next)
		{
			int to=T.edge[i].to;
			if(to==f[u]||to==hson[u])continue;
			dfs2(to,to);
		}
	}
	int get_min(int x,int y)
	{
		int ans=inf,fx=top[x],fy=top[y];
		while(fx!=fy)//两点不在同一条重链
		{
			if(d[fx]>=d[fy])
			{
				ans=min(ans,Query(dfn[fx],dfn[x],1,Taj.sccn,1));
				x=f[fx],fx=top[x];
			}
			else
			{
				ans=min(ans,Query(dfn[fy],dfn[y],1,Taj.sccn,1));
				y=f[fy],fy=top[y];
			}
		}
		if(dfn[x]<=dfn[y])
			ans=min(ans,Query(dfn[x],dfn[y],1,Taj.sccn,1)),LCA=x;
		else
			ans=min(ans,Query(dfn[y],dfn[x],1,Taj.sccn,1)),LCA=y;
		return ans;
	}
}TREE;

int min_[N<<2];
void up(int rt)
{
	min_[rt]=min(min_[ls],min_[rs]);
}
void Build(int l,int r,int rt)
{
	min_[rt]=inf;
	if(l==r)
	{
		min_[rt]=a[TREE.real[l]];
		return;
	}
	int mid=(l+r)>>1;

	Build(l,mid,rt<<1);
	Build(mid+1,r,rt<<1|1);
	up(rt);
}
void update_dot(int pos,int val,int l,int r,int rt)
{
	if(pos>r||pos<l)return;
	if(l==r)
	{
		min_[rt]=val;
		return;
	}

	int mid=(l+r)>>1;
	if(pos<=mid)
		update_dot(pos,val,l,mid,rt<<1);
	else
		update_dot(pos,val,mid+1,r,rt<<1|1);
	up(rt);
}
int Query(int L,int R,int l,int r,int rt)//查询区间和
{
	if(L>R)return inf;
	if(L<=l&&r<=R)return min_[rt];
	int mid=(l+r)>>1;
	int ans=inf;
	if(L<=mid) ans=min(Query(L,R,l,mid,rt<<1),ans);
	if(R> mid) ans=min(Query(L,R,mid+1,r,rt<<1|1),ans);
	return ans;
}

signed main()
{
	sc("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;++i)sc("%d",&a[i]);
	for(int i=1;i<=m;++i)
	{
		int u,v;
		sc("%d%d",&u,&v);
		G.add(u,v);
		G.add(v,u);
	}
	Taj.sccn=n;
	Taj.Tarjan(1);
	Taj.dfs(1,0);
	TREE.dfs1(1,0,1);
	TREE.dfs2(1,1);
	Build(1,Taj.sccn,1);
	for(int i=1;i<=q;++i)
	{
		char temp[5];
		int x,y;
		sc("%s%d%d",temp,&x,&y);
		if(temp[0]=='A')
		{
			int ans=TREE.get_min(x,y);
//			TREE.get_min(x,y);
//			if(LCA>n)
//			{
//				int pre=a[TREE.f[LCA]];
//				mset[LCA].erase(mset[LCA].find(pre));
//				mset[LCA].insert(a[TREE.f[LCA]]);
//				update_dot(TREE.dfn[LCA],*mset[LCA].begin(),1,Taj.sccn,1);
//				a[LCA]=*mset[LCA].begin();
//			}
			if(LCA>n)
				ans=min(ans,a[TREE.f[LCA]]);
			pr("%d\n",ans);
		}
		else
		{
			int fa=TREE.f[x];
			if(fa>n)
			{
				int pre=a[x];
				mset[fa].erase(mset[fa].find(pre));
				mset[fa].insert(y);
				update_dot(TREE.dfn[fa],*mset[fa].begin(),1,Taj.sccn,1);
				a[fa]=*mset[fa].begin();
			}
			a[x]=y;
			update_dot(TREE.dfn[x],y,1,Taj.sccn,1);
		}
	}
	return 0;
}

/**************************************************************************************/


#include <bits/stdc++.h>
using namespace std;

#define pii pair<int, int>

inline void cmin(int &x, int y)
{
    x = min(x, y);
}

const int inf = 1000000007;

int N, M, S, L; // 点数 | 边数 | 询问数量 | ≥总点数的最小2的幂，用于线段树 | (´･_･`)
vector<int> e[100010]; // 存边
int w[200010]; // [1,N]部分存圆点权值，[N,N+bcccnt]部分存方点权值
#define ws ws_
multiset<int> ws[200010]; // 维护方点的可取权值集合。ws好像和某个关键字或者内置函数冲突了

// 这一堆是计算点双联通分量用的
// 顺便，如果Tarjan写存点而不是存边的话应该会简单一些
int dfscnt = 0; // 原图的DFS序
int num[100010]; // 存储某点的原DFS序
int lowpt[100010]; // 就是Tarjan那个lowpt（大雾）
stack<int> st; // 同上（
bool inst[100010];
int bcccnt = 0; // BCC的序号
vector<int> bcc[100010]; // 存每个BCC内的点
int col[100010]; // 用来配合tbcc[]搞出bcc[]的……

// 这一堆大概是和树剖有关的
vector<int> ne[200010]; // 新边
int fa[200010]; // 父节点
int dep[200010]; // 深度
int sz[200010]; // 子树大小
int hson[200100]; // 重儿子
int reccnt = 0; // 树的新DFS序
int id[200010], rec[200010]; // 存储某点的新DFS序，以及某个序号对应的点
int tp[200010]; // 链的顶端

// 线段树用。
#define data data_
int data[800010]; // …似乎data也和某个关键字或者内置函数冲突了

void DFS(int x, int p) // Tarjan求点双连通分量
{
    num[x]=++dfscnt;
    lowpt[x]=num[x];
    st.push(x);
    inst[x]=true;
    for(auto to:e[x])
    {
        if(!num[to])
        {
            DFS(to,x);
            cmin(lowpt[x],lowpt[to]);
            if(lowpt[to]>=num[x])
            {
                bcccnt++;
                while(st.top()!=x)
                {
                    bcc[bcccnt].push_back(st.top());
                    st.pop();
                }
                bcc[bcccnt].push_back(x);
            }
        }
        else if(inst[to])
        {
            cmin(lowpt[x],lowpt[to]);
        }
    }
    if(x==1 && !st.empty())
    {
        bcccnt++;
        while(st.top()!=x)
        {
            bcc[bcccnt].push_back(st.top());
            st.pop();
        }
        bcc[bcccnt].push_back(x);
        if(bcc[bcccnt].size()<=1) bcccnt--;
    }
}

void DFS0(int x, int p, int d) // 树剖第一遍DFS。求fa[],dep[],sz[],hson[]
{
    fa[x] = p;
    dep[x] = d;
    sz[x] = 1;
    for (int i = 0; i < ne[x].size(); i++)
    {
        int &to = ne[x][i];
        if (to != p)
        {
            DFS0(to, x, d + 1);
            sz[x] += sz[to];
        }
    }
    int maxsz = -1;
    hson[x] = -1;
    for (int i = 0; i < ne[x].size(); i++)
    {
        int &to = ne[x][i];
        if (to != p && sz[to] > maxsz)
        {
            maxsz = sz[to];
            hson[x] = to;
        }
    }
}

void DFS1(int x, int p, int t) // 树剖第二遍DFS。求新dfs序id[]以及rec[]，顺便求出tp[]
{
    reccnt++;
    id[x] = reccnt;
    rec[reccnt] = x;
    tp[x] = t;
    if (hson[x] != -1)
        DFS1(hson[x], x, t);
    for (int i = 0; i < ne[x].size(); i++)
    {
        int &to = ne[x][i];
        if (to != p && to != hson[x])
        {
            DFS1(to, x, to);
        }
    }
}

inline void pushup(int o) // 线段树更新当前点
{
    data[o] = min(data[o << 1], data[o << 1 | 1]);
}

void build(int o, int l, int r) // 线段树建树
{
    if (l == r)
    {
        if (l <= N + bcccnt)
            data[o] = w[rec[l]];
        else
            data[o] = inf;
        return;
    }
    int mid = (l + r) >> 1;
    build(o << 1, l, mid);
    build(o << 1 | 1, mid + 1, r);
    pushup(o);
}

int query(int o, int l, int r, int ql, int qr) // 线段树区间查询最小值
{
    if (l == r || (ql <= l && r <= qr))
        return data[o];
    int mid = (l + r) >> 1;
    int res = inf;
    if (ql <= mid)
        cmin(res, query(o << 1, l, mid, ql, qr));
    if (mid + 1 <= qr)
        cmin(res, query(o << 1 | 1, mid + 1, r, ql, qr));
    return res;
}

void upd(int o, int l, int r, int pos, int val) // 线段树单点更新
{
    if (l == r)
    {
        data[o] = val;
        return;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid)
        upd(o << 1, l, mid, pos, val);
    else
        upd(o << 1 | 1, mid + 1, r, pos, val);
    pushup(o);
}

inline int lca(int u, int v) // 树剖求lca
{
    int fu = tp[u], fv = 304; fv = tp[v]; // FV304天下第一（无关
    while (fu != fv)
    {
        if (dep[fu] > dep[fv])
        {
            u = fa[fu];
            fu = tp[u];
        }
        else
        {
            v = fa[fv];
            fv = tp[v];
        }
    }
    if (dep[u] < dep[v])
        return u;
    else
        return v;
}

int getmin(int u, int v) // 树剖求树上两点间最小值
{
    int ans = inf;
    int fu = tp[u], fv = 304; fv = tp[v];
    while (fu != fv)
    {
        if (dep[fu] > dep[fv])
        {
            cmin(ans, query(1, 1, L, id[fu], id[u]));
            u = fa[fu];
            fu = tp[u];
        }
        else
        {
            cmin(ans, query(1, 1, L, id[fv], id[v]));
            v = fa[fv];
            fv = tp[v];
        }
    }
    cmin(ans, query(1, 1, L, min(id[u], id[v]), max(id[u], id[v])));
    int an = lca(u, v);
    if (an > N) // 特判：u,v的lca为方点
    {
        cmin(ans, w[fa[an]]);
    }
    return ans;
}

void update(int x, int val) // 修改操作
{
    if (fa[x] != -1) // 更新圆点父亲的权值
    {
        ws[fa[x]].erase(ws[fa[x]].lower_bound(w[x]));
        ws[fa[x]].insert(val);
        w[fa[x]] = *ws[fa[x]].begin();
        upd(1, 1, L, id[fa[x]], w[fa[x]]);
    }
    w[x] = val; // 更新圆点权值
    upd(1, 1, L, id[x], val);
}

signed main()
{
    ios::sync_with_stdio(false);

    cin >> N >> M >> S;
    for (int i = 1; i <= N; i++)
        cin >> w[i];
    for (int i = 1; i <= M; i++)
    {
        int u, v;
        cin >> u >> v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    DFS(1, -1);
    L = N + bcccnt;
    while (L & (L - 1))
        L++;
    for (int i = 1; i <= bcccnt; i++) // 重新构图
    {
        for (int j = 0; j < bcc[i].size(); j++)
        {
            int &cur = bcc[i][j];
            ne[cur].push_back(N + i);
            ne[N + i].push_back(cur);
        }
    }
    DFS0(1, -1, 1);
    DFS1(1, -1, 1);
    for (int i = N + 1; i <= N + bcccnt; i++) // 求方点初始权值。注意方点序号从N+1开始
    {
        for (int j = 0; j < ne[i].size(); j++)
        {
            int &to = ne[i][j];
            if (to != fa[i])
                ws[i].insert(w[to]);
        }
        w[i] = *ws[i].begin();
    }
    build(1, 1, L);
    while (S--)
    {
        char op;
        int x, y;
        cin >> op >> x >> y;
        if (op == 'A')
            cout << getmin(x, y) << endl;
        else
            update(x, y);
    }

    return 0;
}