/*
这道题一看可以知道是平衡树+持久化.如果是持久化,
那么我们就要保存历史信息,每次修改logn个点,所以内存要靠2nlogn.
split是把以i为根节点的子树分成两部分,一部分小于等于k,一部分大于k,必须保证其BST所有的性质
merge是合并以x为根节点和以y为根节点的两颗子树。
*/
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
struct node{
int l,r;
int v,rd,sum;
}a[N*50];
int cnt;
void update(int i){
if(!i)return ;
a[i].sum=a[a[i].l].sum+a[a[i].r].sum+1;
}
int newnode(int x){
++cnt;
a[cnt].l=a[cnt].r=0;
a[cnt].sum=1;a[cnt].v=x;
a[cnt].rd=rand();
return cnt;
}
int merge(int x,int y){//合并操作,按照treap的rd的优先级来合并(小跟堆或大根堆都行)
//这里是大根堆
if(!x||!y)return x+y;
if(a[x].rd>a[y].rd){
int p=++cnt;a[p]=a[x];
a[p].r=merge(a[p].r,y);
update(p);return p;
}
else {
int p=++cnt;a[p]=a[y];
a[p].l=merge(x,a[p].l);
update(p);return p;
}
}
void split(int now,int k,int &x,int &y){//把小于等于k的数放x子树里面,大于k的放y子树里面
if(now==0){x=y=0;return ;}
if(a[now].v<=k){
x=++cnt;a[x]=a[now];
split(a[x].r,k,a[x].r,y);
update(x);
}
else {
y=++cnt;a[y]=a[now];
split(a[y].l,k,x,a[y].l);
update(y);
}
}
void insert(int &root,int v){//插入一个新结点
int x=0,y=0,z=0;
split(root,v-1,x,y);
z=newnode(v);
root=merge(merge(x,z),y);
}
void del(int &root,int v){//删除一个结点
int x=0,y=0,z=0;
split(root,v,x,z);
split(x,v-1,x,y);
y=merge(a[y].l,a[y].r);
root=merge(merge(x,y),z);
}
int rank_value(int i,int k){
if(k==a[a[i].l].sum+1)return a[i].v;
if(k<=a[a[i].l].sum)return rank_value(a[i].l,k);
return rank_value(a[i].r,k-a[a[i].l].sum-1);
}
int kth_rank(int &root,int v){//查询排名为x的数
int x,y;
split(root,v-1,x,y);
int ans=a[x].sum+1;
root=merge(x,y);
return ans;
}
int pre(int &root,int v){//求前驱
int x,y,k;
split(root,v-1,x,y);
if(x==0)return -2147483647;
k=a[x].sum;
int ans=rank_value(x,k);
root=merge(x,y);
return ans;
}
int nex(int &root,int v){//求后驱
int x,y,ans;
split(root,v,x,y);
if(y==0)return 2147483647;
ans=rank_value(y,1);
root=merge(x,y);
return ans;
}
int n,root[N];
int main(){
scanf("%d",&n);
int x,y,op;
for(int i=1;i<=n;i++){
scanf("%d%d%d",&x,&op,&y);
root[i]=root[x];
if(op==1)insert(root[i],y);
if(op==2)del(root[i],y);
if(op==3)printf("%d\n",kth_rank(root[i],y));
if(op==4)printf("%d\n",rank_value(root[i],y));
if(op==5)printf("%d\n",pre(root[i],y));
if(op==6)printf("%d\n",nex(root[i],y));
}
return 0;
}