#include <bits/stdc++.h>
using namespace std;
/* Merge 2 vector thanh 1
merge(Tree[2 * id].begin(), Tree[2 * id].end(),
Tree[2 * id + 1].begin(), Tree[2 * id + 1].end(),
back_inserter(Tree[id]));
*/
/*legendry
int legendry(int n, int p)
{
int ans = 0, x = 1;
while (x * p <= n)
{
x *= p;
ans += n/x;
}
return ans;
}
*/
/* Phi ham euler
int Phi(int x)
{
int res = 0;
for (int i = 2; i <= sqrt(x); i++)
{
if (x % i == 0)
{
res -= res / i;
while (x % i == 0)
{
x /= i;
}
}
}
if (x > 1) res -= res / x;
return res;
}
int phi[N];
void sang(int x)
{
fu(i, 1, x) phi[i] = i;
fu(i, 2, x)
{
if (phi[i] == i)
{
for (int j = i; j <= x; j += i)
{
phi[j] -= phi[j] / i;
}
}
}
}
*/
/* To Hop
const int MAX = 2e5 + 1;
int powmod(int a, int b)
{
if (b == 0) return 1;
else if (b == 1) return a % MOD;
int vl = powmod(a, b/2);
if (b % 2 == 0) return vl * vl % MOD;
return 1ll * (vl * vl % MOD) * (a % MOD) % MOD;
}
void preComb()
{
frac[0] = 1;
fu(i,1,MAX) frac[i] = 1LL * frac[i - 1] * i % MOD;
finv[MAX] = powmod(frac[MAX], MOD - 2);
fd(i,MAX,1) finv[i - 1] = 1LL * finv[i] * i % MOD;
}
int Comb(int k, int n)
{
return k > n ? 0 : 1LL * frac[n] * finv[k] % MOD * finv[n - k] % MOD;
}
*/
/* Fenwick 2d
struct Fenwick2D
{
vector<vector<int>> Tree;
int m, n;
Fenwick2D(int _m = 0, int _n = 0)
{
m = _m;
n = _n;
Tree.resize(m + 1);
fu(i,0,m)
{
Tree[i].resize(n + 1);
fill(Tree[i].begin(), Tree[i].end(), 0);
}
}
void update(int x, int y, int vl)
{
for(int i = x; i <= m; i += i&-i)
{
for(int j = y; j <= n; j += j&-j)
{
Tree[i][j] += vl;
}
}
}
int get(int x, int y)
{
int res = 0;
for(int i = x; i > 0; i -= i&-i)
{
for(int j = y; j > 0; j -= j&-j)
{
res += Tree[i][j];
}
}
return res;
}
} F2D;
*/
/* HLD
void dfs(int u, int p)
{
child[u] = 1;
for (int v : adj[u]) if (v != p)
{
par[v] = u;
depth[v] = depth[u] + 1;
dfs(v, u);
child[u] += child[v];
}
}
int lca(int u, int v)
{
while(ChainId[u] != ChainId[v])
{
if(ChainId[u] > ChainId[v])
{
u = par[head[ChainId[u]]];
}
else
{
v = par[head[ChainId[v]]];
}
}
if(depth[u] < depth[v]) return u;
return v;
}
void hld(int u, int p)
{
if (!head[CurChain]) head[CurChain] = u;
ChainId[u] = CurChain;
Pos[u] = ++CurPos;
Arr[CurPos] = v[u];
int MaxNode = 0;
for(int v : adj[u]) if (v != p)
{
if (child[v] > child[MaxNode]) MaxNode = v;
}
if (MaxNode) hld(MaxNode, u);
for(int v : adj[u]) if (v != p && v != MaxNode)
{
CurChain++;
hld(v, u);
}
}
int Query(int u, int v)
{
int Lca = lca(u, v);
int ans = LLONG_MIN;
while (ChainId[u] != ChainId[Lca])
{
maximize(ans, S.query(1,1,CurPos,Pos[head[ChainId[u]]], Pos[u]));
u = par[head[ChainId[u]]];
}
while (ChainId[v] != ChainId[Lca])
{
maximize(ans, S.query(1,1,CurPos,Pos[head[ChainId[v]]], Pos[v]));
v = par[head[ChainId[v]]];
}
if (depth[u] < depth[v])
{
maximize(ans, S.query(1,1,CurPos,Pos[u],Pos[v]));
}else maximize(ans, S.query(1,1,CurPos,Pos[v],Pos[u]));
return ans;
}
*/
/*
Convex Hull Trick Min
int pointer;
vector<ll> M;
vector<ll> B;
bool bad(int l1,int l2,int l3)
{
return (B[l3] - B[l1]) * (M[l1] - M[l2]) < (B[l2] - B[l1]) * (M[l1] - M[l3]);
}
void add(ll m,ll b)
{
M.push_back(m);
B.push_back(b);
while (M.size() >= 3 && bad(M.size() - 3, M.size() - 2, M.size() - 1))
{
M.erase(M.end()-2);
B.erase(B.end()-2);
}
}
ll query(ll x)
{
if (pointer >= M.size())
pointer = M.size() - 1;
while (pointer < M.size() - 1 && M[pointer+1] * x + B[pointer+1] < M[pointer] * x + B[pointer])
pointer++;
return M[pointer] * x + B[pointer];
}
*/
/* TRIE
struct Trie
{
struct Node
{
bool isEnd;
Node *child[26];
Node()
{
fu(i,0,25) child[i] = nullptr;
isEnd = 0;
}
};
Node *root = new Node();
void add(string str)
{
Node *x = root;
fu(i,0,str.size()-1)
{
int c = str[i] - 'a';
if (x->child[c] == nullptr) x->child[c] = new Node();
x = x->child[c];
}
x->isEnd = 1;
}
bool query(string str)
{
Node *x = root;
fu(i,0,str.size()-1)
{
int c = str[i] - 'a';
if (x->child[c] == nullptr) return false;
else x = x->child[c];
}
return (x->isEnd == 1);
}
} T;
*/
/* KMP
int kmp[N], match[N];
void cre_kmp()
{
int k = kmp[1] = 0;
fu(i,2,m)
{
while (k > 0 && B[i] != B[k+1]) k = kmp[k];
kmp[i] = B[i] == B[k+1] ? ++k : 0;
}
}
void cre_match()
{
int k = 0;
fu(i,1,n)
{
while(k > 0 && A[i] != B[k+1]) k = kmp[k];
match[i] = A[i] == B[k+1] ? ++k : 0;
if (match[i] == m) cout<<i - m + 1<<sp;
}
}
*/
/* CHIA CAN
fu(i,1,q)
{
int t; cin>>t;
if (t == 1)
{
int u, v; cin>>u>>v;
auto it = blck[u/sq].lower_bound(a[u]);
blck[u/sq].erase(it);
a[u] = v;
blck[u/sq].insert(a[u]);
}
else
{
int L, R, k; cin>>L>>R>>k;
int res = INT_MAX;
int blockL = (L - 1) / sq + 1;
int blockR = R / sq - 1;
fu(i,blockL,blockR)
{
auto it = blck[i].lower_bound(k);
if (it != blck[i].end()) minimize(res, *it);
}
if (L/sq != R/sq)
{
fu(i,L,blockL*sq-1) if (a[i] >= k) minimize(res, a[i]);
fu(i,(blockR+1)*sq,R) if (a[i] >= k) minimize(res, a[i]);
}
else fu(i,L,R) if (a[i] >= k) minimize(res, a[i]);
cout<<(res == INT_MAX ? -1 : res)<<el;
}
}
*/
/* DIJSKTRA
void dijkstra(int st)
{
d[st] = 0;
priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> q;
q.push({0,st});
while (!q.empty())
{
pair<l, int> tmp = q.top();
q.pop();
int u = tmp.second;
int w = tmp.first;
if (w > d[u]) continue;
for (auto it : adj[u])
{
int v = it.first;
int c = it.second;
if (maximize(d[v], w + c))
{
q.push({d[v], v});
}
}
}
}
/* FENWICK TREE
struct Fenwick
{
vector<pair<ll, int>> Tree;
int n;
Fenwick(int _n = 0)
{
n = _n;
Tree.resize(n+1);
}
void update(ll x, ll vl)
{
for(;x<=n;x+=x&-x)
{
Tree[x].first+=vl;
Tree[x].second++;
}
}
pair<ll,int> get(ll x)
{
pair<ll, int> tmp;
for(;x;x-=x&-x)
{
tmp.first += Tree[x].first;
tmp.second += Tree[x].second;
}
return tmp;
}
pair<ll,int> query(int l, int r)
{
if (l == 0) return get(r);
return {get(r).first - get(l-1).first, get(r).se - get(l-1).se};
}
} F;
/* SEGMENT TREE
struct Segment
{
struct Node
{
ll vl, lz;
Node(ll _vl = 0, ll _lz = 0)
{
vl = _vl;
lz = _lz;
}
};
vector<Node> Tree;
int n;
Segment(int _n = 0)
{
n = _n;
Tree.resize(4*n+1);
}
void build(int id, int l, int r)
{
if (l == r)
{
Tree[id].vl = a[l];
}else
{
int m = (l + r)/2;
build(id*2, l, m);
build(id*2+1, m+1, r);
Tree[id].vl = max(Tree[id*2].vl, Tree[id*2+1].vl);
}
}
void down(int id)
{
Node &P = Tree[id], &L = Tree[id*2], &R = Tree[id*2+1];
if (P.lz)
{
L.vl += P.lz;
R.vl += P.lz;
L.lz += P.lz;
R.lz += P.lz;
P.lz = 0;
}
}
void update(int id, int l, int r, int u, int v, ll vl)
{
if (l > v || r < u) return;
if (l >= u && r <= v)
{
Tree[id].vl += vl;
Tree[id].lz += vl;
return;
}
down(id);
int m = (l + r)/2;
update(id*2, l, m, u, v, vl);
update(id*2+1, m+1, r, u, v, vl);
Tree[id].vl = max(Tree[id*2].vl, Tree[id*2+1].vl);
}
ll query(int id, int l, int r, int u, int v)
{
if (l > v || r < u) return INT_MIN;
if (l >= u && r <= v) return Tree[id].vl;
down(id);
int m = (l+r)/2;
int L = query(id*2, l, m, u, v);
int R = query(id*2+1, m+1, r, u, v);
return max(L, R);
}
} S;
/*
/* DSU
struct DSU
{
vector<ll> lab;
int n;
DSU(int _n = 0)
{
n = _n;
lab.resize(n + 1);
fill(lab.begin(), lab.end(), -1);
}
int Find(int u)
{
return lab[u] < 0 ? u : lab[u] = Find(lab[u]);
}
ll Union(int u, int v)
{
u = Find(u);
v = Find(v);
if (u == v) return 0;
ll res = 1ll * lab[u] * lab[v];
if (lab[u] > lab[v]) swap(u, v);
lab[u] += lab[v];
lab[v] = u;
return res;
}
} D;
*/
/* NENSO
void nenso()
{
sort(vt.begin(), vt.end());
vt.resize(unique(vt.begin(), vt.end()) - vt.begin());
fu(i,1,n) a[i] = lower_bound(vt.begin(), vt.end(), a[i]) - vt.begin() + 1;
fu(i,1,q)
{
st[i].x = lower_bound(vt.begin(), vt.end(), st[i].x) - vt.begin() + 1;
if (st[i].tp == '?') st[i].k = lower_bound(vt.begin(), vt.end(), st[i].k) - vt.begin() + 1;
}
}
*/
/* Kruskal
bool cmp(Edge a, Edge b)
{
return a.c < b.c;
}
vector<Edge> mst;
void kruskal()
{
sort(st + 1, st + m +1, cmp);
ll d = 0;
for (int i = 1; i <= m; i++)
{
if (mst.size() == n - 1) break;
if (Union(st[i].u, st[i].v))
{
mst.push_back(st[i]);
d += st[i].c;
}
}
}
*/
/* SPARSE TABLE
int log2_floor(int n) { return 31 - __builtin_clz(n); }
ll query_rmq(int l, int r)
{
int i = log2_floor(r-l+1);
return min(table[i][l], table[i][r - MASK(i) + 1]);
}
void pre
{
fu(i,1,n) table[0][i] = a[i];
fu(j,1,Log)
{
for (int i = 1; i + MASK(j) - 1 <= n; i++)
{
table[j][i] = min(table[j-1][i], table[j-1][i + MASK(j - 1)]);//rmq hay rsq thi thay doi min hoac s
}
}
}
*/
/* KIEM TRA CHU TRINH
1. DO THI VO HUONG DUNG DSU
2. DO THI CO HUONG
bool dfs(int u)
{
col[u] = 1;
for (int v : adj[u])
{
if (col[v] == 0)
{
par[v] = u;
if (dfs(v)) return true;
}else if (col[v] == 1) return true;
}
col[u] = 2;
return false;
}
*/
/*
LCA
void dfs(int u, int p)
{
for (int v : adj[u]) if (v != p)
{
high[v] = high[u] + 1;
par[v][0] = u;
dfs(v, u);
}
}
void pre()
{
dfs(1, -1);
for (int j = 1; j <= Log; j++)
{
for (int i = 1; i <= n; i++)
{
par[i][j] = par[par[i][j-1]][j-1];
}
}
high[0] = -1;
}
int lca(int u, int v)
{
if (high[v] > high[u]) return lca(v, u);
fd(i, Log, 0)
{
if(high[par[u][i]] >= high[v])
u = par[u][i];
}
if (u == v) return u;
fd(i, Log, 0)
{
if (par[u][i] != par[v][i])
{
u = par[u][i];
v = par[v][i];
}
}
return par[u][0];
}
*/
/* ERAS DOAN
void eras_doan()
{
fu(i,2,(int)1e6)
{
ll j = (l + i - 1) /i *i;
for (;j<=r; j+=i) if (j != i)
d[j-l] = 1
}
for (int i = 0; i < r-l; i++) if (d[i]==0) cout<<i+l<<sp;
}
*/
/* LUONG CUC DAI
struct edge
{
int x, y, cap, flow;
};
struct Flow
{
int n, S, T;
vector < vector <int> > a;
vector <int> cur, d;
vector <edge> e;
Flow() {}
Flow(int _n, int _S, int _T)
{
n = _n; S = _S; T = _T;
a = vector < vector <int> >(n + 1);
cur = vector <int>(n + 1);
d = vector <int>(n + 1);
}
void addEdge(int x, int y, int _cap)
{
edge e1 = {x, y, _cap, 0};
edge e2 = {y, x, 0, 0};
a[x].push_back(e.size()); e.push_back(e1);
a[y].push_back(e.size()); e.push_back(e2);
}
int bfs()
{
queue<int> q;
for (int i = 1; i <= n; i++) d[i] = -1;
q.push(S); d[S] = 0;
while (!q.empty() && d[T] < 0)
{
int x = q.front(); q.pop();
for (int i = 0; i < (int)a[x].size(); i++)
{
int id = a[x][i], y = e[id].y;
if (d[y] < 0 && e[id].flow < e[id].cap)
q.push(y), d[y] = d[x] + 1;
}
}
return d[T] >= 0;
}
int dfs(int x, int val)
{
if (!val) return 0;
if (x == T) return val;
for (; cur[x] < (int)a[x].size(); cur[x]++)
{
int id = a[x][cur[x]], y = e[id].y;
if (d[y] != d[x] + 1) continue;
int pushed = dfs(y, min(val, e[id].cap - e[id].flow));
if (pushed)
{
e[id].flow += pushed;
e[id ^ 1].flow -= pushed;
return pushed;
}
}
return 0;
}
int maxFlow()
{
int res = 0;
while (bfs())
{
for (int i = 1; i <= n; i++) cur[i] = 0;
while (1)
{
int val = dfs(S, oo);
if (!val) break;
res += val;
}
}
return res;
}
};
*/
/* Matrix Multiplication
const int MATRIX_SIZE = 20;
struct Matrix {
int m, n;
long long d[MATRIX_SIZE][MATRIX_SIZE];
Matrix(int _m = 0, int _n = 0) {
m = _m; n = _n;
memset(d, 0, sizeof d);
}
Matrix operator + (const Matrix &a) const {
Matrix res(m, n);
for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) {
res.d[i][j] = d[i][j] + a.d[i][j];
if (res.d[i][j] >= MOD) res.d[i][j] -= MOD;
}
return res;
}
Matrix operator * (const Matrix &a) const {
int x = m, y = n, z = a.n;
Matrix res(x, z);
for (int i = 0; i < x; i++) for (int j = 0; j < y; j++)
for (int k = 0; k < z; k++) {
res.d[i][k] += 1LL * d[i][j] * a.d[j][k];
if (res.d[i][k] >= 1LL * MOD * MOD) res.d[i][k] -= 1LL * MOD * MOD;
}
for (int i = 0; i < x; i++) for (int k = 0; k < z; k++) res.d[i][k] %= MOD;
return res;
}
Matrix operator ^ (long long k) const {
Matrix res(n, n);
for (int i = 0; i < n; i++) res.d[i][i] = 1;
Matrix mul = *this;
while (k > 0) {
if (k & 1) res = res * mul;
mul = mul * mul;
k >>= 1;
}
return res;
}
long long* operator[] (int i) {
return d[i];
}
const long long* operator[] (int i) const {
return d[i];
}
};
*/
/* CAP GHEP CUC DAI KHONG TRONG SO
struct matcher {
const int oo = 100000000;
int m, n;
vector<int> mx, my, dist;
vector<vector<int>> ke;
int matched;
matcher(int m, int n):
m(m), n(n),
mx(m+1, 0), my(n+1, 0), dist(m+1),
ke(m+1),
matched(0) {}
void add_edge(int u, int v) {
ke[u].push_back(v);
}
bool bfs() {
queue<int> Q;
for (int u=1; u<=m; u++) {
if (!mx[u]) {
dist[u] = 0;
Q.push(u);
} else {
dist[u] = oo;
}
}
bool found = false;
while (!Q.empty()) {
int u = Q.front(); Q.pop();
for (int v: ke[u]) {
if (!my[v]) {
found = true;
} else if (dist[my[v]] == oo) {
dist[my[v]] = dist[u] + 1;
Q.push(my[v]);
}
}
}
return found;
}
bool dfs(int u) {
if (dist[u] == oo) return false;
for (int v: ke[u]) {
if (!my[v] || (dist[my[v]]==dist[u]+1 && dfs(my[v]))) {
mx[u] = v;
my[v] = u;
return true;
}
}
return false;
}
void match() {
while(bfs()) {
for (int u=1; u<=m; u++) if (!mx[u]) matched += dfs(u);
}
}
};
int get()
{
matcher z(n, n);
fu(i,1,m)
{
int u, v; cin>>u>>v;
z.add_edge(u, v);
}
z.match();
return z.matched;
}
*/
signed main()
{
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwovKiBNZXJnZSAyIHZlY3RvciB0aGFuaCAxCiBtZXJnZShUcmVlWzIgKiBpZF0uYmVnaW4oKSwgVHJlZVsyICogaWRdLmVuZCgpLAogICAgICAgICAgICAgIFRyZWVbMiAqIGlkICsgMV0uYmVnaW4oKSwgVHJlZVsyICogaWQgKyAxXS5lbmQoKSwKICAgICAgICAgICAgICBiYWNrX2luc2VydGVyKFRyZWVbaWRdKSk7CiovCgovKmxlZ2VuZHJ5CmludCBsZWdlbmRyeShpbnQgbiwgaW50IHApCnsKICAgIGludCBhbnMgPSAwLCB4ID0gMTsKICAgIHdoaWxlICh4ICogcCA8PSBuKQogICAgewogICAgICAgIHggKj0gcDsKICAgICAgICBhbnMgKz0gbi94OwogICAgfQogICAgcmV0dXJuIGFuczsKfQoqLwoKLyogUGhpIGhhbSBldWxlcgppbnQgUGhpKGludCB4KQp7CiAgICBpbnQgcmVzID0gMDsKICAgIGZvciAoaW50IGkgPSAyOyBpIDw9IHNxcnQoeCk7IGkrKykKICAgIHsKICAgICAgICBpZiAoeCAlIGkgPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHJlcyAtPSByZXMgLyBpOwogICAgICAgICAgICB3aGlsZSAoeCAlIGkgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgeCAvPSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgaWYgKHggPiAxKSByZXMgLT0gcmVzIC8geDsKICAgIHJldHVybiByZXM7Cn0KCmludCBwaGlbTl07Cgp2b2lkIHNhbmcoaW50IHgpCnsKICAgIGZ1KGksIDEsIHgpIHBoaVtpXSA9IGk7CgogICAgZnUoaSwgMiwgeCkKICAgIHsKICAgICAgICBpZiAocGhpW2ldID09IGkpCiAgICAgICAgewogICAgICAgICAgICBmb3IgKGludCBqID0gaTsgaiA8PSB4OyBqICs9IGkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHBoaVtqXSAtPSBwaGlbal0gLyBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CiovCgovKiBUbyBIb3AKY29uc3QgaW50IE1BWCA9IDJlNSArIDE7CgppbnQgcG93bW9kKGludCBhLCBpbnQgYikKewogICAgaWYgKGIgPT0gMCkgcmV0dXJuIDE7CiAgICBlbHNlIGlmIChiID09IDEpIHJldHVybiBhICUgTU9EOwogICAgaW50IHZsID0gcG93bW9kKGEsIGIvMik7CiAgICBpZiAoYiAlIDIgPT0gMCkgcmV0dXJuIHZsICogdmwgJSBNT0Q7CiAgICByZXR1cm4gMWxsICogKHZsICogdmwgJSBNT0QpICogKGEgJSBNT0QpICUgTU9EOwp9Cgp2b2lkIHByZUNvbWIoKQp7CiAgICBmcmFjWzBdID0gMTsKICAgIGZ1KGksMSxNQVgpIGZyYWNbaV0gPSAxTEwgKiBmcmFjW2kgLSAxXSAqIGkgJSBNT0Q7CiAgICBmaW52W01BWF0gPSBwb3dtb2QoZnJhY1tNQVhdLCBNT0QgLSAyKTsKICAgIGZkKGksTUFYLDEpIGZpbnZbaSAtIDFdID0gMUxMICogZmludltpXSAqIGkgJSBNT0Q7Cn0KCmludCBDb21iKGludCBrLCBpbnQgbikKewogICAgcmV0dXJuIGsgPiBuID8gMCA6IDFMTCAqIGZyYWNbbl0gKiBmaW52W2tdICUgTU9EICogZmludltuIC0ga10gJSBNT0Q7Cn0KKi8KCi8qIEZlbndpY2sgMmQKc3RydWN0IEZlbndpY2syRAp7CiAgICB2ZWN0b3I8dmVjdG9yPGludD4+IFRyZWU7CiAgICBpbnQgbSwgbjsKICAgIEZlbndpY2syRChpbnQgX20gPSAwLCBpbnQgX24gPSAwKQogICAgewogICAgICAgIG0gPSBfbTsKICAgICAgICBuID0gX247CiAgICAgICAgVHJlZS5yZXNpemUobSArIDEpOwogICAgICAgIGZ1KGksMCxtKQogICAgICAgIHsKICAgICAgICAgICAgVHJlZVtpXS5yZXNpemUobiArIDEpOwogICAgICAgICAgICBmaWxsKFRyZWVbaV0uYmVnaW4oKSwgVHJlZVtpXS5lbmQoKSwgMCk7CiAgICAgICAgfQogICAgfQogICAgdm9pZCB1cGRhdGUoaW50IHgsIGludCB5LCBpbnQgdmwpCiAgICB7CiAgICAgICAgZm9yKGludCBpID0geDsgaSA8PSBtOyBpICs9IGkmLWkpCiAgICAgICAgewogICAgICAgICAgICBmb3IoaW50IGogPSB5OyBqIDw9IG47IGogKz0gaiYtaikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVHJlZVtpXVtqXSArPSB2bDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGludCBnZXQoaW50IHgsIGludCB5KQogICAgewogICAgICAgIGludCByZXMgPSAwOwogICAgICAgIGZvcihpbnQgaSA9IHg7IGkgPiAwOyBpIC09IGkmLWkpCiAgICAgICAgewogICAgICAgICAgICBmb3IoaW50IGogPSB5OyBqID4gMDsgaiAtPSBqJi1qKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXMgKz0gVHJlZVtpXVtqXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzOwogICAgfQp9IEYyRDsKKi8KLyogSExECiB2b2lkIGRmcyhpbnQgdSwgaW50IHApCiB7CiAgICAgY2hpbGRbdV0gPSAxOwogICAgIGZvciAoaW50IHYgOiBhZGpbdV0pIGlmICh2ICE9IHApCiAgICAgewogICAgICAgICBwYXJbdl0gPSB1OwogICAgICAgICBkZXB0aFt2XSA9IGRlcHRoW3VdICsgMTsKICAgICAgICAgZGZzKHYsIHUpOwogICAgICAgICBjaGlsZFt1XSArPSBjaGlsZFt2XTsKICAgICB9CiB9CgogaW50IGxjYShpbnQgdSwgaW50IHYpCiB7CiAgICB3aGlsZShDaGFpbklkW3VdICE9IENoYWluSWRbdl0pCiAgICB7CiAgICAgICAgaWYoQ2hhaW5JZFt1XSA+IENoYWluSWRbdl0pCiAgICAgICAgewogICAgICAgICAgICB1ID0gcGFyW2hlYWRbQ2hhaW5JZFt1XV1dOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICB2ID0gcGFyW2hlYWRbQ2hhaW5JZFt2XV1dOwogICAgICAgIH0KICAgIH0KICAgIGlmKGRlcHRoW3VdIDwgZGVwdGhbdl0pIHJldHVybiB1OwogICAgcmV0dXJuIHY7Cn0KCnZvaWQgaGxkKGludCB1LCBpbnQgcCkKIHsKICAgICBpZiAoIWhlYWRbQ3VyQ2hhaW5dKSBoZWFkW0N1ckNoYWluXSA9IHU7CiAgICAgQ2hhaW5JZFt1XSA9IEN1ckNoYWluOwogICAgIFBvc1t1XSA9ICsrQ3VyUG9zOwogICAgIEFycltDdXJQb3NdID0gdlt1XTsKICAgICBpbnQgTWF4Tm9kZSA9IDA7CiAgICAgZm9yKGludCB2IDogYWRqW3VdKSBpZiAodiAhPSBwKQogICAgIHsKICAgICAgICAgaWYgKGNoaWxkW3ZdID4gY2hpbGRbTWF4Tm9kZV0pIE1heE5vZGUgPSB2OwogICAgIH0KICAgICBpZiAoTWF4Tm9kZSkgaGxkKE1heE5vZGUsIHUpOwogICAgIGZvcihpbnQgdiA6IGFkalt1XSkgaWYgKHYgIT0gcCAmJiB2ICE9IE1heE5vZGUpCiAgICAgewogICAgICAgICBDdXJDaGFpbisrOwogICAgICAgICBobGQodiwgdSk7CiAgICAgfQogfQoKIGludCBRdWVyeShpbnQgdSwgaW50IHYpCnsKICAgIGludCBMY2EgPSBsY2EodSwgdik7CiAgICBpbnQgYW5zID0gTExPTkdfTUlOOwogICAgd2hpbGUgKENoYWluSWRbdV0gIT0gQ2hhaW5JZFtMY2FdKQogICAgewogICAgICAgIG1heGltaXplKGFucywgUy5xdWVyeSgxLDEsQ3VyUG9zLFBvc1toZWFkW0NoYWluSWRbdV1dXSwgUG9zW3VdKSk7CiAgICAgICAgdSA9IHBhcltoZWFkW0NoYWluSWRbdV1dXTsKICAgIH0KICAgIHdoaWxlIChDaGFpbklkW3ZdICE9IENoYWluSWRbTGNhXSkKICAgIHsKICAgICAgICBtYXhpbWl6ZShhbnMsIFMucXVlcnkoMSwxLEN1clBvcyxQb3NbaGVhZFtDaGFpbklkW3ZdXV0sIFBvc1t2XSkpOwogICAgICAgIHYgPSBwYXJbaGVhZFtDaGFpbklkW3ZdXV07CiAgICB9CiAgICBpZiAoZGVwdGhbdV0gPCBkZXB0aFt2XSkKICAgIHsKICAgICAgICBtYXhpbWl6ZShhbnMsIFMucXVlcnkoMSwxLEN1clBvcyxQb3NbdV0sUG9zW3ZdKSk7CiAgICB9ZWxzZSBtYXhpbWl6ZShhbnMsIFMucXVlcnkoMSwxLEN1clBvcyxQb3Nbdl0sUG9zW3VdKSk7CiAgICByZXR1cm4gYW5zOwp9CiovCgovKgpDb252ZXggSHVsbCBUcmljayBNaW4KaW50IHBvaW50ZXI7CnZlY3RvcjxsbD4gTTsKdmVjdG9yPGxsPiBCOwoKYm9vbCBiYWQoaW50IGwxLGludCBsMixpbnQgbDMpCnsKCXJldHVybiAoQltsM10gLSBCW2wxXSkgKiAoTVtsMV0gLSBNW2wyXSkgPCAoQltsMl0gLSBCW2wxXSkgKiAoTVtsMV0gLSBNW2wzXSk7Cn0KCnZvaWQgYWRkKGxsIG0sbGwgYikKewoJTS5wdXNoX2JhY2sobSk7CglCLnB1c2hfYmFjayhiKTsKCXdoaWxlIChNLnNpemUoKSA+PSAzICYmIGJhZChNLnNpemUoKSAtIDMsIE0uc2l6ZSgpIC0gMiwgTS5zaXplKCkgLSAxKSkKCXsKCQlNLmVyYXNlKE0uZW5kKCktMik7CgkJQi5lcmFzZShCLmVuZCgpLTIpOwoJfQp9CgpsbCBxdWVyeShsbCB4KQp7CglpZiAocG9pbnRlciA+PSBNLnNpemUoKSkKICAgICAgICBwb2ludGVyID0gTS5zaXplKCkgLSAxOwoJd2hpbGUgKHBvaW50ZXIgPCBNLnNpemUoKSAtIDEgJiYgTVtwb2ludGVyKzFdICogeCArIEJbcG9pbnRlcisxXSA8IE1bcG9pbnRlcl0gKiB4ICsgQltwb2ludGVyXSkKCQlwb2ludGVyKys7CglyZXR1cm4gTVtwb2ludGVyXSAqIHggKyBCW3BvaW50ZXJdOwp9CiovCgovKiBUUklFCnN0cnVjdCBUcmllCnsKICAgIHN0cnVjdCBOb2RlCiAgICB7CiAgICAgICAgYm9vbCBpc0VuZDsKICAgICAgICBOb2RlICpjaGlsZFsyNl07CiAgICAgICAgTm9kZSgpCiAgICAgICAgewogICAgICAgICAgICBmdShpLDAsMjUpIGNoaWxkW2ldID0gbnVsbHB0cjsKICAgICAgICAgICAgaXNFbmQgPSAwOwogICAgICAgIH0KICAgIH07CiAgICBOb2RlICpyb290ID0gbmV3IE5vZGUoKTsKICAgIHZvaWQgYWRkKHN0cmluZyBzdHIpCiAgICB7CiAgICAgICAgTm9kZSAqeCA9IHJvb3Q7CiAgICAgICAgZnUoaSwwLHN0ci5zaXplKCktMSkKICAgICAgICB7CiAgICAgICAgICAgIGludCBjID0gc3RyW2ldIC0gJ2EnOwogICAgICAgICAgICBpZiAoeC0+Y2hpbGRbY10gPT0gbnVsbHB0cikgeC0+Y2hpbGRbY10gPSBuZXcgTm9kZSgpOwogICAgICAgICAgICB4ID0geC0+Y2hpbGRbY107CiAgICAgICAgfQogICAgICAgIHgtPmlzRW5kID0gMTsKICAgIH0KICAgIGJvb2wgcXVlcnkoc3RyaW5nIHN0cikKICAgIHsKICAgICAgICBOb2RlICp4ID0gcm9vdDsKICAgICAgICBmdShpLDAsc3RyLnNpemUoKS0xKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGMgPSBzdHJbaV0gLSAnYSc7CiAgICAgICAgICAgIGlmICh4LT5jaGlsZFtjXSA9PSBudWxscHRyKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGVsc2UgeCA9IHgtPmNoaWxkW2NdOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKHgtPmlzRW5kID09IDEpOwogICAgfQp9IFQ7CiovCgovKiBLTVAKaW50IGttcFtOXSwgbWF0Y2hbTl07Cgp2b2lkIGNyZV9rbXAoKQp7CiAgICBpbnQgayA9IGttcFsxXSA9IDA7CiAgICBmdShpLDIsbSkKICAgIHsKICAgICAgICB3aGlsZSAoayA+IDAgJiYgQltpXSAhPSBCW2srMV0pIGsgPSBrbXBba107CiAgICAgICAga21wW2ldID0gQltpXSA9PSBCW2srMV0gPyArK2sgOiAwOwogICAgfQp9Cgp2b2lkIGNyZV9tYXRjaCgpCnsKICAgIGludCBrID0gMDsKICAgIGZ1KGksMSxuKQogICAgewogICAgICAgIHdoaWxlKGsgPiAwICYmIEFbaV0gIT0gQltrKzFdKSBrID0ga21wW2tdOwogICAgICAgIG1hdGNoW2ldID0gQVtpXSA9PSBCW2srMV0gPyArK2sgOiAwOwogICAgICAgIGlmIChtYXRjaFtpXSA9PSBtKSBjb3V0PDxpIC0gbSArIDE8PHNwOwogICAgfQp9CiovCgovKiBDSElBIENBTgogICBmdShpLDEscSkKICAgIHsKICAgICAgICBpbnQgdDsgY2luPj50OwogICAgICAgIGlmICh0ID09IDEpCiAgICAgICAgewogICAgICAgICAgICBpbnQgdSwgdjsgY2luPj51Pj52OwogICAgICAgICAgICBhdXRvIGl0ID0gYmxja1t1L3NxXS5sb3dlcl9ib3VuZChhW3VdKTsKICAgICAgICAgICAgYmxja1t1L3NxXS5lcmFzZShpdCk7CiAgICAgICAgICAgIGFbdV0gPSB2OwogICAgICAgICAgICBibGNrW3Uvc3FdLmluc2VydChhW3VdKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaW50IEwsIFIsIGs7IGNpbj4+TD4+Uj4+azsKICAgICAgICAgICAgaW50IHJlcyA9IElOVF9NQVg7CiAgICAgICAgICAgIGludCBibG9ja0wgPSAoTCAtIDEpIC8gc3EgKyAxOwogICAgICAgICAgICBpbnQgYmxvY2tSID0gUiAvIHNxIC0gMTsKCiAgICAgICAgICAgIGZ1KGksYmxvY2tMLGJsb2NrUikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYXV0byBpdCA9IGJsY2tbaV0ubG93ZXJfYm91bmQoayk7CiAgICAgICAgICAgICAgICBpZiAoaXQgIT0gYmxja1tpXS5lbmQoKSkgbWluaW1pemUocmVzLCAqaXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoTC9zcSAhPSBSL3NxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmdShpLEwsYmxvY2tMKnNxLTEpIGlmIChhW2ldID49IGspIG1pbmltaXplKHJlcywgYVtpXSk7CiAgICAgICAgICAgICAgICBmdShpLChibG9ja1IrMSkqc3EsUikgaWYgKGFbaV0gPj0gaykgbWluaW1pemUocmVzLCBhW2ldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGZ1KGksTCxSKSBpZiAoYVtpXSA+PSBrKSBtaW5pbWl6ZShyZXMsIGFbaV0pOwogICAgICAgICAgICBjb3V0PDwocmVzID09IElOVF9NQVggPyAtMSA6IHJlcyk8PGVsOwogICAgICAgIH0KICAgIH0KICAgICovCgovKiBESUpTS1RSQQp2b2lkIGRpamtzdHJhKGludCBzdCkKewogICAgZFtzdF0gPSAwOwogICAgcHJpb3JpdHlfcXVldWU8cGFpcjxsbCwgaW50PiwgdmVjdG9yPHBhaXI8bGwsIGludD4+LCBncmVhdGVyPHBhaXI8bGwsIGludD4+PiBxOwogICAgcS5wdXNoKHswLHN0fSk7CiAgICB3aGlsZSAoIXEuZW1wdHkoKSkKICAgIHsKICAgICAgICBwYWlyPGwsIGludD4gdG1wID0gcS50b3AoKTsKICAgICAgICBxLnBvcCgpOwogICAgICAgIGludCB1ID0gdG1wLnNlY29uZDsKICAgICAgICBpbnQgdyA9IHRtcC5maXJzdDsKICAgICAgICBpZiAodyA+IGRbdV0pIGNvbnRpbnVlOwogICAgICAgIGZvciAoYXV0byBpdCA6IGFkalt1XSkKICAgICAgICB7CiAgICAgICAgICAgIGludCB2ID0gaXQuZmlyc3Q7CiAgICAgICAgICAgIGludCBjID0gaXQuc2Vjb25kOwogICAgICAgICAgICBpZiAobWF4aW1pemUoZFt2XSwgdyArIGMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBxLnB1c2goe2Rbdl0sIHZ9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKLyogRkVOV0lDSyBUUkVFCnN0cnVjdCBGZW53aWNrCnsKICAgIHZlY3RvcjxwYWlyPGxsLCBpbnQ+PiBUcmVlOwogICAgaW50IG47CiAgICBGZW53aWNrKGludCBfbiA9IDApCiAgICB7CiAgICAgICAgbiA9IF9uOwogICAgICAgIFRyZWUucmVzaXplKG4rMSk7CiAgICB9CiAgICB2b2lkIHVwZGF0ZShsbCB4LCBsbCB2bCkKICAgIHsKICAgICAgICBmb3IoO3g8PW47eCs9eCYteCkKICAgICAgICB7CiAgICAgICAgICAgIFRyZWVbeF0uZmlyc3QrPXZsOwogICAgICAgICAgICBUcmVlW3hdLnNlY29uZCsrOwogICAgICAgIH0KICAgIH0KICAgIHBhaXI8bGwsaW50PiBnZXQobGwgeCkKICAgIHsKICAgICAgICBwYWlyPGxsLCBpbnQ+IHRtcDsKICAgICAgICBmb3IoO3g7eC09eCYteCkKICAgICAgICB7CiAgICAgICAgICAgIHRtcC5maXJzdCArPSBUcmVlW3hdLmZpcnN0OwogICAgICAgICAgICB0bXAuc2Vjb25kICs9IFRyZWVbeF0uc2Vjb25kOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdG1wOwogICAgfQogICAgcGFpcjxsbCxpbnQ+IHF1ZXJ5KGludCBsLCBpbnQgcikKICAgIHsKICAgICAgICBpZiAobCA9PSAwKSByZXR1cm4gZ2V0KHIpOwogICAgICAgIHJldHVybiB7Z2V0KHIpLmZpcnN0IC0gZ2V0KGwtMSkuZmlyc3QsIGdldChyKS5zZSAtIGdldChsLTEpLnNlfTsKICAgIH0KfSBGOwoKLyogU0VHTUVOVCBUUkVFCnN0cnVjdCBTZWdtZW50CnsKICAgIHN0cnVjdCBOb2RlCiAgICB7CiAgICAgICAgbGwgdmwsIGx6OwogICAgICAgIE5vZGUobGwgX3ZsID0gMCwgbGwgX2x6ID0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHZsID0gX3ZsOwogICAgICAgICAgICBseiA9IF9sejsKICAgICAgICB9CiAgICB9OwogICAgdmVjdG9yPE5vZGU+IFRyZWU7CiAgICBpbnQgbjsKICAgIFNlZ21lbnQoaW50IF9uID0gMCkKICAgIHsKICAgICAgICBuID0gX247CiAgICAgICAgVHJlZS5yZXNpemUoNCpuKzEpOwogICAgfQogICAgdm9pZCBidWlsZChpbnQgaWQsIGludCBsLCBpbnQgcikKICAgIHsKICAgICAgICBpZiAobCA9PSByKQogICAgICAgIHsKICAgICAgICAgICAgVHJlZVtpZF0udmwgPSBhW2xdOwogICAgICAgIH1lbHNlCiAgICAgICAgewogICAgICAgICAgICBpbnQgbSA9IChsICsgcikvMjsKICAgICAgICAgICAgYnVpbGQoaWQqMiwgbCwgbSk7CiAgICAgICAgICAgIGJ1aWxkKGlkKjIrMSwgbSsxLCByKTsKICAgICAgICAgICAgVHJlZVtpZF0udmwgPSBtYXgoVHJlZVtpZCoyXS52bCwgVHJlZVtpZCoyKzFdLnZsKTsKICAgICAgICB9CiAgICB9CiAgICB2b2lkIGRvd24oaW50IGlkKQogICAgewogICAgICAgIE5vZGUgJlAgPSBUcmVlW2lkXSwgJkwgPSBUcmVlW2lkKjJdLCAmUiA9IFRyZWVbaWQqMisxXTsKICAgICAgICBpZiAoUC5seikKICAgICAgICB7CiAgICAgICAgICAgIEwudmwgKz0gUC5sejsKICAgICAgICAgICAgUi52bCArPSBQLmx6OwogICAgICAgICAgICBMLmx6ICs9IFAubHo7CiAgICAgICAgICAgIFIubHogKz0gUC5sejsKICAgICAgICAgICAgUC5seiA9IDA7CiAgICAgICAgfQogICAgfQogICAgdm9pZCB1cGRhdGUoaW50IGlkLCBpbnQgbCwgaW50IHIsIGludCB1LCBpbnQgdiwgbGwgdmwpCiAgICB7CiAgICAgICAgaWYgKGwgPiB2IHx8IHIgPCB1KSByZXR1cm47CiAgICAgICAgaWYgKGwgPj0gdSAmJiByIDw9IHYpCiAgICAgICAgewogICAgICAgICAgICBUcmVlW2lkXS52bCArPSB2bDsKICAgICAgICAgICAgVHJlZVtpZF0ubHogKz0gdmw7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgZG93bihpZCk7CiAgICAgICAgaW50IG0gPSAobCArIHIpLzI7CiAgICAgICAgdXBkYXRlKGlkKjIsIGwsIG0sIHUsIHYsIHZsKTsKICAgICAgICB1cGRhdGUoaWQqMisxLCBtKzEsIHIsIHUsIHYsIHZsKTsKICAgICAgICBUcmVlW2lkXS52bCA9IG1heChUcmVlW2lkKjJdLnZsLCBUcmVlW2lkKjIrMV0udmwpOwogICAgfQogICAgbGwgcXVlcnkoaW50IGlkLCBpbnQgbCwgaW50IHIsIGludCB1LCBpbnQgdikKICAgIHsKICAgICAgICBpZiAobCA+IHYgfHwgciA8IHUpIHJldHVybiBJTlRfTUlOOwogICAgICAgIGlmIChsID49IHUgJiYgciA8PSB2KSByZXR1cm4gVHJlZVtpZF0udmw7CiAgICAgICAgZG93bihpZCk7CiAgICAgICAgaW50IG0gPSAobCtyKS8yOwogICAgICAgIGludCBMID0gcXVlcnkoaWQqMiwgbCwgbSwgdSwgdik7CiAgICAgICAgaW50IFIgPSBxdWVyeShpZCoyKzEsIG0rMSwgciwgdSwgdik7CiAgICAgICAgcmV0dXJuIG1heChMLCBSKTsKICAgIH0KfSBTOwovKgoKLyogRFNVCnN0cnVjdCBEU1UKewogICAgdmVjdG9yPGxsPiBsYWI7CiAgICBpbnQgbjsKICAgIERTVShpbnQgX24gPSAwKQogICAgewogICAgICAgIG4gPSBfbjsKICAgICAgICBsYWIucmVzaXplKG4gKyAxKTsKICAgICAgICBmaWxsKGxhYi5iZWdpbigpLCBsYWIuZW5kKCksIC0xKTsKICAgIH0KICAgIGludCBGaW5kKGludCB1KQogICAgewogICAgICAgIHJldHVybiBsYWJbdV0gPCAwID8gdSA6IGxhYlt1XSA9IEZpbmQobGFiW3VdKTsKICAgIH0KICAgIGxsIFVuaW9uKGludCB1LCBpbnQgdikKICAgIHsKICAgICAgICB1ID0gRmluZCh1KTsKICAgICAgICB2ID0gRmluZCh2KTsKICAgICAgICBpZiAodSA9PSB2KSByZXR1cm4gMDsKICAgICAgICBsbCByZXMgPSAxbGwgKiBsYWJbdV0gKiBsYWJbdl07CiAgICAgICAgaWYgKGxhYlt1XSA+IGxhYlt2XSkgc3dhcCh1LCB2KTsKICAgICAgICBsYWJbdV0gKz0gbGFiW3ZdOwogICAgICAgIGxhYlt2XSA9IHU7CiAgICAgICAgcmV0dXJuIHJlczsKICAgIH0KfSBEOwoqLwoKLyogTkVOU08Kdm9pZCBuZW5zbygpCnsKICAgIHNvcnQodnQuYmVnaW4oKSwgdnQuZW5kKCkpOwogICAgdnQucmVzaXplKHVuaXF1ZSh2dC5iZWdpbigpLCB2dC5lbmQoKSkgLSB2dC5iZWdpbigpKTsKICAgIGZ1KGksMSxuKSBhW2ldID0gbG93ZXJfYm91bmQodnQuYmVnaW4oKSwgdnQuZW5kKCksIGFbaV0pIC0gdnQuYmVnaW4oKSArIDE7CiAgICBmdShpLDEscSkKICAgIHsKICAgICAgICBzdFtpXS54ID0gbG93ZXJfYm91bmQodnQuYmVnaW4oKSwgdnQuZW5kKCksIHN0W2ldLngpIC0gdnQuYmVnaW4oKSArIDE7CiAgICAgICAgaWYgKHN0W2ldLnRwID09ICc/Jykgc3RbaV0uayA9IGxvd2VyX2JvdW5kKHZ0LmJlZ2luKCksIHZ0LmVuZCgpLCBzdFtpXS5rKSAtIHZ0LmJlZ2luKCkgKyAxOwogICAgfQp9CiovCgovKiBLcnVza2FsCmJvb2wgY21wKEVkZ2UgYSwgRWRnZSBiKQp7CiAgICByZXR1cm4gYS5jIDwgYi5jOwp9Cgp2ZWN0b3I8RWRnZT4gbXN0OwoKdm9pZCBrcnVza2FsKCkKewogICAgc29ydChzdCArIDEsIHN0ICsgbSArMSwgY21wKTsKICAgIGxsIGQgPSAwOwogICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gbTsgaSsrKQogICAgewogICAgICAgIGlmIChtc3Quc2l6ZSgpID09IG4gLSAxKSBicmVhazsKICAgICAgICBpZiAoVW5pb24oc3RbaV0udSwgc3RbaV0udikpCiAgICAgICAgewogICAgICAgICAgICBtc3QucHVzaF9iYWNrKHN0W2ldKTsKICAgICAgICAgICAgZCArPSBzdFtpXS5jOwogICAgICAgIH0KICAgIH0KfQoqLwoKLyogU1BBUlNFIFRBQkxFCgppbnQgbG9nMl9mbG9vcihpbnQgbikgeyByZXR1cm4gMzEgLSBfX2J1aWx0aW5fY2x6KG4pOyB9CgoKbGwgcXVlcnlfcm1xKGludCBsLCBpbnQgcikKewogICAgaW50IGkgPSBsb2cyX2Zsb29yKHItbCsxKTsKICAgIHJldHVybiBtaW4odGFibGVbaV1bbF0sIHRhYmxlW2ldW3IgLSBNQVNLKGkpICsgMV0pOwp9Cgp2b2lkIHByZQp7CiAgICBmdShpLDEsbikgdGFibGVbMF1baV0gPSBhW2ldOwoKICAgIGZ1KGosMSxMb2cpCiAgICB7CiAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgKyBNQVNLKGopIC0gMSA8PSBuOyBpKyspCiAgICAgICAgewogICAgICAgICAgICB0YWJsZVtqXVtpXSA9IG1pbih0YWJsZVtqLTFdW2ldLCB0YWJsZVtqLTFdW2kgKyBNQVNLKGogLSAxKV0pOy8vcm1xIGhheSByc3EgdGhpIHRoYXkgZG9pIG1pbiBob2FjIHMKICAgICAgICB9CiAgICB9Cn0KKi8KCi8qIEtJRU0gVFJBIENIVSBUUklOSAoxLiBETyBUSEkgVk8gSFVPTkcgRFVORyBEU1UKMi4gRE8gVEhJIENPIEhVT05HCmJvb2wgZGZzKGludCB1KQp7CiAgICBjb2xbdV0gPSAxOwogICAgZm9yIChpbnQgdiA6IGFkalt1XSkKICAgIHsKICAgICAgICBpZiAoY29sW3ZdID09IDApCiAgICAgICAgewogICAgICAgICAgICBwYXJbdl0gPSB1OwogICAgICAgICAgICBpZiAoZGZzKHYpKSByZXR1cm4gdHJ1ZTsKICAgICAgICB9ZWxzZSBpZiAoY29sW3ZdID09IDEpIHJldHVybiB0cnVlOwogICAgfQogICAgY29sW3VdID0gMjsKICAgIHJldHVybiBmYWxzZTsKfQoqLwoKLyoKTENBCgp2b2lkIGRmcyhpbnQgdSwgaW50IHApCnsKICAgIGZvciAoaW50IHYgOiBhZGpbdV0pIGlmICh2ICE9IHApCiAgICB7CiAgICAgICAgaGlnaFt2XSA9IGhpZ2hbdV0gKyAxOwogICAgICAgIHBhclt2XVswXSA9IHU7CiAgICAgICAgZGZzKHYsIHUpOwogICAgfQp9Cgp2b2lkIHByZSgpCnsKICAgIGRmcygxLCAtMSk7CgogICAgZm9yIChpbnQgaiA9IDE7IGogPD0gTG9nOyBqKyspCiAgICB7CiAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gbjsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgcGFyW2ldW2pdID0gcGFyW3BhcltpXVtqLTFdXVtqLTFdOwogICAgICAgIH0KICAgIH0KICAgIGhpZ2hbMF0gPSAtMTsKfQoKaW50IGxjYShpbnQgdSwgaW50IHYpCnsKICAgIGlmIChoaWdoW3ZdID4gaGlnaFt1XSkgcmV0dXJuIGxjYSh2LCB1KTsKCiAgICBmZChpLCBMb2csIDApCiAgICB7CiAgICAgICAgaWYoaGlnaFtwYXJbdV1baV1dID49IGhpZ2hbdl0pCiAgICAgICAgICAgIHUgPSBwYXJbdV1baV07CiAgICB9CgogICAgaWYgKHUgPT0gdikgcmV0dXJuIHU7CgogICAgZmQoaSwgTG9nLCAwKQogICAgewogICAgICAgIGlmIChwYXJbdV1baV0gIT0gcGFyW3ZdW2ldKQogICAgICAgIHsKICAgICAgICAgICAgdSA9IHBhclt1XVtpXTsKICAgICAgICAgICAgdiA9IHBhclt2XVtpXTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gcGFyW3VdWzBdOwp9CiovCgovKiBFUkFTIERPQU4Kdm9pZCBlcmFzX2RvYW4oKQp7CiAgICBmdShpLDIsKGludCkxZTYpCiAgICB7CiAgICAgICAgbGwgaiA9IChsICsgaSAtIDEpIC9pICppOwogICAgICAgIGZvciAoO2o8PXI7IGorPWkpIGlmIChqICE9IGkpCiAgICAgICAgICAgIGRbai1sXSA9IDEKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgci1sOyBpKyspIGlmIChkW2ldPT0wKSBjb3V0PDxpK2w8PHNwOwp9CiovCgovKiBMVU9ORyBDVUMgREFJCnN0cnVjdCBlZGdlCnsKICAgIGludCB4LCB5LCBjYXAsIGZsb3c7Cn07CgpzdHJ1Y3QgRmxvdwp7CiAgICBpbnQgbiwgUywgVDsKICAgIHZlY3RvciA8IHZlY3RvciA8aW50PiA+IGE7CiAgICB2ZWN0b3IgPGludD4gY3VyLCBkOwogICAgdmVjdG9yIDxlZGdlPiBlOwoKICAgIEZsb3coKSB7fQogICAgRmxvdyhpbnQgX24sIGludCBfUywgaW50IF9UKQogICAgewogICAgICAgIG4gPSBfbjsgUyA9IF9TOyBUID0gX1Q7CiAgICAgICAgYSA9IHZlY3RvciA8IHZlY3RvciA8aW50PiA+KG4gKyAxKTsKICAgICAgICBjdXIgPSB2ZWN0b3IgPGludD4obiArIDEpOwogICAgICAgIGQgPSB2ZWN0b3IgPGludD4obiArIDEpOwogICAgfQoKICAgIHZvaWQgYWRkRWRnZShpbnQgeCwgaW50IHksIGludCBfY2FwKQogICAgewogICAgICAgIGVkZ2UgZTEgPSB7eCwgeSwgX2NhcCwgMH07CiAgICAgICAgZWRnZSBlMiA9IHt5LCB4LCAwLCAwfTsKICAgICAgICBhW3hdLnB1c2hfYmFjayhlLnNpemUoKSk7IGUucHVzaF9iYWNrKGUxKTsKICAgICAgICBhW3ldLnB1c2hfYmFjayhlLnNpemUoKSk7IGUucHVzaF9iYWNrKGUyKTsKICAgIH0KCiAgICBpbnQgYmZzKCkKICAgIHsKICAgICAgICBxdWV1ZTxpbnQ+IHE7CiAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gbjsgaSsrKSBkW2ldID0gLTE7CiAgICAgICAgcS5wdXNoKFMpOyBkW1NdID0gMDsKICAgICAgICB3aGlsZSAoIXEuZW1wdHkoKSAmJiBkW1RdIDwgMCkKICAgICAgICB7CiAgICAgICAgICAgIGludCB4ID0gcS5mcm9udCgpOyBxLnBvcCgpOwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IChpbnQpYVt4XS5zaXplKCk7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IGlkID0gYVt4XVtpXSwgeSA9IGVbaWRdLnk7CiAgICAgICAgICAgICAgICBpZiAoZFt5XSA8IDAgJiYgZVtpZF0uZmxvdyA8IGVbaWRdLmNhcCkKICAgICAgICAgICAgICAgICAgICBxLnB1c2goeSksIGRbeV0gPSBkW3hdICsgMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZFtUXSA+PSAwOwogICAgfQoKICAgIGludCBkZnMoaW50IHgsIGludCB2YWwpCiAgICB7CiAgICAgICAgaWYgKCF2YWwpIHJldHVybiAwOwogICAgICAgIGlmICh4ID09IFQpIHJldHVybiB2YWw7CiAgICAgICAgZm9yICg7IGN1clt4XSA8IChpbnQpYVt4XS5zaXplKCk7IGN1clt4XSsrKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGlkID0gYVt4XVtjdXJbeF1dLCB5ID0gZVtpZF0ueTsKICAgICAgICAgICAgaWYgKGRbeV0gIT0gZFt4XSArIDEpIGNvbnRpbnVlOwogICAgICAgICAgICBpbnQgcHVzaGVkID0gZGZzKHksIG1pbih2YWwsIGVbaWRdLmNhcCAtIGVbaWRdLmZsb3cpKTsKICAgICAgICAgICAgaWYgKHB1c2hlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZVtpZF0uZmxvdyArPSBwdXNoZWQ7CiAgICAgICAgICAgICAgICBlW2lkIF4gMV0uZmxvdyAtPSBwdXNoZWQ7CiAgICAgICAgICAgICAgICByZXR1cm4gcHVzaGVkOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGludCBtYXhGbG93KCkKICAgIHsKICAgICAgICBpbnQgcmVzID0gMDsKICAgICAgICB3aGlsZSAoYmZzKCkpCiAgICAgICAgewogICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBuOyBpKyspIGN1cltpXSA9IDA7CiAgICAgICAgICAgIHdoaWxlICgxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgdmFsID0gZGZzKFMsIG9vKTsKICAgICAgICAgICAgICAgIGlmICghdmFsKSBicmVhazsKICAgICAgICAgICAgICAgIHJlcyArPSB2YWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlczsKICAgIH0KfTsKKi8KCi8qIE1hdHJpeCBNdWx0aXBsaWNhdGlvbgpjb25zdCBpbnQgTUFUUklYX1NJWkUgPSAyMDsKCnN0cnVjdCBNYXRyaXggewogICAgaW50IG0sIG47CiAgICBsb25nIGxvbmcgZFtNQVRSSVhfU0laRV1bTUFUUklYX1NJWkVdOwoKICAgIE1hdHJpeChpbnQgX20gPSAwLCBpbnQgX24gPSAwKSB7CiAgICAgICAgbSA9IF9tOyBuID0gX247CiAgICAgICAgbWVtc2V0KGQsIDAsIHNpemVvZiBkKTsKICAgIH0KCiAgICBNYXRyaXggb3BlcmF0b3IgKyAoY29uc3QgTWF0cml4ICZhKSBjb25zdCB7CiAgICAgICAgTWF0cml4IHJlcyhtLCBuKTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG07IGkrKykgZm9yIChpbnQgaiA9IDA7IGogPCBuOyBqKyspIHsKICAgICAgICAgICAgcmVzLmRbaV1bal0gPSBkW2ldW2pdICsgYS5kW2ldW2pdOwogICAgICAgICAgICBpZiAocmVzLmRbaV1bal0gPj0gTU9EKSByZXMuZFtpXVtqXSAtPSBNT0Q7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXM7CiAgICB9CgogICAgTWF0cml4IG9wZXJhdG9yICogKGNvbnN0IE1hdHJpeCAmYSkgY29uc3QgewogICAgICAgIGludCB4ID0gbSwgeSA9IG4sIHogPSBhLm47CiAgICAgICAgTWF0cml4IHJlcyh4LCB6KTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHg7IGkrKykgZm9yIChpbnQgaiA9IDA7IGogPCB5OyBqKyspCgkJZm9yIChpbnQgayA9IDA7IGsgPCB6OyBrKyspIHsKICAgICAgICAgICAgCXJlcy5kW2ldW2tdICs9IDFMTCAqIGRbaV1bal0gKiBhLmRbal1ba107CiAgICAgICAgICAgIAlpZiAocmVzLmRbaV1ba10gPj0gMUxMICogTU9EICogTU9EKSByZXMuZFtpXVtrXSAtPSAxTEwgKiBNT0QgKiBNT0Q7CiAgICAgICAgCX0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHg7IGkrKykgZm9yIChpbnQgayA9IDA7IGsgPCB6OyBrKyspIHJlcy5kW2ldW2tdICU9IE1PRDsKCiAgICAgICAgcmV0dXJuIHJlczsKICAgIH0KCiAgICBNYXRyaXggb3BlcmF0b3IgXiAobG9uZyBsb25nIGspIGNvbnN0IHsKICAgICAgICBNYXRyaXggcmVzKG4sIG4pOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSByZXMuZFtpXVtpXSA9IDE7CiAgICAgICAgTWF0cml4IG11bCA9ICp0aGlzOwogICAgICAgIHdoaWxlIChrID4gMCkgewogICAgICAgICAgICBpZiAoayAmIDEpIHJlcyA9IHJlcyAqIG11bDsKICAgICAgICAgICAgbXVsID0gbXVsICogbXVsOwogICAgICAgICAgICBrID4+PSAxOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzOwogICAgfQoKICAgIGxvbmcgbG9uZyogb3BlcmF0b3JbXSAoaW50IGkpIHsKICAgICAgICByZXR1cm4gZFtpXTsKICAgIH0KCiAgICBjb25zdCBsb25nIGxvbmcqIG9wZXJhdG9yW10gKGludCBpKSBjb25zdCB7CiAgICAgICAgcmV0dXJuIGRbaV07CiAgICB9Cn07CiovCgovKiBDQVAgR0hFUCBDVUMgREFJIEtIT05HIFRST05HIFNPCnN0cnVjdCBtYXRjaGVyIHsKICAgIGNvbnN0IGludCBvbyA9IDEwMDAwMDAwMDsKICAgIGludCBtLCBuOwogICAgdmVjdG9yPGludD4gbXgsIG15LCBkaXN0OwogICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiBrZTsKICAgIGludCBtYXRjaGVkOwoKICAgIG1hdGNoZXIoaW50IG0sIGludCBuKToKICAgICAgICBtKG0pLCBuKG4pLAogICAgICAgIG14KG0rMSwgMCksIG15KG4rMSwgMCksIGRpc3QobSsxKSwKICAgICAgICBrZShtKzEpLAogICAgICAgIG1hdGNoZWQoMCkge30KCiAgICB2b2lkIGFkZF9lZGdlKGludCB1LCBpbnQgdikgewogICAgICAgIGtlW3VdLnB1c2hfYmFjayh2KTsKICAgIH0KCiAgICBib29sIGJmcygpIHsKICAgICAgICBxdWV1ZTxpbnQ+IFE7CiAgICAgICAgZm9yIChpbnQgdT0xOyB1PD1tOyB1KyspIHsKICAgICAgICAgICAgaWYgKCFteFt1XSkgewogICAgICAgICAgICAgICAgZGlzdFt1XSA9IDA7CiAgICAgICAgICAgICAgICBRLnB1c2godSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkaXN0W3VdID0gb287CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGJvb2wgZm91bmQgPSBmYWxzZTsKICAgICAgICB3aGlsZSAoIVEuZW1wdHkoKSkgewogICAgICAgICAgICBpbnQgdSA9IFEuZnJvbnQoKTsgUS5wb3AoKTsKICAgICAgICAgICAgZm9yIChpbnQgdjoga2VbdV0pIHsKICAgICAgICAgICAgICAgIGlmICghbXlbdl0pIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRpc3RbbXlbdl1dID09IG9vKSB7CiAgICAgICAgICAgICAgICAgICAgZGlzdFtteVt2XV0gPSBkaXN0W3VdICsgMTsKICAgICAgICAgICAgICAgICAgICBRLnB1c2gobXlbdl0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZm91bmQ7CiAgICB9CgogICAgYm9vbCBkZnMoaW50IHUpIHsKICAgICAgICBpZiAoZGlzdFt1XSA9PSBvbykgcmV0dXJuIGZhbHNlOwogICAgICAgIGZvciAoaW50IHY6IGtlW3VdKSB7CiAgICAgICAgICAgIGlmICghbXlbdl0gfHwgKGRpc3RbbXlbdl1dPT1kaXN0W3VdKzEgJiYgZGZzKG15W3ZdKSkpIHsKICAgICAgICAgICAgICAgIG14W3VdID0gdjsKICAgICAgICAgICAgICAgIG15W3ZdID0gdTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICB2b2lkIG1hdGNoKCkgewogICAgICAgIHdoaWxlKGJmcygpKSB7CiAgICAgICAgICAgIGZvciAoaW50IHU9MTsgdTw9bTsgdSsrKSBpZiAoIW14W3VdKSBtYXRjaGVkICs9IGRmcyh1KTsKICAgICAgICB9CiAgICB9Cn07CgppbnQgZ2V0KCkKewogICAgbWF0Y2hlciB6KG4sIG4pOwogICAgZnUoaSwxLG0pCiAgICB7CiAgICAgICAgaW50IHUsIHY7IGNpbj4+dT4+djsKICAgICAgICB6LmFkZF9lZGdlKHUsIHYpOwogICAgfQogICAgei5tYXRjaCgpOwogICAgcmV0dXJuIHoubWF0Y2hlZDsKfQoqLwoKc2lnbmVkIG1haW4oKQp7Cgp9Cg==