#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m;
vector<int> tree[N];
int col[N];
int size[N];
int dep[N];
int fa[N];
int son[N];
int top[N];
int pos[N];
int new_id=0;
char opt;
struct SegementTreeNode
{
int l,r,num,tag;
int lc,rc;
}seg_tree[N<<2];
int Lc,Rc;
void dfs1(int u,int father,int depth)
{
size[u]=1;
fa[u]=father;
dep[u]=depth;
son[u]=0;
for(auto v:tree[u])
{
if(v==father) continue;
dfs1(v,u,depth+1);
size[u]+=size[v];
if(size[v]>size[son[u]])
son[u]=v;
}
}
void dfs2(int u,int top_node)
{
pos[u]=++new_id;
top[u]=top_node;
if(son[u]) dfs2(son[u],top_node);
for(auto v:tree[u])
{
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
void push_down(int u)
{
if(seg_tree[u].tag)
{
seg_tree[u<<1].tag=seg_tree[u].tag;
seg_tree[u<<1].num=1;
seg_tree[u<<1].lc = seg_tree[u<<1].rc = seg_tree[u].lc;
seg_tree[u<<1|1].tag=seg_tree[u].tag;
seg_tree[u<<1|1].num=1;
seg_tree[u<<1|1].lc = seg_tree[u<<1|1].rc = seg_tree[u].lc;
seg_tree[u].tag=0;
}
}
void push_up(int u)
{
seg_tree[u].lc=seg_tree[u<<1].lc;
seg_tree[u].rc=seg_tree[u<<1|1].rc;
seg_tree[u].num=seg_tree[u<<1].num+seg_tree[u<<1|1].num;
if(seg_tree[u<<1].rc==seg_tree[u<<1|1].lc) seg_tree[u].num--;
}
void build(int u,int l,int r)
{
seg_tree[u].l=l;
seg_tree[u].r=r;
seg_tree[u].num=seg_tree[u].tag=0;
if(l==r) return;
int mid=(l+r)>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
}
void update(int u,int l,int r,int color)
{
if(seg_tree[u].l==l&&seg_tree[u].r==r)
{
seg_tree[u].tag=1;
seg_tree[u].num=1;
seg_tree[u].lc=seg_tree[u].rc=color;
return;
}
push_down(u);
int mid=(seg_tree[u].l+seg_tree[u].r)>>1;
if(r<=mid) update(u<<1,l,r,color);
else if(l>mid) update(u<<1|1,l,r,color);
else update(u<<1,l,mid,color),update(u<<1|1,mid+1,r,color);
push_up(u);
}
int query(int u,int l,int r,int L,int R)
{
if(seg_tree[u].l==L) Lc=seg_tree[u].lc;
if(seg_tree[u].r==R) Rc=seg_tree[u].rc;
if(seg_tree[u].l==l&&seg_tree[u].r==r) return seg_tree[u].num;
int mid=(seg_tree[u].l+seg_tree[u].r)>>1;
if(r<=mid) return query(u<<1,l,r,L,R);
else if(l>mid) return query(u<<1|1,l,r,L,R);
else return (query(u<<1,l,mid,L,R)+query(u<<1|1,mid+1,r,L,R))-((seg_tree[u<<1].rc==seg_tree[u<<1|1].lc)? 1:0);
}
int path_operation(int u,int v,int type,int color=0)
{
int res=0;
int _=-1,__=-1;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])
{
swap(u,v);
if(type==2) swap(_,__);
}
if(type==1) update(1,pos[top[u]],pos[u],color);
else res+=query(1,pos[top[u]],pos[u],pos[top[u]],pos[u])-((Rc==_)? 1:0),_=Lc;
u=fa[top[u]];
}
if(dep[u]>dep[v])
{
swap(u,v);
if(type==2) swap(_,__);
}
if(type==1) update(1,pos[u],pos[v],color);
else res+=query(1,pos[u],pos[v],pos[u],pos[v])-((Lc==__)? 1:0)-((Rc==_)? 1:0);
return res;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>col[i];
for(int i=1,u,v;i<=n-1;i++)
{
cin>>u>>v;
tree[u].push_back(v);
tree[v].push_back(u);
}
dfs1(1,0,1);
dfs2(1,1);
build(1,1,n);
for(int i=1;i<=n;i++) update(1,pos[i],pos[i],col[i]);
while(m--)
{
cin>>opt;
if(opt=='C')
{
int u,v,c;
cin>>u>>v>>c;
path_operation(u,v,1,c);
}
else
{
int u,v;
cin>>u>>v;
cout<<path_operation(u,v,2)<<endl;
}
}
return 0;
}