#include <limits.h>
#include <stdio.h>
#include <string.h>
#define int long long
#define each(i, x) for (int i = x[head]; i; i = i[nxt])
#define SLC(x) (x * 2)
#define SRC(x) (x * 2 + 1)
#define N size_t(3e5 + 4)
int n, q;
int head[N], to[2 * N], nxt[2 * N], mtp;
int siz[N], son[N], fa[N], dep[N], top[N];
int dfn[N], rnk[N], cnt;
int segMax[4 * N], segSum[4 * N];
int max(int x, int y) { return x > y ? x : y; }
void swap(int& x, int& y) {
int z = y;
y = x;
x = z;
}
void CFS_add_edge_1(int f, int t) {
mtp++;
mtp[to] = t;
mtp[nxt] = f[head];
f[head] = mtp;
}
void CFS_add_edge_2(int f, int t) {
CFS_add_edge_1(f, t);
CFS_add_edge_1(t, f);
}
void HLD_build_1(int now, int last) {
now[siz] = 1;
each(i, now) {
if (i[to] != last) {
i[to][dep] = now[dep] + 1;
i[to][fa] = now;
HLD_build_1(i[to], now);
now[siz] += i[to][siz];
if (i[to][siz] > now[son][siz]) now[son] = i[to];
}
}
}
void HLD_build_2(int now, int tp) {
cnt++;
dfn[now] = cnt;
rnk[cnt] = now;
now[top] = tp;
if (now[son]) HLD_build_2(now[son], tp);
each(i, now) {
if (i[to] != now[fa] && i[to] != now[son]) HLD_build_2(i[to], i[to]);
}
}
void Seg_pushup(int now) {
now[segSum] = SLC(now)[segSum] + SRC(now)[segSum];
now[segMax] = max(SLC(now)[segMax], SRC(now)[segMax]);
}
void Seg_build(int now, int nl, int nr) {
int nm = (nl + nr) / 2;
if (nl == nr) {
scanf("%lld", now + segSum);
now[segMax] = now[segSum];
} else {
Seg_build(SLC(now), nl, nm);
Seg_build(SRC(now), nm + 1, nr);
Seg_pushup(now);
}
}
void Seg_update(int now, int nl, int nr, int cid, int cval) {
if (nl == nr)
now[segSum] = now[segMax] = cval;
else {
int nm = (nl + nr) / 2;
if (cid <= nm)
Seg_update(SLC(now), nl, nm, cid, cval);
else
Seg_update(SRC(now), nm + 1, nr, cid, cval);
Seg_pushup(now);
}
}
int Seg_query_sum(int now, int nl, int nr, int ql, int qr) {
if (ql <= nl && nr <= qr) return now[segSum];
int nm = (nl + nr) / 2, ret = 0;
if (ql <= nm) ret += Seg_query_sum(SLC(now), nl, nm, ql, qr);
if (nm + 1 <= qr) ret += Seg_query_sum(SRC(now), nm + 1, nr, ql, qr);
return ret;
}
int Seg_query_max(int now, int nl, int nr, int ql, int qr) {
if (ql <= nl && nr <= qr) return now[segMax];
int nm = (nl + nr) / 2, ret = INT_MIN;
if (ql <= nm) ret = max(ret, Seg_query_max(SLC(now), nl, nm, ql, qr));
if (nm + 1 <= qr) ret = max(ret, Seg_query_max(SRC(now), nm + 1, nr, ql, qr));
return ret;
}
int HLD_query_sum(int u, int v) {
int ans = 0;
while (top[u] != top[v]) {
if (u[top][dep] < v[top][dep]) swap(u, v);
ans += Seg_query_sum(1, 1, n, u[top][dfn], u[dfn]);
u = u[top][fa];
}
if (dep[u] < dep[v]) swap(u, v);
ans += Seg_query_sum(1, 1, n, dfn[v], dfn[u]);
return ans;
}
int HLD_query_max(int u, int v) {
int ans = INT_MIN;
while (top[u] != top[v]) {
if (u[top][dep] < v[top][dep]) swap(u, v);
ans = max(ans, Seg_query_max(1, 1, n, u[top][dfn], u[dfn]));
u = u[top][fa];
}
if (dep[u] < dep[v]) swap(u, v);
ans = max(ans, Seg_query_max(1, 1, n, dfn[v], dfn[u]));
return ans;
}
signed main() {
scanf("%lld", &n);
for (int i = 2; i <= n; i++) {
int x, y;
scanf("%lld%lld", &x, &y);
CFS_add_edge_2(x, y);
}
dep[1] = fa[1] = 1;
HLD_build_1(1, 0);
HLD_build_2(1, 1);
Seg_build(1, 1, n);
scanf("%lld", &q);
for (int i = 1; i <= q; i++) {
int x, y;
char cmd[10];
scanf("%s%lld%lld", cmd, &x, &y);
if (!strcmp(cmd, "CHANGE")) Seg_update(1, 1, n, dfn[x], y);
if (!strcmp(cmd, "QMAX")) printf("%lld\n", HLD_query_max(x, y));
if (!strcmp(cmd, "QSUM")) printf("%lld\n", HLD_query_sum(x, y));
}
return 0;
}