#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,w[N],dep[N],son[N],siz[N],f[N],id[N],cnt,top[N],a[N];
int t[N<<2],lazt[N<<2],tl[N<<2],tr[N<<2];
vector<int> A[N];
void dfs1(int u,int fa){
dep[u]=dep[fa]+1;
siz[u]=1;f[u]=fa;
for(auto v:A[u]){
if(v!=fa){
dfs1(v,u);
siz[u]+=siz[v];
if(!son[u]||siz[son[u]]<siz[v])
son[u]=v;
}
}
}
void dfs2(int u,int topu){
id[u]=++cnt;
a[cnt]=w[u];
top[u]=topu;
if(!son[u])return ;
dfs2(son[u],topu);
for(auto v:A[u]){
if(v!=son[u]&&v!=f[u])
dfs2(v,v);
}
}
struct node{
int lx,rx,num;
};
int ls(int p){return p<<1;}
int rs(int p){return p<<1|1;}
void Push_up(int p){
if(tr[ls(p)]!=tl[rs(p)])
t[p]=t[ls(p)]+t[rs(p)];
else t[p]=t[ls(p)]+t[rs(p)]-1;
tl[p]=tl[ls(p)];tr[p]=tr[rs(p)];
}
void Build(int l,int r,int p){
if(l==r){
tl[p]=tr[p]=a[l];
t[p]=1;
return ;
}
int mid=(l+r)>>1;
Build(l,mid,ls(p));
Build(mid+1,r,rs(p));
Push_up(p);
}
void Push_down(int p){
if(!lazt[p])return ;
t[ls(p)]=t[rs(p)]=1;
tl[ls(p)]=tr[ls(p)]=tl[rs(p)]=tr[rs(p)]=lazt[p];
lazt[p]=0;
}
void Update(int l,int r,int x,int y,int p,int val){
if(x<=l&&r<=y){
t[p]=1;tl[p]=tr[p]=val;
lazt[p]=val;
return ;
}
Push_down(p);
int mid=(l+r)>>1;
if(x<=mid)Update(l,mid,x,y,ls(p),val);
if(y>mid)Update(mid+1,r,x,y,rs(p),val);
Push_up(p);
}
node Query(int l,int r,int x,int y,int p){
if(x<=l&&r<=y)
return node{tl[p],tr[p],t[p]};
int mid=(l+r)>>1;
Push_down(p);
if(x>mid)return Query(mid+1,r,x,y,rs(p));
if(y<=mid)return Query(l,mid,x,y,ls(p));
node L=Query(l,mid,x,y,ls(p)),R=Query(mid+1,r,x,y,rs(p));
node All;
if(L.rx!=R.lx)All.num=L.num+R.num;
else All.num=L.num+R.num-1;
All.lx=L.lx,All.rx=R.rx;
return All;
}
void Update_R(int x,int y,int z){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
Update(1,n,id[top[x]],id[x],1,z);
x=f[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
Update(1,n,id[x],id[y],1,z);
}
int Query_R(int x,int y){
int ans=0;int lsx=0,rsy=0;
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]){
node P=Query(1,n,id[top[x]],id[x],1);
ans+=P.num;
if(P.rx==lsx)ans--;
lsx=P.lx;
x=f[top[x]];
}
else{
node P=Query(1,n,id[top[y]],id[y],1);
ans+=P.num;
if(P.rx==rsy)ans--;
rsy=P.lx;
y=f[top[y]];
}
}
if(dep[x]<dep[y]){
node P=Query(1,n,id[x],id[y],1);
ans+=P.num;
if(P.rx==rsy)ans--;
if(P.lx==lsx)ans--;
}
else{
node P=Query(1,n,id[y],id[x],1);
ans+=P.num;
if(P.rx==lsx)ans--;
if(P.lx==rsy)ans--;
}
return ans;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>w[i];
for(int i=1,u,v;i<n;i++)
cin>>u>>v,A[u].push_back(v),A[v].push_back(u);
dfs1(1,0);dfs2(1,1);
Build(1,n,1);
while(m--){
char opt;
cin>>opt;
if(opt == 'C'){
int a1,b1,c1;
cin>>a1>>b1>>c1;
Update_R(a1,b1,c1);
}
else{
int a1,b1;
cin>>a1>>b1;
cout<<Query_R(a1,b1)<<endl;
}
}
return 0;
}