#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define per(i, a, b) for (int i = (a); i >= (b); i--)
#define D(x) cerr<< #x << " : " << x << endl
using namespace std;
const int inf = 0x3fffffff;
const int N = 100011;
vector<int> edge[N];
int n;
int dep[N], fa[N], siz[N], hson[N], top[N], dfn[N], rnk[N], clk = 0;
int w[N];
void dfs1(int u) {
siz[u] = 1, hson[u] = -1;
for (int v : edge[u]) {
if(v == fa[u]) continue;
dep[v] = dep[u] + 1, fa[v] = u;
dfs1(v);
siz[u] += siz[v];
if (hson[u] == -1 || siz[v] > siz[hson[u]]) hson[u] = v;
}
}
void dfs2(int u, int tp) {
dfn[u] = ++clk, rnk[clk] = u;
top[u] = tp;
if (hson[u] == -1) return;
dfs2(hson[u], tp);
for (int v : edge[u])
if (v != fa[u] && v != hson[u]) dfs2(v, v);
}
int mx[N], sum[N];
inline void maintain(int u) {
mx[u] = max(mx[u * 2], mx[u * 2 + 1]);
sum[u] = sum[u * 2] + sum[u * 2 + 1];
}
void build(int u, int l, int r) {
if (l == r) {
mx[u] = sum[u] = w[rnk[l]];
return;
}
int mid = (l + r) / 2;
build(u * 2, l, mid), build(u * 2 + 1, mid + 1, r);
maintain (u);
}
void update(int u, int pos, int val, int l, int r) {
if (l == r) {
mx[u] = sum[u] = val;
return;
}
int mid = (l + r) / 2;
if (pos <= mid)
update(u * 2, pos, val, l, mid);
else
update(u * 2 + 1, pos, val, mid + 1, r);
maintain(u);
}
int queryMx (int u, int l, int r, int L, int R) {
if (l == L && r == R) return mx[u];
int mid = (L + R) / 2;
if (r <= mid) return queryMx(u * 2, l, r, L, mid);
if (l > mid) return queryMx(u * 2 + 1, l, r, mid + 1, R);
return max(queryMx(u * 2, l, mid, L, mid),
queryMx(u * 2 + 1, mid + 1, r, mid + 1, R));
}
int querySum(int u, int l, int r, int L, int R) {
if (l == L && r == R) return sum[u];
int mid = (L + R) / 2;
if (r <= mid) return querySum(u * 2, l, r, L, mid);
if (l > mid) return querySum(u * 2 + 1, l, r, mid + 1, R);
return querySum(u * 2, l, mid, L, mid) +
querySum(u * 2 + 1, mid + 1, r, mid + 1, R);
}
int queryMx(int l,int r) {
if(l > r) swap(l, r);
return queryMx(1,l,r,1,n);
}
int querySum(int l,int r) {
if(l > r) swap(l, r);
return querySum(1,l,r,1,n);
}
int Sum(int u, int v) {
int tot = 0;
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
tot += querySum(dfn[top[u]], dfn[u]);
u = fa[top[u]];
}
return tot + querySum(dfn[u], dfn[v]);
}
int Max(int u, int v) {
int tot = -inf;
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
tot = max(tot, queryMx(dfn[top[u]], dfn[u]));
u = fa[top[u]];
}
return max(tot, queryMx(dfn[u], dfn[v]));
}
int main() {
cin >> n;
rep(i, 1, n - 1) {
int x, y;
scanf("%d %d", &x, &y);
edge[x].push_back(y), edge[y].push_back(x);
}
rep(i, 1, n) scanf("%d", &w[i]);
fa[1] = 1, dep[1] = 1, dfs1(1);
dfs2(1, 1);
build(1, 1, n);
char opt[20];
int m, x, y;
cin >> m;
rep(i, 1, m) {
scanf("%s %d %d", opt, &x, &y);
if (opt[0] == 'C')
update(1, dfn[x], y, 1, n);
else {
int ans;
if (opt[1] == 'M')
ans = Max(x, y);
else
ans = Sum(x, y);
printf("%d\n", ans);
}
}
return 0;
}