1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=1e6+5,inf=0x3f3f3f3f;
4 int next[2*N],head[2*N],to[N*2],d[N],fa[N],v[2*N],seg[4*N],rev[4*N],top[N],size[N],son[N],w[N];
5 int n;
6 int m,q,p,tot,cnt;
7 int sum,ma;
8 struct node{
9 int lc,rc,sum,col;
10 }tree[N];
11 void ADD(int k,int l,int r,int v)
12 {
13 tree[k].lc=tree[k].rc=v;
14 tree[k].sum=1;
15 tree[k].col=v;
16 return ;
17 }
18 void pushdown(int k,int l,int r,int mid)
19 {
20 if(!tree[k].col)return ;
21 ADD(k<<1,l,mid,tree[k].col);
22 ADD(k<<1|1,mid+1,r,tree[k].col);
23 tree[k].col=0;
24 }
25 void dfs1(int s,int ff)
26 {
27 size[s]=1;d[s]=d[ff]+1;fa[s]=ff;
28 for(int i=head[s],t;i,t=to[i];i=next[i])
29 {
30 if(t!=fa[s])
31 {
32 dfs1(t,s);
33 size[s]+=size[t];
34 if(size[t]>size[son[s]])son[s]=t;
35 }
36 }
37 }
38 void dfs2(int s)
39 {
40 if(son[s])
41 {
42 seg[son[s]]=++seg[0];
43 top[son[s]]=top[s];
44 rev[seg[0]]=son[s];
45 dfs2(son[s]);
46 }
47 for(int i=head[s],t;t=to[i],i;i=next[i])
48 {
49 if(!top[t])
50 {
51 seg[t]=++seg[0];
52 rev[seg[0]]=t;
53 top[t]=t;
54 dfs2(t);
55 }
56 }
57 }
58 void update(int k)
59 {
60 tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
61 if(tree[k<<1].rc==tree[k<<1|1].lc)tree[k].sum--;
62 tree[k].lc=tree[k<<1].lc;
63 tree[k].rc=tree[k<<1|1].rc;
64 }
65 void build(int k,int l,int r)
66 {
67 if(l==r)
68 {
69 tree[k].lc=tree[k].rc=w[rev[l]];
70 tree[k].sum=1;
71 return ;
72 }
73 int mid=l+r>>1;
74 build(k<<1,l,mid);
75 build(k<<1|1,mid+1,r);
76 update(k);
77 }
78 node query2(int k,int l,int r,int x,int y)
79 {
80 if(l>=x&&r<=y)
81 {
82 return tree[k];
83 }
84 int mid=l+r>>1;
85 pushdown(k,l,r,mid);
86 if(mid>=x)
87 {
88 if(mid<y)
89 {
90 node res,ll=query2(k<<1,l,mid,x,y),rr=query2(k<<1|1,mid+1,r,x,y);
91 res.sum=ll.sum+rr.sum+(ll.rc==rr.lc?-1:0);
92 res.lc=ll.lc;res.rc=rr.rc;
93 return res;
94 }
95 else return query2(k<<1,l,mid,x,y);
96 }
97 else return query2(k<<1|1,mid+1,r,x,y);
98 }
99 int query1(int x,int y)
100 {
101 //这里可能不是很好理解,但是把a、b当做现任和备胎可能会好想一些(机房大佬lhy指点)
102 int sum=0,a=0,b=0;
103 int fx=top[x],fy=top[y];
104 while(fx!=fy)
105 {
106 if(d[fx]<d[fy])swap(x,y),swap(fx,fy),swap(a,b);
107 node res=query2(1,1,n,seg[fx],seg[x]);
108 sum+=res.sum;
109 if(res.rc==a)sum--;
110 a=res.lc;
111 x=fa[fx];fx=top[x];
112 }
113 if(d[x]>d[y])swap(x,y),swap(a,b);
114 node res=query2(1,1,n,seg[x],seg[y]);
115 sum+=res.sum;
116 if(res.lc==a) sum--;
117 if(res.rc==b) sum--;
118 return sum;
119 }
120 int read()
121 {
122 int f=1;char ch;
123 while((ch=getchar())<'0'||ch>'9')
124 if(ch=='-')f=-1;
125 int res=ch-'0';
126 while((ch=getchar())>='0'&&ch<='9')
127 res=res*10+ch-'0';
128 return res*f;
129 }
130 void write(int x)
131 {
132 if(x<0)
133 {
134 putchar('-');
135 x=-x;
136 }
137 if(x>9)write(x/10);
138 putchar(x%10+'0');
139 }
140 void add(int x,int y)
141 {
142 next[++tot]=head[x];
143 head[x]=tot;
144 to[tot]=y;
145 }
146 void change2(int k,int l,int r,int x,int y,int v)
147 {
148 if(l>=x&&r<=y)return ADD(k,l,r,v);
149 int mid=l+r>>1;
150 pushdown(k,l,r,mid);
151 if(mid>=x)change2(k<<1,l,mid,x,y,v);
152 if(mid<y)change2(k<<1|1,mid+1,r,x,y,v);
153 update(k);
154 }
155 void change1(int x,int y,int v)
156 {
157 int fx=top[x],fy=top[y];
158 while(fx!=fy)
159 {
160 if(d[fx]<d[fy])swap(x,y),swap(fx,fy);
161 change2(1,1,n,seg[fx],seg[x],v);
162 x=fa[fx];fx=top[x];
163 }
164 if(d[x]>d[y])swap(x,y);
165 change2(1,1,n,seg[x],seg[y],v);
166 }
167 int main()
168 {
169 n=read();m=read();
170 for(int i=1;i<=n;i++)w[i]=read();
171 for(int i=1;i<n;i++)
172 {
173 int x,y;
174 x=read();y=read();
175 add(x,y);add(y,x);
176 }
177 dfs1(1,0);
178 seg[0]=top[1]=rev[1]=seg[1]=1;
179 dfs2(1);
180 build(1,1,n);
181 while(m--)
182 {
183 char ch;int a,b;
184 while((ch=getchar())<'A'||ch>'Z');
185 //这个地方读入一定要小心!我的爆零经验就是前车之鉴!!!
186 a=read();b=read();
187 if(ch=='C')
188 {
189 int c;c=read();
190 change1(a,b,c);
191 }
192 else
193 {
194 write(query1(a,b));
195 putchar('\n');
196 }
197 }
198 return 0;
199 }
200 //硬生生凑个200行 ~(~ ̄▽ ̄)~