#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pb push_back
#define pii pair<ll,ll>
#define fi first
#define se second
#define il inline
#define fastio ios::sync_with_stdio(false), cin.tie(0)
const int N = 1e5+5;
const int M = 5e5+5;
char *p1,*p2,buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
il ll read()
{
ll x=0,f=1; char ch=nc();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=nc(); }
while(ch>=48&&ch<=57) x=x*10+ch-48,ch=nc();
return x*f;
}
ll head[N],tlt,n,m,nn,nnn,bel[N],len,fa[N][25],dep[N],a[N],dfn[N],rnk[N],siz[N],b[N],num[N],ans[M],T;
ll DFN_CLOCK,L=0,R=0;
ll res, cnt[3][N];
struct Edge{
ll to,nxt;
} E[2*N];
il void addedge(ll u, ll v){
E[++tlt].to = v;
E[tlt].nxt = head[u];
head[u] = tlt; return ;
}
struct Ask{
ll l,r,idx;
} q[10*M];
il bool CMP(Ask &ask1, Ask &ask2){
if(bel[ask1.l] == bel[ask2.l]) return ask1.r < ask2.r;
return ask1.l < ask2.l;
}
il void predfs(ll u, ll pre){
dep[u] = dep[pre]+1, fa[u][0] = pre; dfn[u] = ++DFN_CLOCK; rnk[DFN_CLOCK] = u;
siz[u]=1;
for(int i=1; i<=24; i++) fa[u][i] = fa[fa[u][i-1]][i-1];
for(int i=head[u]; i; i=E[i].nxt){
if(E[i].to == pre) continue;
predfs(E[i].to, u);
siz[u] += siz[E[i].to];
} return ;
}
il ll getKthfa(ll u, ll k){
for(int i=24; i>=0; i--) if((k>>i)&1) u = fa[u][i];
return u;
}
il void init(){
len = sqrt(n);
for(int i=1; i<=n; i++) bel[i]=(i+len-1)/len;
for(int i=1; i<=nn; i++) if(q[i].l > q[i].r) swap(q[i].l, q[i].r);
sort(q+1, q+nn+1, CMP);
sort(b+1, b+n+1);
nnn = unique(b+1, b+n+1) - b - 1;
for(int i=1; i<=n; i++) num[dfn[i]] = lower_bound(b+1, b+nnn+1, a[i]) - b;
return ;
}
il void AddSplit(pii segl, pii segr, ll idx){
q[++nn] = (Ask){segl.se, segr.se, idx};
q[++nn] = (Ask){segl.fi-1, segr.se, -idx};
q[++nn] = (Ask){segl.se, segr.fi-1, -idx};
q[++nn] = (Ask){segl.fi-1, segr.fi-1, idx};
return ;
}
il void addask(ll u, ll v, ll rt, ll idx){
vector<pii> lques,rques;
ll tu=getKthfa(rt,abs(dep[rt]-dep[u])), tv=getKthfa(v,abs(dep[rt]-dep[v]));
if(u==rt) lques.pb({1,n});
else if(tu==u){
ll uson=getKthfa(rt,abs(dep[rt]-dep[u]-1));
if(dfn[uson]-1>=1) lques.pb({1,dfn[uson]-1});
if(dfn[uson]+siz[uson]<=n) lques.pb({dfn[uson]+siz[uson], n});
}
else lques.pb({dfn[u], dfn[u]+siz[u]-1});
if(v==rt) rques.pb({1,n});
else if(tv==v){
ll vson=getKthfa(rt,abs(dep[rt]-dep[v]-1));
if(dfn[vson]-1>=1) rques.pb({1,dfn[vson]-1});
if(dfn[vson]+siz[vson]<=n) rques.pb({dfn[vson]+siz[vson], n});
}
else rques.pb({dfn[v], dfn[v]+siz[v]-1});
for(pii segl : lques) for(pii segr : rques) AddSplit(segl, segr, idx);
return ;
}
il void Add(ll val, ll pot){
res -= cnt[1][val]*cnt[2][val];
cnt[pot][val]++;
res += cnt[1][val]*cnt[2][val];
return ;
}
il void Del(ll val, ll pot){
res -= cnt[1][val]*cnt[2][val];
cnt[pot][val]--;
res += cnt[1][val]*cnt[2][val];
return ;
}
signed main(){
fastio;
n=read(),m=read();
for(int i=1; i<=n; i++) a[i]=read(),b[i]=a[i];
for(int i=2,u,v; i<=n; i++){
u=read(),v=read();
addedge(u,v), addedge(v,u);
}
predfs(1,0);
for(int i=1,rt=1,opt,u,v; i<=m; i++){
opt=read();
if(opt==1) rt = read();
else if(opt==2){
u=read(),v=read();
addask(u, v, rt, ++T);
}
}
init();
for(int i=1; i<=nn; i++){
while(L<q[i].l) Add(num[++L], 1);
while(L>q[i].l) Del(num[L--], 1);
while(R<q[i].r) Add(num[++R], 2);
while(R>q[i].r) Del(num[R--], 2);
ans[abs(q[i].idx)] += res * (q[i].idx / abs(q[i].idx));
}
for(int i=1; i<=T; i++) printf("%lld\n", ans[i]);
return 0;
}