#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>
using namespace std;
template <typename T>
inline void read(T &x)
{
T f = 0;
x = 1;
char c = getchar();
while(c < '0' || c > '9')
{
if(c == '-') x = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
{
f = (f << 3) + (f << 1) + (c ^ 48);
c = getchar();
}
x *= f;
}
typedef long long LL;
const int N = 3e4 + 10, M = N << 1;
const LL INF = 1e18;
int n, q, w[N];
int h[N], ne[M], e[M], idx;
int dep[N], fa[N], nw[N], id[N], sz[N], top[N], son[N], cnt;
struct SegmentTree
{
int l, r;
LL v, sum;
}tr[N << 2];
void add(int a, int b)
{
e[ ++ idx] = b, ne[idx] = h[a], h[a] = idx;
}
void dfs1(int u, int father, int depth)
{
sz[u] = 1, fa[u] = father, dep[u] = depth;
for(int i = h[u] ; i ; i = ne[i])
{
int j = e[i];
if(j == father) continue;
dfs1(j, u, depth + 1);
sz[u] += sz[j];
if(sz[son[u]] < sz[j]) son[u] = j;
}
}
void dfs2(int u, int t)
{
id[u] = ++ cnt, top[u] = t, nw[id[u]] = w[u];
if(!son[u]) return;
dfs2(son[u], t);
for(int i = h[u] ; i ; i = ne[i])
{
int j = e[i];
if(j == fa[u] || j == son[u]) continue;
dfs2(j, j);
}
}
void pushup(int u)
{
tr[u].v = max(tr[u << 1].v, tr[u << 1 | 1].v);
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void build(int u, int l, int r)
{
tr[u] = {l, r, (LL)nw[r], (LL)nw[r]};
if(l == r) return;
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void modify(int u, int k, int x)
{
if(tr[u].l == tr[u].r && tr[u].l == k)
{
tr[u].sum = tr[u].v = (LL)x;
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if(mid >= k) modify(u << 1, k, x);
else modify(u << 1 | 1, k, x);
pushup(u);
}
LL query(int u, int l, int r, int type)
{
if(tr[u].l >= l && tr[u].r <= r) return type ? tr[u].sum : tr[u].v;
int mid = tr[u].l + tr[u].r >> 1;
LL v = type ? 0 : -INF;
if(mid >= l) v = type ? (v + query(u << 1, l, r, type)) : max(v, query(u << 1, l, r, type));
if(mid < r) v = type ? (v + query(u << 1 | 1, l, r, type)) : max(v, query(u << 1 | 1, l, r, type));
return v;
}
LL query_max(int u, int v)
{
LL res = -INF;
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]]) swap(u, v);
res = max(res, query(1, id[top[u]], id[u], 0));
u = fa[top[u]];
}
if(dep[u] < dep[v]) swap(u, v);
res = max(res, query(1, id[v], id[u], 0));
return res;
}
LL query_sum(int u, int v)
{
LL res = 0;
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]]) swap(u, v);
res += query(1, id[top[u]], id[u], 1);
u = fa[top[u]];
}
if(dep[u] < dep[v]) swap(u, v);
res += query(1, id[v], id[u], 1);
return res;
}
int main()
{
read(n);
for(int i = 1 ; i < n ; i ++ )
{
int a, b;
read(a), read(b);
add(a, b), add(b, a);
}
for(int i = 1 ; i <= n ; i ++ ) read(w[i]);
dfs1(1, -1, 1);
dfs2(1, 1);
build(1, 1, n);
read(q);
while(q -- )
{
char op[10];
int u, v;
scanf("%s", op), read(u), read(v);
if(!strcmp(op, "CHANGE")) modify(1, u, v);
else if(!strcmp(op, "QMAX")) printf("%lld\n", query_max(u, v));
else printf("%lld\n", query_sum(u, v));
}
return 0;
}