#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct treap {
int l, r;
int key, val;
int siz;
}tr[N];
int idx, root;
int newnode(int v) {
tr[++idx].val = v;
tr[idx].key = rand();
tr[idx].siz = 1;
return idx;
}
void pushup(int p) {
tr[p].siz = tr[tr[p].l].siz + tr[tr[p].r].siz + 1;
}
void split(int p, int v, int &x, int &y) {
if (!p) {
x = y = 0;
return;
}
if (tr[p].val <= v) {
x = p;
split(tr[p].r, v, tr[p].r, y);
} else {
y = p;
split(tr[p].l, v, x, tr[p].l);
}
pushup(p);
}
int merge(int x, int y) {
if (!x || !y) return x + y;
if (tr[x].key < tr[y].key) {
tr[x].r = merge(tr[x].r, y);
pushup(x);
return x;
} else {
tr[y].l = merge(x, tr[y].l);
pushup(y);
return y;
}
}
void insert(int v) {
int x, y, z;
split(root, v, x, y);
z = newnode(v);
root = merge(merge(x, z), y);
}
void del(int v) {
int x, y, z;
split(root, v, x, z);
split(x, v - 1, x, y);
y = merge(tr[x].l, tr[x].r);
root = merge(merge(x, y), z);
}
int getrank(int v) {
int x, y;
split(root, v - 1, x, y);
int ans = tr[x].siz + 1;
root = merge(x, y);
return ans;
}
int getval(int p, int k) {
if (k == tr[tr[p].l].siz + 1) {
return tr[p].val;
}
else if (k <= tr[tr[p].l].siz) {
return getval(tr[p].l, k);
} else {
return getval(tr[p].r, k - tr[tr[p].l].siz - 1);
}
}
int getpre(int v) {
int x, y, s, ans;
split(root, v - 1, x, y);
s = tr[x].siz;
ans = getval(x, s);
root = merge(x, y);
return ans;
}
int getnxt(int v) {
int x, y, ans;
split(root, v, x, y);
ans = getval(y, 1);
root = merge(x, y);
return ans;
}
int n;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
int op, x;
scanf("%d%d", &op, &x);
switch (op) {
case(1): insert(x);
case(2): del(x);
case(3): printf("%d\n", getrank(x));
case(4): printf("%d\n", getval(root, x));
case(5): printf("%d\n", getpre(x));
case(6): printf("%d\n", getnxt(x));
}
}
return 0;
}