#include <bits/stdc++.h>
using namespace std;

struct node;
using nodeptr = node*;
mt19937 rng;

struct node
{
    int x, y, cnt;
    nodeptr l, r;
    /// эквивалентно node* l, r;

    node (const int key) : x(key), y(rng()), cnt(1), l(nullptr), r(nullptr) {}
};

int cnt (nodeptr v)
{
    return v == nullptr ? 0 : v->cnt;
}

void update (nodeptr v)
{
    if (v != nullptr)
        v->cnt = cnt(v->l) + 1 + cnt(v->r);
}

/// В l отправляем всё с кдючами меньще xs, в r -- всё остальное
void split (nodeptr v, const int xs, nodeptr &left, nodeptr &right)
{
    if (v == nullptr)
    {
        left = right = nullptr;
        return;
    }

    /// v->x -- сокращения для (*v).x;
    /// v->l, v->r, v->y, ...
    if (v->x < xs)
    {
///        nodeptr temp_l;
        split(v->r, xs, v->r, right);
///        v->r = temp_l;
        left = v;
    }
    else
    {
        split(v->l, xs, left, v->l);
        right = v;
    }

    update(left);
    update(right);
}

nodeptr merge (nodeptr left, nodeptr right)
{
    if (left == nullptr)
        return right;
    if (right == nullptr)
        return left;

    if (left->y > right->y)
    {
        left->r = merge(left->r, right);
        update(left);
        return left;
    }
    else
    {
        right->l = merge(left, right->l);
        update(right);
        return right;
    }
}

/// tree + heap
struct treap
{
    nodeptr root;

    treap() : root(nullptr) {}

    void dfs_print (nodeptr v)
    {
        if (v == nullptr)
            return;

        dfs_print(v->l);
        cerr << v->x << ' ' << v->y << ' ' << v->cnt << endl;
        dfs_print(v->r);
    }

    void print()
    {
        //dfs_print(root);
        //cerr << "===" << endl;
    }

    void insert (const int x)
    {
        nodeptr tl, tr;
        split(root, x, tl, tr);
        const nodeptr tm = new node(x);
        root = merge(tl, merge(tm, tr));
    }

    void erase (const int x)
    {
        nodeptr tl, tm, tr;
        split(root, x, tl, tm);
        split(tm, x + 1, tm, tr);
        /// tl -> (-inf, x), tm -> [x, x + 1), tr -> [x+1, +inf)
        root = merge(tl, tr);
    }

    bool dfs_find (nodeptr v, const int x)
    {
        if (v == nullptr)
            return false;
        if (v->x == x)
            return true;
        if (x < v->x)
            return dfs_find(v->l, x);
        return dfs_find(v->r, x);
    }

    /// k in 0-indexation, гарантируется 0 <= k < (v->cnt)
    int find_kth (nodeptr v, const int k)
    {
        assert(v != nullptr);
        if (k < cnt(v->l))
            return find_kth(v->l, k);
        if (k == cnt(v->l))
            return v->x;
        return find_kth(v->r, k - cnt(v->l) - 1);
    }

    int find_kth_max (const int k)
    {
        //cerr << cnt(root) << ' ' << cnt(root) - k << endl;
        return find_kth(root, cnt(root) - k);
    }

    bool find (const int x)
    {
        return dfs_find(root, x);
    }
};

int main()
{
    /// set<int> сами реализовали
    //freopen("input.txt", "rt", stdin);

    int n;
    cin >> n;

    treap info;
    for (int i = 0; i < n; i++)
    {
        info.print();

        int t, k;
        cin >> t >> k;

        if (t == +1)
            info.insert(k);
        else if (t == -1)
            info.erase(k);
        else if (t == 0)
            cout << info.find_kth_max(k) << "\n";
    }
}
