rt
#include <bits/stdc++.h>
using namespace std;
#define lson x<<1
#define rson x<<1|1
struct Tree{
int clo,cro,cnt,b;
}tree[400010];
char s[10];
int tim,n,m,x,y,col,top[100010],cll[100010],w[100010],dfn[100010],siz[100010],son[100010],dep[100010],fat[100010];
vector<int> ed[100010];
void dfs1(int x){
int len=ed[x].size(),heavyson=-1;
dep[x]=dep[fat[x]]+1;siz[x]=1;
for(int i=0;i<len;i++){
int v=ed[x][i];
if(v==fat[x]) continue;
fat[v]=x;
dfs1(v);
siz[x]+=siz[v];
if(heavyson<siz[v]){
son[x]=v;
heavyson=siz[v];
}
}
}
void dfs2(int x,int t){
int len=ed[x].size();
dfn[x]=++tim;
w[tim]=cll[x];
top[x]=t;
if(son[x]) dfs2(son[x],t);
for(int i=0;i<len;i++){
int v=ed[x][i];
if(v==fat[x]||v==son[x]) continue;
dfs2(v,v);
}
}
void pushup(int x,int l,int r,int mid){
tree[lson].clo=tree[lson].cro=tree[rson].clo=tree[rson].cro=tree[x].b;
tree[lson].cnt=tree[rson].cnt=1;
tree[lson].b=tree[rson].b=tree[x].b;
tree[x].b=0;
}
void build_tree(int x,int l,int r){
if(l==r){
tree[x].clo=tree[x].cro=w[l];
tree[x].cnt=1;
return;
}
int mid=(l+r)>>1;
build_tree(lson,l,mid);
build_tree(rson,mid+1,r);
tree[x].cnt=tree[lson].cnt+tree[rson].cnt-(tree[lson].cro==tree[rson].clo);
tree[x].clo=tree[lson].clo;tree[x].cro=tree[rson].cro;
}
void update(int x,int l,int r,int cl,int cr,int d){
if(cl<=l&&r<=cr){
tree[x].cro=tree[x].clo=d;
tree[x].cnt=1;tree[x].b=d;
return;
}
int mid=(l+r)>>1;
if(tree[x].b) pushup(x,l,r,mid);
if(mid>=cl) update(lson,l,mid,cl,cr,d);
if(mid<cr) update(rson,mid+1,r,cl,cr,d);
tree[x].clo=tree[lson].clo;tree[x].cro=tree[rson].cro;
tree[x].cnt=tree[lson].cnt+tree[rson].cnt-(tree[lson].cro==tree[rson].clo);
}
Tree query(int x,int l,int r,int cl,int cr){
if(cl<=l&&r<=cr) return tree[x];
int mid=(l+r)>>1;
if(tree[x].b) pushup(x,l,r,mid);
Tree res={-1,-1,-1,-1};
if(mid>=cl) res=query(lson,l,mid,cl,cr);
if(mid<cr){
Tree ces=query(rson,mid+1,r,cl,cr);
if(res.b==-1) res=ces;
else{
res.cnt+=ces.cnt-(res.cro==ces.clo);
res.cro=ces.cro;
}
}
return res;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&cll[i]);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
ed[x].push_back(y);
ed[y].push_back(x);
}
dfs1(1);
dfs2(1,1);
build_tree(1,1,n);
while(m--){
scanf("%s%d%d",s+1,&x,&y);
if(s[1]=='C'){
scanf("%d",&col);
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(1,1,n,dfn[x],dfn[top[x]],col);
x=fat[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
update(1,1,n,dfn[y],dfn[x],col);
}else{
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
Tree c1=query(1,1,n,dfn[top[x]],dfn[x]);
ans+=c1.cnt;
x=fat[top[x]];
Tree c2=query(1,1,n,dfn[x],dfn[x]);
ans-=(c1.clo==c2.cro);
}
if(dep[x]<dep[y]) swap(x,y);
Tree c=query(1,1,n,dfn[y],dfn[x]);
ans+=c.cnt;
printf("%d\n",ans);
}
}
return 0;
}