#include <bits/stdc++.h>

using namespace std;

mt19937 mt(736);


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

		const T x;
		nodeptr l, r;
		size_t sz;

		explicit node(const T &x = T{}, const nodeptr &l = nullptr, const nodeptr &r = nullptr) :
				x(x), l(l), r(r), sz(get_size(l) + 1 + get_size(r))
		{}
	};

	using nodeptr = typename node::nodeptr;

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

	static nodeptr make_node(const T &x, const nodeptr &l = nullptr, const nodeptr &r = nullptr)
	{
		return make_shared<node>(x, l, r);
	}

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

		if (uniform_int_distribution<size_t> uid(0, get_size(le) + get_size(ri) - 1); uid(mt) < get_size(le))
			return make_node(le->x, le->l, merge(le->r, ri));
		else
			return make_node(ri->x, merge(le, ri->l), ri->r);
	}

	static pair<nodeptr, nodeptr> split(const nodeptr &h, const function<bool(const nodeptr &)> &fn)
	{
		if (h == nullptr)
			return {nullptr, nullptr};

		if (fn(h))
		{
			auto[le, ri] = split(h->r, fn); // structured binding

			return {make_node(h->x, h->l, le), ri};
		}
		else
		{
			auto[le, ri] = split(move(h->l), fn);

			return {le, make_node(h->x, ri, h->r)};
		}
	}

	static const T &front(const nodeptr &h)
	{
		if (h->l == nullptr)
			return h->x;
		return front(h->l);
	}

	nodeptr root = nullptr;

public:
	// move's in insert and erase functions are no longer necessary, but they make our code a bit faster, because
	// moving is faster than copying (the difference is that you don't need to change the reference counter)
	void insert(const T &x)
	{
		auto cmp_less = [&x](const nodeptr &h) -> bool
		{
			return h->x < x;
		};

		auto[le, ri] = split(move(root), cmp_less);

		root = merge(move(le), merge(make_node(x), move(ri)));
	}

	void erase(const T &x)
	{
		auto cmp_less = [&x](const nodeptr &h) -> bool
		{
			return h->x < x;
		};
		auto cmp_leq = [&x](const nodeptr &h) -> bool
		{
			return h->x <= x;
		};

		auto[le, ri] = split(move(root), cmp_less);
		auto[lri, rri] = split(move(ri), cmp_leq);

		root = merge(move(le), move(rri));
	}


	[[nodiscard]] const T &nth_element(size_t n) const
	{
		auto cmp = [&n](const nodeptr &h)
		{
			if (auto sz = get_size(h->l); sz < n)
			{
				n -= sz + 1;

				return true;
			}
			else
				return false;
		};

		auto[le, ri] = split(move(root), cmp);

		if (ri == nullptr)
			throw out_of_range("");

		return front(ri); // here we can omit merge because our treap is now persistent
	}


	[[nodiscard]] bool empty() const
	{
		return root == nullptr;
	}


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

	[[nodiscard]] const T &front() const
	{
		if (empty())
			throw out_of_range("front of an empty treap");

		return front(root);
	}
};


void solve(istream &cin = std::cin, ostream &cout = std::cout)
{
	int q;

	cin >> q;

	treap<int> tr;

	for (int i = 0; i < q; i++)
	{
		char ch;
		int x;

		cin >> ch >> x;

		if (ch == '+')
			tr.insert(x);
		if (ch == '-')
			tr.erase(x);

		cout << (tr.empty() ? -1 : tr.nth_element(tr.size() - 1)) << endl;
	}
}


void stress(istream &cin = std::cin, ostream &cout = std::cout)
{
	int q;

	cin >> q;

	multiset<int> tr;

	for (int i = 0; i < q; i++)
	{
		char ch;
		int x;

		cin >> ch >> x;

		if (ch == '+')
			tr.insert(x);
		if (ch == '-')
			tr.erase(x);

		cout << (tr.empty() ? -1 : *tr.rbegin()) << endl;
	}
}


void gen(ostream &cout = std::cout)
{
	const int q = 10;

	cout << q << endl;

	uniform_int_distribution<int> uid(0, 10), type(0, 1);

	for (int j = 0; j < q; j++)
		cout << (type(mt) ? '+' : '-') << ' ' << uid(mt) << endl;
}


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);

	for (int cnt = 0; cnt < (int) 1e4; cnt++)
	{
		stringstream ss, in1, in2, out1, 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;
	}

	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;
}
