// Priority Heap
#include <stdio.h>
#include <stdlib.h>

#define MAX 200000
#define NIL -1

int H=0; // ヒープの数

int parent(int i){
  return i / 2; // 親の接点番号
}

int left(int i){
  return 2 * i; // 左の子の接点番号
}

int right(int i){
  return 2 * i + 1; // 右の子の接点番号
}

// iの左の子と右の子のうち、キーが大きい方を選び、それが現在のキーよりも大きければ、交換していく
void maxHeapify(int *A, int i){
  int l, r, largest, swp;
  l = left(i);
  r = right(i);

  // 左の子、自分、右の子で値が最大のノードを選ぶ
  if(l <= H && A[l] > A[i]){
    largest = l;
  }
  else largest = i;
  
  if(r <= H && A[r] > A[largest]){
    largest = r;
  }
  if(largest != i){ // i の子の方が値が大きい場合
    swp = A[i];  A[i] = A[largest];  A[largest] = swp; // A[i] と A[largest] を交換
    maxHeapify(A, largest); // 再帰的に呼び出し
  }
}

// ヒープ要素の最大の要素を取得・削除
int heapExtractMax(int *A){
  int max;
  if(H < 1){
    printf("heap underflow\n");
    exit(1);
  }
  max = A[1]; // 最大値は二分ヒープの根から得られる
  A[1] = A[H];
  H--; // ヒープの数を1つ減らす
  maxHeapify(A, 1);
  return max;
}

// 優先度付きキューを表すヒープ要素のキーの変更
void heapIncreaseKey(int *A, int i, int key){
  int swp;
  if(key < A[i]){
    printf("new key is smaller than current key\n");
    exit(1);
  }
  A[i] = key;
  
  // ループでiのヒープ要素とその親のヒープ要素を比べる(親の方へとたどっていく)
  // A[parent(i)] > A[i] となるようにする
  while(i > 1 && A[parent(i)] < A[i]){
    swp = A[i];  A[i] = A[parent(i)];  A[parent(i)] = swp;
    i = parent(i);
  }
}

// 優先度付きキューを表すキューへの挿入
void heapInsert(int *A, int key){
  H++; // ヒープの数を1つ増やす
  A[H] = NIL;
  heapIncreaseKey(A, H, key);
}

int main(){
  int i=1, j, count=0, A[MAX], max[MAX];
  char com[20];

  while(1){
    scanf("%s", com);
    if(com[2] == 'd')break;
    scanf("%d",  &A[i]);
    if(com[0] == 'i'){
      heapInsert(A, A[i]);
    }
    else{
      max[count] = heapExtractMax(A);
      count++;
    }
    i++;
  }
  
  for(j=0; j < count; j++){
    printf("%d\n", max[j]);
  }

  return 0;
}

// 入力された数値は1オリジンの配列に入る
