#include <iostream>
#include <vector>
#include <climits>
#define Min INT_MIN >> 1
#define endl '\n'
using namespace std;
const int N = 3e4 + 5, B = 180;
struct Node{
int dep, siz, fat, top, hvy;
}t[N];
struct Block{
int sum, Max = Min, bn, ed;
}info[B];
int n, q, dfs[N], a[N], c[N], sum, bid[N];
vector<int>g[N];
void s1(int x, int fa){
t[x].dep = t[fa].dep + 1;
t[x].fat = fa, t[x].siz = 1;
int mx = 0;
for(int to : g[x]){
if(to == fa) continue;
s1(to, x);
if(mx < t[to].siz){
mx = t[to].siz;
t[x].hvy = to;
}
t[x].siz += t[to].siz;
}
}
void s2(int x, int fa, int topx){
dfs[x] = ++sum, t[x].top = topx;
if(t[x].hvy != 0) s2(t[x].hvy, x, topx);
for(int to : g[x]){
if(to == fa || to == t[x].hvy) continue;
s2(to, x, to);
}
}
void renew(int id){
int s = 0, mx = Min;
for(int i = info[id].bn; i <= info[id].ed; ++i)
s += a[i], mx = max(mx, a[i]);
info[id].sum = s, info[id].Max = mx;
}
void update(int x, int w){
a[x] = w;
renew(bid[x]);
}
int query_sum(int l, int r){
int ret = 0;
if(bid[l] == bid[r]){
for(int i = l; i <= r; ++i) ret += a[i];
}else{
int i = l, j = r;
while(bid[i] == bid[l]){
ret += a[i], ++i;
}
while(bid[j] == bid[r]){
ret += a[j], --j;
}
for(int p = bid[i]; p <= bid[j]; ++p){
ret += info[p].sum;
}
}
return ret;
}
int query_max(int l, int r){
int ret = Min;
if(bid[l] == bid[r]){
for(int i = l; i <= r; ++i) ret = max(ret, a[i]);
}else{
int i = l, j = r;
while(bid[i] == bid[l]){
ret = max(ret, a[i]), ++i;
}
while(bid[j] == bid[r]){
ret = max(ret, a[j]), --j;
}
for(int p = bid[i]; p <= bid[j]; ++p){
ret = max(ret, info[p].Max);
}
}
return ret;
}
int solve_sum(int x, int y){
int ret = 0;
while(t[x].top != t[y].top){
bool flag = t[t[x].top].dep >= t[t[y].top].dep;
if(flag == 1){
ret += query_sum(dfs[t[x].top], dfs[x]);
x = t[t[x].top].fat;
}else{
ret += query_sum(dfs[t[y].top], dfs[y]);
y = t[t[y].top].fat;
}
}
if(t[x].dep > t[y].dep) swap(x, y);
return ret + query_sum(dfs[x], dfs[y]);
}
int solve_max(int x, int y){
int ret = Min;
while(t[x].top != t[y].top){
bool flag = t[t[x].top].dep >= t[t[y].top].dep;
if(flag == 1){
ret = max(ret, query_max(dfs[t[x].top], dfs[x]));
x = t[t[x].top].fat;
}else{
ret = max(ret, query_max(dfs[t[y].top], dfs[y]));
y = t[t[y].top].fat;
}
}
if(t[x].dep > t[y].dep) swap(x, y);
return max(ret, query_max(dfs[x], dfs[y]));
}
int main(){
ios :: sync_with_stdio(0), cin.tie(0);
cin >> n;
for(int i = 1, x, y; i < n; ++i){
cin >> x >> y;
g[x].push_back(y), g[y].push_back(x);
}
s1(1, 0), s2(1, 0, 1);
for(int i = 1; i <= n; cin >> a[i++]);
for(int i = 1; i <= n; ++i){
c[dfs[i]] = a[i];
bid[i] = i / B;
info[bid[i]].sum += a[i];
info[bid[i]].Max = max(info[bid[i]].Max, a[i]);
}
for(int i = 1; i <= n; ++i) a[i] = c[i];
for(int i = 0; i < B; ++i)
info[i].bn = i * B, info[i].ed = (i + 1) * B - 1;
cin >> q;
while(q--){
string op;
int u, v;
cin >> op >> u >> v;
if(op == "CHANGE"){
update(dfs[u], v);
}else if(op == "QMAX"){
cout << solve_max(u, v) << endl;
}else{
cout << solve_sum(u, v) << endl;
}
}
return 0;
}