#include <iostream>
#include <algorithm>
#define inf 0x7FFFFFFF
const int N = 2e7 + 100;
const int M = 1e6 + 10;
int cnt, root[M], tot, x, y, z;
struct node {
int lc, rc, sz, key, val;
node() { lc = rc = sz = key = val = 0; }
node(int val) { lc = rc = 0; sz = 1; key = std::rand(); this->val = val; }
}treap[N];
inline int getLc(int rt) { return treap[rt].lc; }
inline int getRc(int rt) { return treap[rt].rc; }
inline void pushup(int rt) { treap[rt].sz = treap[getLc(rt)].sz + treap[getRc(rt)].sz + 1; }
inline void split(int rt, int sign, int& x, int& y) {
if (!rt) { x = y = 0; return; }
treap[++cnt] = treap[rt];
int id = cnt;
if (treap[rt].val <= sign) {
x = id;
split(treap[rt].rc, sign, treap[x].rc, y);
}
else {
y = id;
split(treap[rt].lc, sign, x, treap[y].lc);
}
pushup(id);
}
inline int marge(int x, int y) {
if (!x || !y) return x + y;
int id = ++cnt;
if (treap[x].key < treap[y].key) {
treap[id] = treap[x];
treap[id].rc = marge(treap[id].rc, y);
}
else {
treap[id] = treap[y];
treap[id].lc = marge(x, treap[id].lc);
}
pushup(id);
return id;
}
inline void op_insert(int id, int val) {
treap[++cnt] = node(val);
int ins = cnt;
root[++tot] = root[id];
split(root[tot], val, x, y);
root[tot] = marge(marge(x, ins), y);
}
inline void op_delete(int id, int val) {
root[++tot] = root[id];
split(root[tot], val, x, y);
split(x, val - 1, x, z);
if (treap[z].sz > 1) x = marge(x, marge(treap[z].lc, treap[z].rc));
root[tot] = marge(x, y);
}
inline void getRank(int id, int val) {
root[++tot] = root[id];
split(root[tot], val - 1, x, y);
std::cout << treap[x].sz + 1 << std::endl;
root[tot] = marge(x, y);
}
inline void getKth(int id, int kth) {
root[++tot] = root[id];
int rt = root[tot];
if (kth > treap[rt].sz) {
std::cout << inf << std::endl;
return;
}
while (true) {
if (treap[getLc(rt)].sz + 1 == kth) { std::cout << treap[rt].val << std::endl; return; }
else if (treap[getLc(rt)].sz >= kth) rt = getLc(rt);
else { kth = kth - 1 - treap[getLc(rt)].sz; rt = getRc(rt); }
}
}
inline void getPrev(int id, int val) {
root[++tot] = root[id];
split(root[tot], val - 1, x, y);
if (treap[x].sz == 0) {
std::cout << -inf << std::endl;
root[tot] = marge(x, y);
}
else {
int kth = treap[x].sz;
root[tot] = marge(x, y);
getKth(id, kth);
}
}
inline void getNext(int id, int val) {
root[++tot] = root[id];
split(root[tot], val, x, y);
if (treap[y].sz == 0) {
std::cout << inf << std::endl;
root[tot] = marge(x, y);
}
else {
int kth = treap[x].sz + 1;
root[tot] = marge(x, y);
getKth(id, kth);
}
}
signed main() {
int id, op, val, n;
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
std::cin >> n;
while (n--) {
std::cin >> id >> op >> val;
if (op == 1) op_insert(id, val);
else if (op == 2) op_delete(id, val);
else if (op == 3) getRank(id, val);
else if (op == 4) getKth(id, val);
else if (op == 5) getPrev(id, val);
else getNext(id, val);
}
}