#include <bits/stdc++.h>   using namespace std;   int read() {     int q = 0;     char ch =    ;     while (ch <  0  || ch >  9 ) ch = getchar();     while (ch >=  0  && ch <=  9 ) q = q * 10 + ch -  0 , ch = getchar();     return q;   }   const int N = 200005, inf = 0x3f3f3f3f;   int n, m, Q, SZ, st_top, tim;   int w[N], dfn[N], low[N], st[N];   multiset<int> S[N];   struct graph {     int tot, h[N], ne[N], to[N];     void add(int x, int y) { to[++tot] = y, ne[tot] = h[x], h[x] = tot; }   } G, T;   void tarjan(int x, int las) {     dfn[x] = low[x] = ++tim, st[++st_top] = x;     for (register int i = G.h[x]; i; i = G.ne[i]) {       if (G.to[i] == las) continue;       int y = G.to[i];       if (!dfn[y]) {         tarjan(y, x), low[x] = min(low[x], low[y]);         if (low[y] == dfn[x]) {           ++SZ, w[SZ] = inf, T.add(x, SZ);           while (st[st_top] != y) {             T.add(SZ, st[st_top]), S[SZ].insert(w[st[st_top]]);             w[SZ] = min(w[SZ], w[st[st_top]]), --st_top;           }           T.add(SZ, y), S[SZ].insert(w[y]), w[SZ] = min(w[SZ], w[y]), --st_top;         } else if (low[y] > dfn[x])           ++SZ, w[SZ] = w[y], S[SZ].insert(w[y]), T.add(x, SZ), T.add(SZ, y);       } else         low[x] = min(low[x], dfn[y]);     }     if (dfn[x] == low[x]) --st_top;   }   int sz[N], fa[N], top[N], pos[N], repos[N], dep[N], mi[N << 2];   void dfs1(int x) {     sz[x] = 1, dep[x] = dep[fa[x]] + 1;     for (register int i = T.h[x]; i; i = T.ne[i])       fa[T.to[i]] = x, dfs1(T.to[i]), sz[x] += sz[T.to[i]];   }   void dfs2(int x) {     int bj = 0, mx = 0;     pos[x] = ++tim, repos[tim] = x;     for (register int i = T.h[x]; i; i = T.ne[i])       if (sz[T.to[i]] > mx) mx = sz[T.to[i]], bj = T.to[i];     if (bj) top[bj] = top[x], dfs2(bj);     for (register int i = T.h[x]; i; i = T.ne[i])       if (T.to[i] != bj) top[T.to[i]] = T.to[i], dfs2(T.to[i]);   }   void build(int s, int t, int i) {     if (s == t) {       mi[i] = w[repos[s]];       return;     }     int mid = (s + t) >> 1;     build(s, mid, i << 1), build(mid + 1, t, (i << 1) | 1);     mi[i] = min(mi[i << 1], mi[(i << 1) | 1]);   }   void chan(int x, int s, int t, int i, int v) {     if (s == t) {       mi[i] = v;       return;     }     int mid = (s + t) >> 1;     if (x <= mid) chan(x, s, mid, i << 1, v);     if (mid + 1 <= x) chan(x, mid + 1, t, (i << 1) | 1, v);     mi[i] = min(mi[i << 1], mi[(i << 1) | 1]);   }   int query(int l, int r, int s, int t, int i) {     if (l <= s && t <= r) return mi[i];     int mid = (s + t) >> 1, re = inf;     if (l <= mid) re = query(l, r, s, mid, i << 1);     if (mid + 1 <= r) re = min(re, query(l, r, mid + 1, t, (i << 1) | 1));     return re;   }   int getans(int x, int y) {     int re = inf;     while (top[x] != top[y]) {       if (dep[top[x]] < dep[top[y]]) swap(x, y);       re = min(re, query(pos[top[x]], pos[x], 1, SZ, 1));       x = fa[top[x]];     }     if (pos[x] > pos[y]) swap(x, y);     re = min(re, query(pos[x], pos[y], 1, SZ, 1));     if (x > n) re = min(re, query(pos[fa[x]], pos[fa[x]], 1, SZ, 1));     return re;   }   int main() {     int x, y;     char ch[10];     n = read(), m = read(), Q = read();     for (register int i = 1; i <= n; ++i) w[i] = read();     for (register int i = 1; i <= m; ++i)       x = read(), y = read(), G.add(x, y), G.add(y, x);     SZ = n, tarjan(1, 0);     dfs1(1), tim = 0, top[1] = 1, dfs2(1), build(1, SZ, 1);     while (Q--) {       scanf( %s , ch), x = read(), y = read();       if (ch[0] ==  C ) {         chan(pos[x], 1, SZ, 1, y);         if (x != 1) {           S[fa[x]].erase(S[fa[x]].find(w[x]));           S[fa[x]].insert(y);           int kw = *(S[fa[x]].begin());           if (kw != w[fa[x]]) chan(pos[fa[x]], 1, SZ, 1, kw), w[fa[x]] = kw;         }         w[x] = y;       } else         printf( %d n , getans(x, y));     }     return 0;   }