#include <iostream>
#include <random>

using namespace std;

mt19937 rng(100500);

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

	Node(int cx = 0) {
		x = cx;
		y = rng();
		sz = 1;
		mx = x;
		left = nullptr;
		right = nullptr;
	}

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

		mx = x;
		if (left != nullptr) mx = max(mx, left->mx);
		if (right != nullptr) mx = max(mx, right->mx);
	}
};

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

pair<Node*, Node*> split_sz(Node* root, int k) { // k = left->sz
	if (!root) {
		return make_pair(nullptr, nullptr);
	}
	if (root->left != nullptr) {
		if (k <= root->left->sz) {
			auto res = split_sz(root->left, k);
			root->left = res.second;
			root->upd();
			res.second = root;
			return res;
		}
		else k -= root->left->sz;
	}
	if (k == 0) {
		auto res = root->left;
		root->left = nullptr;
		root->upd();
		return make_pair(res, root);
	}

	auto res = split_sz(root->right, k - 1);
	root->right = res.first;
	root->upd();
	res.first = root;
	return res;
}

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

// =====

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

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

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

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

Node* insert_sz(Node* root, int k, int x) {
	auto res = split_sz(root, k);
	Node* node_x = new Node(x);
	root = merge(res.first, node_x);
	root = merge(root, res.second);
	return root;
}

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

Node* switch_segments(Node* root, int lo, int me, int hi) {
	auto res = split_sz(root, me);
	auto res_l = split_sz(res.first, lo);
	auto res_r = split_sz(res.second, hi - me);
	root = merge(res_l.first, res_r.first);
	root = merge(root, res_l.second);
	root = merge(root, res_r.second);
	return root;
}

pair<int, Node*> max_segment(Node* root, int l, int r) {
	auto res = split_sz(root, r);
	auto res_1 = split_sz(res.first, l);
	int mx = res_1.second->mx;
	root = merge(res_1.first, res_1.second);
	root = merge(root, res.second);
	return make_pair(mx, root);
}

// =====

int main() {
	Node* root = nullptr;

	while (true) {
		char ch;
		cin >> ch;
		if (ch == '+') {
			int k;
			int x;
			cin >> k >> x;
			root = insert_sz(root, k, x);
		}
		if (ch == '-') {
			int k;
			cin >> k;
			root = remove_sz(root, k);
		}
		if (ch == '?') {
			int k;
			cin >> k;
			cout << kth_element(root, k) << endl;
		}
		if (ch == 'S') {
			int lo, me, hi;
			cin >> lo >> me >> hi;
			root = switch_segments(root, lo, me, hi);
		}
		if (ch == 'M') {
			int l, r;
			cin >> l >> r;
			auto res = max_segment(root, l, r);
			root = res.second;
			cout << res.first << endl;
		}
	}

	return 0;
}