#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
#define int long long
const double pi = acos (-1);
const int N = 3e4 + 5;
int head[N], n, val[N];
struct edge {
int to, nxt;
} ed[N << 1];
int cnt;
inline void add_edge (int u, int v) {
cnt ++;
ed[cnt].to = v;
ed[cnt].nxt = head[u];
head[u] = cnt;
}
int son[N], siz[N], depth[N], fa[N], top[N], dfn[N], rk[N];
inline void dfs1 (int u) {
son[u] = -1;
siz[u] = 1;
for (int i = head[u]; i ; i = ed[i].nxt) {
if (!depth[ed[i].to]) {
depth[ed[i].to] = depth[u] + 1;
fa[ed[i].to] = u;
dfs1 (ed[i].to);
siz[u] += siz[ed[i].to];
if (son[u] == -1 || siz[ed[i].to] > siz[son[u]]) son[u] = ed[i].to;
}
}
}
int tmd;
inline void dfs2 (int u, int ck) {
top[u] = ck;
tmd ++;
dfn[u] = tmd;
rk[tmd] = u;
if (son[u] == -1) return ;
dfs2 (son[u], ck);
for (int i = head[u]; i ; i = ed[i].nxt) {
if (ed[i].to != son[u] && ed[i].to != fa[u]) dfs2 (ed[i].to, ed[i].to);
}
}
struct segment_tree {
int sum[N << 2], mx[N << 2], inc[N << 2];
inline void push_up (int u) {
sum[u] = sum[u << 1] + sum[u << 1 | 1];
mx[u] = max (mx[u << 1], mx[u << 1 | 1]);
}
inline void push_down (int u, int l, int r) {
if (inc[u] == -2e18) return ;
inc[u << 1] = inc[u << 1 | 1] = inc[u];
mx[u << 1] = mx[u << 1 | 1] = inc[u];
int mid = l + r >> 1;
sum[u << 1] = (mid - l + 1) * inc[u];
sum[u << 1 | 1] = (r - mid) * inc[u];
inc[u] = -2e18;
}
inline void build (int u, int l, int r) {
inc[u] = -2e18;
if (l == r) {
sum[u] = mx[u] = val[l];
return ;
}
int mid = l + r >> 1;
build (u << 1, l, mid);
build (u << 1 | 1, mid + 1, r);
push_up (u);
}
inline void update (int u, int l, int r, int x, int y, int v) {
if (x <= l && r <= y) {
sum[u] = (r - l + 1) * v;
mx[u] = v;
inc[u] = v;
return ;
}
push_down (u, l, r);
int mid = l + r >> 1;
if (x <= mid) update (u << 1, l, mid, x, y, v);
if (y > mid) update (u << 1 | 1, mid + 1, r, x, y, v);
push_up (u);
}
inline int query_sum (int u, int l, int r, int x, int y) {
if (x <= l && r <= y) return sum[u];
push_down (u, l, r);
int mid = l + r >> 1, ans = 0;
if (x <= mid) ans += query_sum (u << 1, l, mid, x, y);
if (y > mid) ans += query_sum (u << 1 | 1, mid + 1, r, x, y);
return ans;
}
inline int query_max (int u, int l, int r, int x, int y) {
if (x <= l && r <= y) return mx[u];
push_down (u, l, r);
int mid = l + r >> 1, ans = -2e18;
if (x <= mid) ans = max (ans, query_max (u << 1, l, mid, x, y));
if (y > mid) ans = max (ans, query_max (u << 1 | 1, mid + 1, r, x, y));
return ans;
}
} sg;
inline void update (int u, int w) {
sg.update (1, 1, n, dfn[u], dfn[u], w);
}
inline int query_max (int u, int v) {
int ans = -2e18, fu = top[u], fv = top[v];
while (fu != fv) {
if (depth[fu] >= depth[fv]) {
ans = max (ans, sg.query_max (1, 1, n, dfn[fu], dfn[u]));
u = fa[fu];
}
else {
ans = max (ans, sg.query_max (1, 1, n, dfn[fv], dfn[v]));
v = fa[fv];
}
fu = top[u];
fv = top[v];
}
if (dfn[u] < dfn[v]) ans = max (ans, sg.query_max (1, 1, n, dfn[u], dfn[v]));
else ans = max (ans, sg.query_max (1, 1, n, dfn[v], dfn[u]));
return ans;
}
inline int query_sum (int u, int v) {
int ans = 0, fu = top[u], fv = top[v];
while (fu != fv) {
if (depth[fu] >= depth[fv]) {
ans += sg.query_sum (1, 1, n, dfn[fu], dfn[u]);
u = fa[fu];
}
else {
ans += sg.query_sum (1, 1, n, dfn[fv], dfn[v]);
v = fa[fv];
}
fu = top[u];
fv = top[v];
}
if (dfn[u] < dfn[v]) ans += sg.query_sum (1, 1, n, dfn[u], dfn[v]);
else ans += sg.query_sum (1, 1, n, dfn[v], dfn[u]);
return ans;
}
signed main () {
scanf ("%lld", &n);
for (int i = 1;i < n; ++ i) {
int u, v;
scanf ("%lld %lld", &u, &v);
add_edge (u, v);
add_edge (v, u);
}
depth[1] = 1;
dfs1 (1);
dfs2 (1, 1);
for (int i = 1;i <= n; ++ i) scanf ("%lld", &val[i]);
sg.build (1, 1, n);
int q;
scanf ("%lld", &q);
while (q --) {
char op[10];
scanf ("%s", op + 1);
if (op[1] == 'C') {
int x, y;
scanf ("%lld %lld", &x, &y);
update (x, y);
}
else if (op[2] == 'M') {
int s, t;
scanf ("%lld %lld", &s, &t);
printf ("%lld\n", query_max (s, t));
}
else {
int s, t;
scanf ("%lld %lld", &s, &t);
printf ("%lld\n", query_sum (s, t));
}
}
return 0;
}