#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
typedef unsigned long long LL;
int n;
//cnt是记录这个堆里面有多少元素的
LL h[N];
int cnt;
//建立小根堆,大的数往下沉
void down(int u){
int t=u;
if(2*u+1<=cnt&&h[t]<=h[2*u+1]) t=2*u+1;
if(2*u<=cnt&&h[t]<=h[2*u]) t=2*u;
if(t!=u){
swap(h[u],h[t]);
down(t);
}
}
void up(int u){
while(u/2&&h[u/2]>=h[u]){
swap(h[u/2],h[u]);
up(u/2);
}
}
void insert(LL x){
h[++cnt]=x;
up(cnt);
}
void put(){
printf("%llu\n",h[1]);
}
void delet(){
swap(h[1],h[cnt]);
cnt--;
down(1);
}
int main(){
scanf("%d",&n);
while(n--){
int op;
scanf("%d",&op);
if(op==1){
LL x;
scanf("%llu",&x);
insert(x);
}else if(op==2){
put();
}else{
delet();
}
}
return 0;
}