#include "bits/stdc++.h"
using namespace std;
#define MAXN 100010
struct EDGE{
int Next,To;
}E[MAXN<<1];
int Head[MAXN<<1],Size;
inline void Add(int From,int To){
E[++Size].Next=Head[From];
Head[From]=Size;
E[Size].To=To;
return;
}
int Fa[MAXN],Tot[MAXN];
int Dep[MAXN],Son[MAXN];
inline void DFS1(int This,int F){
Fa[This]=F;
Tot[This]=1;
int MaxSon=0;
Dep[This]=Dep[F]+1;
for(register int i=Head[This];i;i=E[i].Next){
int To=E[i].To;
if(To==F)continue;
DFS1(To,This);
Tot[This]+=Tot[To];
if(MaxSon<Tot[To]){
MaxSon=Tot[To];
Son[This]=To;
}
}
return;
}
int A[MAXN],InPut[MAXN];
int ID[MAXN],Count,Top[MAXN];
inline void DFS2(int This,int Topf){
Top[This]=Topf;
ID[This]=(++Count);
InPut[Count]=A[This];
if(Son[This]==0)
return;
DFS2(Son[This],Topf);
for(register int i=Head[This];i;i=E[i].Next){
int To=E[i].To;
if(To==Fa[This]||To==Son[This])
continue;
DFS2(To,To);
}
return;
}
struct NPC{
struct SegmentTree{
int Right,Left;
int LC,RC,Sum;
bool Lazy;
}Tree[MAXN<<2];
inline int LeftSon(int i){return i<<1;}
inline int RightSon(int i){return i<<1|1;}
inline void PushUp(int i){
if(Tree[i].Left==Tree[i].Right)
return;
int L=LeftSon(i),R=RightSon(i);
Tree[i].Sum=Tree[L].Sum+Tree[R].Sum;
if(Tree[L].RC==Tree[R].LC)
Tree[i].Sum--;
Tree[i].LC=Tree[L].LC;
Tree[i].RC=Tree[R].RC;
return;
}
inline void Tree_Build(int i,int Left,int Right){
Tree[i].Left=Left;
Tree[i].Right=Right;
if(Left==Right){
Tree[i].LC=Tree[i].RC=InPut[Left];
Tree[i].Lazy=false;
Tree[i].Sum=1;
return;
}
int Mid=(Left+Right)>>1;
int L=LeftSon(i),R=RightSon(i);
Tree_Build(L,Left,Mid);
Tree_Build(R,Mid+1,Right);
PushUp(i);
return;
}
inline void PushDown(int i){
if(Tree[i].Lazy==false)
return;
if(Tree[i].Left==Tree[i].Right)
return;
int L=LeftSon(i),R=RightSon(i);
Tree[R].LC=Tree[R].RC=Tree[i].RC;
Tree[L].LC=Tree[L].RC=Tree[i].LC;
Tree[L].Lazy=Tree[R].Lazy=true;
Tree[L].Sum=Tree[R].Sum=1;
Tree[i].Lazy=false;
return;
}
inline void AddSeg(int i,int Left,int Right,int Add){
if(Tree[i].Left>Right||Left>Tree[i].Right)
return;
if(Left<=Tree[i].Left&&Tree[i].Right<=Right){
Tree[i].LC=Tree[i].RC=Add;
Tree[i].Lazy=true;
Tree[i].Sum=1;
return;
}
PushDown(i);
int L=LeftSon(i),R=RightSon(i);
if(Tree[L].Right>=Left)AddSeg(L,Left,Right,Add);
if(Tree[R].Left<=Right)AddSeg(R,Left,Right,Add);
PushUp(i);
return;
}
inline int SumSeg(int i,int Left,int Right){
if(Tree[i].Left>Right||Left>Tree[i].Right)
return 0;
if(Left<=Tree[i].Left&&Tree[i].Right<=Right)
return Tree[i].Sum;
PushDown(i);
int Sum=0,L=LeftSon(i),R=RightSon(i);
if(Tree[L].Right>=Left)Sum+=SumSeg(L,Left,Right);
if(Tree[R].Left<=Right)Sum+=SumSeg(R,Left,Right);
return Sum;
}
inline int SearchColor(int i,int W){
if(Tree[i].Left>W||W>Tree[i].Right)
return 0;
if(Tree[i].Left==Tree[i].Right)
return Tree[i].LC;
PushDown(i);
int Sum=0,L=LeftSon(i),R=RightSon(i);
if(Tree[L].Right>=W)Sum+=SearchColor(L,W);
if(Tree[R].Left<=W)Sum+=SearchColor(R,W);
return Sum;
}
}Do;
inline void AddTree(int X,int Y,int Z){
while(Top[X]!=Top[Y]){
if(Dep[Top[X]]<Dep[Top[Y]])
swap(X,Y);
Do.AddSeg(1,ID[Top[X]],ID[X],Z);
X=Fa[Top[X]];
}
if(Dep[X]>Dep[Y])
swap(X,Y);
Do.AddSeg(1,ID[X],ID[Y],Z);
return;
}
inline int SumTree(int X,int Y){
int Sum=0,XC=-1,YC=-1;
while(Top[X]!=Top[Y]){
if(Dep[Top[X]]<Dep[Top[Y]])
swap(X,Y),swap(XC,YC);
Sum+=Do.SumSeg(1,ID[Top[X]],ID[X]);
if(Do.SearchColor(1,ID[X])==XC)
Sum--;
XC=Do.SearchColor(1,ID[Top[X]]);
X=Fa[Top[X]];
}
if(Dep[X]>Dep[Y])
swap(X,Y),swap(XC,YC);
Sum+=Do.SumSeg(1,ID[X],ID[Y]);
if(Do.SearchColor(1,ID[X])==XC)
Sum--;
if(Do.SearchColor(1,ID[Y])==YC)
Sum--;
return Sum;
}
inline int Read(void){
int Y=1,X=0;char C=getchar();
while(C<'0'||C>'9'){if(C=='-'){Y=-1;}C=getchar();}
while('0'<=C&&C<='9'){X=X*10+(C-'0');C=getchar();}
return (X*Y);
}
char Type;
int N,M,X,Y,Z;
int main(void){
N=Read(),M=Read();
for(register int i=1;i<=N;i++)
A[i]=Read();
for(register int i=1;i<N;i++){
X=Read(),Y=Read();
Add(X,Y),Add(Y,X);
}
DFS1(1,0),DFS2(1,1);
Do.Tree_Build(1,1,N);
for(register int i=1;i<=M;i++){
Type=getchar();
if(Type=='C'){
X=Read(),Y=Read(),Z=Read();
AddTree(X,Y,Z);
}
if(Type=='Q'){
X=Read(),Y=Read();
printf("%d\n",SumTree(X,Y));
}
}
return 0;
}
救救孩子吧……