#include <bits/stdc++.h>   using namespace std;   int n, m, q, num, tot, tp, cnt, ans, w[200100], head[200100], dfn[200100],       c[200100], low[200100], sta[200100];   int dfc, sz[200100], d[200100], f[200100], son[200100], top[200100],       tree[200100], mn[200100 * 4];   vector<int> v[200100];   multiset<int> s[200100];   struct point {     int fr, to, nxt;   } a[200100 * 2];   void add(int x, int y) {     a[++tot].fr = x;     a[tot].to = y;     a[tot].nxt = head[x];     head[x] = tot;   }   void tarjan(int x) {     dfn[x] = low[x] = ++num;     sta[++tp] = x;     for (int i = 0; i < v[x].size(); i++) {       int y = v[x][i];       if (!dfn[y]) {         tarjan(y);         low[x] = min(low[x], low[y]);         if (low[y] == dfn[x]) {           ++cnt;           int now;           do {             now = sta[tp--];             add(cnt, now);             add(now, cnt);           } while (now != y);           add(cnt, x);           add(x, cnt);         }       } else         low[x] = min(low[x], dfn[y]);     }   }   void dfs1(int x, int fa) {     f[x] = fa;     d[x] = d[fa] + 1;     sz[x] = 1;     for (int i = head[x]; i; i = a[i].nxt) {       int y = a[i].to;       if (y == fa) continue;       dfs1(y, x);       sz[x] += sz[y];       if (sz[y] > sz[son[x]]) son[x] = y;     }   }   void dfs2(int x, int lst) {     top[x] = lst;     dfn[x] = ++dfc;     tree[dfc] = x;     if (son[x]) dfs2(son[x], lst);     for (int i = head[x]; i; i = a[i].nxt)       if (!top[a[i].to]) dfs2(a[i].to, a[i].to);   }   void build(int x, int l, int r) {     if (l == r) return mn[x] = w[tree[l]], void();     int mid = (l + r) >> 1;     build(x << 1, l, mid);     build(x << 1 | 1, mid + 1, r);     mn[x] = min(mn[x << 1], mn[x << 1 | 1]);   }   void modify(int x, int l, int r, int p, int y) {     if (l == r) return mn[x] = y, void();     int mid = (l + r) >> 1;     if (p <= mid)       modify(x << 1, l, mid, p, y);     else       modify(x << 1 | 1, mid + 1, r, p, y);     mn[x] = min(mn[x << 1], mn[x << 1 | 1]);   }   int query(int x, int l, int r, int L, int R) {     if (l >= L && r <= R) return mn[x];     int mid = (l + r) >> 1, ret = 1e9;     if (L <= mid) ret = min(ret, query(x << 1, l, mid, L, R));     if (R > mid) ret = min(ret, query(x << 1 | 1, mid + 1, r, L, R));     return ret;   }   int query(int x, int y, int ret = 1e9) {     while (top[x] != top[y]) {       if (d[top[x]] < d[top[y]]) swap(x, y);       ret = min(ret, query(1, 1, cnt, dfn[top[x]], dfn[x]));       x = f[top[x]];     }     if (d[x] < d[y]) swap(x, y);     ret = min(ret, query(1, 1, cnt, dfn[y], dfn[x]));     if (y > n) ret = min(ret, w[f[y]]);     return ret;   }   int main() {     scanf( %d%d%d , &n, &m, &q);     cnt = n;     for (int i = 1; i <= n; i++) scanf( %d , &w[i]);     for (int i = 1, x, y; i <= m; i++)       scanf( %d%d , &x, &y), v[x].push_back(y), v[y].push_back(x);     tarjan(1);     dfs1(1, 0);     dfs2(1, 1);     memset(mn, 0x3f, sizeof(mn));     for (int i = 1; i <= n; i++) s[f[i]].insert(w[i]);     for (int i = n + 1; i <= cnt; i++) w[i] = (*s[i].begin());     build(1, 1, cnt);     for (int i = 1; i <= q; i++) {       char ch[4];       int a, b;       scanf( %s%d%d , ch + 1, &a, &b);       if (ch[1] ==  C ) {         if (f[a]) {           multiset<int>::iterator pos = s[f[a]].find(w[a]);           s[f[a]].erase(pos);           s[f[a]].insert(b);           w[f[a]] = (*s[f[a]].begin());           modify(1, 1, cnt, dfn[f[a]], (*s[f[a]].begin()));         }         w[a] = b;         modify(1, 1, cnt, dfn[a], w[a]);       } else         printf( %d n , query(a, b));     }   }