#include<bits/stdc++.h>
using namespace std;
int n,m,cnt=1,idx,lc,rc,w[114514],fa[114514],dep[114514],sz[114514],son[114514],dfn[114514],rk[114514],top[114514];
vector<int> g[114514];
struct node
{
int l,r,lc,rc,lcol,rcol,val,lazy;
}segt[400005];
struct Node
{
int val,lc,rc;
};
void pushup(int u)
{
segt[u].val=segt[segt[u].lc].val+segt[segt[u].rc].val;
if(segt[lc].rcol==segt[rc].lcol)segt[u].val--;
}
void pushcol(int u,int lz)
{
segt[u].lcol=segt[u].rcol=segt[u].lazy=lz;
segt[u].val=1;
}
void pushdown(int u)
{
if(segt[u].lazy)
{
if(segt[u].lc)pushcol(segt[u].lc,segt[u].lazy);
if(segt[u].rc)pushcol(segt[u].rc,segt[u].lazy);
segt[u].lazy=0;
}
}
void build(int u,int l,int r)
{
segt[u].l=l;
segt[u].r=r;
if(l==r)
{
segt[u].lcol=segt[u].rcol=w[l];
segt[u].val=1;
return;
}
int mid=l+r>>1;
segt[u].lc=++cnt;
build(cnt,l,mid);
segt[u].rc=++cnt;
build(cnt,mid+1,r);
pushup(u);
}
void update(int u,int l,int r,int w)
{
int L=segt[u].l,R=segt[u].r;
if(l<=L&&R<=r)
{
pushcol(u,w);
return;
}
pushdown(u);
int mid=L+R>>1;
if(l<=mid)update(segt[u].lc,l,r,w);
if(r> mid)update(segt[u].rc,l,r,w);
pushup(u);
}
int query(int u,int l,int r)
{
int L=segt[u].l,R=segt[u].r;
if(l<=L&&R<=r)
{
if(l==L)lc=segt[u].lcol;
if(r==R)rc=segt[u].rcol;
return segt[u].val;
}
pushdown(u);
int mid=L+R>>1;
if(r<=mid)return query(segt[u].lc,l,r);
if(l> mid)return query(segt[u].rc,l,r);
int res=query(segt[u].lc,l,r)+query(segt[u].rc,l,r);
if(segt[segt[u].lc].rcol==segt[segt[u].rc].lcol)res--;
return res;
}
void dfs1(int u,int f,int d)
{
fa[u]=f;
dep[u]=f;
sz[u]=1;
son[u]=0;
for(int v:g[u])
{
if(f==v)continue;
dfs1(v,u,d+1);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]])son[u]=v;
}
}
void dfs2(int u,int topfa)
{
dfn[u]=++idx;
rk[idx]=u;
top[u]=topfa;
if(!son[u])return;
dfs2(son[u],topfa);
for(int v:g[u])
{
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
void updata(int u,int v,int w)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])u^=v^=u^=v;
update(1,dfn[top[u]],dfn[u],w);
u=fa[top[u]];
}
if(dep[u]>dep[v])u^=v^=u^=v;
update(1,dfn[u],dfn[v],w);
}
int queri(int u,int v)
{
int ans1=0,ans2=0,res=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])
{
u^=v^=u^=v;
ans1^=ans2^=ans1^=ans2;
}
res+=query(1,dfn[top[u]],dfn[u]);
if(rc==ans1)res--;
ans1=lc;
u=fa[top[u]];
}
if(dep[u]>dep[v])
{
u^=v^=u^=v;
ans1^=ans2^=ans1^=ans2;
}
res+=query(1,dfn[u],dfn[v]);
if(lc==ans1)res--;
if(rc==ans2)res--;
return res;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>w[i];
build(1,1,n);
for(int i=1,u,v;i<n;i++)
{
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs1(1,0,1);
dfs2(1,1);
while(m--)
{
char op;
int a,b,c;
cin>>op>>a>>b;
if(op=='C')
{
cin>>c;
updata(a,b,c);
}
else cout<<queri(a,b)<<'\n';
}
return 0;
}