#include <iostream>
#include <random>

using namespace std;

mt19937 rng(100500);

struct Node {
	int x;
	//int y;
	int sz;
	int mx;
	int sum;
	bool make_null;
	bool reverse;
	Node* left;
	Node* right;

	Node(int cx = 0) {
		x = cx;
		//y = rng();
		sz = 1;
		mx = x;
		sum = x;
		make_null = false;
		reverse = false;
		left = nullptr;
		right = nullptr;
	}

	Node(Node* v) {
		x = v->x;
		sz = v->sz;
		mx = v->mx;
		sum = v->sum;
		make_null = v->make_null;
		reverse = v->reverse;
		left = v->left;
		right = v->right;
	}

	void push() {
		if (make_null) {
			make_null = false;
			x = 0;
			if (left != nullptr) {
				left->make_null = true;
				left->upd();
			}
			if (right != nullptr) {
				right->make_null = true;
				right->upd();
			}
		}
		if (reverse) {
			reverse = false;
			swap(left, right);
			if (left != nullptr) {
				left->reverse = true;
				left->upd();
			}
			if (right != nullptr) {
				right->reverse = true;
				right->upd();
			}
		}
	}

	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);
		if (make_null) mx = 0;

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

pair<Node*, Node*> split(Node* root, int x) { // < & >=
	if (!root) {
		return make_pair(nullptr, nullptr);
	}
	if (root->x < x) {
		root->push();
		auto res = split(root->right, x);
		root = new Node(root);
		root->right = res.first;
		root->upd();
		res.first = root;
		return res;
	}
	else {
		root->push();
		auto res = split(root->left, x);
		root = new Node(root);
		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) {
			root->push();
			auto res = split_sz(root->left, k);
			root = new Node(root);
			root->left = res.second;
			root->upd();
			res.second = root;
			return res;
		}
		else k -= root->left->sz;
	}
	if (k == 0) {
		root->push();
		auto res = root->left;
		root = new Node(root);
		root->left = nullptr;
		root->upd();
		return make_pair(res, root);
	}

	root->push();
	auto res = split_sz(root->right, k - 1);
	root = new Node(root);
	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 (rng() * 1.0 / rng.max() < l->sz * 1.0 / (l->sz + r->sz)) {
		l->push();
		l = new Node(l);
		l->right = merge(l->right, r);
		l->upd();
		return l;
	}
	else {
		r->push();
		r = new Node(r);
		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;
	root->push();
	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);
}

Node* null_segment(Node* root, int l, int r) {
	auto res = split_sz(root, r);
	auto res_1 = split_sz(res.first, l);
	res_1.second->make_null = true;
	root = merge(res_1.first, res_1.second);
	root = merge(root, res.second);
	return root;
}

Node* reverse_segment(Node* root, int l, int r) {
	auto res = split_sz(root, r);
	auto res_1 = split_sz(res.first, l);
	res_1.second->reverse = true;
	root = merge(res_1.first, res_1.second);
	root = merge(root, res.second);
	return root;
}

Node* append_segment(Node* root, int l, int r) {
	auto res = split_sz(root, r);
	auto res_1 = split_sz(res.first, l);
	return merge(root, res_1.second);
}

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

// =====

int main() {
	Node* root = nullptr;
	vector<Node*> root_history = { 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, t;
			cin >> k >> t;
			cout << kth_element(root_history[t], 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, t;
			cin >> l >> r >> t;
			auto res = max_segment(root_history[t], l, r);
			//root = res.second;
			cout << res.first << endl;
		}
		if (ch == 's') {
			int l, r, t;
			cin >> l >> r >> t;
			auto res = sum_segment(root_history[t], l, r);
			//root = res.second;
			cout << res.first << endl;
		}
		if (ch == '0') {
			int l, r;
			cin >> l >> r;
			root = null_segment(root, l, r);
		}
		if (ch == 'R') {
			int l, r;
			cin >> l >> r;
			root = reverse_segment(root, l, r);
		}
		if (ch == 'A') {
			int l, r;
			cin >> l >> r;
			root = append_segment(root, l, r);
		}
		root_history.push_back(root);
		cout << "# " << root_history.size() - 1 << endl;
	}

	return 0;
}