#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define endl "\n"
auto random_address = []
{ char *p = new char; delete p; return uint64_t(p); };
const uint64_t SEED = chrono::steady_clock::now().time_since_epoch().count() * (random_address() | 1);
std::mt19937 rnd(SEED);
#define rng(l, r) uniform_int_distribution<int64_t>(l, r)(rnd)
/*
Large Primes for hash
1000000007
10000000019
100000000003
1000000000039
10000000000037
100000000000031
1000000000000037
10000000000000061
2305843009213693951 = (1LL << 61) - 1
*/
constexpr ll mod = 10000000019; // Large prime,
// Takes more time, choose a smaller prime and omit mult64() for faster code but higher probability of collision
// constexpr ll mod = 1e9 + 7; // Is usually sufficient for most of the hashing problems
inline ll mult64(const ll &a, const ll &b)
{
return __int128_t(a) * b % mod;
}
ll modPow(ll N, ll power, ll mod)
{
ll res{1};
while (power)
{
if (power & 1)
res = mult64(res, N);
N = mult64(N, N);
power >>= 1;
}
return res;
}
ll b1 = rng(100, 100000), b2 = rng(1000, 100000);
ll b1I = modPow(b1, mod - 2, mod), b2I = modPow(b2, mod - 2, mod);
vector<ll> Pb1, Pb2, sumB1, sumB2;
void pre(ll maxSize)
{
Pb1 = Pb2 = sumB1 = sumB2 = vector<ll>(maxSize + 1, 1);
for (int i = 1; i <= maxSize; i++)
{
Pb1[i] = mult64(Pb1[i - 1], b1);
Pb2[i] = mult64(Pb2[i - 1], b2);
sumB1[i] = ((sumB1[i - 1] + Pb1[i]) % mod);
sumB2[i] = ((sumB2[i - 1] + Pb2[i]) % mod);
}
}
class Hash
{
using pll = pair<ll, ll>;
ll plus(const ll &x, const ll &y)
{
return ((__int128_t(x) + y + mod) % mod);
}
public:
pll code{};
int size{};
explicit Hash(pair<ll, ll> x = {}, ll sz = {}) : code(std::move(x)), size(sz) {}
Hash(const ll &x) : code({x % mod, x % mod}), size(1) {}
Hash(const string &x) : code(), size(0)
{
for (const char &c : x)
*this = *(this) + c;
}
void pop_front(int x)
{
code.first = (code.first - mult64(Pb1[--size], x) + mod) % mod;
code.second = (code.second - mult64(Pb2[size], x) + mod) % mod;
}
void pop_back(int x)
{
code.first = mult64((code.first - x + mod), b1I);
code.second = mult64((code.second - x + mod), b2I);
size--;
}
void clear()
{
code = {}, size = 0;
}
Hash operator+(const Hash &o)
{
Hash ans;
ans.code = {plus(mult64(code.first, Pb1[o.size]), o.code.first),
plus(mult64(code.second, Pb2[o.size]), o.code.second)};
ans.size = size + o.size;
return ans;
}
friend Hash operator+(const Hash &f, const Hash &o)
{
return Hash({((mult64(f.code.first, Pb1[o.size]) + o.code.first) % mod),
((mult64(f.code.second, Pb2[o.size]) + o.code.second) % mod)},
f.size + o.size);
}
bool operator<(const Hash &o) const
{
if (code == o.code)
return size < o.size;
return code < o.code;
}
bool operator>(const Hash &o) const
{
if (code == o.code)
return size > o.size;
return code > o.code;
}
bool operator>=(const Hash &o) const
{
if (code == o.code)
return (size >= o.size);
return code > o.code;
}
bool operator==(const Hash &o) const
{
return size == o.size && code == o.code;
}
bool operator!=(const Hash &o) const
{
return size != o.size || code != o.code;
}
};
// Rabin-Karp Algorithm
struct HashRange
{
vector<Hash> p, s;
HashRange(const string &t) : p(t.size()), s(t.size())
{
if (t.empty())
return;
p.front() = t.front();
for (int i = 1; i < t.size(); i++)
p[i] = p[i - 1] + t[i];
s.back() = t.back();
for (int i = int(t.size()) - 2; i >= 0; i--)
s[i] = s[i + 1] + t[i];
}
Hash get(int l, int r) const // 0-based indices
{
if (l > r)
return Hash();
if (!l)
return p[r];
return Hash({(p[r].code.first - mult64(p[l - 1].code.first, Pb1[r - l + 1]) + mod) % mod,
(p[r].code.second - mult64(p[l - 1].code.second, Pb2[r - l + 1]) + mod) % mod},
r - l + 1);
}
Hash inv(int l, int r) const // 0-based indices
{
if (l > r)
return Hash();
if (r + 1 == s.size())
return s[l];
return Hash({(s[l].code.first - mult64(s[r + 1].code.first, Pb1[r - l + 1]) + mod) % mod,
(s[l].code.second - mult64(s[r + 1].code.second, Pb2[r - l + 1]) + mod) % mod},
r - l + 1);
}
};
/////////////////////////////////////////////
namespace SuffixArray
{
const int maxN = (1000001);
string S;
int N, gap;
int SA[maxN], pos[maxN], tmp[maxN], lcp[maxN];
bool sufCmp(int i, int j)
{
if (pos[i] != pos[j])
return pos[i] < pos[j];
i += gap;
j += gap;
return (i < N && j < N) ? pos[i] < pos[j] : i > j;
}
void buildSA()
{
N = S.size();
for (int i{}; i < N; i++)
SA[i] = i,
pos[i] = S[i];
for (gap = 1;; gap *= 2)
{
sort(SA, SA + N, sufCmp);
for (int i{}; i < N - 1; i++)
tmp[i + 1] = tmp[i] + sufCmp(SA[i], SA[i + 1]);
for (int i{}; i < N; i++)
pos[SA[i]] = tmp[i];
if (tmp[N - 1] == N - 1)
break;
}
}
void buildLCP()
{
for (int i = 0, k = 0; i < N; ++i)
{
if (pos[i] != N - 1)
{
for (int j = SA[pos[i] + 1]; S[i + k] == S[j + k];)
++k;
lcp[pos[i]] = k;
if (k)
--k;
}
}
}
}
using namespace SuffixArray;
int countSubstrings(const HashRange &H, const Hash &s)
{
// A substring is a prefix of some suffix
int last = S.length(), first = -1;
// Upper bound
{
int L{}, R = S.length();
while (L <= R)
{
int mid = ((L + R) >> 1);
if (H.get(SA[mid], SA[mid] + s.size - 1) > s)
last = mid, R = mid - 1;
else
L = mid + 1;
}
}
// Lower bound
{
int L{}, R = S.length();
while (L <= R)
{
int mid = ((L + R) >> 1);
if (H.get(SA[mid], SA[mid] + s.size - 1) >= s)
first = mid, R = mid - 1;
else
L = mid + 1;
}
}
if (~first)
return last - first;
else
return 0;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
#ifndef ONLINE_JUDGE
freopen("Output.txt", "w", stdout
); #endif //! ONLINE_JUDGE
int t = 1;
ll N, Q;
// cin >> t;
while (t--)
{
cin >> N;
vector<ll> P(N);
for (int i{}; i < N; i++)
cin >> P[i];
string suff("");
for (int i = 1; i < N; i++)
{
if (P[i] > P[i - 1])
suff += "U"; // Up
else if (P[i] < P[i - 1])
suff += "D"; // Down
else
suff += "C"; // Constant
}
S = suff;
S += '#';
buildSA(); // Suffix Array
pre(2000001);
HashRange StrHash = S;
HashRange SuffHash = suff;
cin >> Q;
while (Q--)
{
int X;
cin >> X;
Hash cur = SuffHash.get(N - X, suff.length() - 1);
cout << countSubstrings(StrHash, cur) << endl;
}
}
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiNkZWZpbmUgbGwgbG9uZyBsb25nIGludAojZGVmaW5lIGVuZGwgIlxuIgoKYXV0byByYW5kb21fYWRkcmVzcyA9IFtdCnsgY2hhciAqcCA9IG5ldyBjaGFyOyBkZWxldGUgcDsgcmV0dXJuIHVpbnQ2NF90KHApOyB9Owpjb25zdCB1aW50NjRfdCBTRUVEID0gY2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKS5jb3VudCgpICogKHJhbmRvbV9hZGRyZXNzKCkgfCAxKTsKc3RkOjptdDE5OTM3IHJuZChTRUVEKTsKI2RlZmluZSBybmcobCwgcikgdW5pZm9ybV9pbnRfZGlzdHJpYnV0aW9uPGludDY0X3Q+KGwsIHIpKHJuZCkKLyoKTGFyZ2UgUHJpbWVzIGZvciBoYXNoCjEwMDAwMDAwMDcKMTAwMDAwMDAwMTkKMTAwMDAwMDAwMDAzCjEwMDAwMDAwMDAwMzkKMTAwMDAwMDAwMDAwMzcKMTAwMDAwMDAwMDAwMDMxCjEwMDAwMDAwMDAwMDAwMzcKMTAwMDAwMDAwMDAwMDAwNjEKMjMwNTg0MzAwOTIxMzY5Mzk1MSA9ICgxTEwgPDwgNjEpIC0gMQoqLwpjb25zdGV4cHIgbGwgbW9kID0gMTAwMDAwMDAwMTk7IC8vIExhcmdlIHByaW1lLAovLyBUYWtlcyBtb3JlIHRpbWUsIGNob29zZSBhIHNtYWxsZXIgcHJpbWUgYW5kIG9taXQgbXVsdDY0KCkgZm9yIGZhc3RlciBjb2RlIGJ1dCBoaWdoZXIgcHJvYmFiaWxpdHkgb2YgY29sbGlzaW9uCi8vIGNvbnN0ZXhwciBsbCBtb2QgPSAxZTkgKyA3OyAvLyBJcyB1c3VhbGx5IHN1ZmZpY2llbnQgZm9yIG1vc3Qgb2YgdGhlIGhhc2hpbmcgcHJvYmxlbXMKCmlubGluZSBsbCBtdWx0NjQoY29uc3QgbGwgJmEsIGNvbnN0IGxsICZiKQp7CglyZXR1cm4gX19pbnQxMjhfdChhKSAqIGIgJSBtb2Q7Cn0KbGwgbW9kUG93KGxsIE4sIGxsIHBvd2VyLCBsbCBtb2QpCnsKCWxsIHJlc3sxfTsKCXdoaWxlIChwb3dlcikKCXsKCQlpZiAocG93ZXIgJiAxKQoJCQlyZXMgPSBtdWx0NjQocmVzLCBOKTsKCQlOID0gbXVsdDY0KE4sIE4pOwoJCXBvd2VyID4+PSAxOwoJfQoJcmV0dXJuIHJlczsKfQpsbCBiMSA9IHJuZygxMDAsIDEwMDAwMCksIGIyID0gcm5nKDEwMDAsIDEwMDAwMCk7CmxsIGIxSSA9IG1vZFBvdyhiMSwgbW9kIC0gMiwgbW9kKSwgYjJJID0gbW9kUG93KGIyLCBtb2QgLSAyLCBtb2QpOwp2ZWN0b3I8bGw+IFBiMSwgUGIyLCBzdW1CMSwgc3VtQjI7CnZvaWQgcHJlKGxsIG1heFNpemUpCnsKCVBiMSA9IFBiMiA9IHN1bUIxID0gc3VtQjIgPSB2ZWN0b3I8bGw+KG1heFNpemUgKyAxLCAxKTsKCWZvciAoaW50IGkgPSAxOyBpIDw9IG1heFNpemU7IGkrKykKCXsKCQlQYjFbaV0gPSBtdWx0NjQoUGIxW2kgLSAxXSwgYjEpOwoJCVBiMltpXSA9IG11bHQ2NChQYjJbaSAtIDFdLCBiMik7CgkJc3VtQjFbaV0gPSAoKHN1bUIxW2kgLSAxXSArIFBiMVtpXSkgJSBtb2QpOwoJCXN1bUIyW2ldID0gKChzdW1CMltpIC0gMV0gKyBQYjJbaV0pICUgbW9kKTsKCX0KfQpjbGFzcyBIYXNoCnsKCXVzaW5nIHBsbCA9IHBhaXI8bGwsIGxsPjsKCWxsIHBsdXMoY29uc3QgbGwgJngsIGNvbnN0IGxsICZ5KQoJewoJCXJldHVybiAoKF9faW50MTI4X3QoeCkgKyB5ICsgbW9kKSAlIG1vZCk7Cgl9CgpwdWJsaWM6CglwbGwgY29kZXt9OwoJaW50IHNpemV7fTsKCWV4cGxpY2l0IEhhc2gocGFpcjxsbCwgbGw+IHggPSB7fSwgbGwgc3ogPSB7fSkgOiBjb2RlKHN0ZDo6bW92ZSh4KSksIHNpemUoc3opIHt9CgoJSGFzaChjb25zdCBsbCAmeCkgOiBjb2RlKHt4ICUgbW9kLCB4ICUgbW9kfSksIHNpemUoMSkge30KCglIYXNoKGNvbnN0IHN0cmluZyAmeCkgOiBjb2RlKCksIHNpemUoMCkKCXsKCQlmb3IgKGNvbnN0IGNoYXIgJmMgOiB4KQoJCQkqdGhpcyA9ICoodGhpcykgKyBjOwoJfQoKCXZvaWQgcG9wX2Zyb250KGludCB4KQoJewoJCWNvZGUuZmlyc3QgPSAoY29kZS5maXJzdCAtIG11bHQ2NChQYjFbLS1zaXplXSwgeCkgKyBtb2QpICUgbW9kOwoJCWNvZGUuc2Vjb25kID0gKGNvZGUuc2Vjb25kIC0gbXVsdDY0KFBiMltzaXplXSwgeCkgKyBtb2QpICUgbW9kOwoJfQoKCXZvaWQgcG9wX2JhY2soaW50IHgpCgl7CgkJY29kZS5maXJzdCA9IG11bHQ2NCgoY29kZS5maXJzdCAtIHggKyBtb2QpLCBiMUkpOwoJCWNvZGUuc2Vjb25kID0gbXVsdDY0KChjb2RlLnNlY29uZCAtIHggKyBtb2QpLCBiMkkpOwoJCXNpemUtLTsKCX0KCXZvaWQgY2xlYXIoKQoJewoJCWNvZGUgPSB7fSwgc2l6ZSA9IDA7Cgl9CglIYXNoIG9wZXJhdG9yKyhjb25zdCBIYXNoICZvKQoJewoJCUhhc2ggYW5zOwoJCWFucy5jb2RlID0ge3BsdXMobXVsdDY0KGNvZGUuZmlyc3QsIFBiMVtvLnNpemVdKSwgby5jb2RlLmZpcnN0KSwKCQkJCQlwbHVzKG11bHQ2NChjb2RlLnNlY29uZCwgUGIyW28uc2l6ZV0pLCBvLmNvZGUuc2Vjb25kKX07CgkJYW5zLnNpemUgPSBzaXplICsgby5zaXplOwoJCXJldHVybiBhbnM7Cgl9CglmcmllbmQgSGFzaCBvcGVyYXRvcisoY29uc3QgSGFzaCAmZiwgY29uc3QgSGFzaCAmbykKCXsKCQlyZXR1cm4gSGFzaCh7KChtdWx0NjQoZi5jb2RlLmZpcnN0LCBQYjFbby5zaXplXSkgKyBvLmNvZGUuZmlyc3QpICUgbW9kKSwKCQkJCQkgKChtdWx0NjQoZi5jb2RlLnNlY29uZCwgUGIyW28uc2l6ZV0pICsgby5jb2RlLnNlY29uZCkgJSBtb2QpfSwKCQkJCQlmLnNpemUgKyBvLnNpemUpOwoJfQoJYm9vbCBvcGVyYXRvcjwoY29uc3QgSGFzaCAmbykgY29uc3QKCXsKCQlpZiAoY29kZSA9PSBvLmNvZGUpCgkJCXJldHVybiBzaXplIDwgby5zaXplOwoJCXJldHVybiBjb2RlIDwgby5jb2RlOwoJfQoJYm9vbCBvcGVyYXRvcj4oY29uc3QgSGFzaCAmbykgY29uc3QKCXsKCQlpZiAoY29kZSA9PSBvLmNvZGUpCgkJCXJldHVybiBzaXplID4gby5zaXplOwoJCXJldHVybiBjb2RlID4gby5jb2RlOwoJfQoJYm9vbCBvcGVyYXRvcj49KGNvbnN0IEhhc2ggJm8pIGNvbnN0Cgl7CgkJaWYgKGNvZGUgPT0gby5jb2RlKQoJCQlyZXR1cm4gKHNpemUgPj0gby5zaXplKTsKCQlyZXR1cm4gY29kZSA+IG8uY29kZTsKCX0KCWJvb2wgb3BlcmF0b3I9PShjb25zdCBIYXNoICZvKSBjb25zdAoJewoJCXJldHVybiBzaXplID09IG8uc2l6ZSAmJiBjb2RlID09IG8uY29kZTsKCX0KCWJvb2wgb3BlcmF0b3IhPShjb25zdCBIYXNoICZvKSBjb25zdAoJewoJCXJldHVybiBzaXplICE9IG8uc2l6ZSB8fCBjb2RlICE9IG8uY29kZTsKCX0KfTsKCi8vIFJhYmluLUthcnAgQWxnb3JpdGhtCnN0cnVjdCBIYXNoUmFuZ2UKewoJdmVjdG9yPEhhc2g+IHAsIHM7CglIYXNoUmFuZ2UoY29uc3Qgc3RyaW5nICZ0KSA6IHAodC5zaXplKCkpLCBzKHQuc2l6ZSgpKQoJewoJCWlmICh0LmVtcHR5KCkpCgkJCXJldHVybjsKCQlwLmZyb250KCkgPSB0LmZyb250KCk7CgkJZm9yIChpbnQgaSA9IDE7IGkgPCB0LnNpemUoKTsgaSsrKQoJCQlwW2ldID0gcFtpIC0gMV0gKyB0W2ldOwoJCXMuYmFjaygpID0gdC5iYWNrKCk7CgkJZm9yIChpbnQgaSA9IGludCh0LnNpemUoKSkgLSAyOyBpID49IDA7IGktLSkKCQkJc1tpXSA9IHNbaSArIDFdICsgdFtpXTsKCX0KCUhhc2ggZ2V0KGludCBsLCBpbnQgcikgY29uc3QgLy8gMC1iYXNlZCBpbmRpY2VzCgl7CgkJaWYgKGwgPiByKQoJCQlyZXR1cm4gSGFzaCgpOwoJCWlmICghbCkKCQkJcmV0dXJuIHBbcl07CgkJcmV0dXJuIEhhc2goeyhwW3JdLmNvZGUuZmlyc3QgLSBtdWx0NjQocFtsIC0gMV0uY29kZS5maXJzdCwgUGIxW3IgLSBsICsgMV0pICsgbW9kKSAlIG1vZCwKCQkJCQkgKHBbcl0uY29kZS5zZWNvbmQgLSBtdWx0NjQocFtsIC0gMV0uY29kZS5zZWNvbmQsIFBiMltyIC0gbCArIDFdKSArIG1vZCkgJSBtb2R9LAoJCQkJCXIgLSBsICsgMSk7Cgl9CglIYXNoIGludihpbnQgbCwgaW50IHIpIGNvbnN0IC8vIDAtYmFzZWQgaW5kaWNlcwoJewoJCWlmIChsID4gcikKCQkJcmV0dXJuIEhhc2goKTsKCQlpZiAociArIDEgPT0gcy5zaXplKCkpCgkJCXJldHVybiBzW2xdOwoJCXJldHVybiBIYXNoKHsoc1tsXS5jb2RlLmZpcnN0IC0gbXVsdDY0KHNbciArIDFdLmNvZGUuZmlyc3QsIFBiMVtyIC0gbCArIDFdKSArIG1vZCkgJSBtb2QsCgkJCQkJIChzW2xdLmNvZGUuc2Vjb25kIC0gbXVsdDY0KHNbciArIDFdLmNvZGUuc2Vjb25kLCBQYjJbciAtIGwgKyAxXSkgKyBtb2QpICUgbW9kfSwKCQkJCQlyIC0gbCArIDEpOwoJfQp9OwovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCm5hbWVzcGFjZSBTdWZmaXhBcnJheQp7Cgljb25zdCBpbnQgbWF4TiA9ICgxMDAwMDAxKTsKCXN0cmluZyBTOwoJaW50IE4sIGdhcDsKCWludCBTQVttYXhOXSwgcG9zW21heE5dLCB0bXBbbWF4Tl0sIGxjcFttYXhOXTsKCglib29sIHN1ZkNtcChpbnQgaSwgaW50IGopCgl7CgkJaWYgKHBvc1tpXSAhPSBwb3Nbal0pCgkJCXJldHVybiBwb3NbaV0gPCBwb3Nbal07CgkJaSArPSBnYXA7CgkJaiArPSBnYXA7CgkJcmV0dXJuIChpIDwgTiAmJiBqIDwgTikgPyBwb3NbaV0gPCBwb3Nbal0gOiBpID4gajsKCX0KCgl2b2lkIGJ1aWxkU0EoKQoJewoJCU4gPSBTLnNpemUoKTsKCQlmb3IgKGludCBpe307IGkgPCBOOyBpKyspCgkJCVNBW2ldID0gaSwKCQkJcG9zW2ldID0gU1tpXTsKCQlmb3IgKGdhcCA9IDE7OyBnYXAgKj0gMikKCQl7CgkJCXNvcnQoU0EsIFNBICsgTiwgc3VmQ21wKTsKCQkJZm9yIChpbnQgaXt9OyBpIDwgTiAtIDE7IGkrKykKCQkJCXRtcFtpICsgMV0gPSB0bXBbaV0gKyBzdWZDbXAoU0FbaV0sIFNBW2kgKyAxXSk7CgkJCWZvciAoaW50IGl7fTsgaSA8IE47IGkrKykKCQkJCXBvc1tTQVtpXV0gPSB0bXBbaV07CgkJCWlmICh0bXBbTiAtIDFdID09IE4gLSAxKQoJCQkJYnJlYWs7CgkJfQoJfQoKCXZvaWQgYnVpbGRMQ1AoKQoJewoJCWZvciAoaW50IGkgPSAwLCBrID0gMDsgaSA8IE47ICsraSkKCQl7CgkJCWlmIChwb3NbaV0gIT0gTiAtIDEpCgkJCXsKCQkJCWZvciAoaW50IGogPSBTQVtwb3NbaV0gKyAxXTsgU1tpICsga10gPT0gU1tqICsga107KQoJCQkJCSsrazsKCQkJCWxjcFtwb3NbaV1dID0gazsKCQkJCWlmIChrKQoJCQkJCS0tazsKCQkJfQoJCX0KCX0KfQp1c2luZyBuYW1lc3BhY2UgU3VmZml4QXJyYXk7CgppbnQgY291bnRTdWJzdHJpbmdzKGNvbnN0IEhhc2hSYW5nZSAmSCwgY29uc3QgSGFzaCAmcykKewoJLy8gQSBzdWJzdHJpbmcgaXMgYSBwcmVmaXggb2Ygc29tZSBzdWZmaXgKCWludCBsYXN0ID0gUy5sZW5ndGgoKSwgZmlyc3QgPSAtMTsKCS8vIFVwcGVyIGJvdW5kCgl7CgkJaW50IEx7fSwgUiA9IFMubGVuZ3RoKCk7CgkJd2hpbGUgKEwgPD0gUikKCQl7CgkJCWludCBtaWQgPSAoKEwgKyBSKSA+PiAxKTsKCQkJaWYgKEguZ2V0KFNBW21pZF0sIFNBW21pZF0gKyBzLnNpemUgLSAxKSA+IHMpCgkJCQlsYXN0ID0gbWlkLCBSID0gbWlkIC0gMTsKCQkJZWxzZQoJCQkJTCA9IG1pZCArIDE7CgkJfQoJfQoJLy8gTG93ZXIgYm91bmQKCXsKCQlpbnQgTHt9LCBSID0gUy5sZW5ndGgoKTsKCQl3aGlsZSAoTCA8PSBSKQoJCXsKCQkJaW50IG1pZCA9ICgoTCArIFIpID4+IDEpOwoJCQlpZiAoSC5nZXQoU0FbbWlkXSwgU0FbbWlkXSArIHMuc2l6ZSAtIDEpID49IHMpCgkJCQlmaXJzdCA9IG1pZCwgUiA9IG1pZCAtIDE7CgkJCWVsc2UKCQkJCUwgPSBtaWQgKyAxOwoJCX0KCX0KCWlmICh+Zmlyc3QpCgkJcmV0dXJuIGxhc3QgLSBmaXJzdDsKCWVsc2UKCQlyZXR1cm4gMDsKfQoKaW50IG1haW4oKQp7Cglpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsKCWNpbi50aWUobnVsbHB0cik7CiNpZm5kZWYgT05MSU5FX0pVREdFCglmcmVvcGVuKCJpbnB1dC50eHQiLCAiciIsIHN0ZGluKTsKCWZyZW9wZW4oIk91dHB1dC50eHQiLCAidyIsIHN0ZG91dCk7CiNlbmRpZiAvLyEgT05MSU5FX0pVREdFCglpbnQgdCA9IDE7CglsbCBOLCBROwoJLy8gY2luID4+IHQ7Cgl3aGlsZSAodC0tKQoJewoJCWNpbiA+PiBOOwoJCXZlY3RvcjxsbD4gUChOKTsKCQlmb3IgKGludCBpe307IGkgPCBOOyBpKyspCgkJCWNpbiA+PiBQW2ldOwoKCQlzdHJpbmcgc3VmZigiIik7CgkJZm9yIChpbnQgaSA9IDE7IGkgPCBOOyBpKyspCgkJewoJCQlpZiAoUFtpXSA+IFBbaSAtIDFdKQoJCQkJc3VmZiArPSAiVSI7IC8vIFVwCgkJCWVsc2UgaWYgKFBbaV0gPCBQW2kgLSAxXSkKCQkJCXN1ZmYgKz0gIkQiOyAvLyBEb3duCgkJCWVsc2UKCQkJCXN1ZmYgKz0gIkMiOyAvLyBDb25zdGFudAoJCX0KCQlTID0gc3VmZjsKCQlTICs9ICcjJzsKCQlidWlsZFNBKCk7IC8vIFN1ZmZpeCBBcnJheQoJCXByZSgyMDAwMDAxKTsKCQlIYXNoUmFuZ2UgU3RySGFzaCA9IFM7CgkJSGFzaFJhbmdlIFN1ZmZIYXNoID0gc3VmZjsKCQljaW4gPj4gUTsKCQl3aGlsZSAoUS0tKQoJCXsKCQkJaW50IFg7CgkJCWNpbiA+PiBYOwoJCQlIYXNoIGN1ciA9IFN1ZmZIYXNoLmdldChOIC0gWCwgc3VmZi5sZW5ndGgoKSAtIDEpOwoJCQljb3V0IDw8IGNvdW50U3Vic3RyaW5ncyhTdHJIYXNoLCBjdXIpIDw8IGVuZGw7CgkJfQoJfQoJcmV0dXJuIDA7Cn0=