#include <fstream>
using namespace std ;
ifstream cin ("heapuri.in") ;
ofstream cout ("heapuri.out") ;
const int MAX = 200014 ;
int V[MAX] , nr ;
int values [MAX], sz ;
bool isErased [MAX] ;
void UpHeap (int node) {
if ( node == 1 )
return ;
if ( values[V[node]] < values[V[node/2]]) {
swap( V[node] , V[node/2]) ;
UpHeap(node/2) ;
}
}
void Insert (int x) {
++nr ;
V[nr] = x ;
UpHeap(nr) ;
}
void DownHeap (int node) {
if ( node > nr)
return ;
if ( node *2 +1 <= nr) {
if ( values[V[node]] < values[V[node*2]] && values[V[node]] < values[V[node * 2 +1]]){
return ;
}
if (values[V[node]] > values[V[node*2 +1]] && values[V[node]] > values[V[node*2]]) {
if ( values[V[node*2 +1]] > values[V[node*2]]) {
swap(V[node] , V[node *2]) ;
DownHeap (node * 2) ;
return ;
}
else {
swap (V[node] , V[node * 2 + 1]) ;
DownHeap (node * 2 + 1);
return ;
}
return ;
}
if ( values[V[node]] > values[V[node*2+1]]) {
swap ( V[node] , V[node*2 +1]) ;
DownHeap (node * 2 + 1);
return ;
}
}
if ( node * 2 <= nr) {
if ( values[V[node]] > values[V[node *2]]) {
swap (V[node] , V[node*2]) ;
DownHeap (node * 2);
return ;
}
return ;
}
return ;
}
int Delette() {
while (1) {
int value = V[1] ;
if (isErased [value] == false) {
return values [value] ;
}
swap ( V[1] , V[nr]) ;
nr-- ;
DownHeap(1) ;
}
}
int main()
{
int m ;
cin >> m ;
while (m --) {
int tip ;
cin >> tip ;
if (tip == 1) {
int x ;
cin >> x ;
++ sz ;
values [sz] = x ;
Insert (sz) ;
}
else if (tip == 2) {
int x ;
cin >> x ;
isErased [x] = true ;
}
else {
cout << Delette () << '\n' ;
}
}
return 0 ;
}