#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std; using namespace __gnu_pbds;
//#pragma GCC optimize("Ofast") //#pragma GCC optimize "unroll-loops" //#pragma GCC optimize "prefetch-loop-arrays" //#pragma GCC target "sse,sse2,sse3,sse4,abm,avx,aes,sse4a,sse4.1,sse4.2,mmx,popcnt,tune=native"
#define foru(i,a,b) for(int i=(a);i<(b);i++)
#define ford(i,a,b) for(int i=(a);i>=(b);i--)
#define fori(a,b) foru(i,a,b)
#define forj(a,b) foru(j,a,b)
#define fork(a,b) foru(k,a,b)
#define seto(x,i) memset(x,i,sizeof x)
#define pf first
#define ps second
#define pb push_back
#define eb emplace_back
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define clz __builtin_clz
#define clzll __builtin_clzll
#define ctz __builtin_ctz
#define ctzll __builtin_ctzll
#define P2(x) (1LL<<(x))
#define sz(x) (int)x.size()
#define all(x) begin(x),end(x)
#if __SIZEOF_INT128__
    typedef __int128_t i128; typedef __uint128_t ui128;
#else
    typedef long long i128; typedef unsigned long long ui128;
#endif
typedef int64_t ll;  typedef uint64_t ull; typedef int8_t byte; typedef long double lld;
typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<lld,lld> pdd;
template<typename T1,typename T2> using ordered_map=tree<T1,T2,less<T1>,rb_tree_tag,tree_order_statistics_node_update>;
template<typename T1> using ordered_set=ordered_map<T1,null_type>;
const int inf=0x3f3f3f3f,MOD=1e9+7; const ll INF=0x3f3f3f3f3f3f3f3f; const lld PI=acos((lld)-1);
ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll fpow(ll a,ll b){if(!b) return 1; ll t=fpow(a,b/2); if(b&1) return t*t%MOD*a%MOD; return t*t%MOD;}
const ll SEED=chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
mt19937 randgen(SEED); int randint(int a, int b){return uniform_int_distribution<int>(a,b)(randgen);} ll randll(ll a, ll b){return uniform_int_distribution<ll>(a,b)(randgen);}
template<class T1,class T2>constexpr const auto _min(const T1&x,const T2&y){return x<y?x:y;} template<class T,class...Ts>constexpr auto _min(const T&x,const Ts&...xs){return _min(x,_min(xs...));}
template<class T1,class T2>constexpr const auto _max(const T1&x,const T2&y){return x>y?x:y;} template<class T,class...Ts>constexpr auto _max(const T&x,const Ts&...xs){return _max(x,_max(xs...));}
#define min(...) _min(__VA_ARGS__)
#define max(...) _max(__VA_ARGS__)
struct chash{
    static ll splitmix64(ll x){x+=0x9e3779b97f4a7c15; x=(x^(x>>30))*0xbf58476d1ce4e5b9; x=(x^(x>>27))*0x94d049bb133111eb; return x^(x>>31);}
    template<class T> size_t operator()(const T &x) const{return splitmix64(hash<T>()(x)+SEED);}
    template<class T1,class T2> size_t operator()(const pair<T1,T2>&x)const{return 31*operator()(x.first)+operator()(x.second);}
};
#define nl "\n"

const int N=P2(18),M=MOD;
int n,m,q,n2,a,b,val[N],dfn[N],low[N],sz[N],par[N],top[N],dep[N];
vector<int> gr[N],gr2[N];
stack<int> scc;
bitset<N> art;
set<int> vals[N];
char ch;
struct SegTree{
    int seg[2*N];
    SegTree(){seto(seg,inf);}
    void pull(int x){seg[x]=min(seg[2*x],seg[2*x+1]);}
    void upd(int x,int v){
        seg[x+=N]=v;
        for(x/=2;x;x/=2) pull(x);
    }
    int query(int l,int r){
        int ret=inf;
        for(l+=N,r+=N+1;l<r;l/=2,r/=2){
            if(l&1) ret=min(ret,seg[l++]);
            if(r&1) ret=min(seg[--r],ret);
        }
        return ret;
    }
} st;
void tarjan(int v,int p=-1){
    dfn[v]=low[v]=a++; scc.push(v);
    for(auto i:gr2[v]) if(i!=p){
        if(dfn[i]) low[v]=min(low[v],dfn[i]);
        else{
            tarjan(i,v);
            if(low[i]>=dfn[v]){
                n2++; val[n2]=inf; art[v]=1;
                for(;scc.top()!=v&&low[scc.top()]>=dfn[v];scc.pop()){
                    int x=scc.top(); gr[x].pb(n2); gr[n2].pb(x);
                }
                if(low[i]==dfn[v]){
                    gr[n2].pb(v); gr[v].pb(n2);
                }
                else{
                    gr[i].pb(v); gr[v].pb(i); art[i]=1;
                }
            }
            low[v]=min(low[v],low[i]);
        }
    }
}
void szdfs(int v,int p=0){
    sz[v]=1;
    for(auto& i:gr[v]) if(i!=p){
        szdfs(i,v); sz[v]+=sz[i];
        if(gr[v][0]==p||sz[i]>sz[gr[v][0]]) swap(i,gr[v][0]);
    }
}
void hlddfs(int v,int p=0){
    dfn[v]=a++; par[v]=p;
    for(auto i:gr[v]) if(i!=p){
        top[i]=i==gr[v][0]? top[v]: i;
        hlddfs(i,v);
    }
}
int query(int u,int v){
    if(u==v) return val[u];
    int ret=inf;
    while(top[u]!=top[v]){
        if(dfn[top[u]]>dfn[top[v]]) swap(u,v);
        ret=min(ret,st.query(dfn[top[v]],dfn[v]));
        v=par[top[v]];
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    ret=min(ret,st.query(dfn[u],dfn[v]));
    if(art[par[u]]) ret=min(ret,st.query(dfn[par[u]],dfn[par[u]]));
    return ret;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("", "r", stdin); //freopen("", "w", stdout);
    cin>>n>>m>>q;
    fori(1,n+1) cin>>val[i];
    fori(0,m){
        cin>>a>>b; gr2[a].pb(b); gr2[b].pb(a);
    }
    gr2[0].pb(1); n2=n; tarjan(0); szdfs(1); a=0; top[1]=1; hlddfs(1); art[0]=0;
    fori(1,n+1) if(par[a]&&!art[par[a]]) vals[par[a]].insert(val[i]);
    fori(1,n+1) if(art[i]) st.upd(dfn[i],val[i]);
    fori(n+1,n2+1) if(sz(vals[i])) st.upd(dfn[i],*vals[i].begin());
    while(q--){
        cin>>ch>>a>>b;
        if(ch=='A') cout<<query(a,b)<<nl;
        else if(ch=='C'){
            if(art[a]) st.upd(dfn[a],b);
            if(par[a]&&!art[par[a]]){
                vals[par[a]].erase(val[a]);
                vals[par[a]].insert(b);
                st.upd(dfn[par[a]],*vals[par[a]].begin());
            }
            val[a]=b;
        }
    }
    return 0;
}
/**

*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std; using namespace __gnu_pbds;
//#pragma GCC optimize("Ofast") //#pragma GCC optimize "unroll-loops" //#pragma GCC optimize "prefetch-loop-arrays" //#pragma GCC target "sse,sse2,sse3,sse4,abm,avx,aes,sse4a,sse4.1,sse4.2,mmx,popcnt,tune=native"
#define foru(i,a,b) for(int i=(a);i<(b);i++)
#define ford(i,a,b) for(int i=(a);i>=(b);i--)
#define fori(a,b) foru(i,a,b)
#define forj(a,b) foru(j,a,b)
#define fork(a,b) foru(k,a,b)
#define seto(x,i) memset(x,i,sizeof x)
#define pf first
#define ps second
#define pb push_back
#define eb emplace_back
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define clz __builtin_clz
#define clzll __builtin_clzll
#define ctz __builtin_ctz
#define ctzll __builtin_ctzll
#define P2(x) (1LL<<(x))
#define sz(x) (int)x.size()
#define all(x) begin(x),end(x)
#if __SIZEOF_INT128__
    typedef __int128_t i128; typedef __uint128_t ui128;
#else
    typedef long long i128; typedef unsigned long long ui128;
#endif
typedef int64_t ll;  typedef uint64_t ull; typedef int8_t byte; typedef long double lld;
typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<lld,lld> pdd;
template<typename T1,typename T2> using ordered_map=tree<T1,T2,less<T1>,rb_tree_tag,tree_order_statistics_node_update>;
template<typename T1> using ordered_set=ordered_map<T1,null_type>;
const int inf=0x3f3f3f3f,MOD=1e9+7; const ll INF=0x3f3f3f3f3f3f3f3f; const lld PI=acos((lld)-1);
ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll fpow(ll a,ll b){if(!b) return 1; ll t=fpow(a,b/2); if(b&1) return t*t%MOD*a%MOD; return t*t%MOD;}
const ll SEED=chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
mt19937 randgen(SEED); int randint(int a, int b){return uniform_int_distribution<int>(a,b)(randgen);} ll randll(ll a, ll b){return uniform_int_distribution<ll>(a,b)(randgen);}
template<class T1,class T2>constexpr const auto _min(const T1&x,const T2&y){return x<y?x:y;} template<class T,class...Ts>constexpr auto _min(const T&x,const Ts&...xs){return _min(x,_min(xs...));}
template<class T1,class T2>constexpr const auto _max(const T1&x,const T2&y){return x>y?x:y;} template<class T,class...Ts>constexpr auto _max(const T&x,const Ts&...xs){return _max(x,_max(xs...));}
#define min(...) _min(__VA_ARGS__)
#define max(...) _max(__VA_ARGS__)
struct chash{
    static ll splitmix64(ll x){x+=0x9e3779b97f4a7c15; x=(x^(x>>30))*0xbf58476d1ce4e5b9; x=(x^(x>>27))*0x94d049bb133111eb; return x^(x>>31);}
    template<class T> size_t operator()(const T &x) const{return splitmix64(hash<T>()(x)+SEED);}
    template<class T1,class T2> size_t operator()(const pair<T1,T2>&x)const{return 31*operator()(x.first)+operator()(x.second);}
};
#define nl "\n"

const int N=P2(18),M=MOD;
int n,m,q,n2,a,b,val[N],dfn[N],low[N],sz[N],par[N],top[N];
vector<int> gr[N],gr2[N];
stack<int> scc;
bool  art[N];
set<int> vals[N];
char ch;
struct SegTree{
    int seg[2*N];
    SegTree(){seto(seg,inf);}
    void pull(int x){seg[x]=min(seg[2*x],seg[2*x+1]);}
    void upd(int x,int v){
        seg[x+=N]=v;
        for(x/=2;x;x/=2) pull(x);
    }
    int query(int l,int r){
        int ret=inf;
        for(l+=N,r+=N+1;l<r;l/=2,r/=2){
            if(l&1) ret=min(ret,seg[l++]);
            if(r&1) ret=min(seg[--r],ret);
        }
        return ret;
    }
} st;
void tarjan(int v,int p=-1){
    dfn[v]=low[v]=a++; scc.push(v);
    for(auto i:gr2[v]) if(i!=p){
        if(dfn[i]) low[v]=min(low[v],dfn[i]);
        else{
            tarjan(i,v);
            if(low[i]>=dfn[v]){
                n2++; val[n2]=inf; art[v]=1;
                for(;scc.top()!=v&&low[scc.top()]>=dfn[v];scc.pop()){
                    int x=scc.top(); gr[x].pb(n2); gr[n2].pb(x);
                }
                if(low[i]==dfn[v]){
                    gr[n2].pb(v); gr[v].pb(n2);
                }
                else{
                    gr[i].pb(v); gr[v].pb(i); art[i]=1;
                }
            }
            low[v]=min(low[v],low[i]);
        }
    }
}
void szdfs(int v,int p=0){
    sz[v]=1;
    for(auto& i:gr[v]) if(i!=p){
        szdfs(i,v); sz[v]+=sz[i];
        if(gr[v][0]==p||sz[i]>sz[gr[v][0]]) swap(i,gr[v][0]);
    }
}
void hlddfs(int v,int p=0){
    dfn[v]=++a; par[v]=p;
    for(auto i:gr[v]) if(i!=p){
        top[i]=i==gr[v][0]? top[v]: i;
        hlddfs(i,v);
    }
}
int query(int u,int v){
    if(u==v) return val[u];
    int ret=inf;
    while(top[u]!=top[v]){
        if(dfn[top[u]]>dfn[top[v]]) swap(u,v);
        ret=min(ret,st.query(dfn[top[v]],dfn[v]));
        v=par[top[v]];
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    ret=min(ret,st.query(dfn[u],dfn[v]));
    if(art[par[u]]) ret=min(ret,st.query(dfn[par[u]],dfn[par[u]]));
    return ret;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("", "r", stdin); //freopen("", "w", stdout);
    cin>>n>>m>>q;
    fori(1,n+1) cin>>val[i];
    fori(0,m){
        cin>>a>>b; gr2[a].pb(b); gr2[b].pb(a);
    }
    gr2[0].pb(1); n2=n; tarjan(0); szdfs(1); a=0; top[1]=1; hlddfs(1); art[0]=0;
    fori(1,n+1) if(par[i]&&!art[par[i]]) vals[par[i]].insert(val[i]);
    fori(1,n+1) if(art[i]) st.upd(dfn[i],val[i]);
    fori(n+1,n2+1) if(sz(vals[i])) st.upd(dfn[i],*vals[i].begin());
    while(q--){
        cin>>ch>>a>>b;
        if(ch=='A') cout<<query(a,b)<<nl;
        else if(ch=='C'){
            if(art[a]) st.upd(dfn[a],b);
            if(par[a]&&!art[par[a]]){
                vals[par[a]].erase(val[a]);
                vals[par[a]].insert(b);
                st.upd(dfn[par[a]],*vals[par[a]].begin());
            }
            val[a]=b;
        }
    }
    return 0;
}
/**
5 4 0
0 0 0 0 0
1 2
2 3
3 4
4 5
*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std; using namespace __gnu_pbds;
//#pragma GCC optimize("Ofast") //#pragma GCC optimize "unroll-loops" //#pragma GCC optimize "prefetch-loop-arrays" //#pragma GCC target "sse,sse2,sse3,sse4,abm,avx,aes,sse4a,sse4.1,sse4.2,mmx,popcnt,tune=native"
#define foru(i,a,b) for(int i=(a);i<(b);i++)
#define ford(i,a,b) for(int i=(a);i>=(b);i--)
#define fori(a,b) foru(i,a,b)
#define forj(a,b) foru(j,a,b)
#define fork(a,b) foru(k,a,b)
#define seto(x,i) memset(x,i,sizeof x)
#define pf first
#define ps second
#define pb push_back
#define eb emplace_back
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define clz __builtin_clz
#define clzll __builtin_clzll
#define ctz __builtin_ctz
#define ctzll __builtin_ctzll
#define P2(x) (1LL<<(x))
#define sz(x) (int)x.size()
#define all(x) begin(x),end(x)
#if __SIZEOF_INT128__
    typedef __int128_t i128; typedef __uint128_t ui128;
#else
    typedef long long i128; typedef unsigned long long ui128;
#endif
typedef int64_t ll;  typedef uint64_t ull; typedef int8_t byte; typedef long double lld;
typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<lld,lld> pdd;
template<typename T1,typename T2> using ordered_map=tree<T1,T2,less<T1>,rb_tree_tag,tree_order_statistics_node_update>;
template<typename T1> using ordered_set=ordered_map<T1,null_type>;
const int inf=0x3f3f3f3f,MOD=1e9+7; const ll INF=0x3f3f3f3f3f3f3f3f; const lld PI=acos((lld)-1);
ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll fpow(ll a,ll b){if(!b) return 1; ll t=fpow(a,b/2); if(b&1) return t*t%MOD*a%MOD; return t*t%MOD;}
const ll SEED=chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
mt19937 randgen(SEED); int randint(int a, int b){return uniform_int_distribution<int>(a,b)(randgen);} ll randll(ll a, ll b){return uniform_int_distribution<ll>(a,b)(randgen);}
template<class T1,class T2>constexpr const auto _min(const T1&x,const T2&y){return x<y?x:y;} template<class T,class...Ts>constexpr auto _min(const T&x,const Ts&...xs){return _min(x,_min(xs...));}
template<class T1,class T2>constexpr const auto _max(const T1&x,const T2&y){return x>y?x:y;} template<class T,class...Ts>constexpr auto _max(const T&x,const Ts&...xs){return _max(x,_max(xs...));}
#define min(...) _min(__VA_ARGS__)
#define max(...) _max(__VA_ARGS__)
struct chash{
    static ll splitmix64(ll x){x+=0x9e3779b97f4a7c15; x=(x^(x>>30))*0xbf58476d1ce4e5b9; x=(x^(x>>27))*0x94d049bb133111eb; return x^(x>>31);}
    template<class T> size_t operator()(const T &x) const{return splitmix64(hash<T>()(x)+SEED);}
    template<class T1,class T2> size_t operator()(const pair<T1,T2>&x)const{return 31*operator()(x.first)+operator()(x.second);}
};
#define nl "\n"

const int N=P2(19),M=MOD;
int n,m,q,n2,a,b,val[N],dfn[N],low[N],sz[N],par[N],top[N],dep[N];
vector<int> gr[N],gr2[N];
stack<int> scc;
bool art[N];
set<int> vals[N];
char ch;
struct SegTree{
    int seg[2*N];
    SegTree(){seto(seg,inf);}
    void pull(int x){seg[x]=min(seg[2*x],seg[2*x+1]);}
    void upd(int x,int v){
        seg[x+=N]=v;
        for(x/=2;x;x/=2) pull(x);
    }
    int query(int l,int r){
        int ret=inf;
        for(l+=N,r+=N+1;l<r;l/=2,r/=2){
            if(l&1) ret=min(ret,seg[l++]);
            if(r&1) ret=min(seg[--r],ret);
        }
        return ret;
    }
} st;
void tarjan(int v,int p=-1){
    dfn[v]=low[v]=a++; scc.push(v);
    for(auto i:gr2[v]) if(i!=p){
        if(dfn[i]) low[v]=min(low[v],dfn[i]);
        else{
            tarjan(i,v);
            if(low[i]>=dfn[v]){
                n2++; val[n2]=inf; art[v]=1;
                for(;scc.top()!=v&&low[scc.top()]>=dfn[v];scc.pop()){
                    int x=scc.top(); gr[x].pb(n2); gr[n2].pb(x);
                }
                if(low[i]==dfn[v]){
                    gr[n2].pb(v); gr[v].pb(n2);
                }
                else{
                    gr[i].pb(v); gr[v].pb(i); art[i]=1;
                }
            }
            low[v]=min(low[v],low[i]);
        }
    }
}
void szdfs(int v,int p=0){
    sz[v]=1;
    for(auto& i:gr[v]) if(i!=p){
        szdfs(i,v); sz[v]+=sz[i];
        if(gr[v][0]==p||sz[i]>sz[gr[v][0]]) swap(i,gr[v][0]);
    }
}
void hlddfs(int v,int p=0){
    dfn[v]=a++; par[v]=p;
    for(auto i:gr[v]) if(i!=p){
        top[i]=i==gr[v][0]? top[v]: i;
        hlddfs(i,v);
    }
}
int query(int u,int v){
    if(u==v) return val[u];
    int ret=inf;
    while(top[u]!=top[v]){
        if(dfn[top[u]]>dfn[top[v]]) swap(u,v);
        ret=min(ret,st.query(dfn[top[v]],dfn[v]));
        v=par[top[v]];
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    ret=min(ret,st.query(dfn[u],dfn[v]));
    if(art[par[u]]) ret=min(ret,st.query(dfn[par[u]],dfn[par[u]]));
    return ret;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("", "r", stdin); //freopen("", "w", stdout);
    cin>>n>>m>>q;
    fori(1,n+1) cin>>val[i];
    fori(0,m){
        cin>>a>>b; gr2[a].pb(b); gr2[b].pb(a);
    }
    gr2[0].pb(1); n2=n; tarjan(0); szdfs(1); a=0; top[1]=1; hlddfs(1); art[0]=0;
    fori(1,n+1) if(par[i]&&!art[par[i]])
        vals[par[i]].insert(val[i]);
    fori(1,n+1) if(art[i]) st.upd(dfn[i],val[i]);
    fori(n+1,n2+1) if(sz(vals[i])) st.upd(dfn[i],*vals[i].begin());
    while(q--){
        cin>>ch>>a>>b;
        if(ch=='A') cout<<query(a,b)<<nl;
        else if(ch=='C'){
            if(art[a]) st.upd(dfn[a],b);
            if(par[a]&&!art[par[a]]){
                vals[par[a]].erase(val[a]);
                vals[par[a]].insert(b);
                st.upd(dfn[par[a]],*vals[par[a]].begin());
            }
            val[a]=b;
        }
    }
    return 0;
}
/**

*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std; using namespace __gnu_pbds;
//#pragma GCC optimize("Ofast") //#pragma GCC optimize "unroll-loops" //#pragma GCC optimize "prefetch-loop-arrays" //#pragma GCC target "sse,sse2,sse3,sse4,abm,avx,aes,sse4a,sse4.1,sse4.2,mmx,popcnt,tune=native"
#define foru(i,a,b) for(int i=(a);i<(b);i++)
#define ford(i,a,b) for(int i=(a);i>=(b);i--)
#define fori(a,b) foru(i,a,b)
#define forj(a,b) foru(j,a,b)
#define fork(a,b) foru(k,a,b)
#define seto(x,i) memset(x,i,sizeof x)
#define pf first
#define ps second
#define pb push_back
#define eb emplace_back
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define clz __builtin_clz
#define clzll __builtin_clzll
#define ctz __builtin_ctz
#define ctzll __builtin_ctzll
#define P2(x) (1LL<<(x))
#define sz(x) (int)x.size()
#define all(x) begin(x),end(x)
#if __SIZEOF_INT128__
    typedef __int128_t i128; typedef __uint128_t ui128;
#else
    typedef long long i128; typedef unsigned long long ui128;
#endif
typedef int64_t ll;  typedef uint64_t ull; typedef int8_t byte; typedef long double lld;
typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<lld,lld> pdd;
template<typename T1,typename T2> using ordered_map=tree<T1,T2,less<T1>,rb_tree_tag,tree_order_statistics_node_update>;
template<typename T1> using ordered_set=ordered_map<T1,null_type>;
const int inf=0x3f3f3f3f,MOD=1e9+7; const ll INF=0x3f3f3f3f3f3f3f3f; const lld PI=acos((lld)-1);
ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll fpow(ll a,ll b){if(!b) return 1; ll t=fpow(a,b/2); if(b&1) return t*t%MOD*a%MOD; return t*t%MOD;}
const ll SEED=chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
mt19937 randgen(SEED); int randint(int a, int b){return uniform_int_distribution<int>(a,b)(randgen);} ll randll(ll a, ll b){return uniform_int_distribution<ll>(a,b)(randgen);}
template<class T1,class T2>constexpr const auto _min(const T1&x,const T2&y){return x<y?x:y;} template<class T,class...Ts>constexpr auto _min(const T&x,const Ts&...xs){return _min(x,_min(xs...));}
template<class T1,class T2>constexpr const auto _max(const T1&x,const T2&y){return x>y?x:y;} template<class T,class...Ts>constexpr auto _max(const T&x,const Ts&...xs){return _max(x,_max(xs...));}
#define min(...) _min(__VA_ARGS__)
#define max(...) _max(__VA_ARGS__)
struct chash{
    static ll splitmix64(ll x){x+=0x9e3779b97f4a7c15; x=(x^(x>>30))*0xbf58476d1ce4e5b9; x=(x^(x>>27))*0x94d049bb133111eb; return x^(x>>31);}
    template<class T> size_t operator()(const T &x) const{return splitmix64(hash<T>()(x)+SEED);}
    template<class T1,class T2> size_t operator()(const pair<T1,T2>&x)const{return 31*operator()(x.first)+operator()(x.second);}
};
#define nl "\n"

const int N=P2(18),M=MOD;
int n,m,q,n2,a,b,val[N],dfn[N],low[N],sz[N],par[N],top[N],dep[N];
vector<int> gr[N],gr2[N];
stack<int> scc;
bitset<N> art;
char ch;
struct SegTree{
    int seg[2*N];
    SegTree(){seto(seg,inf);}
    void pull(int x){seg[x]=min(seg[2*x],seg[2*x+1]);}
    void upd(int x,int v){
        seg[x+=N]=v;
        for(x/=2;x;x/=2) pull(x);
    }
    int query(int l,int r){
        int ret=inf;
        for(l+=N,r+=N+1;l<r;l/=2,r/=2){
            if(l&1) ret=min(ret,seg[l++]);
            if(r&1) ret=min(seg[--r],ret);
        }
        return ret;
    }
} st;
void tarjan(int v,int p=-1){
    dfn[v]=low[v]=a++; scc.push(v);
    for(auto i:gr2[v]) if(i!=p){
        if(dfn[i]) low[v]=min(low[v],dfn[i]);
        else{
            tarjan(i,v);
            if(low[i]>=dfn[v]){
                n2++; val[n2]=inf; art[v]=1;
                for(;scc.top()!=v&&low[scc.top()]>=dfn[v];scc.pop()){
                    int x=scc.top(); gr[x].pb(n2); gr[n2].pb(x); val[n2]=min(val[n2],val[x]);
                }
                if(low[i]==dfn[v]){
                    gr[n2].pb(v); gr[v].pb(n2);
                }
                else{
                    gr[i].pb(v); gr[v].pb(i); art[i]=1;
                }
            }
            low[v]=min(low[v],low[i]);
        }
    }
}
void szdfs(int v,int p=-1){
    sz[v]=1;
    for(auto& i:gr[v]) if(i!=p){
        szdfs(i,v); sz[v]+=sz[i];
        if(gr[v][0]==p||sz[i]>sz[gr[v][0]]) swap(i,gr[v][0]);
    }
}
void hlddfs(int v,int p=0){
    dfn[v]=a++; par[v]=p; st.upd(dfn[v],val[v]);
    for(auto i:gr[v]) if(i!=p){
        top[i]=i==gr[v][0]? top[v]: i;
        hlddfs(i,v);
    }
}
int query(int u,int v){
    int ret=inf;
    while(top[u]!=top[v]){
        if(dfn[top[u]]>dfn[top[v]]) swap(u,v);
        ret=min(ret,st.query(dfn[top[v]],dfn[v]));
        v=par[top[v]];
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    ret=min(ret,st.query(dfn[u],dfn[v]));
    if(art[par[u]]) ret=min(ret,st.query(dfn[par[u]],dfn[par[u]]));
    return ret;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("", "r", stdin); //freopen("", "w", stdout);
    cin>>n>>m>>q;
    fori(1,n+1) cin>>val[i];
    fori(0,m){
        cin>>a>>b; gr2[a].pb(b); gr2[b].pb(a);
    }
    gr2[0].pb(1); n2=n; tarjan(0); szdfs(1); a=0; top[1]=1; hlddfs(1); art[0]=0;
    while(q--){
        cin>>ch>>a>>b;
        if(ch=='A') cout<<query(a,b)<<nl;
        else if(ch=='C'){
            if(art[a]) st.upd(dfn[a],b);
            if(!art[par[a]]) st.upd(dfn[par[a]],b);
        }
    }
    return 0;
}
/**

*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std; using namespace __gnu_pbds;
//#pragma GCC optimize("Ofast") //#pragma GCC optimize "unroll-loops" //#pragma GCC optimize "prefetch-loop-arrays" //#pragma GCC target "sse,sse2,sse3,sse4,abm,avx,aes,sse4a,sse4.1,sse4.2,mmx,popcnt,tune=native"
#define foru(i,a,b) for(int i=(a);i<(b);i++)
#define ford(i,a,b) for(int i=(a);i>=(b);i--)
#define fori(a,b) foru(i,a,b)
#define forj(a,b) foru(j,a,b)
#define fork(a,b) foru(k,a,b)
#define seto(x,i) memset(x,i,sizeof x)
#define pf first
#define ps second
#define pb push_back
#define eb emplace_back
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define clz __builtin_clz
#define clzll __builtin_clzll
#define ctz __builtin_ctz
#define ctzll __builtin_ctzll
#define P2(x) (1LL<<(x))
#define sz(x) (int)x.size()
#define all(x) begin(x),end(x)
#if __SIZEOF_INT128__
    typedef __int128_t i128; typedef __uint128_t ui128;
#else
    typedef long long i128; typedef unsigned long long ui128;
#endif
typedef int64_t ll;  typedef uint64_t ull; typedef int8_t byte; typedef long double lld;
typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<lld,lld> pdd;
template<typename T1,typename T2> using ordered_map=tree<T1,T2,less<T1>,rb_tree_tag,tree_order_statistics_node_update>;
template<typename T1> using ordered_set=ordered_map<T1,null_type>;
const int inf=0x3f3f3f3f,MOD=1e9+7; const ll INF=0x3f3f3f3f3f3f3f3f; const lld PI=acos((lld)-1);
ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll fpow(ll a,ll b){if(!b) return 1; ll t=fpow(a,b/2); if(b&1) return t*t%MOD*a%MOD; return t*t%MOD;}
const ll SEED=chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
mt19937 randgen(SEED); int randint(int a, int b){return uniform_int_distribution<int>(a,b)(randgen);} ll randll(ll a, ll b){return uniform_int_distribution<ll>(a,b)(randgen);}
template<class T1,class T2>constexpr const auto _min(const T1&x,const T2&y){return x<y?x:y;} template<class T,class...Ts>constexpr auto _min(const T&x,const Ts&...xs){return _min(x,_min(xs...));}
template<class T1,class T2>constexpr const auto _max(const T1&x,const T2&y){return x>y?x:y;} template<class T,class...Ts>constexpr auto _max(const T&x,const Ts&...xs){return _max(x,_max(xs...));}
#define min(...) _min(__VA_ARGS__)
#define max(...) _max(__VA_ARGS__)
struct chash{
    static ll splitmix64(ll x){x+=0x9e3779b97f4a7c15; x=(x^(x>>30))*0xbf58476d1ce4e5b9; x=(x^(x>>27))*0x94d049bb133111eb; return x^(x>>31);}
    template<class T> size_t operator()(const T &x) const{return splitmix64(hash<T>()(x)+SEED);}
    template<class T1,class T2> size_t operator()(const pair<T1,T2>&x)const{return 31*operator()(x.first)+operator()(x.second);}
};
#define nl "\n"

const int N=P2(18),M=MOD;
int n,m,q,n2,a,b,val[N],dfn[N],low[N],sz[N],par[N],top[N],dep[N];
vector<int> gr[N],gr2[N];
stack<int> scc;
bitset<N> art;
set<int> vals[N];
char ch;
struct SegTree{
    int seg[2*N];
    SegTree(){seto(seg,inf);}
    void pull(int x){seg[x]=min(seg[2*x],seg[2*x+1]);}
    void upd(int x,int v){
        seg[x+=N]=v;
        for(x/=2;x;x/=2) pull(x);
    }
    int query(int l,int r){
        int ret=inf;
        for(l+=N,r+=N+1;l<r;l/=2,r/=2){
            if(l&1) ret=min(ret,seg[l++]);
            if(r&1) ret=min(seg[--r],ret);
        }
        return ret;
    }
} st;
void tarjan(int v,int p=-1){
    dfn[v]=low[v]=a++; scc.push(v);
    for(auto i:gr2[v]) if(i!=p){
        if(dfn[i]) low[v]=min(low[v],dfn[i]);
        else{
            tarjan(i,v);
            if(low[i]>=dfn[v]){
                n2++; val[n2]=inf; art[v]=1;
                for(;scc.top()!=v&&low[scc.top()]>=dfn[v];scc.pop()){
                    int x=scc.top(); gr[x].pb(n2); gr[n2].pb(x);
                }
                if(low[i]==dfn[v]){
                    gr[n2].pb(v); gr[v].pb(n2);
                }
                else{
                    gr[i].pb(v); gr[v].pb(i); art[i]=1;
                }
            }
            low[v]=min(low[v],low[i]);
        }
    }
}
void szdfs(int v,int p=0){
    sz[v]=1;
    for(auto& i:gr[v]) if(i!=p){
        szdfs(i,v); sz[v]+=sz[i];
        if(gr[v][0]==p||sz[i]>sz[gr[v][0]]) swap(i,gr[v][0]);
    }
}
void hlddfs(int v,int p=0){
    dfn[v]=a++; par[v]=p;
    for(auto i:gr[v]) if(i!=p){
        top[i]=i==gr[v][0]? top[v]: i;
        hlddfs(i,v);
    }
}
int query(int u,int v){
    if(u==v) return val[u];
    int ret=inf;
    while(top[u]!=top[v]){
        if(dfn[top[u]]>dfn[top[v]]) swap(u,v);
        ret=min(ret,st.query(dfn[top[v]],dfn[v]));
        v=par[top[v]];
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    ret=min(ret,st.query(dfn[u],dfn[v]));
    if(art[par[u]]) ret=min(ret,st.query(dfn[par[u]],dfn[par[u]]));
    return ret;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("", "r", stdin); //freopen("", "w", stdout);
    cin>>n>>m>>q;
    fori(1,n+1) cin>>val[i];
    fori(0,m){
        cin>>a>>b; gr2[a].pb(b); gr2[b].pb(a);
    }
    gr2[0].pb(1); n2=n; tarjan(0); szdfs(1); a=0; top[1]=1; hlddfs(1); art[0]=0;
    fori(1,n+1) if(par[a]&&!art[par[a]]) vals[par[a]].insert(val[i]);
    fori(1,n+1) if(art[i]) st.upd(dfn[i],val[i]);
    fori(n+1,n2+1) if(sz(vals[i])) st.upd(dfn[i],*val[i].begin());
    while(q--){
        cin>>ch>>a>>b;
        if(ch=='A') cout<<query(a,b)<<nl;
        else if(ch=='C'){
            if(art[a]) st.upd(dfn[a],b);
            if(par[a]&&!art[par[a]]){
                vals[par[a]].erase(val[a]);
                vals[par[a]].insert(b);
                st.upd(dfn[par[a]],*vals[par[a]].begin());
            }
            val[a]=b;
        }
    }
    return 0;
}
/**

*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std; using namespace __gnu_pbds;
//#pragma GCC optimize("Ofast") //#pragma GCC optimize "unroll-loops" //#pragma GCC optimize "prefetch-loop-arrays" //#pragma GCC target "sse,sse2,sse3,sse4,abm,avx,aes,sse4a,sse4.1,sse4.2,mmx,popcnt,tune=native"
#define foru(i,a,b) for(int i=(a);i<(b);i++)
#define ford(i,a,b) for(int i=(a);i>=(b);i--)
#define fori(a,b) foru(i,a,b)
#define forj(a,b) foru(j,a,b)
#define fork(a,b) foru(k,a,b)
#define seto(x,i) memset(x,i,sizeof x)
#define pf first
#define ps second
#define pb push_back
#define eb emplace_back
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define clz __builtin_clz
#define clzll __builtin_clzll
#define ctz __builtin_ctz
#define ctzll __builtin_ctzll
#define P2(x) (1LL<<(x))
#define sz(x) (int)x.size()
#define all(x) begin(x),end(x)
#if __SIZEOF_INT128__
    typedef __int128_t i128; typedef __uint128_t ui128;
#else
    typedef long long i128; typedef unsigned long long ui128;
#endif
typedef int64_t ll;  typedef uint64_t ull; typedef int8_t byte; typedef long double lld;
typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<lld,lld> pdd;
template<typename T1,typename T2> using ordered_map=tree<T1,T2,less<T1>,rb_tree_tag,tree_order_statistics_node_update>;
template<typename T1> using ordered_set=ordered_map<T1,null_type>;
const int inf=0x3f3f3f3f,MOD=1e9+7; const ll INF=0x3f3f3f3f3f3f3f3f; const lld PI=acos((lld)-1);
ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll fpow(ll a,ll b){if(!b) return 1; ll t=fpow(a,b/2); if(b&1) return t*t%MOD*a%MOD; return t*t%MOD;}
const ll SEED=chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
mt19937 randgen(SEED); int randint(int a, int b){return uniform_int_distribution<int>(a,b)(randgen);} ll randll(ll a, ll b){return uniform_int_distribution<ll>(a,b)(randgen);}
template<class T1,class T2>constexpr const auto _min(const T1&x,const T2&y){return x<y?x:y;} template<class T,class...Ts>constexpr auto _min(const T&x,const Ts&...xs){return _min(x,_min(xs...));}
template<class T1,class T2>constexpr const auto _max(const T1&x,const T2&y){return x>y?x:y;} template<class T,class...Ts>constexpr auto _max(const T&x,const Ts&...xs){return _max(x,_max(xs...));}
#define min(...) _min(__VA_ARGS__)
#define max(...) _max(__VA_ARGS__)
struct chash{
    static ll splitmix64(ll x){x+=0x9e3779b97f4a7c15; x=(x^(x>>30))*0xbf58476d1ce4e5b9; x=(x^(x>>27))*0x94d049bb133111eb; return x^(x>>31);}
    template<class T> size_t operator()(const T &x) const{return splitmix64(hash<T>()(x)+SEED);}
    template<class T1,class T2> size_t operator()(const pair<T1,T2>&x)const{return 31*operator()(x.first)+operator()(x.second);}
};
#define nl "\n"

const int N=P2(18),M=MOD;
int n,m,q,n2,a,b,val[N],dfn[N],low[N],sz[N],par[N],top[N],dep[N];
vector<int> gr[N],gr2[N];
stack<int> scc;
bool art[N];
set<int> vals[N];
char ch;
struct SegTree{
    int seg[2*N];
    SegTree(){seto(seg,inf);}
    void pull(int x){seg[x]=min(seg[2*x],seg[2*x+1]);}
    void upd(int x,int v){
        seg[x+=N]=v;
        for(x/=2;x;x/=2) pull(x);
    }
    int query(int l,int r){
        int ret=inf;
        for(l+=N,r+=N+1;l<r;l/=2,r/=2){
            if(l&1) ret=min(ret,seg[l++]);
            if(r&1) ret=min(seg[--r],ret);
        }
        return ret;
    }
} st;
void tarjan(int v,int p=-1){
    dfn[v]=low[v]=a++; scc.push(v);
    for(auto i:gr2[v]) if(i!=p){
        if(dfn[i]) low[v]=min(low[v],dfn[i]);
        else{
            tarjan(i,v);
            if(low[i]>=dfn[v]){
                n2++; val[n2]=inf; art[v]=1;
                for(;scc.top()!=v&&low[scc.top()]>=dfn[v];scc.pop()){
                    int x=scc.top(); gr[x].pb(n2); gr[n2].pb(x);
                }
                if(low[i]==dfn[v]){
                    gr[n2].pb(v); gr[v].pb(n2);
                }
                else{
                    gr[i].pb(v); gr[v].pb(i); art[i]=1;
                }
            }
            low[v]=min(low[v],low[i]);
        }
    }
}
void szdfs(int v,int p=0){
    sz[v]=1;
    for(auto& i:gr[v]) if(i!=p){
        szdfs(i,v); sz[v]+=sz[i];
        if(gr[v][0]==p||sz[i]>sz[gr[v][0]]) swap(i,gr[v][0]);
    }
}
void hlddfs(int v,int p=0){
    dfn[v]=a++; par[v]=p;
    for(auto i:gr[v]) if(i!=p){
        top[i]=i==gr[v][0]? top[v]: i;
        hlddfs(i,v);
    }
}
int query(int u,int v){
    if(u==v) return val[u];
    int ret=inf;
    while(top[u]!=top[v]){
        if(dfn[top[u]]>dfn[top[v]]) swap(u,v);
        ret=min(ret,st.query(dfn[top[v]],dfn[v]));
        v=par[top[v]];
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    ret=min(ret,st.query(dfn[u],dfn[v]));
    if(art[par[u]]) ret=min(ret,st.query(dfn[par[u]],dfn[par[u]]));
    return ret;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("", "r", stdin); //freopen("", "w", stdout);
    cin>>n>>m>>q;
    fori(1,n+1) cin>>val[i];
    fori(0,m){
        cin>>a>>b; gr2[a].pb(b); gr2[b].pb(a);
    }
    gr2[0].pb(1); n2=n; tarjan(0); szdfs(1); a=0; top[1]=1; hlddfs(1); art[0]=0;
    fori(1,n+1) if(par[i]&&!art[par[i]])
        vals[par[i]].insert(val[i]);
    fori(1,n+1) if(art[i]) st.upd(dfn[i],val[i]);
    fori(n+1,n2+1) if(sz(vals[i])) st.upd(dfn[i],*vals[i].begin());
    while(q--){
        cin>>ch>>a>>b;
        if(ch=='A') cout<<query(a,b)<<nl;
        else if(ch=='C'){
            if(art[a]) st.upd(dfn[a],b);
            if(par[a]&&!art[par[a]]){
                vals[par[a]].erase(val[a]);
                vals[par[a]].insert(b);
                st.upd(dfn[par[a]],*vals[par[a]].begin());
            }
            val[a]=b;
        }
    }
    return 0;
}
/**

*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std; using namespace __gnu_pbds;
//#pragma GCC optimize("Ofast") //#pragma GCC optimize "unroll-loops" //#pragma GCC optimize "prefetch-loop-arrays" //#pragma GCC target "sse,sse2,sse3,sse4,abm,avx,aes,sse4a,sse4.1,sse4.2,mmx,popcnt,tune=native"
#define foru(i,a,b) for(int i=(a);i<(b);i++)
#define ford(i,a,b) for(int i=(a);i>=(b);i--)
#define fori(a,b) foru(i,a,b)
#define forj(a,b) foru(j,a,b)
#define fork(a,b) foru(k,a,b)
#define seto(x,i) memset(x,i,sizeof x)
#define pf first
#define ps second
#define pb push_back
#define eb emplace_back
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define clz __builtin_clz
#define clzll __builtin_clzll
#define ctz __builtin_ctz
#define ctzll __builtin_ctzll
#define P2(x) (1LL<<(x))
#define sz(x) (int)x.size()
#define all(x) begin(x),end(x)
#if __SIZEOF_INT128__
    typedef __int128_t i128; typedef __uint128_t ui128;
#else
    typedef long long i128; typedef unsigned long long ui128;
#endif
typedef int64_t ll;  typedef uint64_t ull; typedef int8_t byte; typedef long double lld;
typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<lld,lld> pdd;
template<typename T1,typename T2> using ordered_map=tree<T1,T2,less<T1>,rb_tree_tag,tree_order_statistics_node_update>;
template<typename T1> using ordered_set=ordered_map<T1,null_type>;
const int inf=0x3f3f3f3f,MOD=1e9+7; const ll INF=0x3f3f3f3f3f3f3f3f; const lld PI=acos((lld)-1);
ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll fpow(ll a,ll b){if(!b) return 1; ll t=fpow(a,b/2); if(b&1) return t*t%MOD*a%MOD; return t*t%MOD;}
const ll SEED=chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
mt19937 randgen(SEED); int randint(int a, int b){return uniform_int_distribution<int>(a,b)(randgen);} ll randll(ll a, ll b){return uniform_int_distribution<ll>(a,b)(randgen);}
template<class T1,class T2>constexpr const auto _min(const T1&x,const T2&y){return x<y?x:y;} template<class T,class...Ts>constexpr auto _min(const T&x,const Ts&...xs){return _min(x,_min(xs...));}
template<class T1,class T2>constexpr const auto _max(const T1&x,const T2&y){return x>y?x:y;} template<class T,class...Ts>constexpr auto _max(const T&x,const Ts&...xs){return _max(x,_max(xs...));}
#define min(...) _min(__VA_ARGS__)
#define max(...) _max(__VA_ARGS__)
struct chash{
    static ll splitmix64(ll x){x+=0x9e3779b97f4a7c15; x=(x^(x>>30))*0xbf58476d1ce4e5b9; x=(x^(x>>27))*0x94d049bb133111eb; return x^(x>>31);}
    template<class T> size_t operator()(const T &x) const{return splitmix64(hash<T>()(x)+SEED);}
    template<class T1,class T2> size_t operator()(const pair<T1,T2>&x)const{return 31*operator()(x.first)+operator()(x.second);}
};
#define nl "\n"

const int N=P2(18),M=MOD;
int n,m,q,n2,a,b,val[N],dfn[N],low[N],sz[N],par[N],top[N],dep[N];
vector<int> gr[N],gr2[N];
stack<int> scc;
bitset<N> art;
char ch;
struct SegTree{
    int seg[2*N];
    SegTree(){seto(seg,inf);}
    void pull(int x){seg[x]=min(seg[2*x],seg[2*x+1]);}
    void upd(int x,int v){
        seg[x+=N]=v;
        for(x/=2;x;x/=2) pull(x);
    }
    int query(int l,int r){
        int ret=inf;
        for(l+=N,r+=N+1;l<r;l/=2,r/=2){
            if(l&1) ret=min(ret,seg[l++]);
            if(r&1) ret=min(seg[--r],ret);
        }
        return ret;
    }
} st;
void tarjan(int v,int p=-1){
    dfn[v]=low[v]=a++; scc.push(v);
    for(auto i:gr2[v]) if(i!=p){
        if(dfn[i]) low[v]=min(low[v],dfn[i]);
        else{
            tarjan(i,v);
            if(low[i]>=dfn[v]){
                n2++; val[n2]=inf; art[v]=1;
                for(;scc.top()!=v&&low[scc.top()]>=dfn[v];scc.pop()){
                    int x=scc.top(); gr[x].pb(n2); gr[n2].pb(x); val[n2]=min(val[n2],val[x]);
                }
                if(low[i]==dfn[v]){
                    gr[n2].pb(v); gr[v].pb(n2);
                }
                else{
                    gr[i].pb(v); gr[v].pb(i); art[i]=1;
                }
            }
            low[v]=min(low[v],low[i]);
        }
    }
}
void szdfs(int v,int p=-1){
    sz[v]=1;
    for(auto& i:gr[v]) if(i!=p){
        szdfs(i,v); sz[v]+=sz[i];
        if(gr[v][0]==p||sz[i]>sz[gr[v][0]]) swap(i,gr[v][0]);
    }
}
void hlddfs(int v,int p=0){
    dfn[v]=++a; par[v]=p; st.upd(dfn[v],val[v]);
    for(auto i:gr[v]) if(i!=p){
        top[i]=i==gr[v][0]? top[v]: i;
        hlddfs(i,v);
    }
}
int query(int u,int v){
    int ret=inf;
    while(top[u]!=top[v]){
        if(dfn[top[u]]>dfn[top[v]]) swap(u,v);
        ret=min(ret,st.query(dfn[top[v]],dfn[v]));
        v=par[top[v]];
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    ret=min(ret,st.query(dfn[u],dfn[v]));
    if(art[par[u]]) ret=min(ret,st.query(dfn[par[u]],dfn[par[u]]));
    return ret;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("", "r", stdin); //freopen("", "w", stdout);
    cin>>n>>m>>q;
    fori(1,n+1) cin>>val[i];
    fori(0,m){
        cin>>a>>b; gr2[a].pb(b); gr2[b].pb(a);
    }
    gr2[0].pb(1); n2=n; tarjan(0); szdfs(1); a=0; top[1]=1; hlddfs(1);
    while(q--){
        cin>>ch>>a>>b;
        if(ch=='A') cout<<query(a,b)<<nl;
        else if(ch=='C'){
            if(art[a]) st.upd(dfn[a],b);
            if(!art[par[a]]) st.upd(dfn[par[a]],b);
        }
    }
    return 0;
}
/**

*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std; using namespace __gnu_pbds;
//#pragma GCC optimize("Ofast") //#pragma GCC optimize "unroll-loops" //#pragma GCC optimize "prefetch-loop-arrays" //#pragma GCC target "sse,sse2,sse3,sse4,abm,avx,aes,sse4a,sse4.1,sse4.2,mmx,popcnt,tune=native"
#define foru(i,a,b) for(int i=(a);i<(b);i++)
#define ford(i,a,b) for(int i=(a);i>=(b);i--)
#define fori(a,b) foru(i,a,b)
#define forj(a,b) foru(j,a,b)
#define fork(a,b) foru(k,a,b)
#define seto(x,i) memset(x,i,sizeof x)
#define pf first
#define ps second
#define pb push_back
#define eb emplace_back
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define clz __builtin_clz
#define clzll __builtin_clzll
#define ctz __builtin_ctz
#define ctzll __builtin_ctzll
#define P2(x) (1LL<<(x))
#define sz(x) (int)x.size()
#define all(x) begin(x),end(x)
#if __SIZEOF_INT128__
    typedef __int128_t i128; typedef __uint128_t ui128;
#else
    typedef long long i128; typedef unsigned long long ui128;
#endif
typedef int64_t ll;  typedef uint64_t ull; typedef int8_t byte; typedef long double lld;
typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<lld,lld> pdd;
template<typename T1,typename T2> using ordered_map=tree<T1,T2,less<T1>,rb_tree_tag,tree_order_statistics_node_update>;
template<typename T1> using ordered_set=ordered_map<T1,null_type>;
const int inf=0x3f3f3f3f,MOD=1e9+7; const ll INF=0x3f3f3f3f3f3f3f3f; const lld PI=acos((lld)-1);
ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll fpow(ll a,ll b){if(!b) return 1; ll t=fpow(a,b/2); if(b&1) return t*t%MOD*a%MOD; return t*t%MOD;}
const ll SEED=chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
mt19937 randgen(SEED); int randint(int a, int b){return uniform_int_distribution<int>(a,b)(randgen);} ll randll(ll a, ll b){return uniform_int_distribution<ll>(a,b)(randgen);}
template<class T1,class T2>constexpr const auto _min(const T1&x,const T2&y){return x<y?x:y;} template<class T,class...Ts>constexpr auto _min(const T&x,const Ts&...xs){return _min(x,_min(xs...));}
template<class T1,class T2>constexpr const auto _max(const T1&x,const T2&y){return x>y?x:y;} template<class T,class...Ts>constexpr auto _max(const T&x,const Ts&...xs){return _max(x,_max(xs...));}
#define min(...) _min(__VA_ARGS__)
#define max(...) _max(__VA_ARGS__)
struct chash{
    static ll splitmix64(ll x){x+=0x9e3779b97f4a7c15; x=(x^(x>>30))*0xbf58476d1ce4e5b9; x=(x^(x>>27))*0x94d049bb133111eb; return x^(x>>31);}
    template<class T> size_t operator()(const T &x) const{return splitmix64(hash<T>()(x)+SEED);}
    template<class T1,class T2> size_t operator()(const pair<T1,T2>&x)const{return 31*operator()(x.first)+operator()(x.second);}
};
#define nl "\n"

const int N=P2(18),M=MOD;
int n,m,q,n2,a,b,val[N],dfn[N],low[N],sz[N],par[N],top[N],dep[N];
vector<int> gr[N],gr2[N];
stack<int> scc;
bitset<N> art;
set<int> vals[N];
char ch;
struct SegTree{
    int seg[2*N];
    SegTree(){seto(seg,inf);}
    void pull(int x){seg[x]=min(seg[2*x],seg[2*x+1]);}
    void upd(int x,int v){
        seg[x+=N]=v;
        for(x/=2;x;x/=2) pull(x);
    }
    int query(int l,int r){
        int ret=inf;
        for(l+=N,r+=N+1;l<r;l/=2,r/=2){
            if(l&1) ret=min(ret,seg[l++]);
            if(r&1) ret=min(seg[--r],ret);
        }
        return ret;
    }
} st;
void tarjan(int v,int p=-1){
    dfn[v]=low[v]=a++; scc.push(v); vals[v].insert(val[v]);
    for(auto i:gr2[v]) if(i!=p){
        if(dfn[i]) low[v]=min(low[v],dfn[i]);
        else{
            tarjan(i,v);
            if(low[i]>=dfn[v]){
                n2++; val[n2]=inf; art[v]=1;
                for(;scc.top()!=v&&low[scc.top()]>=dfn[v];scc.pop()){
                    int x=scc.top(); gr[x].pb(n2); gr[n2].pb(x); vals[n2].insert(val[x]);
                }
                if(low[i]==dfn[v]){
                    gr[n2].pb(v); gr[v].pb(n2);
                }
                else{
                    gr[i].pb(v); gr[v].pb(i); art[i]=1;
                }
            }
            low[v]=min(low[v],low[i]);
        }
    }
}
void szdfs(int v,int p=0){
    sz[v]=1;
    for(auto& i:gr[v]) if(i!=p){
        szdfs(i,v); sz[v]+=sz[i];
        if(gr[v][0]==p||sz[i]>sz[gr[v][0]]) swap(i,gr[v][0]);
    }
}
void hlddfs(int v,int p=0){
    dfn[v]=a++; par[v]=p;
    if(v>n||art[v]) st.upd(dfn[v],*vals[v].begin());
    for(auto i:gr[v]) if(i!=p){
        top[i]=i==gr[v][0]? top[v]: i;
        hlddfs(i,v);
    }
}
int query(int u,int v){
    if(u==v) return val[u];
    int ret=inf;
    while(top[u]!=top[v]){
        if(dfn[top[u]]>dfn[top[v]]) swap(u,v);
        ret=min(ret,st.query(dfn[top[v]],dfn[v]));
        v=par[top[v]];
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    ret=min(ret,st.query(dfn[u],dfn[v]));
    if(art[par[u]]) ret=min(ret,st.query(dfn[par[u]],dfn[par[u]]));
    return ret;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("", "r", stdin); //freopen("", "w", stdout);
    cin>>n>>m>>q;
    fori(1,n+1) cin>>val[i];
    fori(0,m){
        cin>>a>>b; gr2[a].pb(b); gr2[b].pb(a);
    }
    gr2[0].pb(1); n2=n; tarjan(0); szdfs(1); a=0; top[1]=1; hlddfs(1); art[0]=0;
    while(q--){
        cin>>ch>>a>>b;
        if(ch=='A') cout<<query(a,b)<<nl;
        else if(ch=='C'){
            if(art[a]) st.upd(dfn[a],b);
            if(par[a]&&!art[par[a]]){
                vals[par[a]].erase(val[a]);
                vals[par[a]].insert(b);
                st.upd(dfn[par[a]],*vals[par[a]].begin());
            }
            val[a]=b;
        }
    }
    return 0;
}
/**

*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std; using namespace __gnu_pbds;
//#pragma GCC optimize("Ofast") //#pragma GCC optimize "unroll-loops" //#pragma GCC optimize "prefetch-loop-arrays" //#pragma GCC target "sse,sse2,sse3,sse4,abm,avx,aes,sse4a,sse4.1,sse4.2,mmx,popcnt,tune=native"
#define foru(i,a,b) for(int i=(a);i<(b);i++)
#define ford(i,a,b) for(int i=(a);i>=(b);i--)
#define fori(a,b) foru(i,a,b)
#define forj(a,b) foru(j,a,b)
#define fork(a,b) foru(k,a,b)
#define seto(x,i) memset(x,i,sizeof x)
#define pf first
#define ps second
#define pb push_back
#define eb emplace_back
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define clz __builtin_clz
#define clzll __builtin_clzll
#define ctz __builtin_ctz
#define ctzll __builtin_ctzll
#define P2(x) (1LL<<(x))
#define sz(x) (int)x.size()
#define all(x) begin(x),end(x)
#if __SIZEOF_INT128__
    typedef __int128_t i128; typedef __uint128_t ui128;
#else
    typedef long long i128; typedef unsigned long long ui128;
#endif
typedef int64_t ll;  typedef uint64_t ull; typedef int8_t byte; typedef long double lld;
typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<lld,lld> pdd;
template<typename T1,typename T2> using ordered_map=tree<T1,T2,less<T1>,rb_tree_tag,tree_order_statistics_node_update>;
template<typename T1> using ordered_set=ordered_map<T1,null_type>;
const int inf=0x3f3f3f3f,MOD=1e9+7; const ll INF=0x3f3f3f3f3f3f3f3f; const lld PI=acos((lld)-1);
ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll fpow(ll a,ll b){if(!b) return 1; ll t=fpow(a,b/2); if(b&1) return t*t%MOD*a%MOD; return t*t%MOD;}
const ll SEED=chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
mt19937 randgen(SEED); int randint(int a, int b){return uniform_int_distribution<int>(a,b)(randgen);} ll randll(ll a, ll b){return uniform_int_distribution<ll>(a,b)(randgen);}
template<class T1,class T2>constexpr const auto _min(const T1&x,const T2&y){return x<y?x:y;} template<class T,class...Ts>constexpr auto _min(const T&x,const Ts&...xs){return _min(x,_min(xs...));}
template<class T1,class T2>constexpr const auto _max(const T1&x,const T2&y){return x>y?x:y;} template<class T,class...Ts>constexpr auto _max(const T&x,const Ts&...xs){return _max(x,_max(xs...));}
#define min(...) _min(__VA_ARGS__)
#define max(...) _max(__VA_ARGS__)
struct chash{
    static ll splitmix64(ll x){x+=0x9e3779b97f4a7c15; x=(x^(x>>30))*0xbf58476d1ce4e5b9; x=(x^(x>>27))*0x94d049bb133111eb; return x^(x>>31);}
    template<class T> size_t operator()(const T &x) const{return splitmix64(hash<T>()(x)+SEED);}
    template<class T1,class T2> size_t operator()(const pair<T1,T2>&x)const{return 31*operator()(x.first)+operator()(x.second);}
};
#define nl "\n"

const int N=P2(18),M=MOD;
int n,m,q,n2,a,b,val[N],dfn[N],low[N],sz[N],par[N],top[N],dep[N];
vector<int> gr[N],gr2[N];
stack<int> scc;
bitset<N> art;
char ch;
struct SegTree{
    int seg[2*N];
    SegTree(){seto(seg,inf);}
    void pull(int x){seg[x]=min(seg[2*x],seg[2*x+1]);}
    void upd(int x,int v){
        seg[x+=N]=v;
        for(x/=2;x;x/=2) pull(x);
    }
    int query(int l,int r){
        int ret=inf;
        for(l+=N,r+=N+1;l<r;l/=2,r/=2){
            if(l&1) ret=min(ret,seg[l++]);
            if(r&1) ret=min(seg[--r],ret);
        }
        return ret;
    }
} st;
void tarjan(int v,int p=-1){
    dfn[v]=low[v]=a++; scc.push(v);
    for(auto i:gr2[v]) if(i!=p){
        if(dfn[i]) low[v]=min(low[v],dfn[i]);
        else{
            tarjan(i,v);
            if(low[i]>=dfn[v]){
                n2++; val[n2]=inf; art[v]=1;
                for(;scc.top()!=v&&low[scc.top()]>=dfn[v];scc.pop()){
                    int x=scc.top(); gr[x].pb(n2); gr[n2].pb(x); val[n2]=min(val[n2],val[x]);
                }
                if(low[i]==dfn[v]){
                    gr[n2].pb(v); gr[v].pb(n2);
                }
                else{
                    gr[i].pb(v); gr[v].pb(i);
                }
            }
            low[v]=min(low[v],low[i]);
        }
    }
}
void szdfs(int v,int p=-1){
    sz[v]=1;
    for(auto& i:gr[v]) if(i!=p){
        szdfs(i,v); sz[v]+=sz[i];
        if(gr[v][0]==p||sz[i]>sz[gr[v][0]]) swap(i,gr[v][0]);
    }
}
void hlddfs(int v,int p=0){
    dfn[v]=++a; par[v]=p; st.upd(dfn[v],val[v]);
    for(auto i:gr[v]) if(i!=p){
        top[i]=i==gr[v][0]? top[v]: i;
        hlddfs(i,v);
    }
}
int query(int u,int v){
    int ret=inf;
    while(top[u]!=top[v]){
        if(dfn[top[u]]>dfn[top[v]]) swap(u,v);
        ret=min(ret,st.query(dfn[top[v]],dfn[v]));
        v=par[top[v]];
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    ret=min(ret,st.query(dfn[u],dfn[v]));
    if(art[par[u]]) ret=min(ret,st.query(dfn[par[u]],dfn[par[u]]));
    return ret;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("", "r", stdin); //freopen("", "w", stdout);
    cin>>n>>m>>q;
    fori(1,n+1) cin>>val[i];
    fori(0,m){
        cin>>a>>b; gr2[a].pb(b); gr2[b].pb(a);
    }
    gr2[0].pb(1); n2=n; tarjan(0); szdfs(1); a=0; top[1]=1; hlddfs(1);
    while(q--){
        cin>>ch>>a>>b;
        if(ch=='A') cout<<query(a,b)<<nl;
        else if(ch=='C'){
            if(art[a]) st.upd(dfn[a],b);
            st.upd(dfn[par[a]],b);
        }
    }
    return 0;
}
/**

*/


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std; using namespace __gnu_pbds;
//#pragma GCC optimize("Ofast") //#pragma GCC optimize "unroll-loops" //#pragma GCC optimize "prefetch-loop-arrays" //#pragma GCC target "sse,sse2,sse3,sse4,abm,avx,aes,sse4a,sse4.1,sse4.2,mmx,popcnt,tune=native"
#define foru(i,a,b) for(int i=(a);i<(b);i++)
#define ford(i,a,b) for(int i=(a);i>=(b);i--)
#define fori(a,b) foru(i,a,b)
#define forj(a,b) foru(j,a,b)
#define fork(a,b) foru(k,a,b)
#define seto(x,i) memset(x,i,sizeof x)
#define pf first
#define ps second
#define pb push_back
#define eb emplace_back
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define clz __builtin_clz
#define clzll __builtin_clzll
#define ctz __builtin_ctz
#define ctzll __builtin_ctzll
#define P2(x) (1LL<<(x))
#define sz(x) (int)x.size()
#define all(x) begin(x),end(x)
#if __SIZEOF_INT128__
    typedef __int128_t i128; typedef __uint128_t ui128;
#else
    typedef long long i128; typedef unsigned long long ui128;
#endif
typedef int64_t ll;  typedef uint64_t ull; typedef int8_t byte; typedef long double lld;
typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<lld,lld> pdd;
template<typename T1,typename T2> using ordered_map=tree<T1,T2,less<T1>,rb_tree_tag,tree_order_statistics_node_update>;
template<typename T1> using ordered_set=ordered_map<T1,null_type>;
const int inf=0x3f3f3f3f,MOD=1e9+7; const ll INF=0x3f3f3f3f3f3f3f3f; const lld PI=acos((lld)-1);
ll gcd(ll a, ll b){return b?gcd(b,a%b):a;}
ll fpow(ll a,ll b){if(!b) return 1; ll t=fpow(a,b/2); if(b&1) return t*t%MOD*a%MOD; return t*t%MOD;}
const ll SEED=chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
mt19937 randgen(SEED); int randint(int a, int b){return uniform_int_distribution<int>(a,b)(randgen);} ll randll(ll a, ll b){return uniform_int_distribution<ll>(a,b)(randgen);}
template<class T1,class T2>constexpr const auto _min(const T1&x,const T2&y){return x<y?x:y;} template<class T,class...Ts>constexpr auto _min(const T&x,const Ts&...xs){return _min(x,_min(xs...));}
template<class T1,class T2>constexpr const auto _max(const T1&x,const T2&y){return x>y?x:y;} template<class T,class...Ts>constexpr auto _max(const T&x,const Ts&...xs){return _max(x,_max(xs...));}
#define min(...) _min(__VA_ARGS__)
#define max(...) _max(__VA_ARGS__)
struct chash{
    static ll splitmix64(ll x){x+=0x9e3779b97f4a7c15; x=(x^(x>>30))*0xbf58476d1ce4e5b9; x=(x^(x>>27))*0x94d049bb133111eb; return x^(x>>31);}
    template<class T> size_t operator()(const T &x) const{return splitmix64(hash<T>()(x)+SEED);}
    template<class T1,class T2> size_t operator()(const pair<T1,T2>&x)const{return 31*operator()(x.first)+operator()(x.second);}
};
#define nl "\n"

const int N=P2(18),M=MOD;
int n,m,q,n2,a,b,val[N],dfn[N],low[N],sz[N],par[N],top[N],dep[N];
vector<int> gr[N],gr2[N];
stack<int> scc;
bitset<N> art;
set<int> vals[N];
char ch;
struct SegTree{
    int seg[2*N];
    SegTree(){seto(seg,inf);}
    void pull(int x){seg[x]=min(seg[2*x],seg[2*x+1]);}
    void upd(int x,int v){
        seg[x+=N]=v;
        for(x/=2;x;x/=2) pull(x);
    }
    int query(int l,int r){
        int ret=inf;
        for(l+=N,r+=N+1;l<r;l/=2,r/=2){
            if(l&1) ret=min(ret,seg[l++]);
            if(r&1) ret=min(seg[--r],ret);
        }
        return ret;
    }
} st;
void tarjan(int v,int p=-1){
    dfn[v]=low[v]=a++; scc.push(v); vals[v].insert(val[v]);
    for(auto i:gr2[v]) if(i!=p){
        if(dfn[i]) low[v]=min(low[v],dfn[i]);
        else{
            tarjan(i,v);
            if(low[i]>=dfn[v]){
                n2++; val[n2]=inf; art[v]=1;
                for(;scc.top()!=v&&low[scc.top()]>=dfn[v];scc.pop()){
                    int x=scc.top(); gr[x].pb(n2); gr[n2].pb(x); vals[n2].insert(val[x]);
                }
                if(low[i]==dfn[v]){
                    gr[n2].pb(v); gr[v].pb(n2);
                }
                else{
                    gr[i].pb(v); gr[v].pb(i); art[i]=1;
                }
            }
            low[v]=min(low[v],low[i]);
        }
    }
}
void szdfs(int v,int p=-1){
    sz[v]=1;
    for(auto& i:gr[v]) if(i!=p){
        szdfs(i,v); sz[v]+=sz[i];
        if(gr[v][0]==p||sz[i]>sz[gr[v][0]]) swap(i,gr[v][0]);
    }
}
void hlddfs(int v,int p=0){
    dfn[v]=a++; par[v]=p;
    if(v>n||art[v]) st.upd(dfn[v],*vals[v].begin());
    for(auto i:gr[v]) if(i!=p){
        top[i]=i==gr[v][0]? top[v]: i;
        hlddfs(i,v);
    }
}
int query(int u,int v){
    if(u==v) return val[u];
    int ret=inf;
    while(top[u]!=top[v]){
        if(dfn[top[u]]>dfn[top[v]]) swap(u,v);
        ret=min(ret,st.query(dfn[top[v]],dfn[v]));
        v=par[top[v]];
    }
    if(dfn[u]>dfn[v]) swap(u,v);
    ret=min(ret,st.query(dfn[u],dfn[v]));
    if(art[par[u]]) ret=min(ret,st.query(dfn[par[u]],dfn[par[u]]));
    return ret;
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    //freopen("", "r", stdin); //freopen("", "w", stdout);
    cin>>n>>m>>q;
    fori(1,n+1) cin>>val[i];
    fori(0,m){
        cin>>a>>b; gr2[a].pb(b); gr2[b].pb(a);
    }
    gr2[0].pb(1); n2=n; tarjan(0); szdfs(1); a=0; top[1]=1; hlddfs(1); art[0]=0;
    while(q--){
        cin>>ch>>a>>b;
        if(ch=='A') cout<<query(a,b)<<nl;
        else if(ch=='C'){
            if(art[a]) st.upd(dfn[a],b);
            if(!art[par[a]]){
                vals[par[a]].erase(val[a]);
                vals[par[a]].insert(b);
                st.upd(dfn[par[a]],*vals[par[a]].begin());
            }
            val[a]=b;
        }
    }
    return 0;
}
/**

*/


#include<bits/stdc++.h>
using namespace std;
const int $=2e5+5,inf=1e9;
int n,m,Q,dfn[$],low[$],t,st[$],tp,N,sz[$],son[$],dep[$],id[$],w[$],Id[$],v[$<<2],f[$],top[$];
vector<int>E[$],T[$]; multiset<int>S[$]; char O[9];
#define pb push_back
void dfs(int p){
	dfn[p]=low[p]=++t; st[++tp]=p;
	for(int y:E[p])if(!dfn[y]){
		dfs(y); low[p]=min(low[p],low[y]);
		if(low[y]>=dfn[p]){
			T[p].pb(++N); f[N]=p;
			while(st[tp+1]^y)f[st[tp]]=N,S[N].insert(w[st[tp]]),T[N].pb(st[tp--]);
		}
	}else low[p]=min(low[p],dfn[y]);
}
void Dfs(int p){
	sz[p]=1; dep[p]=dep[f[p]]+1;
	for(int y:T[p])Dfs(y),sz[p]+=sz[y],sz[son[p]]<sz[y]&&(son[p]=y);
}
void DFS(int p,int tp){
	id[p]=++t; Id[t]=p; top[p]=tp;
	if(son[p])DFS(son[p],tp);
	for(int y:T[p])if(!id[y])DFS(y,y);
}
#define lc p<<1
#define rc lc|1
#define md (L+R>>1)
void build(int l,int r,int p=1,int L=1,int R=N){
	if(L==R){v[p]=Id[L]<=n?w[Id[L]]:*S[Id[L]].begin();return;}
	if(l<=md)build(l,r,lc,L,md); if(r>md)build(l,r,rc,md+1,R); v[p]=min(v[lc],v[rc]);
}
int ask(int l,int r,int p=1,int L=1,int R=N){
	if(l<=L&&R<=r)return v[p];
	return min(l<=md?ask(l,r,lc,L,md):inf,r>md?ask(l,r,rc,md+1,R):inf);
}
int Ask(int a,int b,int W=1e9){
	while(top[a]!=top[b]){if(dep[top[a]]<dep[top[b]])swap(a,b);W=min(W,ask(id[top[a]],id[a]));a=f[top[a]];}
	if(dep[a]>dep[b])swap(a,b); W=min(W,ask(id[a],id[b]));
	return min(W,a>n?w[f[a]]:inf);
}
int main(){
	scanf("%d%d%d",&n,&m,&Q); N=n;
	for(int i=1;i<=n;++i)scanf("%d",&w[i]);
	for(int i=1,a,b;i<=m;++i)scanf("%d%d",&a,&b),E[a].pb(b),E[b].pb(a);
	dfs(1); Dfs(1); t=0; DFS(1,1); build(1,N);
	for(int _=1,a,b;_<=Q;++_){
		scanf("%s%d%d",O,&a,&b);
		if(*O=='A')printf("%d\n",Ask(a,b));
		else{
			if(a^1)S[f[a]].erase(S[f[a]].find(w[a])),S[f[a]].insert(b),build(id[f[a]],id[f[a]]);
			w[a]=b; build(id[a],id[a]);
		}
	}
}


#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]);
            }
        }
    }
    /*
    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;

    if(N > 60000) {
        cout << R;
        return 0;
    }

    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(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;
    //*/

    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);

    if(N > 60000) {
        cout << N << endl;
    }

    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] ]);
    }

    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;
    //*/

    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], 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);
        ccnt++;
    }
}

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(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]);
            }
        }
    }
    /*
    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);

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

    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 = 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 << 1];
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++) {
        add(tin[i], 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];

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]);
            }
        }
    }
    /*
    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);

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

    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);
        }
    }
}