#include <fstream>
using namespace std;
ifstream in("heapuri.in");
ofstream out("heapuri.out");
int heap[200005],poz_heap[200005],poz_vector[200005];
int n,q=0;
void interschimb(int a,int b)
{
int s=poz_vector[a];
int t=poz_vector[b];
int aux;
aux=heap[b];
heap[b]=heap[a];
heap[a]=aux;
poz_vector[b]=s;
poz_heap[s]=b;
poz_vector[a]=t;
poz_heap[t]=a;
return;
}
//heap,cate noduri, nod k =>in jos il normalizeaza
void sift(int heap[],int n,int k)
{
int fiu,fiu_stang,fiu_drept,aux;
do{
fiu=0;
fiu_stang=2*k;
fiu_drept=2*k+1;
if(fiu_stang<=n)
{
fiu=fiu_stang;
if(fiu_drept<=n && heap[fiu_drept]<heap[fiu_stang]) fiu=fiu_drept;
if(heap[fiu]>=heap[k]) fiu=0;
}
if(fiu)
{
interschimb(k,fiu);
//aux=heap[k];
//heap[k]=heap[fiu];
//heap[fiu]=heap[k];
k=fiu;
}
}while(fiu);
return;
}
//heap,cate noduri, nod k =>in sus il normalizeaza
void percolate(int heap[],int n,int k)
{
int cheie=heap[k];
int tata=k/2;
while((k>1)&&(cheie<heap[tata]))
{
interschimb(k,tata);
//heap[k]=heap[tata];
k=tata;
tata=k/2;
}
heap[k]=cheie;
return;
}
//inserarea unui element in heap
void insert(int heap[],int &n,int cheie)
{
n++;
q++;
poz_heap[q]=n;
poz_vector[n]=q;
heap[n]=cheie;
percolate(heap,n,n);
return;
}
//stergerea unui element din heap
void stergere(int heap[],int &n,int cheie)
{
int tata=cheie/2;
interschimb(cheie,n);
//heap[cheie]=heap[n];
n--;
if((cheie>1)&&(heap[cheie] < heap[tata])) percolate(heap,n,cheie);
else sift(heap,n,cheie);
return;
}
int main()
{
int i,x,operatie,nr_noduri=0,j;
in>>n;
for(i=1;i<=n;i++)
{
in>>operatie;
if(operatie==1)
{
in>>x;
insert(heap,nr_noduri,x);
}
if(operatie==2)
{
in>>x;
stergere(heap,nr_noduri,poz_heap[x]);
}
if(operatie==3)
{
out<<heap[1]<<"\n";
}
//out<<"Heapul este: "<<"\n";
//for(j=1;j<=nr_noduri;j++) out<<heap[j]<<" ";
//out<<"\n";
}
in.close();
out.close();
return 0;
}
/*#include <fstream>
using namespace std;
ifstream in("heapuri.in");
ofstream out("heapuri.out");
int n,x,operatie,p=1;
int heap[200005],ordine[200005],pozitie[200005];
//Prin vectorul ordine tin minte ce elemnt a fost inserate al i-lea
//De fiecare data cand fac sift,fa_heap sau inserare (la stergere fac sift/fa_heap) reschimb pozitiile.
//Procedura asta e de pe infoarena si il face heap incepand cu pozitia k (in jos) - sau asa cred :)
void sift(int heap[],int &inaltime,int k)
{
int fiu,aux;
do{
fiu=0;
if(2*k <= inaltime)
{
fiu=2*k;
if(2*k+1 <= inaltime && heap[2*k+1]<heap[2*k]) fiu=2*k+1;
if(heap[fiu] >= heap[k]) fiu=0;
}
if(fiu){
pozitie[heap[fiu]]=k;
pozitie[heap[k]]=fiu;
aux=heap[k];
heap[k]=heap[fiu];
heap[fiu]=aux;
}
}while(fiu);
return;
}
//Si asta e tot de pe infoarena si face vectorul meu heap doar ca opus lui sift(adica in sus) - sau asa cred :)
void fa_heap(int heap[],int &inaltime,int k)
{
int cheie=heap[k];
while((k>1) && (cheie<heap[k/2]))
{
heap[k]=heap[k/2];
pozitie[heap[k/2]]=k;
k=k/2;
}
pozitie[cheie]=k;
heap[k]=cheie;
return;
}
//Inserare de element in heap
void inserare_heap(int heap[],int &inaltime,int x)
{
inaltime++;
heap[inaltime]=x;
ordine[p]=x;
p++;
pozitie[p]=inaltime;
fa_heap(heap,inaltime,inaltime);
return;
}
//stergere element din heap
void stergere_heap(int heap[],int &inaltime,int poz)
{
heap[poz]=heap[inaltime];
inaltime--;
if(poz>1 && heap[poz]<heap[poz/2]) fa_heap(heap,inaltime,poz);
else sift(heap,inaltime,poz);
return;
}
int main()
{
int i,inaltime;
in>>n;
inaltime=0;
for(i=1;i<=n;i++)
{
in>>operatie;
if(operatie==1)
{
in>>x;
inserare_heap(heap,inaltime,x);
}
if(operatie==2)
{
in>>x;
if(inaltime>0) stergere_heap(heap,inaltime,pozitie[ordine[x]]);
}
if(operatie==3)
{
out<<heap[1]<<"\n";
}
}
in.close();
out.close();
return 0;
}
*/