#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ull = unsigned long long;

mt19937 mt(736);


template<class T>
class treap
{
	struct node
	{
		using nodeptr = unique_ptr<node>;

		const T x;
		const unsigned y;
		nodeptr l, r;
		T sum;
		size_t sz;

		explicit node(T x) : x(x), y(mt()), l(nullptr), r(nullptr), sum(x), sz(1)
		{}
	};

	using nodeptr = typename node::nodeptr;

	static nodeptr make_node(T x)
	{
		return make_unique<node>(x);
	}

	static T get_sum(const nodeptr &h)
	{
		return h == nullptr ? T{0} : h->sum;
	}

	static size_t size(const nodeptr &h)
	{
		return h == nullptr ? T{0} : h->sz;
	}

	static void upd(node &h)
	{
		h.sum = get_sum(h.l) + h.x + get_sum(h.r);
		h.sz = size(h.l) + 1 + size(h.r);
	}

	static nodeptr merge(nodeptr &&le, nodeptr &&ri)
	{
		if (le == nullptr)
			return std::move(ri);
		if (ri == nullptr)
			return std::move(le);

		if (le->y < ri->y)
		{
			auto rch = merge(std::move(le->r), std::move(ri));
			le->r = std::move(rch);

			upd(*le);

			return std::move(le);
		}
		else
		{
			auto lch = merge(std::move(le), std::move(ri->l));
			ri->l = std::move(lch);

			upd(*ri);

			return std::move(ri);
		}
	}

	static pair<nodeptr, nodeptr> split(nodeptr &&h, auto &&fn) // C++20
	{
		if (h == nullptr)
			return {nullptr, nullptr};

		if (fn(h))
		{
			auto [le, ri] = split(std::move(h->r), std::forward<decltype(fn)>(fn)); // structured binding, C++17

			h->r = std::move(le);

			upd(*h);

			return {std::move(h), std::move(ri)};
		}
		else
		{
			auto [le, ri] = split(std::move(h->l), std::forward<decltype(fn)>(fn));

			h->l = std::move(ri);

			upd(*h);

			return {std::move(le), std::move(h)};
		}
	}

	static auto split_by_key(nodeptr &&h, const T &x)
	{
		return split(std::move(h), [&x](const nodeptr &h)
		{
			return h->x < x;
		});
	}

	static auto split_by_size(nodeptr &&h, size_t k)
	{
		return split(std::move(h), [&k](const nodeptr &h)
		{
			if (auto ind = size(h->l); ind < k)
			{
				k -= ind + 1;

				return true;
			}
			else
				return false;
		});
	}

	nodeptr root = nullptr;

public:
	void insert(T x)
	{
		auto [le, ri] = split_by_key(std::move(root), x);
		root = merge(std::move(le), merge(make_node(x), std::move(ri)));
	}

	void erase(T x)
	{
		auto [le, tmp] = split_by_key(std::move(root), x);
		auto [mi, ri] = split(std::move(tmp), [&](const nodeptr &h)
		{
			return h->x <= x;
		});

		root = merge(std::move(le), std::move(ri));
	}

	bool contains(T x)
	{
		auto [le, tmp] = split_by_key(std::move(root), x);
		auto [mi, ri] = split(std::move(tmp), [&](const nodeptr &h)
		{
			return h->x <= x;
		});

		auto ans = (mi != nullptr);

		root = merge(std::move(le), merge(std::move(mi), std::move(ri)));

		return ans;
	}

	T segsum(T l, T r)
	{
		auto [le, tmp] = split_by_key(std::move(root), l);
		auto [mi, ri] = split_by_key(std::move(tmp), r);

		auto ans = get_sum(mi);

		root = merge(std::move(le), merge(std::move(mi), std::move(ri)));

		return ans;
	}

	[[nodiscard]] auto size() const
	{
		return size(root);
	}

	const T &operator[](size_t k)
	{
		auto [le, tmp] = split_by_size(std::move(root), k);
		auto [mi, ri] = split_by_size(std::move(tmp), 1);

		assert(mi != nullptr);

		const auto &ans = mi->x;

		root = merge(std::move(le), merge(std::move(mi), std::move(ri)));

		return ans;
	}
};


void solve(istream &cin = std::cin, ostream &cout = std::cout)
{
	treap<int> tr;

	int q;

	cin >> q;

	for (int i = 0; i < q; i++)
	{
		int type, x;

		cin >> type >> x;

		if (type == 1)
			tr.insert(x);
		else if (type == 0)
			cout << tr[tr.size() - x] << '\n';
		else if (type == -1)
			tr.erase(x);
		else
			assert(false);
	}
}


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

	cout << fixed;

#ifdef LOCAL
	auto st = chrono::steady_clock::now();

	ifstream fin("../input.txt");

	do
	{
		solve(fin);

		cout << "===" << endl;

		string str;
		while (getline(fin, str) && str != string(max(1, (int) str.size()), '='));
	} while (fin);

#ifdef STRESS
	for (int cnt = 1;; cnt++)
	{
		stringstream ss, in1, out1, in2, out2;

		gen(ss);

		in1 << ss.str();
		in2 << ss.str();

		solve(in1, out1);
		stress(in2, out2);

		if (out1.str() != out2.str())
		{
			cout << "fail: " << cnt << endl;
			cout << ss.str();
			cout << "solve:" << endl;
			cout << out1.str();
			cout << "stress:" << endl;
			cout << out2.str();

			break;
		}
		else if (cnt % 100 == 0)
			cout << "ok: " << cnt << endl;
	}
#endif

	cout << setprecision((int) floor(log10(chrono::steady_clock::duration::period::den)));
	cout << "clock: " << chrono::duration<double>(chrono::steady_clock::now() - st).count() << endl;
#else
	solve();
#endif

	return 0;
}
