const int MAXN=2e5+5,MAXM=80;
int root[MAXN];
struct fhq_treap{
int tot;
struct Node{
int r,val,sz,flip,ch[2];
LL sum;
}node[MAXN*MAXM];
int New(int v){
int x=++tot;
node[x].sum=node[x].val=v,node[x].r=rand(),node[x].sz=1;
return x;
}
int Copy(int k){
node[++tot]=node[k];
return tot;
}
void pushup(int k){
node[k].sz=node[node[k].ch[0]].sz+node[node[k].ch[1]].sz+1;
node[k].sum=node[node[k].ch[0]].sum+node[node[k].ch[1]].sum+node[k].val;
}
void pushdown(int k){
if(node[k].flip){
if(node[k].ch[0])node[k].ch[0]=Copy(node[k].ch[0]);
if(node[k].ch[1])node[k].ch[1]=Copy(node[k].ch[1]);
swap(node[k].ch[0],node[k].ch[1]);
node[node[k].ch[0]].flip^=1;
node[node[k].ch[1]].flip^=1;
node[k].flip=0;
}
}
void split(int k,int &k1,int &k2,int rk){
if(!k) return k1=k2=0,void();
pushdown(k);
if(node[node[k].ch[0]].sz+1<=rk){
k1=Copy(k);split(node[k].ch[1],node[k1].ch[1],k2,rk-node[node[k].ch[0]].sz-1);pushup(k1);
}else{
k2=Copy(k);split(node[k].ch[0],k1,node[k2].ch[0],rk);pushup(k2);
}
}
void merge(int &k,int k1,int k2){
if(!k1||!k2)return k=k1|k2,void();
if(node[k1].r>node[k2].r){
pushdown(k1);k=k1;merge(node[k].ch[1],node[k1].ch[1],k2);pushup(k);
}else{
pushdown(k2);k=k2;merge(node[k].ch[0],k1,node[k2].ch[0]);pushup(k);
}
}
void Flip(int &root,int p,int L,int R){
int lef,mid,rig;
split(p,lef,rig,R);
split(lef,lef,mid,L-1);
node[mid].flip^=1;
merge(lef,lef,mid);
merge(root,lef,rig);
}
void Insert(int &root,int p,int pos,int v){
int lef,rig;
split(p,lef,rig,pos);
merge(lef,lef,New(v));
merge(root,lef,rig);
}
void erase(int &root,int p,int pos){
int lef,mid,rig;
split(p,lef,rig,pos);
split(lef,lef,mid,pos-1);
merge(root,lef,rig);
}
LL query(int root,int L,int R){
int lef,mid,rig;
split(root,lef,rig,R);
split(lef,lef,mid,L-1);
return node[mid].sum;
}
}tree;
int main()
{
int n,v,opt;
LL p,x,l,r,last=0;
n=read_int();
_rep(i,1,n){
v=read_int(),opt=read_int();
switch(opt){
case 1:
p=read_LL()^last,x=read_LL()^last;
tree.Insert(root[i],root[v],p,x);
break;
case 2:
p=read_LL()^last;
tree.erase(root[i],root[v],p);
break;
case 3:
l=read_LL()^last,r=read_LL()^last;
tree.Flip(root[i],root[v],l,r);
break;
case 4:
l=read_LL()^last,r=read_LL()^last;
enter(last=tree.query(root[i]=root[v],l,r));
break;
}
}
return 0;
}