const int MAXN=1e5+5;
struct Edge{
int to,next;
}edge[MAXN<<1];
int head[MAXN],edge_cnt;
void Insert(int u,int v){
edge[++edge_cnt]=Edge{v,head[u]};
head[u]=edge_cnt;
}
namespace LCA{
int d[MAXN],sz[MAXN],f[MAXN],dfn[MAXN],node_id[MAXN],dfs_t;
int h_son[MAXN],mson[MAXN],p[MAXN];
void dfs_1(int u,int fa,int depth){
dfn[u]=++dfs_t;sz[u]=1;f[u]=fa;d[u]=depth;mson[u]=0;node_id[dfs_t]=u;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fa)
continue;
dfs_1(v,u,depth+1);
sz[u]+=sz[v];
if(sz[v]>mson[u])
h_son[u]=v,mson[u]=sz[v];
}
}
void dfs_2(int u,int top){
p[u]=top;
if(mson[u])dfs_2(h_son[u],top);
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==f[u]||v==h_son[u])
continue;
dfs_2(v,v);
}
}
void init(int root){dfs_1(root,0,0);dfs_2(root,root);}
int query_lca(int u,int v){
while(p[u]!=p[v]){
if(d[p[u]]<d[p[v]])swap(u,v);
u=f[p[u]];
}
return d[u]<d[v]?u:v;
}
int query_dis(int u,int v){
u=node_id[u],v=node_id[v];
return d[u]+d[v]-2*d[query_lca(u,v)];
}
};
typedef set<int>::iterator iter;
set<int>s[MAXN];
int c[MAXN];
LL ans[MAXN];
void del(int c,int u){
iter it=s[c].find(u);
int l=0,r=0;
if(++it!=s[c].end())
r=*it;
if(--it!=s[c].begin())
l=*(--it);
if(l&&r)ans[c]+=LCA::query_dis(l,r);
if(l)ans[c]-=LCA::query_dis(l,u);
if(r)ans[c]-=LCA::query_dis(u,r);
s[c].erase(u);
}
void add(int c,int u){
s[c].insert(u);
iter it=s[c].find(u);
int l=0,r=0;
if(++it!=s[c].end())
r=*it;
if(--it!=s[c].begin())
l=*(--it);
if(l&&r)ans[c]-=LCA::query_dis(l,r);
if(l)ans[c]+=LCA::query_dis(l,u);
if(r)ans[c]+=LCA::query_dis(u,r);
}
int main()
{
int n=read_int();
_for(i,1,n){
int u=read_int(),v=read_int();
Insert(u,v);Insert(v,u);
}
LCA::init(1);
_rep(i,1,n){
c[i]=read_int();
add(c[i],LCA::dfn[i]);
}
int q=read_int();
while(q--){
char opt=get_char();
if(opt=='Q'){
int v=read_int();
if(s[v].empty())
enter(-1);
else
enter((ans[v]+LCA::query_dis(*s[v].begin(),*(--s[v].end())))/2);
}
else{
int u=read_int(),v=read_int();
del(c[u],LCA::dfn[u]);
add(v,LCA::dfn[u]);
c[u]=v;
}
}
return 0;
}