#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <vector>
using namespace std;
struct node {
int value;
int priority;
int cnt;
bool rev;
node* left;
node* right;
node(int _value) : value(_value) {
priority = rand();
cnt = 1;
rev = false;
left = right = nullptr;
}
};
typedef node* pnode;
pnode root;
int getSize(pnode root) {
return root == nullptr ? 0 : root -> cnt;
}
void updateSize(pnode root) {
if (root != nullptr) {
root -> cnt = 1 + getSize(root -> left) + getSize(root -> right);
}
}
void pushUpdates(pnode root) {
if (root != nullptr && root -> rev) {
swap(root -> left, root -> right);
root -> rev = false;
if (root -> left != nullptr) {
root -> left -> rev ^= true;
}
if (root -> right != nullptr) {
root -> right -> rev ^= true;
}
}
}
pair<pnode, pnode> split(pnode root, int key, int add = 0) {
if (root == nullptr) {
return {nullptr, nullptr};
}
pushUpdates(root);
int currKey = add + getSize(root -> left);
pair<pnode, pnode> result;
if (currKey <= key) {
auto rightSplit = split(root -> right, key, currKey + 1);
root -> right = rightSplit.first;
result = {root, rightSplit.second};
} else {
auto leftSplit = split(root -> left, key, add);
root -> left = leftSplit.second;
result = {leftSplit.first, root};
}
updateSize(root);
return result;
}
pnode merge(pnode root1, pnode root2) {
if (root1 == nullptr || root2 == nullptr) {
return root1 == nullptr ? root2 : root1;
}
pushUpdates(root1);
pushUpdates(root2);
pnode result;
if (root1 -> priority > root2 -> priority) {
root1 -> right = merge(root1 -> right, root2);
result = root1;
} else {
root2 -> left = merge(root1, root2 -> left);
result = root2;
}
updateSize(result);
return result;
}
void debug(pnode root, vector<int>& result) {
if (root == nullptr) {
return;
}
pushUpdates(root);
debug(root -> left, result);
result.push_back(root -> value);
debug(root -> right, result);
}
vector<int> debug() {
vector<int> result;
result.reserve(getSize(root));
debug(root, result);
return result;
}
void insert(pnode& root, int pos, int value) {
pnode newNode = new node(value);
auto lt = split(root, pos - 1);
root = merge(lt.first, newNode);
root = merge(root, lt.second);
}
int get(pnode& root, int k) {
auto lt = split(root, k - 1);
auto ge = split(lt.second, 0);
int result = ge.first -> value;
root = merge(ge.first, ge.second);
root = merge(lt.first, root);
return result;
}
void reverse(pnode& root, int from, int to) {
auto lt = split(root, from - 1);
auto ge = split(lt.second, to - from);
ge.first -> rev ^= true;
root = merge(ge.first, ge.second);
root = merge(lt.first, root);
}
void erase(pnode& root, int from, int to) {
auto lt = split(root, from - 1);
auto ge = split(lt.second, to - from);
root = merge(lt.first, ge.second);
}
int main() {
freopen("secv8.in", "r", stdin);
freopen("secv8.out", "w", stdout);
cin.tie(nullptr);
ios_base::sync_with_stdio(false);
int N, revExists;
string op;
int a, b;
cin >> N >> revExists;
for (int idx = 0; idx < N; idx++) {
cin >> op;
if (op == "I") {
cin >> a >> b;
insert(root, a - 1, b);
} else if (op == "A") {
cin >> a;
// cout << "ACCESS " << a - 1 << "\n";
cout << get(root, a - 1) << "\n";
} else if (op == "R") {
cin >> a >> b;
reverse(root, a - 1, b - 1);
} else if (op == "D") {
cin >> a >> b;
erase(root, a - 1, b - 1);
}
}
vector<int> result = debug();
for (auto entry : debug()) {
cout << entry << " ";
}
cout << "\n";
return 0;
}