#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,cnt,opt,root;
int RD(){
int out = 0,flag = 1;char c = getchar();
while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
struct node
{
int lc,rc;
int val,pri;
int num,size;//num表示重复个数,size表示子树大小
}tr[1000010];
int New(int val)
{
tr[++cnt].val=val;
tr[cnt].pri=rand();
tr[cnt].num=tr[cnt].size=1;
tr[cnt].rc=tr[cnt].lc=0;
return cnt;
}
void Update(int p)//更新子树大小
{
tr[p].size=tr[tr[p].lc].size+tr[tr[p].rc].size+tr[p].num;
}
void zag(int &p)
{
int q=tr[p].lc;
tr[p].lc=tr[q].rc;
tr[q].rc=p;
tr[q].size=tr[p].size;
Update(p);
p=q;
}
void zig(int &p)
{
int q=tr[p].rc;
tr[p].rc=tr[q].lc;
tr[q].lc=p;
tr[q].size=tr[p].size;
Update(p);
p=q;
}
void Insert(int &p,int val)
{
if(!p)
{
p=New(val);
return;
}
tr[p].size++;
if(val==tr[p].val)
{
tr[p].num++;
return;
}
if(val<tr[p].val)
{
Insert(tr[p].lc,val);
if(tr[p].pri<tr[tr[p].lc].pri) zig(p);
}
else
{
Insert(tr[p].rc,val);
if(tr[p].pri<tr[tr[p].rc].pri) zag(p);
}
}
void Delete(int &p,int val)
{
if(!p) return;
tr[p].size--;
if(val==tr[p].val)
{
if(tr[p].num>1)
{
tr[p].num--;
return;
}
if(!tr[p].lc||tr[p].rc)
{
p=tr[p].lc+tr[p].rc;
}
else if(tr[tr[p].lc].pri>tr[tr[p].rc].pri)
{
zig(p);
Delete(tr[p].rc,val);
}
else
{
zag(p);
Delete(tr[p].lc,val);
}
return;
}
if(val<tr[p].val)
{
Delete(tr[p].lc,val);
}
else Delete(tr[p].rc,val);
}
int GetPre(int val)
{
int p=root;
int res=0;
while(p)
{
if(tr[p].val<val)
{
res=tr[p].val;
p=tr[p].rc;
}
else
{
p=tr[p].lc;
}
}
return res;
}
int GetNext(int val)
{
int p=root,res=0;
while(p)
{
if(tr[p].val>val)
{
res=tr[p].val;
p=tr[p].lc;
}
else p=tr[p].rc;
}
return res;
}
int GetRankByVal(int p,int val)
{
if(!p) return 0;
if(tr[p].val==val) return tr[tr[p].lc].size+1;
if(val<tr[p].val) return GetRankByVal(tr[p].lc,val);
else return GetRankByVal(tr[p].rc,val)+tr[p].size+tr[p].num;//左子树一定排在它前面
}
int GetValByRank(int p,int rank)
{
if(!p) return 0;
if(tr[tr[p].lc].size>=rank) return GetValByRank(tr[p].lc,rank);
if(tr[tr[p].lc].size+tr[p].num>=rank) return tr[p].val;
return GetValByRank(tr[p].rc,rank-tr[tr[p].lc].size-tr[p].num);
}
int main()
{
n=RD();
int x;
for(int i=1;i<=n;i++)
{
opt=RD();
if(opt==1)
{
x=RD();
Insert(root,x);
}
else if(opt==2)
{
x=RD();
Delete(root,x);
}
else if(opt==3)
{
x=RD();
printf("%d\n",GetRankByVal(root,x));
}
else if(opt==4)
{
x=RD();
printf("%d\n",GetValByRank(root,x));
}
else if(opt==5)
{
x=RD();
printf("%d\n",GetPre(x));
}
else if(opt==6)
{
x=RD();
printf("%d\n",GetNext(x));
}
}
return 0;
}