#include <iostream>
#include <random>

using namespace std;

mt19937 MyLittleRandom(100500);

struct Node {
	int x;
	int y;
	int sz;
	int sum;
	Node* left;
	Node* right;

	Node(int cx) {
		x = cx;
		y = MyLittleRandom();
		sz = 1;
		sum = x;
		left = nullptr;
		right = nullptr;
	}

	void update() {
		sz = 1;
		if (left != nullptr) sz += left->sz;
		if (right != nullptr) sz += right->sz;

		sum = x;
		if (left != nullptr) sum += left->sum;
		if (right != nullptr) sum += right->sum;
	}
};

// =====

pair<Node*, Node*> split(Node* root, int x, bool equal_value_to_right = true) { // < and >=
	if (root == nullptr) {
		return make_pair(nullptr, nullptr);
	}
	if (root->x < x || (root->x == x && !equal_value_to_right)) {
		auto res = split(root->right, x, equal_value_to_right);
		root->right = res.first;
		root->update();
		return make_pair(root, res.second);
	}
	else {
		auto res = split(root->left, x, equal_value_to_right);
		root->left = res.second;
		root->update();
		return make_pair(res.first, root);
	}
}

pair<Node*, Node*> split_k(Node* root, int k) { 
	if (root == nullptr) {
		return make_pair(nullptr, nullptr);
	}
	if (root->left != nullptr) {
		if (root->left->sz >= k) {
			auto res = split_k(root->left, k);
			root->left = res.second;
			root->update();
			return make_pair(res.first, root);
		}
		else k -= root->left->sz;
	}
	if (k == 0) {
		return make_pair(nullptr, root);
	}
	auto res = split_k(root->right, k - 1);
	root->right = res.first;
	root->update();
	return make_pair(root, res.second);
}

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

// =====

Node* insert(Node* root, int x) {
	auto res = split(root, x);
	Node* x_tree = new Node(x);
	root = merge(x_tree, res.second);
	return merge(res.first, root);
}

Node* remove(Node* root, int x) {
	auto res = split(root, x);
	root = res.first;
	res = split(res.second, x, false);
	return merge(root, res.second);
}

Node* insert_k(Node* root, int x, int k) {
	auto res = split_k(root, k);
	Node* x_tree = new Node(x);
	root = merge(x_tree, res.second);
	return merge(res.first, root);
}

Node* remove_k(Node* root, int k) {
	auto res = split_k(root, k);
	root = res.first;
	res = split_k(res.second, 1);
	return merge(root, res.second);
}

Node* find(Node* root, int x) {
	if (root == nullptr) return nullptr;
	if (root->x == x) return root;
	if (root->x < x) {
		return find(root->right, x);
	}
	else {
		return find(root->left, x);
	}
}

Node* kth_element(Node* root, int k) {  // 1-based
	if (root == nullptr) return nullptr;
	if (root->left != nullptr) {
		if (root->left->sz >= k) {
			return kth_element(root->left, k);
		}
		else k -= root->left->sz;
	}
	if (k == 1) {
		return root;
	}
	return kth_element(root->right, k - 1);
}

pair<Node*, int> segment_sum(Node* root, int l, int r) { // [l, r]
	auto res_1 = split_k(root, r);
	auto res_2 = split_k(res_1.first, l - 1);
	int ans = 0;
	if (res_2.second != nullptr) ans = res_2.second->sum;
	root = merge(res_2.first, res_2.second);
	root = merge(root, res_1.second);
	return make_pair(root, ans);
}

// =====

int main() {
	Node* root = nullptr;
	while (true) {
		char ch;
		cin >> ch;
		if (ch == '+') {
			int x, k;
			cin >> x >> k;
			root = insert_k(root, x, k);
		}
		if (ch == '-') {
			int k;
			cin >> k;
			root = remove_k(root, k);
		}
		/* 
		if (ch == '?') {
			int x;
			cin >> x;
			auto res = find(root, x);
			if (res == nullptr) cout << "NO" << endl;
			else cout << "YES" << endl;
		} */
		if (ch == 'k') {
			int k;
			cin >> k;
			auto res = kth_element(root, k);
			if (res == nullptr) cout << "NO" << endl;
			else cout << res->x << endl;
		}
	}

	return 0;
}