#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e7;
int val[maxn];
int size[maxn];
int rank[maxn];
int ch[maxn][2];
int lz[maxn];
int sum[maxn];
int tot=0,root[maxn],last=0;
int seed = 100;
inline int read(){
int x=0,f=1;
char c = getchar();
while(!isdigit(c)){
if(c=='-') f=-1;
c = getchar();
}
while(isdigit(c)){
x = 10*x+c-'0';
c = getchar();
}
return x*f;
}
inline int rrand(){
return seed = int(seed*482711*2147483647);
}
inline int newnode(int value){
val[tot++] = value;
size[tot] = 1;
rank[tot] = rrand();
sum[tot] = value;
lz[tot] = 0;
return tot;
}
inline int copynode(int rt){
val[++tot] = val[rt];
size[tot] = size[rt];
rank[tot] = rank[rt];
ch[tot][0] = ch[rt][0];
ch[tot][1] = ch[rt][1];
sum[tot] = sum[rt];
lz[tot] = lz[rt];
return tot;
}
inline void push_up(int rt){
size[rt] = size[ch[rt][0]]+size[ch[rt][1]]+1;
sum[rt] = sum[ch[rt][0]]+sum[ch[rt][1]]+val[rt];
}
inline void push_down(int rt){
if(lz[rt]){
swap(ch[rt][0],ch[rt][1]);
if(ch[rt][0]){
ch[rt][0] = copynode(ch[rt][0]);
lz[ch[rt][0]] ^= 1;
}
if(ch[rt][1]){
ch[rt][1] = copynode(ch[rt][1]);
lz[ch[rt][1]] ^= 1;
}
lz[rt] = 0;
}
}
//void split(int now,int value,int &x,int &y){
// if(!now){
// x = y = 0;
// return ;
// }
// push_down(now);
// int copy = copynode(now);
// if(val[now]<=value){
// x = copy;
// split(ch[copy][1],value,ch[copy][1],y);
// push_up(x);
// }else{
// y = copy;
// split(ch[copy][0],value,x,ch[copy][0]);
// push_up(y);
// }
//}
void split(int now,int k,int &x,int &y){
if(!now){
x = y = 0;
return ;
}
push_down(now);
int copy = copynode(now);
if(size[ch[now][0]]<=k){
x = copy;
split(ch[copy][1],k-size[ch[copy][0]]-1,ch[copy][1],y);
push_up(x);
}else{
y = copy;
split(ch[copy][0],k,x,ch[copy][0]);
push_up(y);
}
}
int merge(int x,int y){
if(!x||!y) return x+y;
if(rank[x]<rank[y]){
int copy = copynode(x);
ch[copy][1] = merge(ch[copy][1],y);
push_up(copy);
return copy;
}else{
int copy = copynode(y);
ch[copy][0] = merge(x,ch[copy][0]);
push_up(copy);
return copy;
}
}
void insert(int &root,int k,int value){
int x=0,y=0,z=newnode(value);
split(root,k,x,y);
root = merge(merge(x,z),y);
}
void del(int &root,int k){
int x=0,y=0,z=0;
split(root,k,x,z);
split(x,k-1,x,y);
y = merge(ch[y][0],ch[y][1]);
root = merge(merge(x,y),z);
}
void Reverse(int &root,int l,int r){
int x=0,y=0,z=0;
split(root,r,x,z);
split(x,l-1,x,y);
lz[y] ^= 1;
root = merge(merge(x,y),z);
}
long long query(int &root,int l,int r){
int x=0,y=0,z=0;
split(root,r,x,z);
split(x,l-1,x,y);
long long ans = sum[y];
root = merge(merge(x,y),z);
return ans;
}
int main(){
int n;
n = read();
for(int i=1;i<=n;i++){
int v,opt,l,r,p,_x;
v = read();opt = read();
root[i] = root[v];
switch(opt){
case 1:{
p = read();_x = read();
insert(root[i],p^last,_x^last);
break;
}
case 2:{
p = read();
del(root[i],p^last);
break;
}
case 3:{
l = read();r = read();
Reverse(root[i],l^last,r^last);
break;
}
case 4:{
l = read();r = read();
//cout<<(l^last)<<(r^last)<<endl;
last = query(root[i],l^last,r^last);
printf("%lld\n",last);
break;
}
}
}
return 0;
}