#include<algorithm>
#include<iostream>
#include<climits>
#include<cstdio>
#include<stack>
#include<cmath>
#include<set>
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
using namespace std;
namespace fast_IO
{
#define FAST_IO
#define IOSIZE 100000
typedef long long ll;
typedef double db;
typedef long double ldb;
char ibuf[IOSIZE], obuf[IOSIZE];
char *p1 = ibuf, *p2 = ibuf, *p3 = obuf;
#ifdef ONLINE_JUDGE
#define getchar() ((p1==p2)and(p2=(p1=ibuf)+fread(ibuf,1,IOSIZE,stdin),p1==p2)?(EOF):(*p1++))
#define putchar(x) ((p3==obuf+IOSIZE)&&(fwrite(obuf,p3-obuf,1,stdout),p3=obuf),*p3++=x)
#endif
#define isdigit(ch) (ch>47&&ch<58)
#define isspace(ch) (ch<33&&ch!=EOF)
struct fast_IO_t {
~fast_IO_t() {
fwrite(obuf, p3-obuf, 1, stdout);
}
bool flag = false;
operator bool() {
return flag;
}
}io;
template<typename T> inline T read() {
T s = 0; int w = 1; char ch;
while(ch=getchar(), !isdigit(ch)&&(ch!=EOF))
if(ch == '-') w = -1;
if(ch == EOF) return 0;
while(isdigit(ch))
s = s*10+ch-48, ch=getchar();
if(ch == '.') {
ll flt = 0; int cnt = 0;
while(ch=getchar(), isdigit(ch))
if(cnt < 18) flt=flt*10+ch-48, cnt++;
s += (db)flt/pow(10,cnt);
}
return s *= w;
}
template<typename T> inline bool read(T &s) {
s = 0; int w = 1; char ch;
while(ch=getchar(), !isdigit(ch)&&(ch!=EOF))
if(ch == '-') w = -1;
if(ch == EOF) return false;
while(isdigit(ch))
s = s*10+ch-48, ch=getchar();
if(ch == '.') {
ll flt = 0; int cnt = 0;
while(ch=getchar(), isdigit(ch))
if(cnt < 18) flt=flt*10+ch-48, cnt++;
s += (db)flt/pow(10,cnt);
}
return s *= w, true;
}
inline bool read(char &s) {
while(s = getchar(), isspace(s));
return s != EOF;
}
inline bool read(char *s) {
char ch;
while(ch=getchar(), isspace(ch));
if(ch == EOF) return false;
while(!isspace(ch))
*s++ = ch, ch=getchar();
*s = '\000';
return true;
}
template<typename T> void print(T x) {
static int t[20]; int top = 0;
if(x < 0) putchar('-'), x = -x;
do { t[++top] = x%10; x /= 10; } while(x);
while(top) putchar(t[top--]+48);
}
struct empty_type{}; int pcs = 8;
empty_type setpcs(int cnt) {
return pcs = cnt, empty_type();
}
inline void print(empty_type x){}
inline void print(double x) {
if(x < 0) putchar('-'), x = -x;
x += 5.0 / pow(10,pcs+1);
print((ll)(x)); x -= (ll)(x);
if(pcs != 0) putchar('.');
for(int i = 1; i <= pcs; i++)
x *= 10, putchar((int)x+'0'), x -= (int)x;
}
inline void print(float x) {
if(x < 0) putchar('-'), x = -x;
x += 5.0 / pow(10,pcs+1);
print((ll)(x)); x -= (ll)(x);
if(pcs != 0) putchar('.');
for(int i = 1; i <= pcs; i++)
x *= 10, putchar((int)x+'0'), x -= (int)x;
}
inline void print(char x) {
putchar(x);
}
inline void print(char *x) {
for(int i = 0; x[i]; i++)
putchar(x[i]);
}
inline void print(const char *x) {
for(int i = 0; x[i]; i++)
putchar(x[i]);
}
#ifdef _GLIBCXX_STRING//string
inline bool read(std::string& s) {
s = ""; char ch;
while(ch=getchar(), isspace(ch));
if(ch == EOF) return false;
while(!isspace(ch))
s += ch, ch = getchar();
return true;
}
inline void print(std::string x) {
for(string::iterator i = x.begin(); i != x.end(); i++)
putchar(*i);
}
inline bool getline(fast_IO_t &io, string s) {
s = ""; char ch = getchar();
if(ch == EOF) return false;
while(ch != '\n' and ch != EOF)
s += ch, ch = getchar();
return true;
}
#endif
#if __cplusplus >= 201103L
template<typename T, typename... T1>
inline int read(T& a, T1& ...other) {
return read(a)+read(other...);
}
template<typename T, typename... T1>
inline void print(T a, T1... other) {
print(a); print(other...);
}
#endif
template<typename T>
fast_IO_t& operator >> (fast_IO_t &io, T &b) {
return io.flag=read(b), io;
}
fast_IO_t& operator >> (fast_IO_t &io, char *b) {
return io.flag=read(b), io;
}
template<typename T>
fast_IO_t& operator << (fast_IO_t &io, T b) {
return print(b), io;
}
#define cout io
#define cin io
#define endl '\n'
}
using namespace fast_IO;
const int MAXN = 4e5+10;
const int MAXM = 4e5+10;
const int inf = INT_MAX;
multiset<int> cost[MAXM];
struct edge {int from, to;int next;};
struct tree {int l, r; int val;};
namespace Tarjan
{
edge a[MAXN<<1];
stack<int> st; int w[MAXN<<1];
int head[MAXN], cnt, tot, all;
int dfn[MAXN], low[MAXN], tim;
auto tarjan(int x) -> void;
auto add_edge(int from, int to) -> void;
}
namespace Tree
{
edge a[MAXM<<1];
tree tr[MAXM<<2];
int f[MAXM], siz[MAXM], son[MAXM];
int id[MAXM], top[MAXM], dep[MAXM];
int head[MAXM], aid[MAXM], cnt, tim;
auto add_edge(int from, int to) -> void;
auto dfs1(int x, int fa) -> void;
auto dfs2(int x, int tp) -> void;
auto query(int l, int r, int i) -> int;
auto build(int l, int r, int i) -> void;
auto change_r(int x, int k, int i) -> void;
auto change_s(int x, int k, int i) -> void;
auto query_min(int x, int y) -> void;
auto change_val(int x, int k) -> void;
}
int n, m, q, u, v, c[MAXN]; char op;
int main()
{
read(n, m, q);
for(int i = 1; i <= n; i += 1) read(c[i]);
for(int i = 1; i <= m; i += 1)
{
read(u, v);
Tarjan::add_edge(u, v);
Tarjan::add_edge(v, u);
}
Tarjan::tot = n;
Tarjan::tarjan(1);
Tree::dfs1(1, 0);
Tree::dfs2(1, 1);
Tree::build(1, Tarjan::tot, 1);
for(int i = 1; i <= q; i += 1)
{
cin >> op >> u >> v;
if(op == 'A') Tree::query_min(u, v);
else Tree::change_val(u, v);
}
return 0;
}
namespace Tarjan
{
auto add_edge(int from, int to) -> void
{
cnt += 1;
a[cnt].from = from;
a[cnt].to = to;
a[cnt].next = head[from];
head[from] = cnt;
}
auto tarjan(int x) -> void
{
dfn[x] = low[x] = ++tim;
st.push(x); all += 1;
w[x] = c[x]; int y, z;
for(int i = head[x]; i; i = a[i].next)
{
y = a[i].to;
if(!dfn[y])
{
tarjan(y);
low[x] = min(low[x], low[y]);
if(low[y] == dfn[x])
{
w[++tot] = INT_MAX;
while((z = st.top()))
{
st.pop();
Tree::add_edge(z, tot);
Tree::add_edge(tot, z);
if(z == y) break;
}
Tree::add_edge(x, tot);
Tree::add_edge(tot, x);
}
}
else low[x] = min(low[x], dfn[y]);
}
}
}
namespace Tree
{
auto add_edge(int from, int to) -> void
{
cnt += 1;
a[cnt].from = from;
a[cnt].to = to;
a[cnt].next = head[from];
head[from] = cnt;
}
auto dfs1(int x, int fa) -> void
{
f[x] = fa; siz[x] = 1;
dep[x] = dep[f[x]]+1;
int maxson = 0, y;
for(int i = head[x]; i; i = a[i].next)
{
y = a[i].to; if(y == fa) continue;
dfs1(y, x); siz[x] += siz[y];
if(siz[y] > siz[maxson]) maxson = y;
}
if(x > n)
{
for(int i = head[x]; i; i = a[i].next)
{
y = a[i].to; if(y == fa) continue;
Tarjan::w[x] = min(Tarjan::w[x], Tarjan::w[y]);
cost[x].insert(Tarjan::w[y]);
}
}
son[x] = maxson;
}
auto dfs2(int x, int tp) -> void
{
id[x] = ++tim; aid[tim] = x;
top[x] = tp; int y;
if(son[x]) dfs2(son[x], tp);
for(int i = head[x]; i; i = a[i].next)
{
y = a[i].to;
if(y == f[x] or y == son[x]) continue;
dfs2(y, y);
}
}
auto build(int l, int r, int i) -> void
{
tr[i].l = l;
tr[i].r = r;
if(l == r) return (void)(tr[i].val = Tarjan::w[aid[l]]);
int mid = (l+r)>>1;
build(l, mid, ls(i));
build(mid+1, r, rs(i));
tr[i].val = min(tr[ls(i)].val, tr[rs(i)].val);
}
auto change_r(int x, int k, int i) -> void
{
if(tr[i].l > x or tr[i].r < x) return ;
if(tr[i].l == x and tr[i].r == x) return (void)(tr[i].val = k);
change_r(x, k, ls(i));
change_r(x, k, rs(i));
tr[i].val = min(tr[ls(i)].val, tr[rs(i)].val);
}
auto change_s(int x, int k, int i) -> void
{
if(tr[i].l > x or tr[i].r < x) return ;
if(tr[i].l == x and tr[i].r == x) return (void)(tr[i].val = k);
change_s(x, k, ls(i));
change_s(x, k, rs(i));
tr[i].val = min(tr[ls(i)].val, tr[rs(i)].val);
}
auto query(int l, int r, int i) -> int
{
if(tr[i].l > r or tr[i].r < l) return inf;
if(tr[i].l >= l and tr[i].r <= r) return tr[i].val;
return min(query(l, r, ls(i)), query(l, r, rs(i)));
}
auto query_min(int x, int y) -> void
{
int ans = inf;
while(top[x] != top[y])
{
if(dep[top[x]] < dep[top[y]]) swap(x, y);
ans = min(ans, query(id[top[x]], id[x], 1));
x = f[top[x]];
}
if(id[x] > id[y]) swap(x, y);
ans = min(ans, query(id[x], id[y], 1));
if(x > n) ans = min(ans, query(id[f[x]], id[f[x]], 1));
print(ans, '\n');
}
auto change_val(int x, int k) -> void
{
change_r(id[x], k, 1);
int y = f[x];
multiset<int>::iterator iter = lower_bound(cost[y].begin(), cost[y].end(), Tarjan::w[x]);
Tarjan::w[x] = k;
if(x == 1 or iter == cost[y].end()) return ;
cost[y].erase(iter);
cost[y].insert(k);
change_s(id[y], *(cost[y].begin()), 1);
}
}