#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#define DEBUG(...) debug(#__VA_ARGS__, __VA_ARGS__)
#else
#define DEBUG(...) 6
#endif
template<typename T, typename S> ostream& operator << (ostream &os, const pair<T, S> &p) {return os << "(" << p.first << ", " << p.second << ")";}
template<typename C, typename T = decay<decltype(*begin(declval<C>()))>, typename enable_if<!is_same<C, string>::value>::type* = nullptr>
ostream& operator << (ostream &os, const C &c) {bool f = true; os << "["; for (const auto &x : c) {if (!f) os << ", "; f = false; os << x;} return os << "]";}
template<typename T> void debug(string s, T x) {cerr << "\033[1;35m" << s << "\033[0;32m = \033[33m" << x << "\033[0m\n";}
template<typename T, typename... Args> void debug(string s, T x, Args... args) {for (int i=0, b=0; i<(int)s.size(); i++) if (s[i] == '(' || s[i] == '{') b++; else
if (s[i] == ')' || s[i] == '}') b--; else if (s[i] == ',' && b == 0) {cerr << "\033[1;35m" << s.substr(0, i) << "\033[0;32m = \033[33m" << x << "\033[31m | "; debug(s.substr(s.find_first_not_of(' ', i + 1)), args...); break;}}
template<typename T>
struct BIT {
int n, lg;
vector<T> bit;
BIT(int _n) : n(_n), lg(__lg(n)), bit(n + 1) {}
BIT(const vector<T> &a) : n((int) a.size()), lg(__lg(n)), bit(n + 1) {
for (int i=1; i<=n; i++) {
bit[i] += a[i-1];
if (i + (i & -i) <= n)
bit[i+(i&-i)] += bit[i];
}
}
T query(int i) {
T ret = 0;
for (; i>0; i-=i&-i)
ret += bit[i];
return ret;
}
T query(int l, int r) {
return query(r) - query(l-1);
}
void update(int i, T val) {
for (; i<=n; i+=i&-i)
bit[i] += val;
}
int kth(T k) {
int ret = 0;
for (int i=lg; i>=0; i--) {
ret += 1 << i;
if (ret <= n && bit[ret] < k)
k -= bit[ret];
else
ret -= 1 << i;
}
return ret + 1;
}
};
struct SegmentTree {
int n;
vector<int> a, st, lazy;
SegmentTree(int _n) : n(_n), st(4*n), lazy(4*n) {}
SegmentTree(const vector<int> &_a) : n((int) _a.size()), a(_a), st(4*n), lazy(4*n) {
build(1, 0, n-1);
}
void build(int p, int l, int r) {
if (l == r) {
st[p] += a[l];
return;
}
int m = (l + r) / 2;
build(2*p, l, m);
build(2*p+1, m+1, r);
st[p] = min(st[2*p], st[2*p+1]);
}
void push(int p, int l, int r) {
if (lazy[p]) {
st[p] += lazy[p];
if (l != r) {
lazy[2*p] += lazy[p];
lazy[2*p+1] += lazy[p];
}
lazy[p] = 0;
}
}
int query(int p, int l, int r, int i, int j) {
push(p, l, r);
if (i > r || j < l)
return INT_MAX;
if (i <= l && r <= j)
return st[p];
int m = (l + r) / 2;
return min(query(2*p, l, m, i, j), query(2*p+1, m+1, r, i, j));
}
int query(int i, int j) {
return query(1, 0, n-1, i, j);
}
void update(int p, int l, int r, int i, int j, int val) {
push(p, l, r);
if (i > r || j < l)
return;
if (i <= l && r <= j) {
st[p] += val;
if (l != r) {
lazy[2*p] += val;
lazy[2*p+1] += val;
}
return;
}
int m = (l + r) / 2;
update(2*p, l, m, i, j, val);
update(2*p+1, m+1, r, i, j, val);
st[p] = min(st[2*p], st[2*p+1]);
}
void update(int i, int j, int val) {
update(1, 0, n-1, i, j, val);
}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
for (int cn=1; cn<=t; cn++) {
int r, c, k, q;
cin >> r >> c >> k >> q;
k--;
vector<string> g(r);
vector<BIT<int>> bit(c, BIT<int>(r));
vector<set<int>> st(c);
for (int i=0; i<r; i++) {
cin >> g[i];
for (int j=0; j<c; j++)
if (g[i][j] == 'X') {
bit[j].update(i + 1, 1);
st[j].insert(i);
}
}
vector<pair<int, int>> queries;
for (int i=0; i<q; i++) {
int a, b;
cin >> a >> b;
a--, b--;
queries.emplace_back(a, b);
}
// 0-based to 1-based
auto upd = [&] (int j, int i, int x) -> void {
bit[j].update(i + 1, x);
};
auto query = [&] (int j, int l, int r) -> int {
return bit[j].query(l + 1, r + 1);
};
auto shiz = [&] (int i) -> int {
return max(k - i, -1);
};
// down shifts (use upper row)
// find clog point
// shift 0, 1, 2, ..., r times (might be r - 1 but whatever)
// if it's clogged at shift s, then all later shifts are guaranteed to have a car there
SegmentTree stDown(r + 1);
vector<int> cnt(c), clog(c, -1);
int tot = 0;
for (int j=0; j<c; j++) {
cnt[j] = query(j, k, r - 1);
if (cnt[j] == r - k)
clog[j] = 0;
tot += g[k][j] == 'X';
}
// DEBUG("INIT", cn, cnt);
stDown.update(0, 0, tot);
for (int s=1; s<=r; s++) {
int tot = s;
for (int j=0; j<c; j++) {
bool car = k - s >= 0 ? g[k-s][j] == 'X' : false;
if (clog[j] == -1) {
// shift one above
if (car) {
cnt[j]++;
if (cnt[j] == r - k)
clog[j] = s;
}
}
tot += car || clog[j] != -1;
}
stDown.update(s, s, tot);
}
// DEBUG(cn, clog);
// do the updates for the down shifts
vector<int> ret(q, INT_MAX);
vector<string> old = g;
for (int i=0; i<q; i++) {
auto [a, b] = queries[i];
int yyyy = shiz(a);
if (g[a][b] == 'X') {
// remove car
// clog point could move up
g[a][b] = '.';
st[b].erase(a);
upd(b, a, -1);
if (clog[b] != -1 && yyyy <= clog[b]) {
// DEBUG("REM", cn, a, b, clog[b], st[b]);
if (cn == 6) DEBUG(yyyy);
if (yyyy != -1) stDown.update(yyyy, yyyy, -1);
stDown.update(clog[b] + 1, r, -1);
auto it = st[b].lower_bound(k - clog[b]);
if (it == st[b].begin()) {
// no clog point
clog[b] = -1;
} else {
// yes clog point
clog[b] = shiz(*prev(it));
stDown.update(clog[b], r, 1);
}
// DEBUG(clog[b]);
} else if (clog[b] == -1) {
if (yyyy != -1) stDown.update(yyyy, yyyy, -1);
}
} else {
// insert car
// clog point could move down
g[a][b] = 'X';
st[b].insert(a);
upd(b, a, 1);
if (clog[b] != -1 && yyyy < clog[b]) {
// DEBUG("INS", cn, a, b, clog[b]);
if (yyyy != -1) stDown.update(yyyy, yyyy, 1);
stDown.update(clog[b], r, -1);
auto it = next(st[b].find(k - clog[b]));
// yes clog point
clog[b] = shiz(*it);
stDown.update(clog[b] + 1, r, 1);
} else if (clog[b] == -1 && (int) st[b].size() >= r - k) {
// DEBUG("PP?");
int pp = bit[b].kth((int) st[b].size() - (r - k) + 1) - 1;
DEBUG(i, pp);
int cnt = query(b, pp, r - 1);
DEBUG(cnt);
if (cnt == r - k) {
// clog point
clog[b] = shiz(pp);
stDown.update(clog[b] + (clog[b] != yyyy), r, 1);
DEBUG(clog[b]);
if (yyyy < clog[b] && yyyy != -1) stDown.update(yyyy, yyyy, 1);
}
} else if (clog[b] == -1) {
if (yyyy != -1) stDown.update(yyyy, yyyy, 1);
}
}
if (cn == 6) DEBUG(cn, i, a, b, st[b], clog);
// DEBUG(stDown.query(0, r));
// for (int i=0; i<=r; i++)
// DEBUG(i, stDown.query(i, i));
ret[i] = min(ret[i], stDown.query(0, r));
}
// holy fuck do the same thing with up shift kill me please
// check rows below
{
vector<BIT<int>> bit(c, BIT<int>(r));
vector<set<int>> st(c);
g = old;
for (int i=0; i<r; i++) {
// cin >> g[i];
for (int j=0; j<c; j++)
if (g[i][j] == 'X') {
bit[j].update(i + 1, 1);
st[j].insert(i);
}
}
// 0-based to 1-based
auto upd = [&] (int j, int i, int x) -> void {
bit[j].update(i + 1, x);
};
auto query = [&] (int j, int l, int r) -> int {
return bit[j].query(l + 1, r + 1);
};
auto blah = [&] (int i) -> int {
return max(i - k, -1);
};
SegmentTree stDown(r + 1);
vector<int> cnt(c), clog(c, -1);
int tot = 0;
for (int j=0; j<c; j++) {
cnt[j] = query(j, 0, k);
if (cnt[j] == k + 1)
clog[j] = 0;
tot += g[k][j] == 'X';
}
// DEBUG("INIT", cn, cnt);
stDown.update(0, 0, tot);
for (int s=1; s<=r; s++) {
int tot = s;
for (int j=0; j<c; j++) {
bool car = k + s < r ? g[k+s][j] == 'X' : false;
if (clog[j] == -1) {
// shift one above
if (car) {
cnt[j]++;
if (cnt[j] == k + 1)
clog[j] = s;
}
}
tot += car || clog[j] != -1;
}
stDown.update(s, s, tot);
}
if (cn == 5) DEBUG(cn, clog);
// do the updates for the up shifts
for (int i=0; i<q; i++) {
auto [a, b] = queries[i];
int yyyy = blah(a);
if (g[a][b] == 'X') {
// remove car
// clog point could move down
g[a][b] = '.';
st[b].erase(a);
upd(b, a, -1);
if (clog[b] != -1 && yyyy <= clog[b]) {
if (cn == 5) DEBUG("REM", cn, a, b, yyyy, clog[b], st[b]);
if (yyyy != -1) stDown.update(yyyy, yyyy, -1);
stDown.update(clog[b] + 1, r, -1);
auto it = st[b].upper_bound(k + clog[b]);
if (cn == 5) DEBUG(st[b]);
if (it == st[b].end()) {
// no clog point
if (cn == 5) DEBUG("NONONO");
clog[b] = -1;
} else {
// yes clog point
clog[b] = blah(*(it));
stDown.update(clog[b], r, 1);
}
// DEBUG(clog[b]);
} else if (clog[b] == -1) {
if (yyyy != -1) stDown.update(yyyy, yyyy, -1);
}
} else {
// insert car
// clog point could move down
g[a][b] = 'X';
st[b].insert(a);
upd(b, a, 1);
DEBUG("HEY", yyyy);
if (clog[b] != -1 && yyyy < clog[b]) {
// DEBUG("INS", cn, a, b, clog[b]);
if (yyyy != -1) stDown.update(yyyy, yyyy, 1);
stDown.update(clog[b], r, -1);
auto it = prev(st[b].find(k + clog[b]));
// yes clog point
clog[b] = blah(*it);
stDown.update(clog[b] + 1, r, 1);
} else if (clog[b] == -1 && (int) st[b].size() >= k + 1) {
DEBUG(i, "PP?");
int pp = bit[b].kth(k + 1) - 1;
// DEBUG(pp, r, k + 1, st[b].size(), st[b]);
// for (int j=0; j<r; j++)
// DEBUG(bit[j].query(j + 1, j + 1));
int cnt = query(b, 0, pp);
// DEBUG(cnt);
if (cnt == k + 1) {
// clog point
clog[b] = blah(pp);
stDown.update(clog[b] + (clog[b] != yyyy), r, 1);
DEBUG(clog[b]);
DEBUG(stDown.query(0, 0));
if (yyyy < clog[b] && yyyy != -1) stDown.update(yyyy, yyyy, 1);
}
} else if (clog[b] == -1) {
if (yyyy != -1) stDown.update(yyyy, yyyy, 1);
}
}
// DEBUG(cn, i, a, b, st[b], clog[b]);
DEBUG(i, stDown.query(0, r));
for (int i=0; i<=r; i++)
DEBUG(i, stDown.query(i, i));
DEBUG(clog);
ret[i] = min(ret[i], stDown.query(0, r));
}
}
DEBUG(cn, ret);
cout << "Case #" << cn << ": " << accumulate(ret.begin(), ret.end(), 0LL) << "\n";
}
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojaWZkZWYgTE9DQUwKI2RlZmluZSBERUJVRyguLi4pIGRlYnVnKCNfX1ZBX0FSR1NfXywgX19WQV9BUkdTX18pCiNlbHNlCiNkZWZpbmUgREVCVUcoLi4uKSA2CiNlbmRpZgoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgUz4gb3N0cmVhbSYgb3BlcmF0b3IgPDwgKG9zdHJlYW0gJm9zLCBjb25zdCBwYWlyPFQsIFM+ICZwKSB7cmV0dXJuIG9zIDw8ICIoIiA8PCBwLmZpcnN0IDw8ICIsICIgPDwgcC5zZWNvbmQgPDwgIikiO30KdGVtcGxhdGU8dHlwZW5hbWUgQywgdHlwZW5hbWUgVCA9IGRlY2F5PGRlY2x0eXBlKCpiZWdpbihkZWNsdmFsPEM+KCkpKT4sIHR5cGVuYW1lIGVuYWJsZV9pZjwhaXNfc2FtZTxDLCBzdHJpbmc+Ojp2YWx1ZT46OnR5cGUqID0gbnVsbHB0cj4Kb3N0cmVhbSYgb3BlcmF0b3IgPDwgKG9zdHJlYW0gJm9zLCBjb25zdCBDICZjKSB7Ym9vbCBmID0gdHJ1ZTsgb3MgPDwgIlsiOyBmb3IgKGNvbnN0IGF1dG8gJnggOiBjKSB7aWYgKCFmKSBvcyA8PCAiLCAiOyBmID0gZmFsc2U7IG9zIDw8IHg7fSByZXR1cm4gb3MgPDwgIl0iO30KdGVtcGxhdGU8dHlwZW5hbWUgVD4gdm9pZCBkZWJ1ZyhzdHJpbmcgcywgVCB4KSB7Y2VyciA8PCAiXDAzM1sxOzM1bSIgPDwgcyA8PCAiXDAzM1swOzMybSA9IFwwMzNbMzNtIiA8PCB4IDw8ICJcMDMzWzBtXG4iO30KdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi4gQXJncz4gdm9pZCBkZWJ1ZyhzdHJpbmcgcywgVCB4LCBBcmdzLi4uIGFyZ3MpIHtmb3IgKGludCBpPTAsIGI9MDsgaTwoaW50KXMuc2l6ZSgpOyBpKyspIGlmIChzW2ldID09ICcoJyB8fCBzW2ldID09ICd7JykgYisrOyBlbHNlCmlmIChzW2ldID09ICcpJyB8fCBzW2ldID09ICd9JykgYi0tOyBlbHNlIGlmIChzW2ldID09ICcsJyAmJiBiID09IDApIHtjZXJyIDw8ICJcMDMzWzE7MzVtIiA8PCBzLnN1YnN0cigwLCBpKSA8PCAiXDAzM1swOzMybSA9IFwwMzNbMzNtIiA8PCB4IDw8ICJcMDMzWzMxbSB8ICI7IGRlYnVnKHMuc3Vic3RyKHMuZmluZF9maXJzdF9ub3Rfb2YoJyAnLCBpICsgMSkpLCBhcmdzLi4uKTsgYnJlYWs7fX0KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBCSVQgewogICAgaW50IG4sIGxnOwogICAgdmVjdG9yPFQ+IGJpdDsKCiAgICBCSVQoaW50IF9uKSA6IG4oX24pLCBsZyhfX2xnKG4pKSwgYml0KG4gKyAxKSB7fQoKICAgIEJJVChjb25zdCB2ZWN0b3I8VD4gJmEpIDogbigoaW50KSBhLnNpemUoKSksIGxnKF9fbGcobikpLCBiaXQobiArIDEpIHsKICAgICAgICBmb3IgKGludCBpPTE7IGk8PW47IGkrKykgewogICAgICAgICAgICBiaXRbaV0gKz0gYVtpLTFdOwogICAgICAgICAgICBpZiAoaSArIChpICYgLWkpIDw9IG4pCiAgICAgICAgICAgICAgICBiaXRbaSsoaSYtaSldICs9IGJpdFtpXTsKICAgICAgICB9CiAgICB9CgogICAgVCBxdWVyeShpbnQgaSkgewogICAgICAgIFQgcmV0ID0gMDsKICAgICAgICBmb3IgKDsgaT4wOyBpLT1pJi1pKQogICAgICAgICAgICByZXQgKz0gYml0W2ldOwogICAgICAgIHJldHVybiByZXQ7CiAgICB9CgogICAgVCBxdWVyeShpbnQgbCwgaW50IHIpIHsKICAgICAgICByZXR1cm4gcXVlcnkocikgLSBxdWVyeShsLTEpOwogICAgfQoKICAgIHZvaWQgdXBkYXRlKGludCBpLCBUIHZhbCkgewogICAgICAgIGZvciAoOyBpPD1uOyBpKz1pJi1pKQogICAgICAgICAgICBiaXRbaV0gKz0gdmFsOwogICAgfQoKICAgIGludCBrdGgoVCBrKSB7CiAgICAgICAgaW50IHJldCA9IDA7CiAgICAgICAgZm9yIChpbnQgaT1sZzsgaT49MDsgaS0tKSB7CiAgICAgICAgICAgIHJldCArPSAxIDw8IGk7CiAgICAgICAgICAgIGlmIChyZXQgPD0gbiAmJiBiaXRbcmV0XSA8IGspCiAgICAgICAgICAgICAgICBrIC09IGJpdFtyZXRdOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXQgLT0gMSA8PCBpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0ICsgMTsKICAgIH0KfTsKCnN0cnVjdCBTZWdtZW50VHJlZSB7CiAgICBpbnQgbjsKICAgIHZlY3RvcjxpbnQ+IGEsIHN0LCBsYXp5OwoKICAgIFNlZ21lbnRUcmVlKGludCBfbikgOiBuKF9uKSwgc3QoNCpuKSwgbGF6eSg0Km4pIHt9CgogICAgU2VnbWVudFRyZWUoY29uc3QgdmVjdG9yPGludD4gJl9hKSA6IG4oKGludCkgX2Euc2l6ZSgpKSwgYShfYSksIHN0KDQqbiksIGxhenkoNCpuKSB7CiAgICAgICAgYnVpbGQoMSwgMCwgbi0xKTsKICAgIH0KCiAgICB2b2lkIGJ1aWxkKGludCBwLCBpbnQgbCwgaW50IHIpIHsKICAgICAgICBpZiAobCA9PSByKSB7CiAgICAgICAgICAgIHN0W3BdICs9IGFbbF07CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaW50IG0gPSAobCArIHIpIC8gMjsKICAgICAgICBidWlsZCgyKnAsIGwsIG0pOwogICAgICAgIGJ1aWxkKDIqcCsxLCBtKzEsIHIpOwogICAgICAgIHN0W3BdID0gbWluKHN0WzIqcF0sIHN0WzIqcCsxXSk7CiAgICB9CgogICAgdm9pZCBwdXNoKGludCBwLCBpbnQgbCwgaW50IHIpIHsKICAgICAgICBpZiAobGF6eVtwXSkgewogICAgICAgICAgICBzdFtwXSArPSBsYXp5W3BdOwogICAgICAgICAgICBpZiAobCAhPSByKSB7CiAgICAgICAgICAgICAgICBsYXp5WzIqcF0gKz0gbGF6eVtwXTsKICAgICAgICAgICAgICAgIGxhenlbMipwKzFdICs9IGxhenlbcF07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGF6eVtwXSA9IDA7CiAgICAgICAgfQogICAgfQoKICAgIGludCBxdWVyeShpbnQgcCwgaW50IGwsIGludCByLCBpbnQgaSwgaW50IGopIHsKICAgICAgICBwdXNoKHAsIGwsIHIpOwogICAgICAgIGlmIChpID4gciB8fCBqIDwgbCkKICAgICAgICAgICAgcmV0dXJuIElOVF9NQVg7CiAgICAgICAgaWYgKGkgPD0gbCAmJiByIDw9IGopCiAgICAgICAgICAgIHJldHVybiBzdFtwXTsKICAgICAgICBpbnQgbSA9IChsICsgcikgLyAyOwogICAgICAgIHJldHVybiBtaW4ocXVlcnkoMipwLCBsLCBtLCBpLCBqKSwgcXVlcnkoMipwKzEsIG0rMSwgciwgaSwgaikpOwogICAgfQoKICAgIGludCBxdWVyeShpbnQgaSwgaW50IGopIHsKICAgICAgICByZXR1cm4gcXVlcnkoMSwgMCwgbi0xLCBpLCBqKTsKICAgIH0KCiAgICB2b2lkIHVwZGF0ZShpbnQgcCwgaW50IGwsIGludCByLCBpbnQgaSwgaW50IGosIGludCB2YWwpIHsKICAgICAgICBwdXNoKHAsIGwsIHIpOwogICAgICAgIGlmIChpID4gciB8fCBqIDwgbCkKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIGlmIChpIDw9IGwgJiYgciA8PSBqKSB7CiAgICAgICAgICAgIHN0W3BdICs9IHZhbDsKICAgICAgICAgICAgaWYgKGwgIT0gcikgewogICAgICAgICAgICAgICAgbGF6eVsyKnBdICs9IHZhbDsKICAgICAgICAgICAgICAgIGxhenlbMipwKzFdICs9IHZhbDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGludCBtID0gKGwgKyByKSAvIDI7CiAgICAgICAgdXBkYXRlKDIqcCwgbCwgbSwgaSwgaiwgdmFsKTsKICAgICAgICB1cGRhdGUoMipwKzEsIG0rMSwgciwgaSwgaiwgdmFsKTsKICAgICAgICBzdFtwXSA9IG1pbihzdFsyKnBdLCBzdFsyKnArMV0pOwogICAgfQoKICAgIHZvaWQgdXBkYXRlKGludCBpLCBpbnQgaiwgaW50IHZhbCkgewogICAgICAgIHVwZGF0ZSgxLCAwLCBuLTEsIGksIGosIHZhbCk7CiAgICB9Cn07CgppbnQgbWFpbigpIHsKICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOwogICAgY2luLnRpZShOVUxMKTsKCiAgICBpbnQgdDsKICAgIGNpbiA+PiB0OwogICAgZm9yIChpbnQgY249MTsgY248PXQ7IGNuKyspIHsKICAgICAgICBpbnQgciwgYywgaywgcTsKICAgICAgICBjaW4gPj4gciA+PiBjID4+IGsgPj4gcTsKICAgICAgICBrLS07CiAgICAgICAgdmVjdG9yPHN0cmluZz4gZyhyKTsKICAgICAgICB2ZWN0b3I8QklUPGludD4+IGJpdChjLCBCSVQ8aW50PihyKSk7CiAgICAgICAgdmVjdG9yPHNldDxpbnQ+PiBzdChjKTsKICAgICAgICBmb3IgKGludCBpPTA7IGk8cjsgaSsrKSB7CiAgICAgICAgICAgIGNpbiA+PiBnW2ldOwogICAgICAgICAgICBmb3IgKGludCBqPTA7IGo8YzsgaisrKQogICAgICAgICAgICAgICAgaWYgKGdbaV1bal0gPT0gJ1gnKSB7CiAgICAgICAgICAgICAgICAgICAgYml0W2pdLnVwZGF0ZShpICsgMSwgMSk7CiAgICAgICAgICAgICAgICAgICAgc3Rbal0uaW5zZXJ0KGkpOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB2ZWN0b3I8cGFpcjxpbnQsIGludD4+IHF1ZXJpZXM7CiAgICAgICAgZm9yIChpbnQgaT0wOyBpPHE7IGkrKykgewogICAgICAgICAgICBpbnQgYSwgYjsKICAgICAgICAgICAgY2luID4+IGEgPj4gYjsKICAgICAgICAgICAgYS0tLCBiLS07CiAgICAgICAgICAgIHF1ZXJpZXMuZW1wbGFjZV9iYWNrKGEsIGIpOwogICAgICAgIH0KCiAgICAgICAgLy8gMC1iYXNlZCB0byAxLWJhc2VkCiAgICAgICAgYXV0byB1cGQgPSBbJl0gKGludCBqLCBpbnQgaSwgaW50IHgpIC0+IHZvaWQgewogICAgICAgICAgICBiaXRbal0udXBkYXRlKGkgKyAxLCB4KTsKICAgICAgICB9OwoKICAgICAgICBhdXRvIHF1ZXJ5ID0gWyZdIChpbnQgaiwgaW50IGwsIGludCByKSAtPiBpbnQgewogICAgICAgICAgICByZXR1cm4gYml0W2pdLnF1ZXJ5KGwgKyAxLCByICsgMSk7CiAgICAgICAgfTsKCiAgICAgICAgYXV0byBzaGl6ID0gWyZdIChpbnQgaSkgLT4gaW50IHsKICAgICAgICAgICAgcmV0dXJuIG1heChrIC0gaSwgLTEpOwogICAgICAgIH07CgogICAgICAgIC8vIGRvd24gc2hpZnRzICh1c2UgdXBwZXIgcm93KQogICAgICAgIC8vIGZpbmQgY2xvZyBwb2ludAogICAgICAgIC8vIHNoaWZ0IDAsIDEsIDIsIC4uLiwgciB0aW1lcyAobWlnaHQgYmUgciAtIDEgYnV0IHdoYXRldmVyKQogICAgICAgIC8vIGlmIGl0J3MgY2xvZ2dlZCBhdCBzaGlmdCBzLCB0aGVuIGFsbCBsYXRlciBzaGlmdHMgYXJlIGd1YXJhbnRlZWQgdG8gaGF2ZSBhIGNhciB0aGVyZQogICAgICAgIFNlZ21lbnRUcmVlIHN0RG93bihyICsgMSk7CiAgICAgICAgdmVjdG9yPGludD4gY250KGMpLCBjbG9nKGMsIC0xKTsKICAgICAgICBpbnQgdG90ID0gMDsKICAgICAgICBmb3IgKGludCBqPTA7IGo8YzsgaisrKSB7CiAgICAgICAgICAgIGNudFtqXSA9IHF1ZXJ5KGosIGssIHIgLSAxKTsKICAgICAgICAgICAgaWYgKGNudFtqXSA9PSByIC0gaykKICAgICAgICAgICAgICAgIGNsb2dbal0gPSAwOwogICAgICAgICAgICB0b3QgKz0gZ1trXVtqXSA9PSAnWCc7CiAgICAgICAgfQogICAgICAgIC8vIERFQlVHKCJJTklUIiwgY24sIGNudCk7CiAgICAgICAgc3REb3duLnVwZGF0ZSgwLCAwLCB0b3QpOwogICAgICAgIGZvciAoaW50IHM9MTsgczw9cjsgcysrKSB7CiAgICAgICAgICAgIGludCB0b3QgPSBzOwogICAgICAgICAgICBmb3IgKGludCBqPTA7IGo8YzsgaisrKSB7CiAgICAgICAgICAgICAgICBib29sIGNhciA9IGsgLSBzID49IDAgPyBnW2stc11bal0gPT0gJ1gnIDogZmFsc2U7CiAgICAgICAgICAgICAgICBpZiAoY2xvZ1tqXSA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIC8vIHNoaWZ0IG9uZSBhYm92ZQogICAgICAgICAgICAgICAgICAgIGlmIChjYXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY250W2pdKys7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjbnRbal0gPT0gciAtIGspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9nW2pdID0gczsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0b3QgKz0gY2FyIHx8IGNsb2dbal0gIT0gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3REb3duLnVwZGF0ZShzLCBzLCB0b3QpOwogICAgICAgIH0KICAgICAgICAvLyBERUJVRyhjbiwgY2xvZyk7CgogICAgICAgIC8vIGRvIHRoZSB1cGRhdGVzIGZvciB0aGUgZG93biBzaGlmdHMKICAgICAgICB2ZWN0b3I8aW50PiByZXQocSwgSU5UX01BWCk7CiAgICAgICAgdmVjdG9yPHN0cmluZz4gb2xkID0gZzsKICAgICAgICBmb3IgKGludCBpPTA7IGk8cTsgaSsrKSB7CiAgICAgICAgICAgIGF1dG8gW2EsIGJdID0gcXVlcmllc1tpXTsKICAgICAgICAgICAgaW50IHl5eXkgPSBzaGl6KGEpOwogICAgICAgICAgICBpZiAoZ1thXVtiXSA9PSAnWCcpIHsKICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBjYXIKICAgICAgICAgICAgICAgIC8vIGNsb2cgcG9pbnQgY291bGQgbW92ZSB1cAogICAgICAgICAgICAgICAgZ1thXVtiXSA9ICcuJzsKICAgICAgICAgICAgICAgIHN0W2JdLmVyYXNlKGEpOwogICAgICAgICAgICAgICAgdXBkKGIsIGEsIC0xKTsKICAgICAgICAgICAgICAgIGlmIChjbG9nW2JdICE9IC0xICYmIHl5eXkgPD0gY2xvZ1tiXSkgewogICAgICAgICAgICAgICAgICAgIC8vIERFQlVHKCJSRU0iLCBjbiwgYSwgYiwgY2xvZ1tiXSwgc3RbYl0pOwogICAgICAgICAgICAgICAgICAgIGlmIChjbiA9PSA2KSBERUJVRyh5eXl5KTsKICAgICAgICAgICAgICAgICAgICBpZiAoeXl5eSAhPSAtMSkgc3REb3duLnVwZGF0ZSh5eXl5LCB5eXl5LCAtMSk7CiAgICAgICAgICAgICAgICAgICAgc3REb3duLnVwZGF0ZShjbG9nW2JdICsgMSwgciwgLTEpOwogICAgICAgICAgICAgICAgICAgIGF1dG8gaXQgPSBzdFtiXS5sb3dlcl9ib3VuZChrIC0gY2xvZ1tiXSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ID09IHN0W2JdLmJlZ2luKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gY2xvZyBwb2ludAogICAgICAgICAgICAgICAgICAgICAgICBjbG9nW2JdID0gLTE7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8geWVzIGNsb2cgcG9pbnQKICAgICAgICAgICAgICAgICAgICAgICAgY2xvZ1tiXSA9IHNoaXooKnByZXYoaXQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3REb3duLnVwZGF0ZShjbG9nW2JdLCByLCAxKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gREVCVUcoY2xvZ1tiXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNsb2dbYl0gPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoeXl5eSAhPSAtMSkgc3REb3duLnVwZGF0ZSh5eXl5LCB5eXl5LCAtMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBpbnNlcnQgY2FyCiAgICAgICAgICAgICAgICAvLyBjbG9nIHBvaW50IGNvdWxkIG1vdmUgZG93bgogICAgICAgICAgICAgICAgZ1thXVtiXSA9ICdYJzsKICAgICAgICAgICAgICAgIHN0W2JdLmluc2VydChhKTsKICAgICAgICAgICAgICAgIHVwZChiLCBhLCAxKTsKICAgICAgICAgICAgICAgIGlmIChjbG9nW2JdICE9IC0xICYmIHl5eXkgPCBjbG9nW2JdKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gREVCVUcoIklOUyIsIGNuLCBhLCBiLCBjbG9nW2JdKTsKICAgICAgICAgICAgICAgICAgICBpZiAoeXl5eSAhPSAtMSkgc3REb3duLnVwZGF0ZSh5eXl5LCB5eXl5LCAxKTsKICAgICAgICAgICAgICAgICAgICBzdERvd24udXBkYXRlKGNsb2dbYl0sIHIsIC0xKTsKICAgICAgICAgICAgICAgICAgICBhdXRvIGl0ID0gbmV4dChzdFtiXS5maW5kKGsgLSBjbG9nW2JdKSk7CiAgICAgICAgICAgICAgICAgICAgLy8geWVzIGNsb2cgcG9pbnQKICAgICAgICAgICAgICAgICAgICBjbG9nW2JdID0gc2hpeigqaXQpOwogICAgICAgICAgICAgICAgICAgIHN0RG93bi51cGRhdGUoY2xvZ1tiXSArIDEsIHIsIDEpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjbG9nW2JdID09IC0xICYmIChpbnQpIHN0W2JdLnNpemUoKSA+PSByIC0gaykgewogICAgICAgICAgICAgICAgICAgIC8vIERFQlVHKCJQUD8iKTsKICAgICAgICAgICAgICAgICAgICBpbnQgcHAgPSBiaXRbYl0ua3RoKChpbnQpIHN0W2JdLnNpemUoKSAtIChyIC0gaykgKyAxKSAtIDE7CiAgICAgICAgICAgICAgICAgICAgREVCVUcoaSwgcHApOwogICAgICAgICAgICAgICAgICAgIGludCBjbnQgPSBxdWVyeShiLCBwcCwgciAtIDEpOwogICAgICAgICAgICAgICAgICAgIERFQlVHKGNudCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNudCA9PSByIC0gaykgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBjbG9nIHBvaW50CiAgICAgICAgICAgICAgICAgICAgICAgIGNsb2dbYl0gPSBzaGl6KHBwKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3REb3duLnVwZGF0ZShjbG9nW2JdICsgKGNsb2dbYl0gIT0geXl5eSksIHIsIDEpOwogICAgICAgICAgICAgICAgICAgICAgICBERUJVRyhjbG9nW2JdKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHl5eXkgPCBjbG9nW2JdICYmIHl5eXkgIT0gLTEpIHN0RG93bi51cGRhdGUoeXl5eSwgeXl5eSwgMSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjbG9nW2JdID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHl5eXkgIT0gLTEpIHN0RG93bi51cGRhdGUoeXl5eSwgeXl5eSwgMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNuID09IDYpIERFQlVHKGNuLCBpLCBhLCBiLCBzdFtiXSwgY2xvZyk7CiAgICAgICAgICAgIC8vIERFQlVHKHN0RG93bi5xdWVyeSgwLCByKSk7CiAgICAgICAgICAgIC8vIGZvciAoaW50IGk9MDsgaTw9cjsgaSsrKQogICAgICAgICAgICAvLyAgICAgREVCVUcoaSwgc3REb3duLnF1ZXJ5KGksIGkpKTsKICAgICAgICAgICAgcmV0W2ldID0gbWluKHJldFtpXSwgc3REb3duLnF1ZXJ5KDAsIHIpKTsKICAgICAgICB9CgogICAgICAgIC8vIGhvbHkgZnVjayBkbyB0aGUgc2FtZSB0aGluZyB3aXRoIHVwIHNoaWZ0IGtpbGwgbWUgcGxlYXNlCiAgICAgICAgLy8gY2hlY2sgcm93cyBiZWxvdwogICAgICAgIHsKICAgICAgICAgICAgdmVjdG9yPEJJVDxpbnQ+PiBiaXQoYywgQklUPGludD4ocikpOwogICAgICAgICAgICB2ZWN0b3I8c2V0PGludD4+IHN0KGMpOwogICAgICAgICAgICBnID0gb2xkOwogICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8cjsgaSsrKSB7CiAgICAgICAgICAgICAgICAvLyBjaW4gPj4gZ1tpXTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGo9MDsgajxjOyBqKyspCiAgICAgICAgICAgICAgICAgICAgaWYgKGdbaV1bal0gPT0gJ1gnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJpdFtqXS51cGRhdGUoaSArIDEsIDEpOwogICAgICAgICAgICAgICAgICAgICAgICBzdFtqXS5pbnNlcnQoaSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyAwLWJhc2VkIHRvIDEtYmFzZWQKICAgICAgICBhdXRvIHVwZCA9IFsmXSAoaW50IGosIGludCBpLCBpbnQgeCkgLT4gdm9pZCB7CiAgICAgICAgICAgIGJpdFtqXS51cGRhdGUoaSArIDEsIHgpOwogICAgICAgIH07CgogICAgICAgIGF1dG8gcXVlcnkgPSBbJl0gKGludCBqLCBpbnQgbCwgaW50IHIpIC0+IGludCB7CiAgICAgICAgICAgIHJldHVybiBiaXRbal0ucXVlcnkobCArIDEsIHIgKyAxKTsKICAgICAgICB9OwoKICAgICAgICAgICAgYXV0byBibGFoID0gWyZdIChpbnQgaSkgLT4gaW50IHsKICAgICAgICAgICAgICAgIHJldHVybiBtYXgoaSAtIGssIC0xKTsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIFNlZ21lbnRUcmVlIHN0RG93bihyICsgMSk7CiAgICAgICAgICAgIHZlY3RvcjxpbnQ+IGNudChjKSwgY2xvZyhjLCAtMSk7CiAgICAgICAgICAgIGludCB0b3QgPSAwOwogICAgICAgICAgICBmb3IgKGludCBqPTA7IGo8YzsgaisrKSB7CiAgICAgICAgICAgICAgICBjbnRbal0gPSBxdWVyeShqLCAwLCBrKTsKICAgICAgICAgICAgICAgIGlmIChjbnRbal0gPT0gayArIDEpCiAgICAgICAgICAgICAgICAgICAgY2xvZ1tqXSA9IDA7CiAgICAgICAgICAgICAgICB0b3QgKz0gZ1trXVtqXSA9PSAnWCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gREVCVUcoIklOSVQiLCBjbiwgY250KTsKICAgICAgICAgICAgc3REb3duLnVwZGF0ZSgwLCAwLCB0b3QpOwogICAgICAgICAgICBmb3IgKGludCBzPTE7IHM8PXI7IHMrKykgewogICAgICAgICAgICAgICAgaW50IHRvdCA9IHM7CiAgICAgICAgICAgICAgICBmb3IgKGludCBqPTA7IGo8YzsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgYm9vbCBjYXIgPSBrICsgcyA8IHIgPyBnW2src11bal0gPT0gJ1gnIDogZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNsb2dbal0gPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2hpZnQgb25lIGFib3ZlCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNudFtqXSsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNudFtqXSA9PSBrICsgMSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9nW2pdID0gczsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0b3QgKz0gY2FyIHx8IGNsb2dbal0gIT0gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdERvd24udXBkYXRlKHMsIHMsIHRvdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNuID09IDUpIERFQlVHKGNuLCBjbG9nKTsKCiAgICAgICAgICAgIC8vIGRvIHRoZSB1cGRhdGVzIGZvciB0aGUgdXAgc2hpZnRzCiAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxxOyBpKyspIHsKICAgICAgICAgICAgICAgIGF1dG8gW2EsIGJdID0gcXVlcmllc1tpXTsKICAgICAgICAgICAgICAgIGludCB5eXl5ID0gYmxhaChhKTsKICAgICAgICAgICAgICAgIGlmIChnW2FdW2JdID09ICdYJykgewogICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBjYXIKICAgICAgICAgICAgICAgICAgICAvLyBjbG9nIHBvaW50IGNvdWxkIG1vdmUgZG93bgogICAgICAgICAgICAgICAgICAgIGdbYV1bYl0gPSAnLic7CiAgICAgICAgICAgICAgICAgICAgc3RbYl0uZXJhc2UoYSk7CiAgICAgICAgICAgICAgICAgICAgdXBkKGIsIGEsIC0xKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY2xvZ1tiXSAhPSAtMSAmJiB5eXl5IDw9IGNsb2dbYl0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNuID09IDUpIERFQlVHKCJSRU0iLCBjbiwgYSwgYiwgeXl5eSwgY2xvZ1tiXSwgc3RbYl0pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoeXl5eSAhPSAtMSkgc3REb3duLnVwZGF0ZSh5eXl5LCB5eXl5LCAtMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0RG93bi51cGRhdGUoY2xvZ1tiXSArIDEsIHIsIC0xKTsKICAgICAgICAgICAgICAgICAgICAgICAgYXV0byBpdCA9IHN0W2JdLnVwcGVyX2JvdW5kKGsgKyBjbG9nW2JdKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNuID09IDUpIERFQlVHKHN0W2JdKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ID09IHN0W2JdLmVuZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBubyBjbG9nIHBvaW50CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY24gPT0gNSkgREVCVUcoIk5PTk9OTyIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvZ1tiXSA9IC0xOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8geWVzIGNsb2cgcG9pbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2dbYl0gPSBibGFoKCooaXQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0RG93bi51cGRhdGUoY2xvZ1tiXSwgciwgMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gREVCVUcoY2xvZ1tiXSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjbG9nW2JdID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh5eXl5ICE9IC0xKSBzdERvd24udXBkYXRlKHl5eXksIHl5eXksIC0xKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIGluc2VydCBjYXIKICAgICAgICAgICAgICAgICAgICAvLyBjbG9nIHBvaW50IGNvdWxkIG1vdmUgZG93bgogICAgICAgICAgICAgICAgICAgIGdbYV1bYl0gPSAnWCc7CiAgICAgICAgICAgICAgICAgICAgc3RbYl0uaW5zZXJ0KGEpOwogICAgICAgICAgICAgICAgICAgIHVwZChiLCBhLCAxKTsKICAgICAgICAgICAgICAgICAgICBERUJVRygiSEVZIiwgeXl5eSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNsb2dbYl0gIT0gLTEgJiYgeXl5eSA8IGNsb2dbYl0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gREVCVUcoIklOUyIsIGNuLCBhLCBiLCBjbG9nW2JdKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHl5eXkgIT0gLTEpIHN0RG93bi51cGRhdGUoeXl5eSwgeXl5eSwgMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0RG93bi51cGRhdGUoY2xvZ1tiXSwgciwgLTEpOwogICAgICAgICAgICAgICAgICAgICAgICBhdXRvIGl0ID0gcHJldihzdFtiXS5maW5kKGsgKyBjbG9nW2JdKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHllcyBjbG9nIHBvaW50CiAgICAgICAgICAgICAgICAgICAgICAgIGNsb2dbYl0gPSBibGFoKCppdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0RG93bi51cGRhdGUoY2xvZ1tiXSArIDEsIHIsIDEpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2xvZ1tiXSA9PSAtMSAmJiAoaW50KSBzdFtiXS5zaXplKCkgPj0gayArIDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgREVCVUcoaSwgIlBQPyIpOwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgcHAgPSBiaXRbYl0ua3RoKGsgKyAxKSAtIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIERFQlVHKHBwLCByLCBrICsgMSwgc3RbYl0uc2l6ZSgpLCBzdFtiXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciAoaW50IGo9MDsgajxyOyBqKyspCiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICBERUJVRyhiaXRbal0ucXVlcnkoaiArIDEsIGogKyAxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBjbnQgPSBxdWVyeShiLCAwLCBwcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIERFQlVHKGNudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjbnQgPT0gayArIDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsb2cgcG9pbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2dbYl0gPSBibGFoKHBwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0RG93bi51cGRhdGUoY2xvZ1tiXSArIChjbG9nW2JdICE9IHl5eXkpLCByLCAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERFQlVHKGNsb2dbYl0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgREVCVUcoc3REb3duLnF1ZXJ5KDAsIDApKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh5eXl5IDwgY2xvZ1tiXSAmJiB5eXl5ICE9IC0xKSBzdERvd24udXBkYXRlKHl5eXksIHl5eXksIDEpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjbG9nW2JdID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh5eXl5ICE9IC0xKSBzdERvd24udXBkYXRlKHl5eXksIHl5eXksIDEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIERFQlVHKGNuLCBpLCBhLCBiLCBzdFtiXSwgY2xvZ1tiXSk7CiAgICAgICAgICAgICAgICBERUJVRyhpLCBzdERvd24ucXVlcnkoMCwgcikpOwogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTw9cjsgaSsrKQogICAgICAgICAgICAgICAgICAgICAgICBERUJVRyhpLCBzdERvd24ucXVlcnkoaSwgaSkpOwogICAgICAgICAgICAgICAgREVCVUcoY2xvZyk7CiAgICAgICAgICAgICAgICByZXRbaV0gPSBtaW4ocmV0W2ldLCBzdERvd24ucXVlcnkoMCwgcikpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBERUJVRyhjbiwgcmV0KTsKICAgICAgICBjb3V0IDw8ICJDYXNlICMiIDw8IGNuIDw8ICI6ICIgPDwgYWNjdW11bGF0ZShyZXQuYmVnaW4oKSwgcmV0LmVuZCgpLCAwTEwpIDw8ICJcbiI7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0K