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

mt19937 rng;

struct node
{
    int x, y;
    int lson, rson;
    int cnt;

    node () : x(-1), y(-1), lson(-1), rson(-1),
              cnt(1) {}

    node (const int x_) : x(x_), y(rng()),
                        lson(-1), rson(-1),
                        cnt(1) {}
};

struct treap_manager
{
    vector<node> v;

    int get_new_node (const int x)
    {
        v.push_back(node(x));
        return int(v.size()) - 1;
    }

    int get_cnt (const int root) const
    {
        return root == -1 ? 0 : v[root].cnt;
    }

    pair<int, int> split (const int t, const int x0)
    {
        if (t == -1)
            return {-1, -1};

        if (v[t].x < x0)
        {
            int l, r;
            tie(l, r) = split(v[t].rson, x0);
            v[t].rson = l;

            v[t].cnt -= get_cnt(r);
            return {t, r};
        }
        else
        {
            int l, r;
            tie(l, r) = split(v[t].lson, x0);
            v[t].lson = r;

            v[t].cnt -= get_cnt(l);
            return {l, t};
        }
    }

    int merge (const int l, const int r)
    {
        if (l == -1)
            return r;
        if (r == -1)
            return l;

        if (v[l].y > v[r].y)
        {
            const int mem_size = get_cnt(r);
            v[l].rson = merge(v[l].rson, r);

            v[l].cnt += mem_size;
            return l;
        }
        else
        {
            const int mem_size = get_cnt(l);
            v[r].lson = merge(l, v[r].lson);

            v[r].cnt += mem_size;
            return r;
        }
    }

    void insert (int &root, const int x)
    {
        int l, r;
        tie(l, r) = split(root, x);
        const int m = get_new_node(x);
        root = merge(merge(l, m), r);
///         "root = merge(l, merge(m, r));" is also correct
    }

    void erase (int &root, const int x)
    {
        int l, m, r;
        tie(l, m) = split(root, x);
        tie(m, r) = split(m, x + 1);
        root = merge(l, r);
    }

    bool find_stupid (int &root, const int x)
    {
        int l, m, r;
        tie(l, m) = split(root, x);
        tie(m, r) = split(m, x + 1);
        const bool ok = (m != -1);
        root = merge(l, merge(m, r));
        return ok;
    }

    int find_min (int root)
    {
        assert(root != -1);
        while (v[root].lson != -1)
            root = v[root].lson;
        return v[root].x;
    }

    void dfs_order (const int root, vector<int> &ans)
    {
        if (root == -1)
            return;

        dfs_order(v[root].lson, ans);
        ans.push_back(v[root].x);
        dfs_order(v[root].rson, ans);
    }

    vector<int> get_order (const int root)
    {
        vector<int> ans;
        dfs_order(root, ans);
        return ans;
    }

    int get_kth (const int root, const int k) const
    {
//        cerr << get_cnt(root) << ' ' << k << endl;
        assert(get_cnt(root) == 1 + get_cnt(v[root].lson) + get_cnt(v[root].rson));
        assert(0 <= k && k < get_cnt(root));
        const int left_size = get_cnt(v[root].lson);
        if (k == left_size)
            return v[root].x;
        if (k < left_size)
            return get_kth(v[root].lson, k);
        /// k > left_size
        return get_kth(v[root].rson, k - left_size - 1);
    }
};

void solve(istream &cin = std::cin,
           ostream &cout = std::cout)
{
    treap_manager manager;
    int root = -1;

    int n;
    cin >> n;

    for (int i = 0; i < n; i++)
    {
        int type, k;
        cin >> type >> k;

        if (type == +1)
            manager.insert(root, k);
        else if (type == -1)
            manager.erase(root, k);
        else if (type == 0)
        {
            const int num = manager.get_cnt(root) - k;
            cout << manager.get_kth(root, num) << "\n";
        }
        else
            assert(false);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

#ifdef LOCAL
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    solve(fin, fout);
#else
    solve(cin, cout);
#endif
}
