#include<iostream>
#include<cstdio>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
#include<cmath>
#include<ctime>
#include<bitset>
#include<deque>
#include<queue>
#include<functional>
#include<limits>
#include<sstream>
#include<string>
#include<cstring>
#include<utility>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#include<ext/pb_ds/trie_policy.hpp>
#include<ext/pb_ds/priority_queue.hpp>
#define int long long
#define db double
#define ls p<<1
#define rs p<<1|1
using namespace std;
template<typename T>
T &read(T &r){
r=0;bool w=0;char ch=getchar();
while(ch<'0'||ch>'9') w=ch=='-'?1:0,ch=getchar();
while(ch>='0'&&ch<='9') r=r*10+(ch^48),ch=getchar();
return r=w?-r:r;
}
const int N=3e4+10,inf=1e9;
int n,q,sm[N<<5],mx[N<<5],v[N];
int dep[N],top[N],f[N],dfn[N],son[N],siz[N],cnt,w[N];
vector<int> g[N];
void up(int p){
sm[p]=sm[ls]+sm[rs];
mx[p]=max(mx[ls],mx[rs]);
return ;
}
void build(int p,int l,int r){
if(l==r){
sm[p]=mx[p]=w[l];
return ;
}
int mid=l+r>>1;
build(ls,l,mid),build(rs,mid+1,r);
up(p);
}
void update(int p,int l,int r,int pos,int val){
if(l==r){
sm[p]=mx[p]=val;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) update(ls,l,mid,pos,val);
else update(rs,mid+1,r,pos,val);
up(p);
}
int query_max(int p,int l,int r,int L,int R){
if(L<=l&&r<=R){
return mx[p];
}
int mid=(l+r)>>1,res=-inf;
if(L<=mid) res=max(res,query_max(ls,l,mid,L,R));
if(R>mid) res=max(res,query_max(rs,mid+1,r,L,R));
return res;
}
int query_sum(int p,int l,int r,int L,int R){
if(L<=l&r<=R){
return sm[p];
}
int mid=l+r>>1,res=0;
if(L<=mid) res+=query_sum(ls,l,mid,L,R);
if(R>mid) res+=query_sum(rs,mid+1,r,L,R);
return res;
}
int qmax(int u,int v){
int ans=-inf;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans=max(ans,query_max(1,1,n,dfn[top[u]],dfn[u]));
u=f[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
ans=max(ans,query_max(1,1,n,dfn[u],dfn[v]));
return ans;
}
int qsum(int u,int v){
int ans=0;
while(top[u]!=top[v]){
if(dep[top[u]<dep[top[v]]]) swap(u,v);
ans+=query_sum(1,1,n,dfn[top[u]],dfn[u]);
u=f[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
ans+=query_sum(1,1,n,dfn[u],dfn[v]);
return ans;
}
void dfs1(int u,int fa){
siz[u]=1;
dep[u]=dep[fa]+1;
f[u]=fa;
for(auto v:g[u]){
if(v==fa) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]){
son[u]=v;
}
}
}
void dfs2(int u,int topf){
top[u]=topf;
dfn[u]=++cnt;
w[cnt]=v[u];
if(!son[u]) return ;
dfs2(son[u],topf);
for(auto v:g[u]){
if(v==f[u]||v==son[u]) continue;
dfs2(v,v);
}
}
signed main(){
read(n);
for(int i=1;i<=n-1;i++){
int a,b;
read(a),read(b);
g[a].push_back(b),g[b].push_back(a);
}
for(int i=1;i<=n;i++){
read(v[i]);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
read(q);
while(q--){
string s;
int u,v;
cin>>s>>u>>v;
if(s[1]=='M'){
printf("%lld\n",qmax(u,v));
}
else if(s[1]=='S'){
printf("%lld\n",qsum(u,v));
}
else{
update(1,1,n,dfn[u],v);
}
}
return 0;
}