调不活了。
// last update: 2022/10/05
//#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define fq(i,a,b) for (int i = (a); i <= (b); i++)
#define fnq(i,a,b) for (int i = (a); i < (b); i++)
#define nfq(i,a,b) for (int i = (a); i >= (b); i--)
#define nfnq(i,a,b) for (int i = (a); i > (b); i--)
#define fqs(i,a,b,c) for (int i = (a); i <= (b); i += (c))
#define fnqs(i,a,b,c) for (int i = (a); i < (b); i += (c))
#define nfqs(i,a,b,c) for (int i = (a); i >= (b); i -= (c))
#define nfnqs(i,a,b,c) for (int i = (a); i > (b); i -= (c))
#define elif else if
// //#define LAY
// //#define ONLINE_JUDGE
// #ifndef ONLINE_JUDGE
// #define EBUG
// #endif
// #ifdef EBUG
// //#undef EBUG
// #endif
// #ifdef EBUG
// #define DEBUG if (1)
// #define NDEBUG if (0)
// #else
// #define DEBUG if (0)
// #define NDEBUG if (1)
// #endif
// using namespace std;
// //#define int long long
// //#define GRAPH
// //const int EDGES = -1;
// //const int VERTEXES = -1;
// ////# define EDGE_W
// ////typedef int W_TYPE;
// #define FileIO
// #if !defined(LAY) || defined(FileIO)
// const string FileIOName = "P4008_1";
// int FILEIO (string IN, string OUT) {
// try {
// freopen ((FileIOName + IN).c_str (), "r", stdin);
// freopen ((FileIOName + OUT).c_str (), "w", stdout);
// return 0;
// } catch (int) {
// return -1;
// }
// }
// int freFILEIO = FILEIO (".in", ".ans");
// #endif
// //#define COMPLEX
// inline int rd () {
// int f = 1;
// char ch = getchar ();
// while (!isdigit (ch)) (ch == '-' ? (f = -1) : 0), ch = getchar ();
// int num = 0;
// while (isdigit (ch)) num = num * 10 + ch - '0', ch = getchar ();
// return num * f;
// }
// #define d rd ()
// inline int rd (const int modp) {
// int f = 1;
// char ch = getchar ();
// while (!isdigit (ch)) (ch == '-' ? (f = -1) : 0), ch = getchar ();
// int num = 0;
// while (isdigit (ch)) num = (num * 10 + ch - '0') % modp, ch = getchar ();
// return (num * f % modp + modp) % modp;
// }
// #ifdef GRAPH
// struct Edge {
// int v, nxt;
// # ifdef EDGE_W
// W_TYPE w;
// # endif
// Edge () {}
// # ifdef EDGE_W
// Edge (int _v, W_TYPE _w, int _nxt) {v = _v, w = _w, nxt = _nxt;}
// # else
// Edge (int _v, int _nxt) {v = _v, nxt = _nxt;}
// # endif
// } edge[EDGES];
// int head[VERTEXES], ecnt;
// # ifdef EDGE_W
// void addedge (int u, int v, W_TYPE w) {edge[++ecnt] = Edge (v, w, head[u]); head[u] = ecnt;}
// # define fe(u) for (int i = head[u], v, w; v = edge[i].v, w = edge[i].w, i; i = edge[i].nxt)
// # else
// void addedge (int u, int v) {edge[++ecnt] = Edge (v, head[u]); head[u] = ecnt;}
// # define fe(u) for (int i = head[u], v; v = edge[i].v, i; i = edge[i].nxt)
// # endif
// void init () {memset (head, 0, sizeof head); ecnt = 0;}
// #endif
// #ifdef COMPLEX
// struct cpx {
// double a, b;
// cpx () {a = 0, b = 0;}
// cpx (double _a) {a = _a, b = 0;}
// cpx (double _a, double _b) {a = _a, b = _b;}
// friend cpx operator + (cpx a, cpx b) {return cpx (a.a + b.a, a.b + b.b);}
// friend cpx operator - (cpx a, cpx b) {return cpx (a.a - b.a, a.b - b.b);}
// friend cpx operator * (cpx a, cpx b) {return cpx (a.a * b.a - a.b * b.b, a.b * b.a + a.a * b.b);}
// friend cpx operator / (cpx a, cpx b) {return cpx ((a.a * b.a + a.b * b.b) / (b.b * b.b + b.a * b.a), (a.b * b.a - a.a * b.b) / (b.b * b.b + b.a * b.a));}
// friend cpx operator += (cpx &a, cpx b) {return a = a + b;}
// friend cpx operator -= (cpx &a, cpx b) {return a = a - b;}
// friend cpx operator *= (cpx &a, cpx b) {return a = a * b;}
// friend cpx operator /= (cpx &a, cpx b) {return a = a / b;}
// };
// #endif
// inline void Write (int x) {
// if (x < 0) putchar ('-'), x *= -1;
// if (x >= 10) Write (x / 10);
// putchar (x % 10 + '0');
// }
// template <typename T> void write (char sep, char end, T x) {Write (x); putchar (end);}
// template <typename T, typename... Ts> void write (char sep, char end, T x, Ts... xs) {Write (x); putchar (sep); write (sep, end, xs...);}
// template <typename... Ts> void output (Ts... xs) {write (' ', '\n', xs...);}
// template <typename T = int>
// class _Math {
// public:
// static T exmax (T x) {return x;}
// template <typename... Ts> static T exmax (T x, Ts... xs) {return max (x, exmax (xs...));}
// static T exmin (T x) {return x;}
// template <typename... Ts> static T exmin (T x, Ts... xs) {return min (x, exmin (xs...));}
// template <typename... Ts> static T exgmax (T &x, Ts... xs) {return x = exmax (x, xs...);}
// template <typename... Ts> static T exgmin (T &x, Ts... xs) {return x = exmin (x, xs...);}
// static T gcd (T a, T b) {return !b ? a : gcd (b, a % b);}
// static T lcm (T a, T b) {return a / gcd (a, b) * b;}
// static T exgcd (T a, T b, T& x, T& y) {
// if (!b) {x = 1; y = 0; return a;}
// T ans = exgcd (b, a % b, y, x);
// y -= a / b * x;
// return ans;
// }
// static T crt (size_t n, T *a, T *p) {
// T M = 1, ans = 0;
// fq (i, 1, n) M *= p[i];
// fq (i, 1, n) {
// T m = M / p[i];
// T x, y;
// exgcd (m, p[i], x, y);
// ans += (x < 0 ? x + p[i] : x) * a[i] * m;
// } return ans % M;
// }
// static T excrt (size_t n, T *a, T *b) {
// T M = b[1], ans = a[1];
// fq (i, 2, n) {
// T aa = M, c = (a[i] - ans % b[i] + b[i]) % b[i];
// T x, y;
// T gcd = exgcd (aa, b[i], x, y);
// if (c % gcd) return -1;
// T bg = b[i] / gcd;
// x = c / gcd * x % bg;
// ans += x * M;
// M *= bg;
// ans = (ans % M + M) % M;
// }
// return (ans % M + M) % M;
// }
// static T power (T a, T b, T p) {
// T c = 1;
// while (b) {
// if (b & 1) c = c * a % p;
// a = a * a % p;
// b >>= 1;
// } return c;
// }
// private:
// static T C (T n, T m, T p) {
// T ans = 1;
// fq (i, n - m + 1, n) ans = ans * i % p;
// fq (i, 2, m) ans = ans * power (i, p - 2, p) % p;
// return ans;
// }
// public:
// static T lucas (T n, T m, T p) {
// if (!m || !n) return 1;
// return lucas (n / p, m / p, p) * C (n % p, m % p, p) % p;
// }
// static T bsgs (T a, T b, T p) {
// T mul = 1, t = sqrt (p) + 1;
// static map <T, T> mp;
// mp.clear ();
// fq (i, 1, t) {
// mul = mul * a % p;
// mp[b * mul % p] = i;
// }
// T mull = mul;
// fq (i, 1, t) {
// if (mp[mull]) return i * t - mp[mull];
// mull = mull * mul % p;
// } return -1;
// }
// };
// const _Math <> iMath;
// auto Math = iMath;
// template <typename T = int>
// class _ExMath {
// private:
// static void expr_skpop (stack <char> &sk1, stack <T> &sk2, T fun (T, T, char)) {
// T r = sk2.top (); sk2.pop ();
// T l = sk2.top (); sk2.pop ();
// char op = sk1.top (); sk1.pop ();
// sk2.push (fun (l, r, op));
// }
// public:
// static T expr (string s, map <char, short> mp, T fun (T, T, char)) {
// static stack <char> sk1;
// static stack <T> sk2;
// while (!sk1.empty ()) sk1.pop ();
// while (!sk2.empty ()) sk2.pop ();
// s = '(' + s + ')';
// int len = s.size ();
// fnq (i, 0, len) {
// if (isdigit (s[i])) {
// T num = 0;
// while (isdigit (s[i])) num = num * 10 + s[i] - '0', ++i;
// --i;
// sk2.push (num);
// } elif (s[i] == '(') {
// sk1.push ('(');
// } elif (s[i] == ')') {
// while (sk1.top () != '(')
// expr_skpop (sk1, sk2, fun);
// sk1.pop ();
// } else {
// while (!sk1.empty () && sk1.top () != '(' && mp[sk1.top ()] >= mp[s[i]])
// expr_skpop (sk1, sk2, fun);
// sk1.push (s[i]);
// }
// }
// return sk2.top ();
// }
// };
// const _ExMath <> iExMath;
// auto ExMath = iExMath;
const int maxn = 2 * 1048576 + 114514;
struct node {
int l, r, sz, pri;
char key;
node () {}
node (char k) {
key = k;
l = r = 0;
sz = 1;
pri = rand ();
}
} p[maxn];
int cnt;
queue <int> Q;
// #define assert(op) if((op) || 1);
int getid () {
if (!Q.empty ()) {
int u = Q.front (); Q.pop ();
if (p[u].l) Q.push (p[u].l);
if (p[u].r) Q.push (p[u].r);
return u;
} else return ++cnt;
}
int addnode (char k) {int u = getid (); assert (u < 2097999); p[u] = node (k); return u;}
#define sz(rt) p[rt].sz
#define ls p[rt].l
#define rs p[rt].r
#define pr(rt) p[rt].pri
#define lson(rt) p[rt].l
#define rson(rt) p[rt].r
void push_up (int rt) {sz(rt) = sz(ls) + sz(rs) + 1;}
pair <int, int> split (int rt, int k) {
// cout << rt << ' ' << k << ' ' << sz(rt) << endl;
assert (k <= sz(rt));
assert (! (rt == 0 && k));
if (!rt) return {0, 0};
if (!k) return {0, rt};
if (k <= sz(ls)) {
auto q = split (ls, k);
ls = q.second;
push_up (rt);
return {q.first, rt};
} else {
auto q = split (rs, k - 1 - sz(ls));
rs = q.first;
push_up (rt);
return {rt, q.second};
}
}
int merge (int l, int r) {
if (!l || !r) return l | r;
if (pr(l) < pr(r)) {
rson(l) = merge (rson(l), r);
push_up (l);
return l;
} else {
lson(r) = merge (l, lson(r));
push_up (r);
return r;
}
}
int root;
int pos;
char s[maxn];
int sk[maxn], top;
void insert (int n) {
assert(pos <= sz(root));
auto q = split (root, pos);
top = 0;
fq (i, 1, n) {
int u = addnode (s[i]);
int k = top;
while (k && pr (sk[k]) >= pr (u)) push_up (sk[k]), --k;
if (k) rson(sk[k]) = u, push_up (sk[k]);
if (k != top) lson(u) = sk[k + 1], push_up (u);
sk[top = ++k] = u;
} while (top) push_up (sk[top--]);
root = merge (q.first, merge (sk[1], q.second));
}
void del (int k) {
assert(pos <= sz(root));
auto q = split (root, pos);
assert(k <= sz(q.second));
auto r = split (q.second, k);
Q.push (q.second);
root = merge (q.first, r.second);
}
void dfs (int rt) {
if (ls) dfs (ls);
putchar (p[rt].key);
if (rs) dfs (rs);
}
void get (int k) {
assert(pos <= sz(root));
auto q = split (root, pos);
assert(k <= sz(q.second));
auto r = split (q.second, k);
dfs (r.first); putchar ('\n');
root = merge (q.first, merge (r.first, r.second));
}
int ccnt;
signed main () {
int q = d;
while (q--) {
assert (ccnt == sz(root));
scanf ("%s", s + 1);
if (s[1] == 'M') {
pos = d;
// cout <<pos << endl;
assert (pos <= sz(root));
} elif (s[1] == 'P') {
pos--;
if (pos < 0) pos = 0;
} elif (s[1] == 'N') {
pos++;
if (pos > sz(root)) pos = sz(root);
assert (pos <= sz(root));
} elif (s[1] == 'G') {
get (d);
} elif (s[1] == 'D') {
int l = d;
del (l);
ccnt -= l;
assert (pos <= sz(root));
} else {
int l = d;
ccnt += l;
int cnt = 1;
char c = getchar ();
while (cnt <= l) {
if (c >= 32 && c <= 128) s[cnt++] = c;
c = getchar ();
} insert (l);
}
}
return 0;
}
/*
15
Insert 26
abcdefghijklmnop
qrstuv wxy
Move 15
Delete 11
Move 5
Insert 1
^
Next
Insert 1
_
Next
Next
Insert 4
.\/.
Get 4
Prev
Insert 1
^
Move 0
Get 22
*/