#include <iostream>
#include <cstdlib>
#include <functional>
#include <fstream>
using namespace std;
namespace treap {
int myRand() {
return ((rand()&((1<<15)-1))<<15) + (rand()&((1<<15)-1));
}
template<typename T>
struct Node {
T val;
int prio, sub;
bool sw;
Node *left, *right, *father;
Node(const T& val) : val(val), prio(myRand()), sub(1), sw(false),
left(NULL), right(NULL), father(NULL) {}
int leftSize() const {
return (left == NULL ? 0 : left->sub);
}
void update() {
sub = 1;
if (left != NULL) {
sub += left->sub;
left->father = this;
}
if (right != NULL) {
sub += right->sub;
right->father = this;
}
}
void lazy() {
if (sw) {
swap(left, right);
if (left != NULL)
left->sw ^= 1;
if (right != NULL)
right->sw ^= 1;
sw = false;
}
}
};
template<typename T>
class Iterator {
Node<T>* current;
int rank;
public:
Iterator(Node<T>* current, int rank=0) : current(current), rank(rank) {}
Iterator operator ++() {
if (current->right != NULL) {
current = current->right;
current->lazy();
while (current->left != NULL) {
current = current->left;
current->lazy();
}
} else {
Node<T>* last = current;
current = current->father;
while (current != NULL) {
if (last == current->left) {
break;
}
last = current;
current = current->father;
}
}
++rank;
return (*this);
}
int getRank() {
return rank;
}
bool invalid() {
return current == NULL;
}
T getValue() {
return current->val;
}
};
template<typename T>
class Treap {
Node<T>* root;
int sz;
int aux;
// First k-1 nodes in L, everything else in R.
void splitAtKth(Node<T>* C, Node<T>*& L, Node<T>*& R, int k) {
if (C == NULL) {
L = NULL;
R = NULL;
return;
}
C->lazy();
if (C->leftSize() + 1 < k) {
L = C;
splitAtKth(C->right, L->right, R, k - C->leftSize() - 1);
L->update();
} else {
R = C;
splitAtKth(C->left, L, R->left, k);
R->update();
}
}
void insertAtKth(Node<T>*& C, Node<T>* N, int k) {
if (C == NULL) {
C = N;
return;
}
C->lazy();
if (N->prio < C->prio) {
Node<T> *L, *R;
splitAtKth(C, L, R, k);
C = N;
C->left = L;
C->right = R;
++sz;
} else if (C->leftSize() >= k-1) {
insertAtKth(C->left, N, k);
} else {
insertAtKth(C->right, N, k - C->leftSize() - 1);
}
C->update();
}
// All nodes smaller than or equal to comp in L, everything else in R
void splitByComparison(Node<T>* C, Node<T>*& L, Node<T>*& R, const T& comp) {
if (C == NULL) {
L = NULL;
R = NULL;
}
C->lazy();
if (C->val <= comp) {
L = C;
splitByComparison(C->right, L->right, R, comp);
L->update();
} else {
R = C;
splitByComparison(C->left, L, R->left, comp);
R->update();
}
}
void insertByComparison(Node<T>*& C, Node<T>* N) {
if (C == NULL) {
C = N;
return;
}
C->lazy();
if (N->prio < C->prio) {
Node<T> *L, *R;
split(C, L, R, N->val);
C = N;
C->left = L;
C->right = R;
++sz;
} else if (N->val <= C->val) {
insertByComparison(C->left, N);
} else {
insertByComparison(C->right, N);
}
C->update();
}
void join(Node<T>*& C, Node<T>* L, Node<T>* R) {
if (L == NULL) {
C = R;
return;
}
if (R == NULL) {
C = L;
return;
}
L->lazy();
R->lazy();
if(L->prio < R->prio) {
C = L;
join(C->right, L->right, R);
C->update();
} else {
C = R;
join(C->left, L, R->left);
C->update();
}
}
void eraseKth(Node<T>*& C, int k) {
C->lazy();
if (C->leftSize() + 1 == k) {
Node<T> *L = C->left, *R = C->right;
delete C;
C = NULL;
join(C, L, R);
--sz;
} else if (C->leftSize() >= k-1) {
eraseKth(C->left, k);
} else {
eraseKth(C->right, k - C->leftSize() - 1);
}
if (C != NULL)
C->update();
}
void eraseByComparison(Node<T>*& C, const T& val) {
if (C == NULL)
return;
C->lazy();
if (C->val == val) {
Node<T> *L = C->left, *R = C->right;
delete C;
C = NULL;
join(C, L, R);
--sz;
} else if (val <= C->val) {
eraseByComparison(C->left, val);
} else {
eraseByComparison(C->right, val);
}
if (C != NULL)
C->update();
}
Iterator<T> getKth(Node<T>* C, int k) {
C->lazy();
if (C->leftSize() + 1 == k) {
return Iterator<T>(C, aux);
} else if (C->leftSize() >= k-1) {
return getKth(C->left, k);
} else {
return getKth(C->right, k - C->leftSize() - 1);
}
}
Iterator<T> firstSatisfying(Node<T>* C, const T& val,
const function<bool (const T&, const T&)>& comp) {
if (C == NULL) {
return Iterator<T>(NULL);
}
C->lazy();
if (comp(val, C->val)) {
auto it = firstSatisfying(C->left, val, comp);
if (it.invalid()) {
it = Iterator<T>(C, aux + 1);
}
return it;
} else {
aux += C->leftSize() + 1;
return firstSatisfying(C->right, val, comp);
}
}
public:
Treap() : root(NULL), sz(0) {}
void insertAtKth(const T& val, int k) {
Node<T> *N = new Node<T>(val);
insertAtKth(root, N, k);
}
// Needs operator <= defined on T.
void insertByComparison(const T& val) {
Node<T> *N = new Node<T>(val);
insertByComparison(root, N);
}
bool eraseKth(int k) {
int oldSz = sz;
eraseKth(root, k);
if (root != NULL) {
root->father = NULL;
}
return sz < oldSz;
}
// Erases one instance of val.
// Needs operator == and <= defined on T.
bool eraseByComparison(const T& val) {
int oldSz = sz;
eraseByComparison(root, val);
if (root != NULL) {
root->father = NULL;
}
return sz < oldSz;
}
Iterator<T> getKth(int k) {
aux = k;
return getKth(root, k);
}
Iterator<T> first() {
return getKth(1);
}
Iterator<T> last() {
return getKth(sz);
}
// Requires operator <= defined on T.
Iterator<T> lowerBound(const T& val) {
aux = 0;
return firstSatisfying(root, val, [](const T& a, const T& b) {
return a <= b;
});
}
// Requires operator < defined on T.
Iterator<T> upperBound(const T& val) {
aux = 0;
return firstSatisfying(root, val, [](const T& a, const T& b) {
return a < b;
});
}
void reverse(int i, int j) {
Node<T> *T12, *T1, *T2, *T3;
splitAtKth(root, T12, T3, j+1);
splitAtKth(T12, T1, T2, i);
if (T2 != NULL) {
T2->sw ^= 1;
}
join(T12, T1, T2);
join(root, T12, T3);
}
// Requires operator << between ostream and T.
void printAll(ostream& out) {
for (Iterator<T> it = first(); !it.invalid(); ++it) {
out << it.getValue() << " ";
}
}
int size() const {
return sz;
}
};
}
int main() {
ifstream fin("secv8.in");
ofstream fout("secv8.out");
treap::Treap<int> t;
int n, op;
fin >> n >> op;
for (int i = 1; i <= n; ++i) {
char op;
fin >> op;
if (op == 'I') {
int k, e;
fin >> k >> e;
t.insertAtKth(e, k);
} else if (op == 'A') {
int k;
fin >> k;
fout << t.getKth(k).getValue() << "\n";
} else if (op == 'R') {
int l, r;
fin >> l >> r;
t.reverse(l, r);
} else {
int l, r;
fin >> l >> r;
for (int j = l; j <= r; ++j) {
t.eraseKth(l);
}
}
}
t.printAll(fout);
}