#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
struct node
{
int top,fa,dep,sz,son,id,sum;
}a[N];
struct G
{
int to,next,val;
}g[N*2];
struct Segment_Tree
{
int l,r,sum,lazy,lc,rc;
}tree[N*4];
struct ans
{
int lc,rc,sum;
};
int n,top,head[N*2],num,sum[N];
void add(int u,int v)
{
g[++top]={v,head[u]};
head[u]=top;
}
void DFS1(int u,int fa)
{
a[u].fa=fa;
a[u].dep=a[fa].dep+1;
a[u].sz=1;
for(int i=head[u];i;i=g[i].next)
{
if(g[i].to==fa)continue;
DFS1(g[i].to,u);
a[u].sz+=a[g[i].to].sz;
if(a[g[i].to].sz>a[a[u].son].sz)a[u].son=g[i].to;
}
}
void DFS2(int u,int topx)
{
a[u].id=++num;
a[u].top=topx;
sum[num]=a[u].sum;
if(!a[u].son)return;
DFS2(a[u].son,topx);
for(int i=head[u];i;i=g[i].next)
{
if(g[i].to==a[u].fa||g[i].to==a[u].son)continue;
DFS2(g[i].to,g[i].to);
}
}
void push_up(int id)
{
tree[id].sum=tree[id*2].sum+tree[id*2+1].sum-(tree[id*2].lc==tree[id*2+1].rc);
tree[id].lc=tree[id*2].lc;
tree[id].rc=tree[id*2+1].rc;
}
void push_down(int id)
{
if(tree[id].lazy==0)return;
tree[id*2].lazy=tree[id*2+1].lazy=tree[id].lazy;
tree[id*2].sum=tree[id*2+1].sum=1;
tree[id*2].lc=tree[id*2].rc=tree[id*2+1].lc=tree[id*2+1].rc=tree[id].lazy;
tree[id].lazy=0;
}
void update(int id,int l,int r,int k)
{
if(tree[id].l>r||tree[id].r<l)return;
if(tree[id].l>=l&&tree[id].r<=r)
{
tree[id].sum=1;
tree[id].lc=tree[id].rc=k;
tree[id].lazy=k;
return;
}
push_down(id);
update(id*2,l,r,k);
update(id*2+1,l,r,k);
push_up(id);
}
ans query(int id,int l,int r)
{
if(tree[id].l>=l&&tree[id].r<=r)return {tree[id].lc,tree[id].rc,tree[id].sum};
push_down(id);
int mid=tree[id].l+tree[id].r>>1;
if(r<=mid)return query(id*2,l,r);
else if(l>mid)return query(id*2+1,l,r);
ans ans1=query(id*2,l,r),ans2=query(id*2+1,l,r);
return {ans1.lc,ans2.rc,ans1.sum+ans2.sum-(ans1.rc==ans2.lc)};
}
void build(int id,int l,int r)
{
tree[id].l=l;
tree[id].r=r;
if(l==r)
{
tree[id].lc=tree[id].rc=sum[l];
tree[id].sum=1;
return;
}
int mid=l+r>>1;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
push_up(id);
}
void update_range(int x,int y,int z)
{
while(a[x].top!=a[y].top)
{
if(a[a[x].top].dep<a[a[y].top].dep)swap(x,y);
update(1,a[a[x].top].id,a[x].id,z);
x=a[a[x].top].fa;
}
if(a[x].dep>a[y].dep)swap(x,y);
update(1,a[x].id,a[y].id,z);
}
int query_range(int x,int y)
{
int res=0,c1=0,c2=0;
ans sum;
while(a[x].top!=a[y].top)
{
if(a[a[x].top].dep<a[a[y].top].dep)
{
swap(x,y);
swap(c1,c2);
}
sum=query(1,a[a[y].top].id,a[y].id);
res+=sum.sum-(sum.rc==c1);
c1=sum.lc;
x=a[a[x].top].fa;
}
if(a[x].dep>a[y].dep)swap(x,y);
sum=query(1,a[x].id,a[y].id);
return res-(sum.rc==c1)-(sum.lc==c2)+sum.sum;
}
signed main()
{
int Q;
cin>>n>>Q;
for(int i=1;i<=n;i++)
{
cin>>a[i].sum;
}
for(int i=1,u,v;i<n;i++)
{
cin>>u>>v;
add(u,v);
add(v,u);
}
DFS1(1,0);
DFS2(1,1);
build(1,1,n);
while(Q--)
{
char op;
int x,y,k;
cin>>op>>x>>y;
if(op=='Q')cout<<query_range(x,y)<<"\n";
else
{
cin>>k;
update_range(x,y,k);
}
}
return 0;
}