import java.util.Scanner;
public class Main{
static int N =100010, size,m;
static int[] h = new int[N]; //h[i]表示下标i这个点是第多少
static int[] hp = new int[N]; //hp[i]表示下标为i的节点是第几个被加进来的
static int[] ph = new int[N]; //ph[i]表示第i个加进来的数再在小顶堆h中的下标
public static void swap(int[] a,int x,int y){
int temp = a[x];
a[x] = a[y];
a[y] = temp;
}
public static void swap_all(int x,int y){
//因为需要知道某个数是第几个加入的,因此要多一层映射关系
//先改变hp和ph之间的指向
swap(ph,hp[x],hp[y]); //改变ph数组下标为hp[x]和hp[y]的指向
swap(hp,x,y); //改变hp数组下标为x和y的指向
swap(h,x,y); //最后在改变h数组下标为x,y的指向
}
public static void down(int x){
int t = x;
//看一下左右孩子有没有更小的,有的话自己需要下潜
if (x * 2 <= size && h[x * 2] < h[t]) t = x * 2;
if (x * 2 + 1<= size && h[x * 2 + 1] < h[t]) t = x * 2 + 1;
if (t != x){
swap_all(x,t);
down(t);
}
}
public static void up(int x){
//x==0违规,x==1不需要上浮
while (x >> 1 > 0 && h[x>>1] > h[x]){
swap_all(x,x>>1);
x = x >> 1;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
size = 0; //h数组的有效索引
m = 0; //映射数组:用来表示h数组中下标为i的数字是第几个数加入的
while (n-- > 0){
String s = sc.next();
if (s.equals("I")){
int x = sc.nextInt();
size++; //是该小顶堆编号为cnt + 1的数 cnt为每个节点的唯一标识
m++; //第m + 1个数加入
hp[size] = m; //标识当前这个数是第m个加入的数
ph[m] = size; //标识第m个数对应在小顶堆中是哪个数的下标
h[size] = x; //把这个数插入到小顶堆的尾巴
up(size);
} else if (s.equals("PM")){
System.out.println(h[1]);
} else if (s.equals("DM")){
//删除集合中的最小值,把第一个数和最后一个数交换,再把最后一个数删掉,再把第一个数下潜
swap_all(1, size); //交换第一个和最后一个
size--; //删掉最后一个数
down(1);
} else if (s.equals("D")){
int k = sc.nextInt();
int x = ph[k]; //x是加入的第k个数在小顶堆中的下标
swap_all(x, size);
size--;
down(x);
up(x);
} else {
int k = sc.nextInt();
int x = sc.nextInt();
//修改第k个数,先知道第k个数在小顶堆x中的下标
int idx = ph[k];
h[idx] = x;
up(idx);
down(idx);
}
}
}
}