#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#define ll long long
using namespace std;
const int N=1e5+5;
int n,Q,sign,lc,rc;
int a[N],w[N];
int prt[N],dep[N],sz[N],son[N];
int top[N],pos[N];
char op;
vector<int>v[N];
void dfs1(int x){
sz[x]=1;
for(auto y:v[x]){
if(y==prt[x])continue;
dep[y]=dep[x]+1;
prt[y]=x;
dfs1(y);
sz[x]+=sz[y];
if(sz[y]>sz[son[x]])son[x]=y;
}
}
void dfs2(int x,int f){
top[x]=f;
pos[x]=++sign;
w[sign]=a[x];
if(!son[x])return ;
dfs2(son[x],f);
for(auto y:v[x]){
if(y!=prt[x]&&y!=son[x])
dfs2(y,y);
}
}
struct Segment_Tree{
#define mid (l+r>>1)
#define Ls x<<1,l,mid
#define Rs x<<1|1,mid+1,r
int t[N<<2],add[N<<2],lo[N<<2],ro[N<<2];
void push_up(int x){
t[x]=t[x<<1]+t[x<<1|1]-(lo[x<<1|1]==ro[x<<1]);
lo[x]=lo[x<<1];
ro[x]=ro[x<<1|1];
}
void push_down(int x){
if(add[x]){
t[x<<1]=t[x<<1|1]=1;
lo[x<<1]=lo[x<<1|1]=ro[x<<1]=ro[x<<1|1]=add[x];
add[x<<1]=add[x<<1|1]=add[x];
add[x]=0;
}
}
void build(int x,int l,int r){
if(l==r){
t[x]=1;
lo[x]=ro[x]=w[l];
return ;
}
build(Ls);
build(Rs);
push_up(x);
}
void upd(int x,int l,int r,int L,int R,int val){
if(l>=L&&r<=R){
t[x]=1;
add[x]=lo[x]=ro[x]=val;
return ;
}
push_down(x);
if(L<=mid)upd(Ls,L,R,val);
if(R>mid)upd(Rs,L,R,val);
push_up(x);
}
int ask(int x,int l,int r,int L,int R){
if(l>=L&&r<=R){
if(l==L)lc=lo[x];
if(r==R)rc=ro[x];
return t[x];
}
push_down(x);
// int ans=0;
// if(L<=mid)ans+=ask(Ls,L,R);
// if(R>mid)ans+=ask(Rs,L,R);
// push_up(x);
// return ans;
if(R<=mid)return ask(Ls,L,R);
if(L>mid)return ask(Rs,L,R);
int ans=ask(Ls,L,R)+ask(Rs,L,R);
if(lo[x<<1|1]==ro[x<<1])ans--;
return ans;
}
}seg;
inline void Upd(int x,int y,int val){
int fx=top[x],fy=top[y];
while(fx!=fy){
if(dep[fx]<dep[fy])
swap(x,y),swap(fx,fy);
seg.upd(1,1,n,pos[fx],pos[x],val);
x=prt[fx],fx=top[x];
}
if(dep[x]>dep[y])swap(x,y);
seg.upd(1,1,n,pos[x],pos[y],val);
}
inline int Ask(int x,int y){
int fx=top[x],fy=top[y],px=0,py=0,ans=0;
while(fx!=fy){
if(dep[fx]<dep[fy])
swap(x,y),swap(fx,fy),swap(px,py);
ans+=seg.ask(1,1,n,pos[fx],pos[x]);
ans-=(rc==px);
x=prt[fx],fx=top[x],px=lc;
}
if(dep[x]>dep[y])swap(x,y);
ans+=seg.ask(1,1,n,pos[x],pos[y]);
ans-=((rc==px)+(lc==py));
return ans;
}
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
scanf("%d%d",&n,&Q);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1,x,y;i<=n-1;i++){
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
dfs1(1);
dfs2(1,1);
seg.build(1,1,n);
for(int x,y,z;Q--;){
scanf("\n%c %d %d",&op,&x,&y);
if(op=='Q')printf("%d\n",Ask(x,y));
else scanf("%d",&z),Upd(x,y,z);
}
return 0;
}
/*
lemon龙保佑我
6 3
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
Q 1 2
Q 4 5
*/