#include <bits/stdc++.h>
#define int long long
using namespace std;
int read()
{
int x = 0, f = 1;
char ch = 0;
while(!isdigit(ch))
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(isdigit(ch))
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
const int N = 100000, Q = 500000, LG = 20, B = 100;
int n, q;
int a[N + 5], lsa[N + 5], fz[N + 5];
struct Edge
{
int v, nxt;
}edge[N * 2 + 5];
int head[N + 5], cnte;
void adde(int u, int v)
{
edge[++cnte] = {v, head[u]};
head[u] = cnte;
}
int dfn[N + 5], siz[N + 5], cntn;
int fa[N + 5][LG + 5], dep[N + 5];
int rk[N + 5];
void dfs(int u, int fath)
{
dep[u] = dep[fath] + 1;
dfn[u] = ++cntn;
siz[u] = 1;
rk[cntn] = u;
fa[u][0] = fath;
for(int i = 1; i <= LG; i++)
{
fa[u][i] = fa[fa[u][i - 1]][i - 1];
}
for(int i = head[u]; i; i = edge[i].nxt)
{
int v = edge[i].v;
if(v == fath)
{
continue;
}
dfs(v, u);
siz[u] += siz[v];
}
}
int LCA(int x, int y)
{
if(dep[x] < dep[y])
{
swap(x, y);
}
for(int i = LG; i >= 0; i--)
{
if(dep[fa[x][i] >= dep[y]])
{
x = fa[x][i];
}
}
if(x == y)
{
return x;
}
for(int i = LG; i >= 0; i--)
{
if(fa[x][i] != fa[y][i])
{
x = fa[x][i], y = fa[y][i];
}
}
return fa[x][0];
}
int get(int x, int y)
{
for(int i = LG; i >= 0; i--)
{
if(dep[fa[x][i]] > dep[y])
{
x = fa[x][i];
}
}
return x;
}
int ans[Q + 5];
bool is[Q + 5];
int get(int x)
{
return (x + B - 1) / B;
}
struct Qu
{
int r1, r2;
int ans, id, f;
bool operator < (const Qu &t) const
{
if(get(r1) != get(t.r1))
{
return get(r1) < get(t.r1);
}
if(get(r1) % 2)
{
return r2 < t.r2;
}
else
{
return r2 > t.r2;
}
}
}qu[Q * 4 + 5];
int cntqu;
int cur;
int cnt1[N + 5], cnt2[N + 5];
void add1(int x)
{
cur += cnt2[lsa[rk[x]]];
cnt1[lsa[rk[x]]]++;
}
void del1(int x)
{
cur -= cnt2[lsa[rk[x]]];
cnt1[lsa[rk[x]]]--;
}
void add2(int x)
{
cur += cnt1[lsa[rk[x]]];
cnt2[lsa[rk[x]]]++;
}
void del2(int x)
{
cur -= cnt1[lsa[rk[x]]];
cnt2[lsa[rk[x]]]--;
}
void mo()
{
int r1 = 0, r2 = 0;
for(int i = 1; i <= cntqu; i++)
{
while(r1 < qu[i].r1)
{
add1(++r1);
}
while(r2 < qu[i].r2)
{
add2(++r2);
}
while(r1 > qu[i].r1)
{
del1(r1--);
}
while(r2 > qu[i].r2)
{
del2(r2--);
}
ans[qu[i].id] += cur * qu[i].f;
// printf("%lld %lld %lld\n", qu[i].r1, qu[i].r2, cur);
}
}
void init()
{
n = read(), q = read();
for(int i = 1; i <= n; i++)
{
a[i] = read();
fz[i] = a[i];
}
sort(fz + 1, fz + n + 1);
for(int i = 1; i <= n; i++)
{
lsa[i] = lower_bound(fz + 1, fz + n + 1, a[i]) - fz;
}
for(int i = 1; i < n; i++)
{
int u = read(), v = read();
adde(u, v);
adde(v, u);
}
dfs(1, 0);
}
int tot[N + 5];
int awa;
int calca[N + 5];
int rt;
void solve()
{
// for(int i = 1; i <= n; i++)
// {
// printf("%lld ", lsa[i]);
// }
// printf("\n");
// for(int i = 1; i <= n; i++)
// {
// printf("%lld ", dfn[i]);
// }
// printf("\n");
for(int i = 1; i <= n; i++)
{
tot[lsa[i]]++;
}
for(int i = 1; i <= n; i++)
{
awa += tot[i] * tot[i];
}
for(int i = 1; i <= n; i++)
{
calca[i] = calca[i - 1] + tot[lsa[rk[i]]];
}
// for(int i = 1; i <= n; i++)
// {
// printf("%lld ", calca[i]);
// }
// printf("\n");
rt = 1;
for(int i = 1; i <= q; i++)
{
int op = read();
if(op == 1)
{
rt = read();
}
else
{
is[i] = 1;
int x = read(), y = read();
int lcax = LCA(x, rt), lcay = LCA(y, rt);
int lx, rx;
int f = 1;
int cnt = 0, tmp = 0;
if(x != rt)
{
if(lcax != x)
{
lx = dfn[x] - 1, rx = dfn[x] + siz[x] - 1;
}
else
{
int g = get(rt, x);
lx = dfn[g] - 1, rx = dfn[g] + siz[g] - 1;
f *= -1;
cnt++;
tmp = 1;
}
}
else
{
lx = 0, rx = n;
}
int ly, ry;
if(y != rt)
{
if(lcay != y)
{
ly = dfn[y] - 1, ry = dfn[y] + siz[y] - 1;
}
else
{
int g = get(rt, y);
ly = dfn[g] - 1, ry = dfn[g] + siz[g] - 1;
f *= -1;
cnt++;
tmp = 2;
}
}
else
{
ly = 0, ry = n;
}
if(cnt == 1)
{
if(tmp == 1)
{
ans[i] += calca[ry] - calca[ly];
}
else
{
ans[i] += calca[rx] - calca[lx];
}
}
else if(cnt == 2)
{
ans[i] -= calca[rx] - calca[lx];
ans[i] -= calca[ry] - calca[ly];
ans[i] += awa;
}
qu[++cntqu] = {lx, ly, 0, i, f};
qu[++cntqu] = {lx, ry, 0, i, -f};
qu[++cntqu] = {rx, ly, 0, i, -f};
qu[++cntqu] = {rx, ry, 0, i, f};
// printf("%lld %lld %lld %lld %lld\n", lx, rx, ly, ry, f);
}
}
sort(qu + 1, qu + cntqu + 1);
mo();
for(int i = 1; i <= q; i++)
{
if(is[i])
{
printf("%lld\n", ans[i]);
}
}
}
signed main()
{
// freopen("gen.out", "r", stdin);
// freopen("my.out", "w", stdout);
init();
solve();
return 0;
}//
awaqwq