#include <cstdio>
#include <vector>
#define ll long long
using namespace std;
namespace fIO{
char c;bool f;void re(int &x){
x=0;f=0;c=getchar();
while(c<'0'||c>'9') f|=c=='-',c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
}
char st[20];int tp;
void wr(ll n){
//printf("%lld",n);return ;
if(!n) return putchar('0'),void();
while(n) st[++tp]=n%10+48,n/=10;
while(tp) putchar(st[tp--]);
}
}using fIO::re;using fIO::wr;
const int N=2e5+02.31,mod=1<<30;
int rtL[N],rtR[N],idf[N],fa[N],dep[N],totL,totR,n;ll dis[N];
int dec(int x,int y){return dep[x]<dep[y]?x:y;}
class sgt{public:
struct node{
int cnt,rmq;ll R,L;int ls,rs;
#define cnt(x) t[x].cnt
#define rmq(x) t[x].rmq
#define dep(x) dep[t[x].rmq]
#define R(x) t[x].R
#define L(x) t[x].L
#define ls(x) t[x].ls
#define rs(x) t[x].rs
}t[N*59];
int cnp,&tot;ll res;
sgt(int& to):tot(to){}
void bound_right(int now,int ln,int rn,int x){
//printf("bound in %d %d %d %d\n",now,ln,rn,x);
if(ln==rn) return dep(now)<=x?res+=R(now):(ll)(cnp+=cnt(now)),void();
int mid=ln+rn>>1;
if(dep(ls(now))<=x) res+=R(now)-R(ls(now)),bound_right(ls(now),ln,mid,x);
else cnp+=cnt(ls(now)),bound_right(rs(now),mid+1,rn,x);
}
node push_right(node a,int x,int l,int r){
res=cnp=0;bound_right(x,l,r,dep[a.rmq]);
//printf("c r %d %lld\n",cnp,res);
return (node){a.cnt+cnt(x),dec(a.rmq,rmq(x)),
a.R+1ll*dis[fa[a.rmq]]*cnp+res,a.L};
}
void bound_left(int now,int ln,int rn,int x){
if(ln==rn) return dep(now)<=x?res+=L(now):(ll)(cnp+=cnt(now)),void();
int mid=ln+rn>>1;
if(dep(rs(now))<=x) res+=L(now)-L(rs(now)),bound_left(rs(now),mid+1,rn,x);
else cnp+=cnt(rs(now)),bound_left(ls(now),ln,mid,x);
}
node push_left(node a,int x,int l,int r){
//printf("push %d %d %lld with %d %d %lld\n",a.cnt,a.rmq,a.L,cnt(x),rmq(x),L(x));
res=cnp=0;bound_left(x,l,r,dep[a.rmq]);
//printf("c r %d %lld\n",cnp,res);
return (node){a.cnt+cnt(x),dec(a.rmq,rmq(x)),
a.R,a.L+1ll*dis[fa[a.rmq]]*cnp+res};
}
void build(int now,int ln,int rn){
if(ln==rn) return rmq(now)=idf[ln],void();
int mid=ln+rn>>1;
build(ls(now)=++tot,ln,mid);
build(rs(now)=++tot,mid+1,rn);
rmq(now)=dec(rmq(ls(now)),rmq(rs(now)));
}
void stick(int bas,int now){t[now]=t[bas];}
int cpy(int &x){t[++tot]=t[x];return x=tot;}
int qryrmq(int now,int ln,int rn,int l,int r){
if(l<=ln&&rn<=r) return rmq(now);
int mid=ln+rn>>1,res=0;
if(l<=mid) res=dec(res,qryrmq(ls(now),ln,mid,l,r));
if(r>mid) res=dec(res,qryrmq(rs(now),mid+1,rn,l,r));
return res;
}
int ql,qr;
void upd(int now,int ln,int rn,int p,int d){
cnt(now)+=d;if(ln==rn) ql=qr=rmq(now);
else{int mid=ln+rn>>1;
if(p<=mid) upd(cpy(ls(now)),ln,mid,p,d),qr=dec(qr,rmq(rs(now)));
else upd(cpy(rs(now)),mid+1,rn,p,d),ql=dec(ql,rmq(ls(now)));
}
R(now)+=dis[fa[ql]]*d;
L(now)+=dis[fa[qr]]*d;
}
void chk(node x){
puts("chknod");
printf("%d %d %lld\n",x.cnt,x.rmq,x.L);
}
node qry_r(int now,int ln,int rn,int l){
//printf("qryr %d %d %d %d\n",now,ln,rn,l);
if(l<=ln) return /*chk(t[now]),*/t[now];
int mid=ln+rn>>1;
if(l>mid) return qry_r(rs(now),mid+1,rn,l);
else return push_right(qry_r(ls(now),ln,mid,l),rs(now),mid+1,rn);
}
node qry_l(int now,int ln,int rn,int r){
//printf("qryl %d %d %d %d\n",now,ln,rn,r);
if(rn<=r) return /*chk(t[now]),*/t[now];
int mid=ln+rn>>1;
if(r<=mid) return qry_l(ls(now),ln,mid,r);
else return push_left(qry_l(rs(now),mid+1,rn,r),ls(now),ln,mid);
}
void chk(int now,int ln,int rn){
printf("node %d [%d , %d] c %d r %d %lld %lld\n",
now,ln,rn,cnt(now),rmq(now),R(now),L(now));
if(ln==rn) return ;
int mid=ln+rn>>1;
chk(ls(now),ln,mid);
chk(rs(now),mid+1,rn);
}
}Rs(totR),Ls(totL);
struct edg{int v,w;};
vector<edg> vc[N];
int dfn[N],dcnt;
void dfs(int now,int lst){
fa[now]=lst;dep[now]=dep[lst]+1;idf[dfn[now]=++dcnt]=now;
for(auto[v,w]:vc[now]) if(v!=lst) dis[v]=dis[now]+w,dfs(v,now);
}
void adp(int v,int p,int d){
if(dfn[p]<n) Ls.upd(rtL[v],1,n,dfn[p]+1,d);
Rs.upd(rtR[v],1,n,dfn[p],d);
}
int p[N],ext[N];ll sd[N];
//#include <ctime>
//#include "xzr.hpp"
int main()
{
//wxd;//xzr;
int q,X,l,r,x;re(n);re(q);X=1;
for(int i=1;i<=n;++i) re(p[i]),ext[p[i]]=i;
for(int i=1;i<n;++i) re(l),re(r),re(x),
vc[l].push_back((edg){r,x}),vc[r].push_back((edg){l,x});
dfs(1,0);dep[0]=2310231;Ls.tot=totL;Rs.tot=totR;
Ls.build(rtL[0]=++totL,1,n);Rs.build(rtR[0]=++totR,1,n);
for(int i=1;i<=n;++i){
Ls.stick(rtL[i-1],rtL[i]=++totL);
Rs.stick(rtR[i-1],rtR[i]=++totR);
adp(i,p[i],1);sd[i]=sd[i-1]+dis[p[i]];
}
/*
printf("time %.3f\n",(double)(clock()-bg)/CLOCKS_PER_SEC);
return 0;
*/
/*
for(int i=1;i<=n;++i) printf("%d ",dfn[i]);puts("");
for(int v=1;v<=4;++v) printf("-----------Version %d\n",v),
Rs.chk(rtR[v],1,n);
*/
//return 0;
int totqry=0,totupd=0;
int la=0;while(q--){int f;re(f);switch(f){
case 1:{
re(l);re(r);re(x);if(X) l^=la,r^=la,x^=la;
ll ans=sd[r]-sd[l-1]+1ll*dis[x]*(r-l+1);
//printf("preans %lld\n",ans);
//clock_t bg=clock();
ll sr=0;if(dfn[x]<n)
sr=Rs.qry_r(rtR[r],1,n,dfn[x]+1).R-Rs.qry_r(rtR[l-1],1,n,dfn[x]+1).R;
ll sl=Ls.qry_l(rtL[r],1,n,dfn[x]).L-Ls.qry_l(rtL[l-1],1,n,dfn[x]).L;
//totqry+=clock()-bg;
//printf("slr %lld %lld\n",sl,sr);
ans-=((sr+sl)<<1);if(ext[x]>=l&&ext[x]<=r) ans-=(dis[x]<<1);
wr(ans);puts("");la=ans%mod;break;
}
case 2:{
//clock_t bg=clock();
re(x);if(X) x^=la;
adp(x,p[x+1],1);adp(x,p[x],-1);
ext[p[x+1]]=x;ext[p[x]]=x+1;
sd[x]+=dis[p[x+1]]-dis[p[x]];
//totupd+=clock()-bg;
swap(p[x],p[x+1]);break;
}
}/*if(clock()>bg+3.99*CLOCKS_PER_SEC) return printf("proced %d operations",n-q),0;*/}
//printf("qry nd %.3f sec\n",1.0*totqry/CLOCKS_PER_SEC);
//printf("upd nd %.3f sec\n",1.0*totupd/CLOCKS_PER_SEC);
}