#include<iostream>
using namespace std;
const int Max=2000000;
long long dui[Max],Long;
long long father(int i)
{
if(i%2)
i-=1;
return i/2;
}
long long left(int i)
{
return i*2;
}
long long right(int i)
{
return i*2+1;
}
long long son(int i)
{
if(i*2<Long)
return dui[left(i)]<=dui[right(i)]?left(i):right(i);
if(i*2==Long)
return left(i);
return 0;
}
void put(int i)
{
Long++;
long long now=Long;
dui[now]=i;
while(dui[father(now)]>dui[now])
{
swap(dui[father(now)],dui[now]);
now=father(now);
}
}
void get()
{
long long now=1;
swap(dui[1],dui[Long]);
Long--;
while((dui[son(now)]<dui[now])&&(now*2<=Long))
{
swap(dui[son(now)],dui[now]);
now=son(now);
}
}
int main()
{
long long n,putv,casee;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>casee;
switch(casee)
{
case 1:
{
cin>>putv;
put(putv);
}
break;
case 2:
cout<<dui[1]<<endl;
break;
case 3:
get();
break;
}
}
return 0;
}
堆的基本操作 P3378