//неявное дд
#include <iostream>
#include <random>
#include <chrono>
using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct Node
{
	//int x;
	int data;
	int y;
	Node* left;
	Node* right;
	int tSize;

	Node(int data_)
	{
		left = nullptr;
		right = nullptr;
		data = data_;
		y = rng();
		tSize = 1;
	}
};


int Recalc(Node* t)
{
	if (t == nullptr)
		return 0;
	t->tSize = 1;
	if (t->left)
	{
		t->tSize += t->left->tSize;
	}
	if (t->right)
	{
		t->tSize += t->right->tSize;
	}
	return t->tSize;
}


int GetSize(Node* t)
{
	if (!t)
	{
		return 0;
	}
	return t->tSize;
}


pair<Node*, Node*> TreapSplit(Node* t, int x)
{
	if (t == nullptr)
		return { nullptr, nullptr };
	if (GetSize(t->left) < x-1)
	{
		auto temp = TreapSplit(t->right, x - GetSize(t->left) -1);
		t->right = temp.first;
		Recalc(t);
		return{ t, temp.second };
	}
	if (GetSize(t->left) > x-1)
	{
		auto temp = TreapSplit(t->left, x);
		t->left = temp.second;
		Recalc(t);
		return { temp.first, t };
	}
	if(GetSize(t->left) == x - 1)
	{
		auto temp = t->left;
		t->left = nullptr;
		return { temp, t };
	}
}

Node* TreapMerge(Node* l, Node* r)
{
	if (l == nullptr)
		return r;
	if (r == nullptr)
		return l;

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

void TreapDelete(Node* t)
{
	if (t == nullptr)
		return;
	TreapDelete(t->left);
	TreapDelete(t->right);
	delete t;
}


Node* TreapInsert(Node* t, int data)
{
	Node* nodex = new Node(data);
	return TreapMerge(t, nodex);
}

/*Node* TreapRemove(Node* t, int x)
{
	auto temp = TreapSplit(t, x);
	auto temp2 = TreapSplit(temp.second, x + 1);
	TreapDelete(temp2.first);
	return TreapMerge(temp.first, temp2.second);
}*/

void TreapOutput(Node* t, int depth)
{
	if (t == nullptr)
		return;
	TreapOutput(t->left, depth + 1);
	for (int i = 0; i < depth; i++)
	{
		cout << " ";
	}
	cout << t->data << endl;
	TreapOutput(t->right, depth + 1);
}

int TreapFind(Node* t, int x)
{

	if (x == GetSize(t->left) + 1)
		return t -> data;
	if (x > GetSize(t->left) + 1)
		return TreapFind(t->right, x - GetSize(t->left)-1);
	if (x < GetSize(t->left) + 1)
		return TreapFind(t->left, x);
}


Node* kthOrdStat(Node* t, int k)
{
	if (!t)
		return nullptr;
	if (GetSize(t->left) == k - 1)
		return t;
	if (GetSize(t->left) > k - 1)
		return kthOrdStat(t->left, k);
	return kthOrdStat(t->right, k - GetSize(t->left) - 1);
}


int main()
{
	/*int size = 50;
	Node* root = new Node(rng() % 100);
	for (int i = 0; i < size; i++)
	{
		root = TreapInsert(root, rng() % 100);
	}
	TreapOutput(root, 0);*/

	char cmd;
	int cnt;
	cin >> cnt;
	int x;
	Node* t = nullptr;

	for (int i = 0; i < cnt; i++)
	{
		cin >> cmd;
		if (cmd == '+')
		{
			cin >> x;
			t = TreapInsert(t, x);
		}
		if (cmd == '-')
		{
			cin >> x;
			//t = TreapRemove(t, x);
		}
		if (cmd == '?')
		{
			cin >> x;
			if (GetSize(t) < x)
				cout << "NO" << endl;
			else
				cout << TreapFind(t, x);
		}
		if (cmd == 's')
		{
			if (!t)
			{
				cout << 0 << endl;
			}
			else
				cout << t->tSize << endl;
		}
		if (cmd == 'p')
		{
			TreapOutput(t, 0);
		}
	}

	return 0;
}
