RT,救救可怜的 vicy 吧/kel
//xtwakioi! xtwddYnoi(双重含义)!
#include <bits/stdc++.h>
#define ri register
#define int long long
#define E (n+1)
using namespace std; const int N=100010;
inline int read()
{
int s=0, w=1; ri char ch=getchar();
while(ch<'0'||ch>'9') { if(ch=='-') w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48), ch=getchar();
return s*w;
}
int n,Q,siz[N],son[N],d[N],f[N],a[N],w[N],top[N],id[N],nowid;
int sum[N<<2][11],flag[N<<2],q[11],pw[N];
int head[N],maxE; struct Edge { int nxt,to,rdis; }e[N<<1];
inline void Add(int u,int v,int w) { e[++maxE].nxt=head[u]; head[u]=maxE; e[maxE].to=v; e[maxE].rdis=w; }
void DFS1(int x,int fa,int wv)
{
siz[x]=1, d[x]=d[fa]+1, f[x]=fa, a[x]=wv;
for(int i=head[x];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fa) continue;
DFS1(v,x,wv^e[i].rdis);
siz[x]+=siz[v];
if(siz[v]>siz[son[x]]) son[x]=v;
}
}
void DFS2(int x,int topf)
{
top[x]=topf, id[x]=++nowid, w[nowid]=a[x];
if(!son[x]) return;
DFS2(son[x],topf);
for(int i=head[x];i;i=e[i].nxt)
{
int v=e[i].to;
if((v^son[x]) && (v^f[x])) DFS2(v,v);
}
}
#define lc (x<<1)
#define rc (x<<1|1)
inline void Push_Up(int x)
{
for(ri int i=0;i<=10;i++) sum[x][i]=sum[lc][i]+sum[rc][i];
}
inline void Chg(int x,int l,int r,int k)
{
int qwq=k;
int now=0;
while(qwq)
{
if(qwq&1ll) sum[x][now]=r-l+1-sum[x][now];
now++, qwq>>=1ll;
}
flag[x]^=k;
}
inline void Push_Down(int x,int l,int r)
{
int mid=(l+r)/2;
Chg(lc,l,mid,flag[x]);
Chg(rc,mid+1,r,flag[x]);
flag[x]=0;
}
void Build(int x,int l,int r)
{
if(l==r)
{
int qwq=w[l];
int now=0;
while(qwq) sum[x][now]=(qwq&1ll), qwq>>=1ll, now++;
return;
}
int mid=(l+r)/2;
Build(lc,l,mid), Build(rc,mid+1,r);
Push_Up(x);
}
void UpDate(int u,int v,int l,int r,int x,int k)
{
if(l>=u&&r<=v)
{
int qwq=k;
int now=0;
while(qwq)
{
if(qwq&1ll) sum[x][now]=r-l+1-sum[x][now];
now++, qwq>>=1ll;
}
flag[x]^=k;
return;
}
int mid=(l+r)/2;
if(flag[x]) Push_Down(x,l,r);
if(u<=mid) UpDate(u,v,l,mid,lc,k);
if(v>mid) UpDate(u,v,mid+1,r,rc,k);
Push_Up(x);
}
void Ask(int u,int v,int l,int r,int x)
{
if(l>=u&&r<=v)
{
for(ri int i=0;i<=10;i++) q[i]+=sum[x][i];
return;
}
if(flag[x]) Push_Down(x,l,r);
int mid=(l+r)/2;
if(u<=mid) Ask(u,v,l,mid,lc);
if(v>mid) Ask(u,v,mid+1,r,rc);
Push_Up(x);
}
inline int LCA(int x,int y)
{
while(top[x]^top[y])
{
if(d[top[x]]<d[top[y]]) swap(x,y);
x=f[top[x]];
}
if(d[x]>d[y]) swap(x,y);
return x;
}
int Query(int x,int y)
{
int res=0;
int lca=LCA(x,y);
int num=d[x]+d[y]-d[lca]*2;
while(top[x]^top[y])
{
if(d[top[x]]<d[top[y]]) swap(x,y);
Ask(id[top[x]],id[x],1,n,1);
x=f[top[x]];
}
if(d[x]>d[y]) swap(x,y);
Ask(id[x],id[y],1,n,1);
for(ri int i=0;i<=10;i++) res+=q[i]*(num-q[i]+1)*pw[i];
return res;
}
#undef lc
#undef rc
signed main()
{
n=read(), Q=read();
pw[0]=1;
for(ri int i=1;i<=20;i++) pw[i]=pw[i-1]*2;
for(ri int i=1;i<n;i++)
{
int u,v,wv;
u=read(), v=read(), wv=read();
Add(u,v,wv), Add(v,u,wv);
}
DFS1(1,0,0), DFS2(1,1);
Build(1,1,n);
for(ri int i=1;i<=Q;i++)
{
int opt,u,v;
opt=read(), u=read(), v=read();
if(opt==1) memset(q,0,sizeof(q)), printf("%lld\n",Query(u,v));
else
{
int k=read();
if(f[u]==v)
{
int qwq=k^a[u]^a[v];
a[u]=a[v]^k;
UpDate(id[u],id[u]+siz[u]-1,1,n,1,qwq);
}
else if(f[v]==u)
{
int qwq=k^a[u]^a[v];
a[v]=a[u]^k;
UpDate(id[v],id[v]+siz[v]-1,1,n,1,qwq);
}
}
}
return 0;
}