#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#define maxn 1000010
using namespace std;
const int INF = 0x7fffffff;
struct node {
int ls = -1;
int rs = -1;
int val;
int size;
int cnt;
} x[maxn];
int bnt = 0;
int a;
int check(int v, int num) {
if (x[num].val == v) {
return 0;
}
if (x[num].val > v) {
if (x[num].ls == -1) {
return 11;
} else {
return 12;
}
} else {
if (x[num].rs == -1) {
return 21;
} else {
return 22;
}
}
}
void add(int v, int num = 0) {
if (bnt == 0) {
x[bnt].val = v;
x[bnt].size = 1;
x[bnt].cnt = 1;
bnt++;
return;
} else {
x[num].size++;
while (1) {
a = check(v, num);
switch (a) {
case 0: {
x[num].cnt++;
return;
}
case 11: {
x[bnt].val = v;
x[bnt].size = 1;
x[bnt].cnt = 1;
x[num].ls = bnt;
bnt++;
break;
}
case 12: {
num = x[num].ls;
break;
}
case 21: {
x[bnt].val = v;
x[bnt].size = 1;
x[bnt].cnt = 1;
x[num].rs = bnt;
bnt++;
break;
}
case 22: {
num = x[num].rs;
break;
}
}
}
return;
}
}
int GetPre(int num, int v, int ans) {
if (x[num].val >= v) {
if (x[num].ls == -1) {
return ans;
} else {
return GetPre(x[num].ls, v, ans);
}
} else {
if (x[num].rs == -1) {
return x[num].val;
} else {
return GetPre(x[num].rs, v, x[num].val);
}
}
}
int GetNext(int num, int v, int ans) {
if (x[num].val <= v) {
if (x[num].rs == -1) {
return ans;
} else {
return GetNext(x[num].rs, v, ans);
}
} else {
if (x[num].ls == -1) {
return x[num].val;
} else {
return GetNext(x[num].ls, v, x[num].val);
}
}
}
int root_size = x[0].size - x[x[0].rs].size;
int GetValByRank(int num, int rank) {
if (rank == 0) {
return INF;
}
if (rank == root_size) {
return x[0].val;
}
if (x[x[num].ls].size >= rank) {
return GetValByRank(x[num].ls, rank);
}
if (x[x[num].ls].size + x[num].cnt >= rank) {
return x[num].val;
}
return GetValByRank(x[num].rs, rank - x[x[num].ls].size - x[num].cnt);
}
int GetRankByVal(int num, int val) {
if (val == x[num].val) {
return x[x[num].ls].size + 1;
}
if (val < x[num].val) {
return GetRankByVal(x[num].ls, val);
}
return GetRankByVal(x[num].rs, val) + x[x[num].ls].size + x[num].cnt;
}
int q, opt, x1;
int main() {
cin >> q;
for (int i = 0; i < q; i++) {
cin >> opt >> x1;
switch (opt) {
case 1: {
cout << GetRankByVal(0, x1) << endl;
break;
}
case 2: {
cout << GetValByRank(0, x1) << endl;
break;
}
case 3: {
cout << GetPre(0, x1, -INF) << endl;
break;
}
case 4: {
cout << GetNext(0, x1, INF) << endl;
break;
}
case 5: {
add(x1);
break;
}
}
}
return 0;
}