#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 300005;
struct TrieInfo
{
int To[26], Fa[4][32], ref, l;
};
struct Match
{
int l, r, len;
Match(void) {}
Match(int a, int b, int c) : l(a), r(b), len(c) {}
} Info[MAXN], Map[26];
int Sa[MAXN], Rank[MAXN], Ti[MAXN], Cnt;
int Final[MAXN], Next[MAXN], total, Ans[MAXN];
namespace Trie
{
const int MAXN = 100005;
TrieInfo T[MAXN];
int Trans[MAXN], A[MAXN], cnt;
void First()
{
cnt = 1;
Trans[1] = -1;
}
int Insert(int cur, char c)
{
c = c - 'a';
if (T[cur].To[c])
return T[cur].To[c];
T[++cnt].Fa[0][1] = cur;
T[cnt].l = T[cur].l + 1;
Trans[cnt] = c;
return (T[cur].To[c] = cnt);
}
int Getfa(int u, int dep)
{
int cur = u;
for (int i = 0; i < 4; i++, dep >>= 5)
{
int p = (dep & 31);
if (!p)
{
continue;
}
cur = T[cur].Fa[i][p];
}
return cur;
}
void Work()
{
for (int i = 2; i < 32; i++)
for (int j = 1; j <= cnt; j++)
T[j].Fa[0][i] = T[T[j].Fa[0][i - 1]].Fa[0][1];
for (int i = 1; i < 4; i++)
for (int j = 1; j < 32; j++)
for (int k = 1; k <= cnt; k++)
{
if (j == 1)
T[k].Fa[i][j] = T[T[k].Fa[i - 1][31]].Fa[i - 1][1];
else
T[k].Fa[i][j] = T[T[k].Fa[i][j - 1]].Fa[i][1];
}
}
void Add(int p, int v)
{
for (; p <= Cnt; p += p & -p)
{
A[p] += v;
}
}
int Sum(int p)
{
if (p < 0)
return 0;
int tmp = 0;
for (; p; p -= p & -p)
tmp += A[p];
return tmp;
}
int Sum(int l, int r)
{
if (l > r)
return 0;
return Sum(r) - Sum(l - 1);
}
void Dfs(int Now)
{
Add(Rank[Now], 1);
for (int j = Final[Now]; j; j = Next[j])
{
Ans[j] = Sum(Info[Ti[j]].l, Info[Ti[j]].r);
if (!Info[Ti[j]].len)
Ans[j] = 0;
}
for (int i = 0; i < 26; i++)
if (T[Now].To[i])
Dfs(T[Now].To[i]);
Add(Rank[Now], -1);
}
void GetAns()
{
Dfs(1);
}
}
namespace SAM
{
struct Node
{
int To[26], fail, len, down, ref;
} T[MAXN];
int Go[MAXN][26];
int Q[MAXN], Ord[MAXN], S, cnt;
bool cmp(int a, int b)
{
return T[a].len < T[b].len;
}
int Add(int Lst, int c, int l, int cur)
{
int Nt = ++cnt, p = Lst;
T[Nt].len = l;
for (; p && !T[p].To[c]; p = T[p].fail)
T[p].To[c] = Nt;
if (!p)
T[Nt].fail = S;
else if (T[T[p].To[c]].len == T[p].len + 1)
T[Nt].fail = T[p].To[c];
else
{
int q = ++cnt, qt = T[p].To[c];
T[q] = T[qt];
T[qt].fail = T[Nt].fail = q;
for (; p && T[p].To[c] == qt; p = T[p].fail)
T[p].To[c] = q;
}
return Nt;
}
void Dfs(int Now)
{
if (T[Now].ref)
Sa[++Cnt] = T[Now].ref, Rank[T[Now].ref] = Cnt;
for (int i = 0; i < 26; i++)
if (Go[Now][i])
Dfs(Go[Now][i]);
}
void Mark(int tnod, int snod)
{
T[snod].down = T[snod].ref = tnod;
for (int i = 0; i < 26; i++)
if (Trie::T[tnod].To[i])
Mark(Trie::T[tnod].To[i], T[snod].To[i]);
}
void Build()
{
int fi = 0, en = 1;
Q[1] = 1;
S = cnt = 1;
Trie::T[1].ref = 1;
T[1].ref = 1;
while (fi < en)
{
int u = Q[++fi];
TrieInfo &c = Trie::T[u];
for (int i = 0; i < 26; i++)
if (c.To[i])
{
TrieInfo &cur = Trie::T[c.To[i]];
Trie::T[c.To[i]];
cur.ref = Add(c.ref, i, cur.l, c.To[i]);
Q[++en] = c.To[i];
}
}
Mark(1, 1);
for (int i = 1; i <= cnt; i++)
Ord[i] = i;
sort(Ord + 1, Ord + cnt + 1, cmp);
for (; cnt > 1; cnt--)
{
int v = Ord[cnt], u = T[v].fail;
T[u].down = T[v].down;
TrieInfo &cur = Trie::T[T[v].down];
int k = Trie::Getfa(T[u].down, cur.l - (T[cur.ref].len - T[u].len));
Go[u][Trie::Trans[k]] = v;
}
Dfs(1);
}
}
struct Quer
{
int type, s, t;
char c;
} Q[MAXN];
int Refer[MAXN], Len[MAXN], N, M, Tc;
inline bool Small(int suf, const Match &a)
{
return Rank[suf] < a.l;
}
inline bool Large(int suf, const Match &a)
{
return Rank[suf] > a.r;
}
Match Merge(const Match &a, const Match &b)
{
if (a.l > a.r)
return Match(0, -1, a.len + b.len);
int l = a.l, r = a.r, l1 = a.l - 1, r1 = a.r + 1, mid;
for (; l <= r;)
{
mid = (l + r) >> 1;
if (Small(Trie::Getfa(Sa[mid], a.len), b))
l1 = mid, l = mid + 1;
else
r = mid - 1;
}
for (l = a.l, r = a.r; l <= r;)
{
mid = (l + r) >> 1;
if (Large(Trie::Getfa(Sa[mid], a.len), b))
r1 = mid, r = mid - 1;
else
l = mid + 1;
}
return Match(l1 + 1, r1 - 1, a.len + b.len);
}
int main()
{
Trie::First();
N = 1;
Refer[1] = 1;
scanf("%d", &M);
for (int i = 1; i <= M; i++)
{
int type, s, t;
char c;
scanf("%d %d", &type, &s);
if (type == 1)
{
scanf("%c", &c);
s = Refer[s];
Refer[++N] = Trie::Insert(s, c);
}
if (type == 2)
{
scanf("%d %c", &t, &c);
Q[i].type = s + 1;
Q[i].s = t;
Q[i].c = c;
}
if (type == 3 || type == 4)
{
scanf("%d", &t), Q[i].type = type, Q[i].s = s, Q[i].t = t;
}
}
Trie::Work();
SAM::Build();
Tc = 1;
Info[1].l = 1, Info[1].r = Cnt;
for (int i = 0; i < 26; i++)
{
int l = 1, r = Cnt, mid;
Map[i].r = Cnt + 1;
for (; l <= r;)
{
mid = (l + r) >> 1;
if (Trie::Trans[Sa[mid]] < i)
Map[i].l = mid, l = mid + 1;
else
r = mid - 1;
}
for (l = 1, r = Cnt; l <= r;)
{
mid = (l + r) >> 1;
if (Trie::Trans[Sa[mid]] > i)
Map[i].r = mid, r = mid - 1;
else
l = mid + 1;
}
Map[i].l++, Map[i].r--;
Map[i].len = 1;
}
for (int i = 1; i <= M; i++)
{
Quer &c = Q[i];
if (!c.type)
continue;
if (c.type != 4)
++Tc;
if (c.type == 4)
{
++total;
c.t = Refer[c.t];
Next[total] = Final[c.t], Final[c.t] = total;
Ti[total] = c.s;
}
else
{
if (c.type == 1)
Info[Tc] = Merge(Info[c.s], Map[c.c - 'a']);
if (c.type == 2)
Info[Tc] = Merge(Map[c.c - 'a'], Info[c.s]);
if (c.type == 3)
Info[Tc] = Merge(Info[c.t], Info[c.s]);
}
}
Trie::GetAns();
for (int i = 1; i <= total; i++)
printf("%d\n", Ans[i]);
return 0;
}
I2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPGNzdHJpbmc+CiNpbmNsdWRlIDxhbGdvcml0aG0+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CmNvbnN0IGludCBNQVhOID0gMzAwMDA1OwpzdHJ1Y3QgVHJpZUluZm8KewogICAgaW50IFRvWzI2XSwgRmFbNF1bMzJdLCByZWYsIGw7Cn07CnN0cnVjdCBNYXRjaAp7CiAgICBpbnQgbCwgciwgbGVuOwogICAgTWF0Y2godm9pZCkge30KICAgIE1hdGNoKGludCBhLCBpbnQgYiwgaW50IGMpIDogbChhKSwgcihiKSwgbGVuKGMpIHt9Cn0gSW5mb1tNQVhOXSwgTWFwWzI2XTsKCmludCBTYVtNQVhOXSwgUmFua1tNQVhOXSwgVGlbTUFYTl0sIENudDsKaW50IEZpbmFsW01BWE5dLCBOZXh0W01BWE5dLCB0b3RhbCwgQW5zW01BWE5dOwoKbmFtZXNwYWNlIFRyaWUKewogICAgY29uc3QgaW50IE1BWE4gPSAxMDAwMDU7CiAgICBUcmllSW5mbyBUW01BWE5dOwogICAgaW50IFRyYW5zW01BWE5dLCBBW01BWE5dLCBjbnQ7CiAgICB2b2lkIEZpcnN0KCkKICAgIHsKICAgICAgICBjbnQgPSAxOwogICAgICAgIFRyYW5zWzFdID0gLTE7CiAgICB9CiAgICBpbnQgSW5zZXJ0KGludCBjdXIsIGNoYXIgYykKICAgIHsKICAgICAgICBjID0gYyAtICdhJzsKICAgICAgICBpZiAoVFtjdXJdLlRvW2NdKQogICAgICAgICAgICByZXR1cm4gVFtjdXJdLlRvW2NdOwogICAgICAgIFRbKytjbnRdLkZhWzBdWzFdID0gY3VyOwogICAgICAgIFRbY250XS5sID0gVFtjdXJdLmwgKyAxOwogICAgICAgIFRyYW5zW2NudF0gPSBjOwogICAgICAgIHJldHVybiAoVFtjdXJdLlRvW2NdID0gY250KTsKICAgIH0KICAgIGludCBHZXRmYShpbnQgdSwgaW50IGRlcCkKICAgIHsKICAgICAgICBpbnQgY3VyID0gdTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDQ7IGkrKywgZGVwID4+PSA1KQogICAgICAgIHsKICAgICAgICAgICAgaW50IHAgPSAoZGVwICYgMzEpOwogICAgICAgICAgICBpZiAoIXApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1ciA9IFRbY3VyXS5GYVtpXVtwXTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGN1cjsKICAgIH0KCiAgICB2b2lkIFdvcmsoKQogICAgewogICAgICAgIGZvciAoaW50IGkgPSAyOyBpIDwgMzI7IGkrKykKICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPD0gY250OyBqKyspCiAgICAgICAgICAgICAgICBUW2pdLkZhWzBdW2ldID0gVFtUW2pdLkZhWzBdW2kgLSAxXV0uRmFbMF1bMV07CiAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCA0OyBpKyspCiAgICAgICAgICAgIGZvciAoaW50IGogPSAxOyBqIDwgMzI7IGorKykKICAgICAgICAgICAgICAgIGZvciAoaW50IGsgPSAxOyBrIDw9IGNudDsgaysrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChqID09IDEpCiAgICAgICAgICAgICAgICAgICAgICAgIFRba10uRmFbaV1bal0gPSBUW1Rba10uRmFbaSAtIDFdWzMxXV0uRmFbaSAtIDFdWzFdOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgVFtrXS5GYVtpXVtqXSA9IFRbVFtrXS5GYVtpXVtqIC0gMV1dLkZhW2ldWzFdOwogICAgICAgICAgICAgICAgfQogICAgfQoKICAgIHZvaWQgQWRkKGludCBwLCBpbnQgdikKICAgIHsKICAgICAgICBmb3IgKDsgcCA8PSBDbnQ7IHAgKz0gcCAmIC1wKQogICAgICAgIHsKICAgICAgICAgICAgQVtwXSArPSB2OwogICAgICAgIH0KICAgIH0KCiAgICBpbnQgU3VtKGludCBwKQogICAgewogICAgICAgIGlmIChwIDwgMCkKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgaW50IHRtcCA9IDA7CiAgICAgICAgZm9yICg7IHA7IHAgLT0gcCAmIC1wKQogICAgICAgICAgICB0bXAgKz0gQVtwXTsKICAgICAgICByZXR1cm4gdG1wOwogICAgfQogICAgaW50IFN1bShpbnQgbCwgaW50IHIpCiAgICB7CiAgICAgICAgaWYgKGwgPiByKQogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICByZXR1cm4gU3VtKHIpIC0gU3VtKGwgLSAxKTsKICAgIH0KICAgIHZvaWQgRGZzKGludCBOb3cpCiAgICB7CiAgICAgICAgQWRkKFJhbmtbTm93XSwgMSk7CiAgICAgICAgZm9yIChpbnQgaiA9IEZpbmFsW05vd107IGo7IGogPSBOZXh0W2pdKQogICAgICAgIHsKICAgICAgICAgICAgQW5zW2pdID0gU3VtKEluZm9bVGlbal1dLmwsIEluZm9bVGlbal1dLnIpOwogICAgICAgICAgICBpZiAoIUluZm9bVGlbal1dLmxlbikKICAgICAgICAgICAgICAgIEFuc1tqXSA9IDA7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjY7IGkrKykKICAgICAgICAgICAgaWYgKFRbTm93XS5Ub1tpXSkKICAgICAgICAgICAgICAgIERmcyhUW05vd10uVG9baV0pOwogICAgICAgIEFkZChSYW5rW05vd10sIC0xKTsKICAgIH0KICAgIHZvaWQgR2V0QW5zKCkKICAgIHsKICAgICAgICBEZnMoMSk7CiAgICB9Cn0KCm5hbWVzcGFjZSBTQU0KewogICAgc3RydWN0IE5vZGUKICAgIHsKICAgICAgICBpbnQgVG9bMjZdLCBmYWlsLCBsZW4sIGRvd24sIHJlZjsKICAgIH0gVFtNQVhOXTsKICAgIGludCBHb1tNQVhOXVsyNl07CiAgICBpbnQgUVtNQVhOXSwgT3JkW01BWE5dLCBTLCBjbnQ7CiAgICBib29sIGNtcChpbnQgYSwgaW50IGIpCiAgICB7CiAgICAgICAgcmV0dXJuIFRbYV0ubGVuIDwgVFtiXS5sZW47CiAgICB9CiAgICBpbnQgQWRkKGludCBMc3QsIGludCBjLCBpbnQgbCwgaW50IGN1cikKICAgIHsKICAgICAgICBpbnQgTnQgPSArK2NudCwgcCA9IExzdDsKICAgICAgICBUW050XS5sZW4gPSBsOwogICAgICAgIGZvciAoOyBwICYmICFUW3BdLlRvW2NdOyBwID0gVFtwXS5mYWlsKQogICAgICAgICAgICBUW3BdLlRvW2NdID0gTnQ7CiAgICAgICAgaWYgKCFwKQogICAgICAgICAgICBUW050XS5mYWlsID0gUzsKICAgICAgICBlbHNlIGlmIChUW1RbcF0uVG9bY11dLmxlbiA9PSBUW3BdLmxlbiArIDEpCiAgICAgICAgICAgIFRbTnRdLmZhaWwgPSBUW3BdLlRvW2NdOwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGludCBxID0gKytjbnQsIHF0ID0gVFtwXS5Ub1tjXTsKICAgICAgICAgICAgVFtxXSA9IFRbcXRdOwogICAgICAgICAgICBUW3F0XS5mYWlsID0gVFtOdF0uZmFpbCA9IHE7CiAgICAgICAgICAgIGZvciAoOyBwICYmIFRbcF0uVG9bY10gPT0gcXQ7IHAgPSBUW3BdLmZhaWwpCiAgICAgICAgICAgICAgICBUW3BdLlRvW2NdID0gcTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIE50OwogICAgfQoKICAgIHZvaWQgRGZzKGludCBOb3cpCiAgICB7CiAgICAgICAgaWYgKFRbTm93XS5yZWYpCiAgICAgICAgICAgIFNhWysrQ250XSA9IFRbTm93XS5yZWYsIFJhbmtbVFtOb3ddLnJlZl0gPSBDbnQ7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyNjsgaSsrKQogICAgICAgICAgICBpZiAoR29bTm93XVtpXSkKICAgICAgICAgICAgICAgIERmcyhHb1tOb3ddW2ldKTsKICAgIH0KCiAgICB2b2lkIE1hcmsoaW50IHRub2QsIGludCBzbm9kKQogICAgewogICAgICAgIFRbc25vZF0uZG93biA9IFRbc25vZF0ucmVmID0gdG5vZDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDI2OyBpKyspCiAgICAgICAgICAgIGlmIChUcmllOjpUW3Rub2RdLlRvW2ldKQogICAgICAgICAgICAgICAgTWFyayhUcmllOjpUW3Rub2RdLlRvW2ldLCBUW3Nub2RdLlRvW2ldKTsKICAgIH0KCiAgICB2b2lkIEJ1aWxkKCkKICAgIHsKICAgICAgICBpbnQgZmkgPSAwLCBlbiA9IDE7CiAgICAgICAgUVsxXSA9IDE7CiAgICAgICAgUyA9IGNudCA9IDE7CiAgICAgICAgVHJpZTo6VFsxXS5yZWYgPSAxOwogICAgICAgIFRbMV0ucmVmID0gMTsKICAgICAgICB3aGlsZSAoZmkgPCBlbikKICAgICAgICB7CiAgICAgICAgICAgIGludCB1ID0gUVsrK2ZpXTsKICAgICAgICAgICAgVHJpZUluZm8gJmMgPSBUcmllOjpUW3VdOwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDI2OyBpKyspCiAgICAgICAgICAgICAgICBpZiAoYy5Ub1tpXSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUcmllSW5mbyAmY3VyID0gVHJpZTo6VFtjLlRvW2ldXTsKICAgICAgICAgICAgICAgICAgICBUcmllOjpUW2MuVG9baV1dOwogICAgICAgICAgICAgICAgICAgIGN1ci5yZWYgPSBBZGQoYy5yZWYsIGksIGN1ci5sLCBjLlRvW2ldKTsKICAgICAgICAgICAgICAgICAgICBRWysrZW5dID0gYy5Ub1tpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgTWFyaygxLCAxKTsKICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBjbnQ7IGkrKykKICAgICAgICAgICAgT3JkW2ldID0gaTsKICAgICAgICBzb3J0KE9yZCArIDEsIE9yZCArIGNudCArIDEsIGNtcCk7CiAgICAgICAgZm9yICg7IGNudCA+IDE7IGNudC0tKQogICAgICAgIHsKICAgICAgICAgICAgaW50IHYgPSBPcmRbY250XSwgdSA9IFRbdl0uZmFpbDsKICAgICAgICAgICAgVFt1XS5kb3duID0gVFt2XS5kb3duOwogICAgICAgICAgICBUcmllSW5mbyAmY3VyID0gVHJpZTo6VFtUW3ZdLmRvd25dOwogICAgICAgICAgICBpbnQgayA9IFRyaWU6OkdldGZhKFRbdV0uZG93biwgY3VyLmwgLSAoVFtjdXIucmVmXS5sZW4gLSBUW3VdLmxlbikpOwogICAgICAgICAgICBHb1t1XVtUcmllOjpUcmFuc1trXV0gPSB2OwogICAgICAgIH0KICAgICAgICBEZnMoMSk7CiAgICB9Cn0KCnN0cnVjdCBRdWVyCnsKICAgIGludCB0eXBlLCBzLCB0OwogICAgY2hhciBjOwp9IFFbTUFYTl07CgppbnQgUmVmZXJbTUFYTl0sIExlbltNQVhOXSwgTiwgTSwgVGM7CmlubGluZSBib29sIFNtYWxsKGludCBzdWYsIGNvbnN0IE1hdGNoICZhKQp7CiAgICByZXR1cm4gUmFua1tzdWZdIDwgYS5sOwp9CmlubGluZSBib29sIExhcmdlKGludCBzdWYsIGNvbnN0IE1hdGNoICZhKQp7CiAgICByZXR1cm4gUmFua1tzdWZdID4gYS5yOwp9Ck1hdGNoIE1lcmdlKGNvbnN0IE1hdGNoICZhLCBjb25zdCBNYXRjaCAmYikKewogICAgaWYgKGEubCA+IGEucikKICAgICAgICByZXR1cm4gTWF0Y2goMCwgLTEsIGEubGVuICsgYi5sZW4pOwogICAgaW50IGwgPSBhLmwsIHIgPSBhLnIsIGwxID0gYS5sIC0gMSwgcjEgPSBhLnIgKyAxLCBtaWQ7CiAgICBmb3IgKDsgbCA8PSByOykKICAgIHsKICAgICAgICBtaWQgPSAobCArIHIpID4+IDE7CiAgICAgICAgaWYgKFNtYWxsKFRyaWU6OkdldGZhKFNhW21pZF0sIGEubGVuKSwgYikpCiAgICAgICAgICAgIGwxID0gbWlkLCBsID0gbWlkICsgMTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHIgPSBtaWQgLSAxOwogICAgfQoKICAgIGZvciAobCA9IGEubCwgciA9IGEucjsgbCA8PSByOykKICAgIHsKICAgICAgICBtaWQgPSAobCArIHIpID4+IDE7CiAgICAgICAgaWYgKExhcmdlKFRyaWU6OkdldGZhKFNhW21pZF0sIGEubGVuKSwgYikpCiAgICAgICAgICAgIHIxID0gbWlkLCByID0gbWlkIC0gMTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGwgPSBtaWQgKyAxOwogICAgfQogICAgcmV0dXJuIE1hdGNoKGwxICsgMSwgcjEgLSAxLCBhLmxlbiArIGIubGVuKTsKfQppbnQgbWFpbigpCnsKICAgIFRyaWU6OkZpcnN0KCk7CiAgICBOID0gMTsKICAgIFJlZmVyWzFdID0gMTsKICAgIHNjYW5mKCIlZCIsICZNKTsKICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IE07IGkrKykKICAgIHsKICAgICAgICBpbnQgdHlwZSwgcywgdDsKICAgICAgICBjaGFyIGM7CiAgICAgICAgc2NhbmYoIiVkICVkIiwgJnR5cGUsICZzKTsKICAgICAgICBpZiAodHlwZSA9PSAxKQogICAgICAgIHsKICAgICAgICAgICAgc2NhbmYoIiVjIiwgJmMpOwogICAgICAgICAgICBzID0gUmVmZXJbc107CiAgICAgICAgICAgIFJlZmVyWysrTl0gPSBUcmllOjpJbnNlcnQocywgYyk7CiAgICAgICAgfQogICAgICAgIGlmICh0eXBlID09IDIpCiAgICAgICAgewogICAgICAgICAgICBzY2FuZigiJWQgJWMiLCAmdCwgJmMpOwogICAgICAgICAgICBRW2ldLnR5cGUgPSBzICsgMTsKICAgICAgICAgICAgUVtpXS5zID0gdDsKICAgICAgICAgICAgUVtpXS5jID0gYzsKICAgICAgICB9CiAgICAgICAgaWYgKHR5cGUgPT0gMyB8fCB0eXBlID09IDQpCiAgICAgICAgewogICAgICAgICAgICBzY2FuZigiJWQiLCAmdCksIFFbaV0udHlwZSA9IHR5cGUsIFFbaV0ucyA9IHMsIFFbaV0udCA9IHQ7CiAgICAgICAgfQogICAgfQogICAgVHJpZTo6V29yaygpOwogICAgU0FNOjpCdWlsZCgpOwogICAgVGMgPSAxOwogICAgSW5mb1sxXS5sID0gMSwgSW5mb1sxXS5yID0gQ250OwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyNjsgaSsrKQogICAgewogICAgICAgIGludCBsID0gMSwgciA9IENudCwgbWlkOwogICAgICAgIE1hcFtpXS5yID0gQ250ICsgMTsKICAgICAgICBmb3IgKDsgbCA8PSByOykKICAgICAgICB7CiAgICAgICAgICAgIG1pZCA9IChsICsgcikgPj4gMTsKICAgICAgICAgICAgaWYgKFRyaWU6OlRyYW5zW1NhW21pZF1dIDwgaSkKICAgICAgICAgICAgICAgIE1hcFtpXS5sID0gbWlkLCBsID0gbWlkICsgMTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgciA9IG1pZCAtIDE7CiAgICAgICAgfQogICAgICAgIGZvciAobCA9IDEsIHIgPSBDbnQ7IGwgPD0gcjspCiAgICAgICAgewogICAgICAgICAgICBtaWQgPSAobCArIHIpID4+IDE7CiAgICAgICAgICAgIGlmIChUcmllOjpUcmFuc1tTYVttaWRdXSA+IGkpCiAgICAgICAgICAgICAgICBNYXBbaV0uciA9IG1pZCwgciA9IG1pZCAtIDE7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGwgPSBtaWQgKyAxOwogICAgICAgIH0KICAgICAgICBNYXBbaV0ubCsrLCBNYXBbaV0uci0tOwogICAgICAgIE1hcFtpXS5sZW4gPSAxOwogICAgfQogICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gTTsgaSsrKQogICAgewogICAgICAgIFF1ZXIgJmMgPSBRW2ldOwogICAgICAgIGlmICghYy50eXBlKQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICBpZiAoYy50eXBlICE9IDQpCiAgICAgICAgICAgICsrVGM7CiAgICAgICAgaWYgKGMudHlwZSA9PSA0KQogICAgICAgIHsKICAgICAgICAgICAgKyt0b3RhbDsKICAgICAgICAgICAgYy50ID0gUmVmZXJbYy50XTsKICAgICAgICAgICAgTmV4dFt0b3RhbF0gPSBGaW5hbFtjLnRdLCBGaW5hbFtjLnRdID0gdG90YWw7CiAgICAgICAgICAgIFRpW3RvdGFsXSA9IGMuczsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGMudHlwZSA9PSAxKQogICAgICAgICAgICAgICAgSW5mb1tUY10gPSBNZXJnZShJbmZvW2Muc10sIE1hcFtjLmMgLSAnYSddKTsKICAgICAgICAgICAgaWYgKGMudHlwZSA9PSAyKQogICAgICAgICAgICAgICAgSW5mb1tUY10gPSBNZXJnZShNYXBbYy5jIC0gJ2EnXSwgSW5mb1tjLnNdKTsKICAgICAgICAgICAgaWYgKGMudHlwZSA9PSAzKQogICAgICAgICAgICAgICAgSW5mb1tUY10gPSBNZXJnZShJbmZvW2MudF0sIEluZm9bYy5zXSk7CiAgICAgICAgfQogICAgfQoKICAgIFRyaWU6OkdldEFucygpOwogICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gdG90YWw7IGkrKykKICAgICAgICBwcmludGYoIiVkXG4iLCBBbnNbaV0pOwogICAgcmV0dXJuIDA7Cn0K