#define ARYANC403
/*
Warn - Don't change next line else you will get WA verdict. Online Judge is configured to give WA if next line is not present.
"An ideal problem has no test data."
Author - Aryan Choudhary (@aryanc403)
*/
#pragma warning(disable:4996)
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize ("Ofast")
//#pragma GCC target ("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize ("-ffloat-store")
#include<iostream>
#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;
#define fo(i,n) for(i=0;i<(n);++i)
#define repA(i,j,n) for(i=(j);i<=(n);++i)
#define repD(i,j,n) for(i=(j);i>=(n);--i)
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define endl "\n"
typedef long long int lli;
typedef unsigned long long int ulli;
typedef long double mytype;
typedef pair<lli,lli> ii;
typedef vector<ii> vii;
typedef vector<lli> vi;
typedef vector<ulli> vui;
clock_t time_p=clock();
void aryanc403()
{
time_p=clock()-time_p;
cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
#ifdef ARYANC403
#define dbg(...) { cerr<<"[ "; __aryanc403__(#__VA_ARGS__, __VA_ARGS__);}
#undef endl
template <typename Arg1,typename Arg2>
ostream& operator << (ostream& out, const pair<Arg1,Arg2> &x) {
return out<<"("<<x.X<<","<<x.Y<<")";
}
template <typename Arg1>
ostream& operator << (ostream& out, const vector<Arg1> &a) {
out<<"[";for(const auto &x:a)out<<x<<",";return out<<"]";
}
template <typename Arg1>
ostream& operator << (ostream& out, const set<Arg1> &a) {
out<<"[";for(const auto &x:a)out<<x<<",";return out<<"]";
}
template <typename Arg1,typename Arg2>
ostream& operator << (ostream& out, const map<Arg1,Arg2> &a) {
out<<"[";for(const auto &x:a)out<<x<<",";return out<<"]";
}
template <typename Arg1>
void __aryanc403__(const string name, Arg1&& arg1){
cerr << name << " : " << arg1 << " ] " << endl;
}
template <typename Arg1, typename... Args>
void __aryanc403__(const string names, Arg1&& arg1, Args&&... args){
const string name = names.substr(0,names.find(','));
cerr<<name<<" : "<<arg1<<" | ";
__aryanc403__(names.substr(1+(int)name.size()), args...);
}
#else
#define dbg(args...)
#endif
const lli INF = 0xFFFFFFFFFFFFFFFL;
lli seed,seedtgen;
mt19937 rng(seed=chrono::steady_clock::now().time_since_epoch().count());
inline lli rnd(lli l=0,lli r=INF)
{return uniform_int_distribution<lli>(l,r)(rng);}
const vector<string> rg={"rax","rbx","rcx"};
const vector<string> rgv={"dl","dx","edx","rdx"};
const lli itn = 25;
struct soln{
private :
vector<string> a;
map<string,ulli> st;
public:
soln() { a.clear(); st.clear();};
soln(const map<string,ulli> m) { a.clear(); st=m;};
void clear(){ a.clear(); st.clear();};
void prt(string s) { a.pb(s);}
map<string,ulli> getStates() { return st;}
void prtsoln() {
for(auto x:a)
cout<<x<<endl;
}
void setStates(const soln &o){
st=o.st;
}
void mergeWithStates(const soln &o){
st=o.st;
for(auto x:o.a)
a.pb(x);
}
void swap(soln &o){
st.swap(o.st);
a.swap(o.a);
}
void add(soln o) {
if(!o.scr())
return;
for(auto x:st)
rst(x.X);
for(auto x:o.a)
a.pb(x);
st=o.st;
}
lli scr(){ return (lli)a.size(); }
lli bt(string s){ return st[s]; }
void max(soln b){
if(b.a.empty())
return;
if(a.empty()||(int)b.a.size()<(int)a.size())
{
st.swap(b.st);
a.swap(b.a);
}
}
void rst(string s)
{
if(!st[s])
return;
st[s]=0;
prt("xor "+s+" "+s);
}
void inc(string s)
{
st[s]++;
prt("inc "+s);
}
void shl(string a,string b)
{
if(!st[b])
return;
st[a]>>=st[b];
prt("shl "+a+" "+b);
}
void add(string a,string b)
{
if(!st[b])
return;
st[a]+=st[b];
prt("add "+a+" "+b);
}
void sub(string a,string b)
{
if(!st[b])
return;
st[a]-=st[b];
prt("sub "+a+" "+b);
}
void xr(string a,string b)
{
st[a]^=st[b];
prt("xor "+a+" "+b);
}
void nt(string a)
{
st[a]=~st[a];
prt("not "+a);
}
void mov(string a,string b)
{
if(st[a]==st[b])
return;
st[a]=st[b];
prt("mov "+a);
}
};
void printans(soln ans)
{
cout<<(int)ans.scr()<<endl;
ans.prtsoln();
aryanc403();
exit(0);
}
namespace testcase{
mt19937 rng(seedtgen=chrono::steady_clock::now().time_since_epoch().count());
inline lli rnd(lli l,lli r)
{return uniform_int_distribution<lli>(l,r)(rng);}
ulli rnd(){
ulli x=rnd(0,1LL<<32),y=rnd(0,1LL<<32);
return (x<<32)+y;
}
vector<vui> test1(){
vector<vui> a;
const lli n=64;
for(int i=0;i<n;++i)
a.pb({rnd(),rnd(),rnd()});
dbg("TC 1 Generated.");
return a;
}
vector<vui> test2(){
vector<vui> a;
vui b;
const lli n=64;
const ulli on=1;
for(int i=0;i<n;++i)
{
for(int j=i;j<n;++j)
b.pb((on<<i)|(on<<j));
}
const lli m=(lli)b.size();
for(int i=0;i<n;++i)
{
ulli x=rnd();
a.pb({x,x^b[rnd(0,m-1)],x^b[rnd(0,m-1)]});
}
dbg("TC 2 Generated.");
return a;
}
vector<vui> test3(){
vector<vui> a;
const lli n=64,bat=8;
ulli d=0;
for(int i=0;i<n;++i)
{
if(i%bat==0)
d=rnd();
ulli x=rnd();
a.pb({x,x+d,x+2*d});
}
dbg("TC 3 Generated.");
return a;
}
void applyop(ulli &x,ulli &y)
{
bool fl=rnd(0,1);
ulli a=x,b=y;
ulli m64=-1;
ulli m32=m64>>32;
if(fl)
{
a&=m32;
b&=m32;
}
switch(rnd(0,4))
{
case 0: a+=b; break;
case 1: a-=b; break;
case 2: a|=b; break;
case 3: a&=b; break;
case 4: a^=b; break;
}
if(fl)
{
a&=m32;
x>>=32;x<<=32;
x|=a;
}
else
x=a;
}
vui test4List(){
vui l;
while(true){
l.clear();
const lli n=64;
vui reg({rnd(),rnd(),rnd()});
unsigned long long last_l = 0;
bool ok = true;
int mistakes = 0;
while((lli)l.size()<9*n)
{
vui old = reg;
int op_id = rnd(0,5);
switch(op_id)
{
case 0: applyop(reg[0],reg[1]); break;
case 1: applyop(reg[0],reg[2]); break;
case 2: applyop(reg[1],reg[0]); break;
case 3: applyop(reg[1],reg[2]); break;
case 4: applyop(reg[2],reg[0]); break;
case 5: applyop(reg[2],reg[1]); break;
}
bool mistake_made = false;
if(l.size()%9 == 6){
mistake_made |= l.size() >= 3 && l[l.size()-1] == reg[2];
mistake_made |= l.size() >= 6 && l[l.size()-4] == reg[2];
}
if(l.size()%9 == 3){
mistake_made |= l.size() >= 3 && l[l.size()-1] == reg[2];
}
if(mistake_made){
reg = old;
if(++mistakes > (1<<8)){
ok = false;
break;
}
continue;
}
l.pb(reg[0]);
l.pb(reg[1]);
l.pb(reg[2]);
last_l = reg[2];
}
if(ok) return l;
}
assert(false);//never reached
}
vector<vui> test4(){
vector<vui> a;
vui b;
const lli n=64;
a.clear();
b=test4List();
for(lli i=2;i<9*n;i+=9)
a.pb({b[i],b[i+3],b[i+6]});
for(int i = 0; i < n; ++i){
if(a[i][0] == a[i][1]) assert(false);
if(a[i][0] == a[i][2]) assert(false);
if(a[i][1] == a[i][2]) assert(false);
}
dbg("TC 4 Generated.");
return a;
}
vector<vui> test5(){
vector<vui> a;
const lli n=64;
ulli k=rnd();
for(int i=0;i<n;++i)
{
ulli x=rnd(),y=rnd();
a.pb({x,y,k-x-y});
}
dbg("TC 5 Generated.");
return a;
}
void printtc(lli id)
{
vector<vui> a;
switch(id)
{
case 1: a=testcase::test1(); break;
case 2: a=testcase::test2(); break;
case 3: a=testcase::test3(); break;
case 4: a=testcase::test4(); break;
case 5: a=testcase::test5(); break;
}
cout<<(lli)a.size()<<endl;
for(auto x:a)
cout<<x[0]<<" "<<x[1]<<" "<<x[2]<<endl;
//cout<<endl;
//cout<<"Seed used for generation : "<<seedtgen<<endl;
}
};
namespace load{
lli bcnt(ulli x)
{
lli cnt=0;
while(x)
{
if(x&1)
cnt++;
x/=2;
}
return cnt;
}
ulli neg(ulli x,int bt)
{
ulli on=1;
ulli lim=on<<bt;
lim--;
x=~x;
x&=lim;
return x;
}
void orr(soln &b,ulli &x,ulli d,string s,string ds){
if(x&d)
{
b.xr(s,ds);
x^=d;
}
}
void loadS(soln &b,ulli x,string s)
{
b.rst(s);
if(!x)
return;
const lli BT=64;
if(load::bcnt(x)>BT/2)
{
loadS(b,~x,s);
b.nt(s);
return;
}
lli i=BT-1;
ulli on=1;
while((x&(on<<i))==0)
i--;
b.inc(s);
while(i)
{
b.add(s,s);
i--;
if(x&(on<<i))
b.inc(s);
}
}
void loadPre(soln &b,vector<pair<ulli,string>> a)
{
if((lli)a.size()==1)
{
loadS(b,a[0].X,a[0].Y);
return;
}
string dg=rgv[3];
// dbg(b.getStates(),a);
for(auto &x:a)
{
// dbg(x.X,b.bt(x.Y));
x.X^=b.bt(x.Y);
}
// dbg("xor",a);
// b.rst(dg);
ulli d=0;
while(true)
{
bool fl=true;
for(auto x:a)
if(x.X)
fl=false;
if(fl)
break;
if(d==0)
{
b.inc(dg);
d++;
}
else
{
b.add(dg,dg);
d+=d;
}
for(auto &x:a)
orr(b,x.X,d,x.Y,dg);
}
// dbg(a);
b.rst(dg);
}
void load(soln &b,vector<pair<ulli,string>> a)
{
const lli n=(lli)a.size();
const lli lim=(1LL<<n);
soln bst;
for(lli msk=0;msk<lim;++msk)
{
soln c;
c.setStates(b);
for(lli i=0;i<n;++i)
{
if(msk&(1LL<<i))
a[i].X=~a[i].X;
}
loadPre(c,a);
for(lli i=0;i<n;++i)
{
if(msk&(1LL<<i))
{
a[i].X=~a[i].X;
c.nt(a[i].Y);
}
}
if(msk==0||c.scr()<bst.scr())
bst.swap(c);
}
b.mergeWithStates(bst);
// dbg(b.getStates());
}
};
namespace graph{
vector<bool> vis;
lli CostCalcPre(vui a)
{
lli cost=0;
if((lli)a.size()==1)
{
lli x=0;
while(x)
{
cost+=(x&1);
x/=2;
cost++;
}
return cost;
}
ulli d=0;
while(true)
{
bool fl=true;
for(auto x:a)
if(x)
fl=false;
if(fl)
break;
if(d==0)
d++;
else
d+=d;
cost++;
for(auto &x:a)
{
if(x&d)
{
cost++;
x^=d;
}
}
}
cost++;
return cost;
}
lli costCalc(vui a){
lli bstCost=INF;
const lli n=(lli)a.size();
const lli lim=(1LL<<n);
for(lli msk=0;msk<lim;++msk)
{
for(lli i=0;i<n;++i)
{
if(msk&(1LL<<i))
a[i]=~a[i];
}
lli cost=0;
cost+=CostCalcPre(a);
for(lli i=0;i<n;++i)
{
if(msk&(1LL<<i))
{
a[i]=~a[i];
cost++;
}
}
bstCost=min(bstCost,cost);
}
return bstCost;
}
lli findCost1(map<string,ulli> st,vui &a)
{
vi bid={0,1,2};
pair<lli,vui> bst={INF,a};
do{
lli cost=costCalc({a[bid[0]]^st[rg[0]],a[bid[1]]^st[rg[1]],a[bid[2]]^st[rg[2]]});
if(bst.X>cost)
bst={cost,{a[bid[0]],a[bid[1]],a[bid[2]]}};
}while(std::next_permutation(bid.begin(),bid.end()));
a=bst.Y;
return bst.X;
}
lli findCost2(map<string,ulli> st,vui &a)
{
lli bstCost=INF;
for(lli msk=0;msk<4;++msk)
{
lli cost=0;
if(msk&1)
a[1]^=a[0];
if(msk&2)
a[2]^=a[0];
cost+=costCalc({a[0]^st[rg[0]],a[1]^st[rg[1]],a[2]^st[rg[2]]});
if(msk&1)
{
a[1]^=a[0];
cost++;
}
if(msk&2)
{
a[2]^=a[0];
cost++;
}
bstCost=min(bstCost,cost);
}
return bstCost;
}
lli findCost5(map<string,ulli> st,vui &a)
{
lli bstCost=INF;
const lli n=(lli)a.size();
for(lli i=0;i<n;++i)
for(lli j=0;j<n;++j)
{
if(i==j)
continue;
for(lli msk=0;msk<4;++msk)
{
lli cost=0;
if(msk&1) a[i]^=a[3-i-j];
if(msk&2) a[j]^=a[3-i-j];
cost+=costCalc({a[i]^st[rg[1]],a[j]^st[rg[2]]});
if(msk&1){ a[i]^=a[3-i-j]; cost++;}
if(msk&2){ a[j]^=a[3-i-j]; cost++;}
bstCost=min(bstCost,cost);
}
}
return bstCost;
}
lli findCost(const map<string,ulli> &st,vui &a,lli fl)
{
if(fl==1)
return findCost1(st,a);
if(fl==2)
return findCost2(st,a);
if(fl==5)
return findCost5(st,a);
assert(false);
}
void load1(map<string,ulli> &st,vui a,lli fstplace)
{
const int n=3;
for(int i=fstplace;i<n;++i)
st[rg[i]]=a[i];
}
void load(map<string,ulli> &st,vui a,lli fl)
{
if(fl==1||fl==2)
{
load1(st,a,0);
return;
}
if(fl==5)
{
load1(st,a,1);
return;
}
assert(false);
}
lli getNext(const map<string,ulli> &st,vector<vui> &a,lli fl)
{
ii nxt=mp(0,INF);
const lli n=(lli)a.size();
for(lli i=0;i<n;++i)
{
if(vis[i])
continue;
lli cost=findCost(st,a[i],fl);
if(cost<nxt.Y)
nxt=mp(i,cost);
}
vis[nxt.X]=true;
return nxt.X;
}
// ii getNext2pair(const map<string,ulli> &st,vector<vui> &a,lli fl)
// {
// ii nxt2=mp(0,0);
// lli bstCost=INF;
// const lli n=(lli)a.size();
// for(lli i=0;i<n;++i)
// for(lli j=0;j<n;++j)
// {
// if(vis[i]||vis[j]||i==j)
// continue;
// lli cost=findCost2pair(st,a[i],a[j],fl);
// if(cost<bstCost)
// {
// nxt2=mp(i,j);
// bstCost=cost;
// }
// }
// vis[nxt2.X]=true;
// vis[nxt2.Y]=true;
// return nxt2;
// }
void solve(vector<vui> a,vector<vui> &ans,lli fl)
{
const lli n=(lli)a.size();
lli cnt=0;
vis.clear();vis.resize(n,false);
ans.clear();
map<string,ulli> st;
while(cnt<n)
{
ans.pb(a[getNext(st,a,fl)]);
load(st,ans.back(),fl);
cnt++;
}
}
// void solve2(vector<vui> a,vector<vui> &ans,lli fl)
// {
// const lli n=(lli)a.size();
// lli cnt=0;
// vis.clear();vis.resize(n,false);
// ans.clear();
// map<string,ulli> st;
// while(cnt<n)
// {
// ii nxt2=getNext2pair(st,a,fl);
// ans.pb(a[nxt2.X]);
// ans.pb(a[nxt2.Y]);
// load2pair(st,{a[nxt2.X],a[nxt2.Y]},fl);
// cnt+=2;
// }
// }
};
namespace matching{
// Ref - https://g...content-available-to-author-only...b.com/Ashishgup1/Competitive-Coding/blob/master/Min%20Cost%20Max%20Flow%20-%20Dijkstra.cpp
//Works for negative costs, but does not work for negative cycles
//Complexity: O(min(E^2 *V log V, E logV * flow))
struct edge
{
int to, flow, cap, cost, rev;
};
struct MinCostMaxFlow
{
int nodes;
vector<int> prio, curflow, prevedge, prevnode, q, pot;
vector<bool> inqueue;
vector<vector<edge> > graph;
MinCostMaxFlow() {}
MinCostMaxFlow(int n): nodes(n), prio(n, 0), curflow(n, 0),
prevedge(n, 0), prevnode(n, 0), q(n, 0), pot(n, 0), inqueue(n, 0), graph(n) {}
void addEdge(int source, int to, int capacity, int cost)
{
edge a = {to, 0, capacity, cost, (int)graph[to].size()};
edge b = {source, 0, 0, -cost, (int)graph[source].size()};
graph[source].push_back(a);
graph[to].push_back(b);
}
void bellman_ford(int source, vector<int> &dist)
{
fill(dist.begin(), dist.end(), INT_MAX);
dist[source] = 0;
int qt=0;
q[qt++] = source;
for(int qh=0;(qh-qt)%nodes!=0;qh++)
{
int u = q[qh%nodes];
inqueue[u] = false;
for(auto &e : graph[u])
{
if(e.flow >= e.cap)
continue;
int v = e.to;
int newDist = dist[u] + e.cost;
if(dist[v] > newDist)
{
dist[v] = newDist;
if(!inqueue[v])
{
inqueue[v] = true;
q[qt++ % nodes] = v;
}
}
}
}
}
pair<int, int> minCostFlow(int source, int dest, int maxflow)
{
bellman_ford(source, pot);
int flow = 0;
int flow_cost = 0;
while(flow < maxflow)
{
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;
q.push({0, source});
fill(prio.begin(), prio.end(), INT_MAX);
prio[source] = 0;
curflow[source] = INT_MAX;
while(!q.empty())
{
int d = q.top().first;
int u = q.top().second;
q.pop();
if(d != prio[u])
continue;
for(int i=0;i<graph[u].size();i++)
{
edge &e=graph[u][i];
int v = e.to;
if(e.flow >= e.cap)
continue;
int newPrio = prio[u] + e.cost + pot[u] - pot[v];
if(prio[v] > newPrio)
{
prio[v] = newPrio;
q.push({newPrio, v});
prevnode[v] = u;
prevedge[v] = i;
curflow[v] = min(curflow[u], e.cap - e.flow);
}
}
}
if(prio[dest] == INT_MAX)
break;
for(int i=0;i<nodes;i++)
pot[i]+=prio[i];
int df = min(curflow[dest], maxflow - flow);
flow += df;
for(int v=dest;v!=source;v=prevnode[v])
{
edge &e = graph[prevnode[v]][prevedge[v]];
e.flow += df;
graph[v][e.rev].flow -= df;
flow_cost += df * e.cost;
}
}
return {flow, flow_cost};
}
};
//Problem 1: https://w...content-available-to-author-only...j.com/problems/GREED/
//Solution 1: http://p...content-available-to-author-only...p.fi/ODRk
//Problem 2 (Double Cost): https://c...content-available-to-author-only...s.com/contest/277/problem/E
//Solution 2: https://c...content-available-to-author-only...s.com/contest/277/submission/43180845
lli arrange(const vui &a,vui &b)
{
const lli n = 3;
MinCostMaxFlow ans(2*n+2);
lli i,j;
repA(i,1,n)
{
ans.addEdge(0,i,1,0);
ans.addEdge(n+i,2*n+1,1,0);
}
repA(i,1,n)
repA(j,n+1,2*n)
ans.addEdge(i,j,1,load::bcnt(a[i-1]^b[j-n-1]));
lli cost=ans.minCostFlow(0,2*n+1,3).Y;
vui c;
repA(i,1,n)
{
for(auto x:ans.graph[i])
if(x.flow>0)
{
c.pb(b[x.to-n-1]);
break;
}
}
b.swap(c);
return cost;
// sort(b.begin(),b.end());
// sort(c.begin(),c.end());
// assert(b==c);
// dbg(b,c);
}
};
namespace type5{
ulli k;
bool chk(vector<vui> a)
{
for(auto v:a)
{
ulli cnt=0;
for(auto x:v)
cnt+=x;
if(cnt!=k)
return false;
}
return true;
}
void shuffle(vector<vui> &a)
{
shuffle(a.begin(),a.end(), rng);
for(auto &c:a)
shuffle(c.begin(),c.end(), rng);
const lli n=(lli)a.size();
for(lli i=1;i<n;++i)
matching::arrange(a[i-1],a[i]);
}
void loadvector(soln &ans,vui a)
{
soln bst,c;
int cnt=0;
const lli n=(lli)a.size();
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
{
if(i==j)
continue;
soln c;
c.setStates(ans);
load::load(c,{{a[i],rg[1]},{a[j],rg[2]}});
if((i==0&&j==1)||c.scr()<bst.scr())
bst.swap(c);
}
ans.mergeWithStates(bst);
ans.prt("sub "+rg[0]+" "+rg[1]);
ans.prt("sub "+rg[0]+" "+rg[2]);
ans.prt("add "+rg[0]+" "+rg[1]);
ans.prt("add "+rg[0]+" "+rg[2]);
}
soln runOnce(vector<vui> a)
{
soln ans;
load::load(ans,{{k,rg[0]}});
for(auto x:a)
loadvector(ans,x);
return ans;
}
soln solve(vector<vui> a)
{
soln ans;
k=a[0][0]+a[0][1]+a[0][2];
if(!chk(a))
return ans;
graph::solve(a,a,5);
ans.max(runOnce(a));
// for(int i=0;i<itn;++i)
// {
// ans.max(runOnce(a));
// shuffle(a);
// }
dbg("type5 : ",ans.scr());
return ans;
}
};
namespace type3{
bool chk(vector<vui> a)
{
const int n=(int)a.size(),bat=8;
ulli d=0;
for(int i=0;i<n;++i)
{
if(i%bat==0)
d=a[i][1]-a[i][0];
if(a[i][1]-a[i][0]!=d||a[i][2]-a[i][1]!=d)
return false;
}
return true;
}
void shuffle(vector<vui> &a)
{
const int n=(int)a.size(),bat=8;
vector<vui> b,c;
for(int i=0;i<n;++i)
{
c.pb(a[i]);
if(i==n-1||(i+1)%bat==0)
{
shuffle(c.begin(),c.end(), rng);
for(auto x:c)
b.pb(x);
c.clear();
}
}
a.swap(b);
}
soln runOnce(vector<vui> a)
{
soln ans;
const int n=(int)a.size(),bat=8;
ulli d=0;
for(int i=0;i<n;i+=2)
{
auto x=a[i],y=a[i+1];
if(i%bat==0)
{
d=x[1]-x[0];
load::load(ans,{{x[0],rg[1]},{d,rg[0]},{y[0],rg[2]}});
// d,a1,a2,0;
ans.mov(rgv[3],rg[0]);
ans.add(rgv[3],rgv[3]); //d,a1,a2,2d
ans.add(rg[0],rg[1]);
ans.add(rgv[3],rg[1]);//a1+d,a1,a2,a1+2d
ans.sub(rg[0],rg[1]);
ans.sub(rgv[3],rg[1]);//d,a1,a2,2d
ans.add(rg[0],rg[2]);
ans.add(rgv[3],rg[2]);//a2+d,a1,a2,a2+2d
ans.sub(rg[0],rg[2]);
ans.sub(rgv[3],rg[2]);//d,a1,a2,2d
ans.rst(rgv[3]);//a1,d,a2,0;
}
else
{
// *,d,*,0
load::load(ans,{{x[0],rg[1]},{y[0],rg[2]}});
// a1,d,a2,0;
ans.mov(rgv[3],rg[0]);
ans.add(rgv[3],rgv[3]); //d,a1,a2,2d
ans.add(rg[0],rg[1]);
ans.add(rgv[3],rg[1]);//a1+d,a1,a2,a1+2d
ans.sub(rg[0],rg[1]);
ans.sub(rgv[3],rg[1]);//d,a1,a2,2d
ans.add(rg[0],rg[2]);
ans.add(rgv[3],rg[2]);//a2+d,a1,a2,a2+2d
ans.sub(rg[0],rg[2]);
ans.sub(rgv[3],rg[2]);//d,a1,a2,2d
ans.rst(rgv[3]);//d,a1,a2,0;
}
}
return ans;
}
soln solve(vector<vui> a)
{
soln ans;
if(!chk(a))
return ans;
for(int i=0;i<itn;++i)
{
ans.max(runOnce(a));
shuffle(a);
}
dbg("type3 : ",ans.scr());
return ans;
}
};
namespace type2{
lli bcnt(ulli x)
{
lli cnt=0;
while(x)
{
if(x&1)
cnt++;
x/=2;
}
return cnt;
}
bool chk(vector<vui> a)
{
for(auto x:a)
{
if(bcnt(x[0]^x[1])>2||bcnt(x[0]^x[2])>2)
return false;
}
return true;
}
void loadvector(soln &ans,vui a)
{
ans.rst(rg[0]);ans.rst(rg[1]);ans.rst(rg[2]);
soln bst;
for(lli msk=0;msk<4;++msk)
{
soln c;
// c.setStates(ans);
if(msk&1)
a[1]^=a[0];
if(msk&2)
a[2]^=a[0];
load::load(c,{{a[0],rg[0]},{a[1],rg[1]},{a[2],rg[2]}});
if(msk&1)
{
a[1]^=a[0];
c.xr(rg[1],rg[0]);
}
if(msk&2)
{
a[2]^=a[0];
c.xr(rg[2],rg[0]);
}
if(msk)
bst.max(c);
else
bst.swap(c);
}
ans.mergeWithStates(bst);
// dbg(a,ans.getStates());
}
soln runSorted(vector<vui> a)
{
for(auto &x:a)
{
if((x[1]^x[0])<(x[2]^x[0]))
swap(x[1],x[0]);
}
sort(a.begin(),a.end(),[&](const vui &a,const vui &b){
ii x={a[1]^a[0],a[2]^a[0]};
ii y={b[1]^b[0],b[2]^b[0]};
return x<y;
});
string s=rg[1];
soln ans;
ans.inc(s);
for(auto x:a)
{
while(ans.bt(s)&&(ans.bt(s)&(x[1]^x[0]))==0)
ans.add(s,s);
load::load(ans,{{x[0],rg[0]},{x[1]^x[0],rg[1]},{x[2]^x[0],rg[2]}});
ans.xr(rg[2],rg[0]);
ans.xr(rg[1],rg[0]);
ans.xr(rg[2],rg[0]);
ans.xr(rg[1],rg[0]);
}
dbg("type2sp : ",ans.scr());
return ans;
}
soln runOnce(vector<vui> a)
{
soln ans;
for(auto x:a)
loadvector(ans,x);
return ans;
}
soln solve(vector<vui> a)
{
soln ans;
ans.max(runSorted(a));
graph::solve(a,a,2);
ans.max(runOnce(a));
dbg("type2 : ",ans.scr());
return ans;
}
};
namespace type1{
void load(soln &ans,vui a)
{
// dbg(a);
load::load(ans,{{a[0],rg[0]},{a[1],rg[1]},{a[2],rg[2]}});
}
soln runOnce(vector<vui> a)
{
soln ans;
for(auto x:a)
load(ans,x);
return ans;
}
void shuffle(vector<vui> &a)
{
shuffle(a.begin(),a.end(), rng);
for(auto &c:a)
shuffle(c.begin(),c.end(), rng);
const lli n=(lli)a.size();
for(lli i=1;i<n;++i)
matching::arrange(a[i-1],a[i]);
}
soln solve(vector<vui> a)
{
soln ans;
graph::solve(a,a,1);
ans.max(runOnce(a));
dbg("type1 : ",ans.scr());
return ans;
}
};
namespace solve{
soln solve(vector<vui> a)
{
soln ans;
ans.max(type1::solve(a));
ans.max(type5::solve(a));
ans.max(type2::solve(a));
ans.max(type3::solve(a));
return ans;
}
};
namespace complete{
void run()
{
const lli n=64;
lli scr=0,cnt=0,scrv=0;
//cnt=solve::solve(testcase::test1()).scr();scr+=cnt;
//dbg(" TC 1 Score : ", cnt, cnt/n);
//cnt=solve::solve(testcase::test2()).scr();scr+=cnt;scrv+=cnt;
//dbg(" TC 2 Score : ", cnt, cnt/n);
//cnt=solve::solve(testcase::test3()).scr();scr+=cnt;scrv+=cnt;
//dbg(" TC 3 Score : ", cnt, cnt/n);
for(int i = 0; i < 100; ++i){
cnt=solve::solve(testcase::test4()).scr();scr+=cnt;
dbg(" TC 4 Score : ", cnt, cnt/n);
}
//cnt=solve::solve(testcase::test5()).scr();scr+=cnt;scrv+=cnt;
//dbg(" TC 5 Score : ", cnt, cnt/n);
//dbg(scr,3*scr/5,scrv);
}
};
int main(void) {
ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
// freopen("txt.in", "r", stdin);
// freopen("txt.out", "w", stdout);
// cout<<std::fixed<<std::setprecision(35);
lli n;
ulli x,y,z;
vector<vui> a;
#ifdef ARYANC403
if(false)
{
complete::run();
dbg(seed,seedtgen);
return 0;
}
{
for(int i = 0; i < 100; ++i)
testcase::printtc(4);
return 0;
}
a=testcase::test1();
n=(lli)a.size();
#else
cin>>n;
a.clear();a.reserve(n);
for(int i=0;i<n;++i)
{
cin>>x>>y>>z;
a.pb({x,y,z});
}
#endif
soln ans;
ans.max(solve::solve(a));
// ans.max(type5::solve(a));
#ifdef ARYANC403
dbg(ans.scr()/n,ans.scr());
dbg(seed,seedtgen);
// printans(ans);
#else
printans(ans);
#endif
aryanc403();
return 0;
}
I2RlZmluZSBBUllBTkM0MDMKLyoKICBXYXJuIC0gRG9uJ3QgY2hhbmdlIG5leHQgbGluZSBlbHNlIHlvdSB3aWxsIGdldCBXQSB2ZXJkaWN0LiBPbmxpbmUgSnVkZ2UgaXMgY29uZmlndXJlZCB0byBnaXZlIFdBIGlmIG5leHQgbGluZSBpcyBub3QgcHJlc2VudC4KICAiQW4gaWRlYWwgcHJvYmxlbSBoYXMgbm8gdGVzdCBkYXRhLiIKICBBdXRob3IgLSBBcnlhbiBDaG91ZGhhcnkgKEBhcnlhbmM0MDMpCiovCgojcHJhZ21hIHdhcm5pbmcoZGlzYWJsZTo0OTk2KQojcHJhZ21hIGNvbW1lbnQobGlua2VyLCAiL3N0YWNrOjIwMDAwMDAwMCIpCiNwcmFnbWEgR0NDIG9wdGltaXplICgiT2Zhc3QiKQovLyNwcmFnbWEgR0NDIHRhcmdldCAoInNzZSxzc2UyLHNzZTMsc3NzZTMsc3NlNCxwb3BjbnQsYWJtLG1teCxhdngsdHVuZT1uYXRpdmUiKQojcHJhZ21hIEdDQyBvcHRpbWl6ZSAoIi1mZmxvYXQtc3RvcmUiKQoKI2luY2x1ZGU8aW9zdHJlYW0+CiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CiNpbmNsdWRlPHN0ZGlvLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiNkZWZpbmUgZm8oaSxuKSAgIGZvcihpPTA7aTwobik7KytpKQojZGVmaW5lIHJlcEEoaSxqLG4pICAgZm9yKGk9KGopO2k8PShuKTsrK2kpCiNkZWZpbmUgcmVwRChpLGosbikgICBmb3IoaT0oaik7aT49KG4pOy0taSkKI2RlZmluZSBwYiBwdXNoX2JhY2sKI2RlZmluZSBtcCBtYWtlX3BhaXIKI2RlZmluZSBYIGZpcnN0CiNkZWZpbmUgWSBzZWNvbmQKI2RlZmluZSBlbmRsICJcbiIKdHlwZWRlZiBsb25nIGxvbmcgaW50IGxsaTsKdHlwZWRlZiB1bnNpZ25lZCBsb25nIGxvbmcgaW50IHVsbGk7CnR5cGVkZWYgbG9uZyBkb3VibGUgbXl0eXBlOwp0eXBlZGVmIHBhaXI8bGxpLGxsaT4gaWk7CnR5cGVkZWYgdmVjdG9yPGlpPiB2aWk7CnR5cGVkZWYgdmVjdG9yPGxsaT4gdmk7CnR5cGVkZWYgdmVjdG9yPHVsbGk+IHZ1aTsKCmNsb2NrX3QgdGltZV9wPWNsb2NrKCk7CnZvaWQgYXJ5YW5jNDAzKCkKewogICAgdGltZV9wPWNsb2NrKCktdGltZV9wOwogICAgY2Vycjw8IlRpbWUgVGFrZW4gOiAiPDwoZmxvYXQpKHRpbWVfcCkvQ0xPQ0tTX1BFUl9TRUM8PCJcbiI7Cn0KCiNpZmRlZiBBUllBTkM0MDMKICAgICNkZWZpbmUgZGJnKC4uLikgeyBjZXJyPDwiWyAiOyBfX2FyeWFuYzQwM19fKCNfX1ZBX0FSR1NfXywgX19WQV9BUkdTX18pO30KICAgICN1bmRlZiBlbmRsCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQXJnMSx0eXBlbmFtZSBBcmcyPgogICAgb3N0cmVhbSYgb3BlcmF0b3IgPDwgKG9zdHJlYW0mIG91dCwgY29uc3QgcGFpcjxBcmcxLEFyZzI+ICZ4KSB7CiAgICAgICAgcmV0dXJuIG91dDw8IigiPDx4Llg8PCIsIjw8eC5ZPDwiKSI7CiAgICB9CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIEFyZzE+CiAgICBvc3RyZWFtJiBvcGVyYXRvciA8PCAob3N0cmVhbSYgb3V0LCBjb25zdCB2ZWN0b3I8QXJnMT4gJmEpIHsKICAgICAgICBvdXQ8PCJbIjtmb3IoY29uc3QgYXV0byAmeDphKW91dDw8eDw8IiwiO3JldHVybiBvdXQ8PCJdIjsKICAgIH0KCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQXJnMT4KICAgIG9zdHJlYW0mIG9wZXJhdG9yIDw8IChvc3RyZWFtJiBvdXQsIGNvbnN0IHNldDxBcmcxPiAmYSkgewogICAgICAgIG91dDw8IlsiO2Zvcihjb25zdCBhdXRvICZ4OmEpb3V0PDx4PDwiLCI7cmV0dXJuIG91dDw8Il0iOwogICAgfQoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBBcmcxLHR5cGVuYW1lIEFyZzI+CiAgICBvc3RyZWFtJiBvcGVyYXRvciA8PCAob3N0cmVhbSYgb3V0LCBjb25zdCBtYXA8QXJnMSxBcmcyPiAmYSkgewogICAgICAgIG91dDw8IlsiO2Zvcihjb25zdCBhdXRvICZ4OmEpb3V0PDx4PDwiLCI7cmV0dXJuIG91dDw8Il0iOwogICAgfQoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBBcmcxPgogICAgdm9pZCBfX2FyeWFuYzQwM19fKGNvbnN0IHN0cmluZyBuYW1lLCBBcmcxJiYgYXJnMSl7CiAgICAgICAgY2VyciA8PCBuYW1lIDw8ICIgOiAiIDw8IGFyZzEgPDwgIiBdICIgPDwgZW5kbDsKICAgIH0KCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQXJnMSwgdHlwZW5hbWUuLi4gQXJncz4KICAgIHZvaWQgX19hcnlhbmM0MDNfXyhjb25zdCBzdHJpbmcgbmFtZXMsIEFyZzEmJiBhcmcxLCBBcmdzJiYuLi4gYXJncyl7CiAgICAgICAgY29uc3Qgc3RyaW5nIG5hbWUgPSBuYW1lcy5zdWJzdHIoMCxuYW1lcy5maW5kKCcsJykpOwogICAgICAgIGNlcnI8PG5hbWU8PCIgOiAiPDxhcmcxPDwiIHwgIjsKICAgICAgICBfX2FyeWFuYzQwM19fKG5hbWVzLnN1YnN0cigxKyhpbnQpbmFtZS5zaXplKCkpLCBhcmdzLi4uKTsKICAgIH0KI2Vsc2UKICAgICNkZWZpbmUgZGJnKGFyZ3MuLi4pCiNlbmRpZgoKY29uc3QgbGxpIElORiA9IDB4RkZGRkZGRkZGRkZGRkZGTDsKCmxsaSBzZWVkLHNlZWR0Z2VuOwptdDE5OTM3IHJuZyhzZWVkPWNocm9ubzo6c3RlYWR5X2Nsb2NrOjpub3coKS50aW1lX3NpbmNlX2Vwb2NoKCkuY291bnQoKSk7CmlubGluZSBsbGkgcm5kKGxsaSBsPTAsbGxpIHI9SU5GKQp7cmV0dXJuIHVuaWZvcm1faW50X2Rpc3RyaWJ1dGlvbjxsbGk+KGwscikocm5nKTt9Cgpjb25zdCB2ZWN0b3I8c3RyaW5nPiByZz17InJheCIsInJieCIsInJjeCJ9Owpjb25zdCB2ZWN0b3I8c3RyaW5nPiByZ3Y9eyJkbCIsImR4IiwiZWR4IiwicmR4In07CmNvbnN0IGxsaSBpdG4gPSAyNTsKCnN0cnVjdCBzb2xuewogICAgcHJpdmF0ZSA6CiAgICB2ZWN0b3I8c3RyaW5nPiBhOwogICAgbWFwPHN0cmluZyx1bGxpPiBzdDsKCiAgICBwdWJsaWM6CiAgICBzb2xuKCkgICAgICB7IGEuY2xlYXIoKTsgc3QuY2xlYXIoKTt9OwogICAgc29sbihjb25zdCBtYXA8c3RyaW5nLHVsbGk+IG0pICAgICAgeyBhLmNsZWFyKCk7IHN0PW07fTsKCiAgICB2b2lkIGNsZWFyKCl7IGEuY2xlYXIoKTsgc3QuY2xlYXIoKTt9OwogICAgdm9pZCBwcnQoc3RyaW5nIHMpIHsgYS5wYihzKTt9CgogICAgbWFwPHN0cmluZyx1bGxpPiBnZXRTdGF0ZXMoKSB7IHJldHVybiBzdDt9CgogICAgdm9pZCBwcnRzb2xuKCkgewogICAgICAgIGZvcihhdXRvIHg6YSkKICAgICAgICAgICAgY291dDw8eDw8ZW5kbDsKICAgIH0KCiAgICB2b2lkIHNldFN0YXRlcyhjb25zdCBzb2xuICZvKXsKICAgICAgICBzdD1vLnN0OwogICAgfQoKICAgIHZvaWQgbWVyZ2VXaXRoU3RhdGVzKGNvbnN0IHNvbG4gJm8pewogICAgICAgIHN0PW8uc3Q7CiAgICAgICAgZm9yKGF1dG8geDpvLmEpCiAgICAgICAgICAgIGEucGIoeCk7CiAgICB9CgogICAgdm9pZCBzd2FwKHNvbG4gJm8pewogICAgICAgIHN0LnN3YXAoby5zdCk7CiAgICAgICAgYS5zd2FwKG8uYSk7CiAgICB9CgogICAgdm9pZCBhZGQoc29sbiBvKSB7CgogICAgICAgIGlmKCFvLnNjcigpKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIGZvcihhdXRvIHg6c3QpCiAgICAgICAgICAgIHJzdCh4LlgpOwoKICAgICAgICBmb3IoYXV0byB4Om8uYSkKICAgICAgICAgICAgYS5wYih4KTsKICAgICAgICBzdD1vLnN0OwogICAgfQoKICAgIGxsaSBzY3IoKXsgIHJldHVybiAobGxpKWEuc2l6ZSgpOyAgIH0KICAgIGxsaSBidChzdHJpbmcgcyl7ICByZXR1cm4gc3Rbc107ICAgfQoKICAgIHZvaWQgbWF4KHNvbG4gYil7CiAgICAgICAgaWYoYi5hLmVtcHR5KCkpCiAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgaWYoYS5lbXB0eSgpfHwoaW50KWIuYS5zaXplKCk8KGludClhLnNpemUoKSkKICAgICAgICB7CiAgICAgICAgICAgIHN0LnN3YXAoYi5zdCk7CiAgICAgICAgICAgIGEuc3dhcChiLmEpOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIHJzdChzdHJpbmcgcykKICAgIHsKICAgICAgICBpZighc3Rbc10pCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBzdFtzXT0wOwogICAgICAgIHBydCgieG9yICIrcysiICIrcyk7CiAgICB9CgogICAgdm9pZCBpbmMoc3RyaW5nIHMpCiAgICB7CiAgICAgICAgc3Rbc10rKzsKICAgICAgICBwcnQoImluYyAiK3MpOwogICAgfQoKICAgIHZvaWQgc2hsKHN0cmluZyBhLHN0cmluZyBiKQogICAgewogICAgICAgIGlmKCFzdFtiXSkKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIHN0W2FdPj49c3RbYl07CiAgICAgICAgcHJ0KCJzaGwgIithKyIgIitiKTsKICAgIH0KCiAgICB2b2lkIGFkZChzdHJpbmcgYSxzdHJpbmcgYikKICAgIHsKICAgICAgICBpZighc3RbYl0pCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBzdFthXSs9c3RbYl07CiAgICAgICAgcHJ0KCJhZGQgIithKyIgIitiKTsKICAgIH0KCiAgICB2b2lkIHN1YihzdHJpbmcgYSxzdHJpbmcgYikKICAgIHsKICAgICAgICBpZighc3RbYl0pCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBzdFthXS09c3RbYl07CiAgICAgICAgcHJ0KCJzdWIgIithKyIgIitiKTsKICAgIH0KCiAgICB2b2lkIHhyKHN0cmluZyBhLHN0cmluZyBiKQogICAgewogICAgICAgIHN0W2FdXj1zdFtiXTsKICAgICAgICBwcnQoInhvciAiK2ErIiAiK2IpOwogICAgfQoKICAgIHZvaWQgbnQoc3RyaW5nIGEpCiAgICB7CiAgICAgICAgc3RbYV09fnN0W2FdOwogICAgICAgIHBydCgibm90ICIrYSk7CiAgICB9CgogICAgdm9pZCBtb3Yoc3RyaW5nIGEsc3RyaW5nIGIpCiAgICB7CiAgICAgICAgaWYoc3RbYV09PXN0W2JdKQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgc3RbYV09c3RbYl07CiAgICAgICAgcHJ0KCJtb3YgIithKTsKICAgIH0KfTsKCnZvaWQgcHJpbnRhbnMoc29sbiBhbnMpCnsKICAgIGNvdXQ8PChpbnQpYW5zLnNjcigpPDxlbmRsOwogICAgYW5zLnBydHNvbG4oKTsKICAgIGFyeWFuYzQwMygpOwogICAgZXhpdCgwKTsKfQoKbmFtZXNwYWNlIHRlc3RjYXNlewogICAgbXQxOTkzNyBybmcoc2VlZHRnZW49Y2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKS5jb3VudCgpKTsKCiAgICBpbmxpbmUgbGxpIHJuZChsbGkgbCxsbGkgcikKICAgIHtyZXR1cm4gdW5pZm9ybV9pbnRfZGlzdHJpYnV0aW9uPGxsaT4obCxyKShybmcpO30KCiAgICB1bGxpIHJuZCgpewogICAgICAgIHVsbGkgeD1ybmQoMCwxTEw8PDMyKSx5PXJuZCgwLDFMTDw8MzIpOwogICAgICAgIHJldHVybiAoeDw8MzIpK3k7CiAgICB9CgogICAgdmVjdG9yPHZ1aT4gdGVzdDEoKXsKICAgICAgICB2ZWN0b3I8dnVpPiBhOwogICAgICAgIGNvbnN0IGxsaSBuPTY0OwogICAgICAgIGZvcihpbnQgaT0wO2k8bjsrK2kpCiAgICAgICAgICAgIGEucGIoe3JuZCgpLHJuZCgpLHJuZCgpfSk7CiAgICAgICAgZGJnKCJUQyAxIEdlbmVyYXRlZC4iKTsKICAgICAgICByZXR1cm4gYTsKICAgIH0KCiAgICB2ZWN0b3I8dnVpPiB0ZXN0MigpewogICAgICAgIHZlY3Rvcjx2dWk+IGE7CiAgICAgICAgdnVpIGI7CgogICAgICAgIGNvbnN0IGxsaSBuPTY0OwogICAgICAgIGNvbnN0IHVsbGkgb249MTsKCiAgICAgICAgZm9yKGludCBpPTA7aTxuOysraSkKICAgICAgICB7CiAgICAgICAgICAgIGZvcihpbnQgaj1pO2o8bjsrK2opCiAgICAgICAgICAgIGIucGIoKG9uPDxpKXwob248PGopKTsKICAgICAgICB9CgogICAgICAgIGNvbnN0IGxsaSBtPShsbGkpYi5zaXplKCk7CiAgICAgICAgZm9yKGludCBpPTA7aTxuOysraSkKICAgICAgICB7CiAgICAgICAgICAgIHVsbGkgeD1ybmQoKTsKICAgICAgICAgICAgYS5wYih7eCx4XmJbcm5kKDAsbS0xKV0seF5iW3JuZCgwLG0tMSldfSk7CiAgICAgICAgfQogICAgICAgIGRiZygiVEMgMiBHZW5lcmF0ZWQuIik7CiAgICAgICAgcmV0dXJuIGE7CiAgICB9CgogICAgdmVjdG9yPHZ1aT4gdGVzdDMoKXsKICAgICAgICB2ZWN0b3I8dnVpPiBhOwogICAgICAgIGNvbnN0IGxsaSBuPTY0LGJhdD04OwogICAgICAgIHVsbGkgZD0wOwogICAgICAgIGZvcihpbnQgaT0wO2k8bjsrK2kpCiAgICAgICAgewogICAgICAgICAgICBpZihpJWJhdD09MCkKICAgICAgICAgICAgICAgIGQ9cm5kKCk7CiAgICAgICAgICAgIHVsbGkgeD1ybmQoKTsKICAgICAgICAgICAgYS5wYih7eCx4K2QseCsyKmR9KTsKICAgICAgICB9CiAgICAgICAgZGJnKCJUQyAzIEdlbmVyYXRlZC4iKTsKICAgICAgICByZXR1cm4gYTsKICAgIH0KCiAgICB2b2lkIGFwcGx5b3AodWxsaSAmeCx1bGxpICZ5KQogICAgewogICAgICAgIGJvb2wgZmw9cm5kKDAsMSk7CiAgICAgICAgdWxsaSBhPXgsYj15OwogICAgICAgIHVsbGkgbTY0PS0xOwogICAgICAgIHVsbGkgbTMyPW02ND4+MzI7CgogICAgICAgIGlmKGZsKQogICAgICAgIHsKICAgICAgICAgICAgYSY9bTMyOwogICAgICAgICAgICBiJj1tMzI7CiAgICAgICAgfQoKICAgICAgICBzd2l0Y2gocm5kKDAsNCkpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIDA6ICBhKz1iOyAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMTogIGEtPWI7ICBicmVhazsKICAgICAgICAgICAgY2FzZSAyOiAgYXw9YjsgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDM6ICBhJj1iOyAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgNDogIGFePWI7ICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmKGZsKQogICAgICAgIHsKICAgICAgICAgICAgYSY9bTMyOwogICAgICAgICAgICB4Pj49MzI7eDw8PTMyOwogICAgICAgICAgICB4fD1hOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIHg9YTsKICAgIH0KCiAgICB2dWkgdGVzdDRMaXN0KCl7CiAgICAgICAgdnVpIGw7CiAgICAgICAgd2hpbGUodHJ1ZSl7CiAgICAgICAgICAgIGwuY2xlYXIoKTsKICAgICAgICAgICAgY29uc3QgbGxpIG49NjQ7CiAgICAgICAgICAgIHZ1aSByZWcoe3JuZCgpLHJuZCgpLHJuZCgpfSk7CgogICAgICAgICAgICB1bnNpZ25lZCBsb25nIGxvbmcgbGFzdF9sID0gMDsKICAgICAgICAgICAgYm9vbCBvayA9IHRydWU7CiAgICAgICAgICAgIGludCBtaXN0YWtlcyA9IDA7CiAgICAgICAgICAgIHdoaWxlKChsbGkpbC5zaXplKCk8OSpuKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2dWkgb2xkID0gcmVnOwoKICAgICAgICAgICAgICAgIGludCBvcF9pZCA9IHJuZCgwLDUpOwogICAgICAgICAgICAgICAgc3dpdGNoKG9wX2lkKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhc2UgMDogICBhcHBseW9wKHJlZ1swXSxyZWdbMV0pOyAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgMTogICBhcHBseW9wKHJlZ1swXSxyZWdbMl0pOyAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgMjogICBhcHBseW9wKHJlZ1sxXSxyZWdbMF0pOyAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgMzogICBhcHBseW9wKHJlZ1sxXSxyZWdbMl0pOyAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgNDogICBhcHBseW9wKHJlZ1syXSxyZWdbMF0pOyAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgNTogICBhcHBseW9wKHJlZ1syXSxyZWdbMV0pOyAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYm9vbCBtaXN0YWtlX21hZGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGlmKGwuc2l6ZSgpJTkgPT0gNil7CiAgICAgICAgICAgICAgICAgICAgbWlzdGFrZV9tYWRlIHw9IGwuc2l6ZSgpID49IDMgJiYgbFtsLnNpemUoKS0xXSA9PSByZWdbMl07CiAgICAgICAgICAgICAgICAgICAgbWlzdGFrZV9tYWRlIHw9IGwuc2l6ZSgpID49IDYgJiYgbFtsLnNpemUoKS00XSA9PSByZWdbMl07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihsLnNpemUoKSU5ID09IDMpewogICAgICAgICAgICAgICAgICAgIG1pc3Rha2VfbWFkZSB8PSBsLnNpemUoKSA+PSAzICYmIGxbbC5zaXplKCktMV0gPT0gcmVnWzJdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYobWlzdGFrZV9tYWRlKXsKICAgICAgICAgICAgICAgICAgICByZWcgPSBvbGQ7CiAgICAgICAgICAgICAgICAgICAgaWYoKyttaXN0YWtlcyA+ICgxPDw4KSl7CiAgICAgICAgICAgICAgICAgICAgICAgIG9rID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGwucGIocmVnWzBdKTsKICAgICAgICAgICAgICAgIGwucGIocmVnWzFdKTsKICAgICAgICAgICAgICAgIGwucGIocmVnWzJdKTsKICAgICAgICAgICAgICAgIGxhc3RfbCA9IHJlZ1syXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihvaykgcmV0dXJuIGw7CiAgICAgICAgfQogICAgICAgIGFzc2VydChmYWxzZSk7Ly9uZXZlciByZWFjaGVkCiAgICB9CgogICAgdmVjdG9yPHZ1aT4gdGVzdDQoKXsKICAgICAgICB2ZWN0b3I8dnVpPiBhOwogICAgICAgIHZ1aSBiOwogICAgICAgIGNvbnN0IGxsaSBuPTY0OwogICAgICAgIGEuY2xlYXIoKTsKICAgICAgICBiPXRlc3Q0TGlzdCgpOwogICAgICAgIGZvcihsbGkgaT0yO2k8OSpuO2krPTkpCiAgICAgICAgICAgIGEucGIoe2JbaV0sYltpKzNdLGJbaSs2XX0pOwogICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBuOyArK2kpewogICAgICAgICAgICBpZihhW2ldWzBdID09IGFbaV1bMV0pIGFzc2VydChmYWxzZSk7CiAgICAgICAgICAgIGlmKGFbaV1bMF0gPT0gYVtpXVsyXSkgYXNzZXJ0KGZhbHNlKTsKICAgICAgICAgICAgaWYoYVtpXVsxXSA9PSBhW2ldWzJdKSBhc3NlcnQoZmFsc2UpOwogICAgICAgIH0KICAgICAgICBkYmcoIlRDIDQgR2VuZXJhdGVkLiIpOwogICAgICAgIHJldHVybiBhOwogICAgfQoKICAgIHZlY3Rvcjx2dWk+IHRlc3Q1KCl7CiAgICAgICAgdmVjdG9yPHZ1aT4gYTsKICAgICAgICBjb25zdCBsbGkgbj02NDsKICAgICAgICB1bGxpIGs9cm5kKCk7CiAgICAgICAgZm9yKGludCBpPTA7aTxuOysraSkKICAgICAgICB7CiAgICAgICAgICAgIHVsbGkgeD1ybmQoKSx5PXJuZCgpOwogICAgICAgICAgICBhLnBiKHt4LHksay14LXl9KTsKICAgICAgICB9CiAgICAgICAgZGJnKCJUQyA1IEdlbmVyYXRlZC4iKTsKICAgICAgICByZXR1cm4gYTsKICAgIH0KCiAgICB2b2lkIHByaW50dGMobGxpIGlkKQogICAgewogICAgICAgIHZlY3Rvcjx2dWk+IGE7CiAgICAgICAgc3dpdGNoKGlkKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSAxOiBhPXRlc3RjYXNlOjp0ZXN0MSgpOyBicmVhazsKICAgICAgICAgICAgY2FzZSAyOiBhPXRlc3RjYXNlOjp0ZXN0MigpOyBicmVhazsKICAgICAgICAgICAgY2FzZSAzOiBhPXRlc3RjYXNlOjp0ZXN0MygpOyBicmVhazsKICAgICAgICAgICAgY2FzZSA0OiBhPXRlc3RjYXNlOjp0ZXN0NCgpOyBicmVhazsKICAgICAgICAgICAgY2FzZSA1OiBhPXRlc3RjYXNlOjp0ZXN0NSgpOyBicmVhazsKICAgICAgICB9CgogICAgICAgIGNvdXQ8PChsbGkpYS5zaXplKCk8PGVuZGw7CiAgICAgICAgZm9yKGF1dG8geDphKQogICAgICAgICAgICBjb3V0PDx4WzBdPDwiICI8PHhbMV08PCIgIjw8eFsyXTw8ZW5kbDsKCiAgICAgICAgLy9jb3V0PDxlbmRsOwogICAgICAgIC8vY291dDw8IlNlZWQgdXNlZCBmb3IgZ2VuZXJhdGlvbiA6ICI8PHNlZWR0Z2VuPDxlbmRsOwogICAgfQp9OwoKbmFtZXNwYWNlIGxvYWR7CgogICAgbGxpIGJjbnQodWxsaSB4KQogICAgewogICAgICAgIGxsaSBjbnQ9MDsKICAgICAgICB3aGlsZSh4KQogICAgICAgIHsKICAgICAgICAgICAgaWYoeCYxKQogICAgICAgICAgICAgICAgY250Kys7CiAgICAgICAgICAgIHgvPTI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjbnQ7CiAgICB9CgogICAgdWxsaSBuZWcodWxsaSB4LGludCBidCkKICAgIHsKICAgICAgICB1bGxpIG9uPTE7CiAgICAgICAgdWxsaSBsaW09b248PGJ0OwogICAgICAgIGxpbS0tOwogICAgICAgIHg9fng7CiAgICAgICAgeCY9bGltOwogICAgICAgIHJldHVybiB4OwogICAgfQoKICAgIHZvaWQgb3JyKHNvbG4gJmIsdWxsaSAmeCx1bGxpIGQsc3RyaW5nIHMsc3RyaW5nIGRzKXsKICAgICAgICBpZih4JmQpCiAgICAgICAgewogICAgICAgICAgICBiLnhyKHMsZHMpOwogICAgICAgICAgICB4Xj1kOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGxvYWRTKHNvbG4gJmIsdWxsaSB4LHN0cmluZyBzKQogICAgewogICAgICAgIGIucnN0KHMpOwogICAgICAgIGlmKCF4KQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIGNvbnN0IGxsaSBCVD02NDsKICAgICAgICBpZihsb2FkOjpiY250KHgpPkJULzIpCiAgICAgICAgewogICAgICAgICAgICBsb2FkUyhiLH54LHMpOwogICAgICAgICAgICBiLm50KHMpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBsbGkgaT1CVC0xOwogICAgICAgIHVsbGkgb249MTsKICAgICAgICB3aGlsZSgoeCYob248PGkpKT09MCkKICAgICAgICAgICAgaS0tOwogICAgICAgIGIuaW5jKHMpOwogICAgICAgIHdoaWxlKGkpCiAgICAgICAgewogICAgICAgICAgICBiLmFkZChzLHMpOwogICAgICAgICAgICBpLS07CiAgICAgICAgICAgIGlmKHgmKG9uPDxpKSkKICAgICAgICAgICAgICAgIGIuaW5jKHMpOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGxvYWRQcmUoc29sbiAmYix2ZWN0b3I8cGFpcjx1bGxpLHN0cmluZz4+IGEpCiAgICB7CgogICAgICAgIGlmKChsbGkpYS5zaXplKCk9PTEpCiAgICAgICAgewogICAgICAgICAgICBsb2FkUyhiLGFbMF0uWCxhWzBdLlkpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBzdHJpbmcgZGc9cmd2WzNdOwogICAgICAgIC8vIGRiZyhiLmdldFN0YXRlcygpLGEpOwogICAgICAgIGZvcihhdXRvICZ4OmEpCiAgICAgICAgewogICAgICAgICAgICAvLyBkYmcoeC5YLGIuYnQoeC5ZKSk7CiAgICAgICAgICAgIHguWF49Yi5idCh4LlkpOwogICAgICAgIH0KICAgICAgICAvLyBkYmcoInhvciIsYSk7CgogICAgICAgIC8vIGIucnN0KGRnKTsKICAgICAgICB1bGxpIGQ9MDsKICAgICAgICB3aGlsZSh0cnVlKQogICAgICAgIHsKICAgICAgICAgICAgYm9vbCBmbD10cnVlOwogICAgICAgICAgICBmb3IoYXV0byB4OmEpCiAgICAgICAgICAgICAgICBpZih4LlgpCiAgICAgICAgICAgICAgICAgICAgZmw9ZmFsc2U7CgogICAgICAgICAgICBpZihmbCkKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgaWYoZD09MCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYi5pbmMoZGcpOwogICAgICAgICAgICAgICAgZCsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYi5hZGQoZGcsZGcpOwogICAgICAgICAgICAgICAgZCs9ZDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yKGF1dG8gJng6YSkKICAgICAgICAgICAgICAgIG9ycihiLHguWCxkLHguWSxkZyk7CiAgICAgICAgfQogICAgICAgIC8vIGRiZyhhKTsKICAgICAgICBiLnJzdChkZyk7CiAgICB9CgogICAgdm9pZCBsb2FkKHNvbG4gJmIsdmVjdG9yPHBhaXI8dWxsaSxzdHJpbmc+PiBhKQogICAgewogICAgICAgIGNvbnN0IGxsaSBuPShsbGkpYS5zaXplKCk7CiAgICAgICAgY29uc3QgbGxpIGxpbT0oMUxMPDxuKTsKCiAgICAgICAgc29sbiBic3Q7CiAgICAgICAgZm9yKGxsaSBtc2s9MDttc2s8bGltOysrbXNrKQogICAgICAgIHsKICAgICAgICAgICAgc29sbiBjOwogICAgICAgICAgICBjLnNldFN0YXRlcyhiKTsKCiAgICAgICAgICAgIGZvcihsbGkgaT0wO2k8bjsrK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKG1zayYoMUxMPDxpKSkKICAgICAgICAgICAgICAgICAgICBhW2ldLlg9fmFbaV0uWDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbG9hZFByZShjLGEpOwoKICAgICAgICAgICAgZm9yKGxsaSBpPTA7aTxuOysraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYobXNrJigxTEw8PGkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFbaV0uWD1+YVtpXS5YOwogICAgICAgICAgICAgICAgICAgIGMubnQoYVtpXS5ZKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYobXNrPT0wfHxjLnNjcigpPGJzdC5zY3IoKSkKICAgICAgICAgICAgICAgIGJzdC5zd2FwKGMpOwogICAgICAgIH0KCiAgICAgICAgYi5tZXJnZVdpdGhTdGF0ZXMoYnN0KTsKICAgICAgICAvLyBkYmcoYi5nZXRTdGF0ZXMoKSk7CiAgICB9Cn07CgpuYW1lc3BhY2UgZ3JhcGh7CiAgICB2ZWN0b3I8Ym9vbD4gdmlzOwoKICAgIGxsaSBDb3N0Q2FsY1ByZSh2dWkgYSkKICAgIHsKICAgICAgICBsbGkgY29zdD0wOwogICAgICAgIGlmKChsbGkpYS5zaXplKCk9PTEpCiAgICAgICAgewogICAgICAgICAgICBsbGkgeD0wOwogICAgICAgICAgICB3aGlsZSh4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb3N0Kz0oeCYxKTsKICAgICAgICAgICAgICAgIHgvPTI7CiAgICAgICAgICAgICAgICBjb3N0Kys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGNvc3Q7CiAgICAgICAgfQoKICAgICAgICB1bGxpIGQ9MDsKICAgICAgICB3aGlsZSh0cnVlKQogICAgICAgIHsKICAgICAgICAgICAgYm9vbCBmbD10cnVlOwogICAgICAgICAgICBmb3IoYXV0byB4OmEpCiAgICAgICAgICAgICAgICBpZih4KQogICAgICAgICAgICAgICAgICAgIGZsPWZhbHNlOwoKICAgICAgICAgICAgaWYoZmwpCiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGlmKGQ9PTApCiAgICAgICAgICAgICAgICBkKys7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGQrPWQ7CgogICAgICAgICAgICBjb3N0Kys7CiAgICAgICAgICAgIGZvcihhdXRvICZ4OmEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKHgmZCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjb3N0Kys7CiAgICAgICAgICAgICAgICAgICAgeF49ZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb3N0Kys7CiAgICAgICAgcmV0dXJuIGNvc3Q7CiAgICB9CgogICAgbGxpIGNvc3RDYWxjKHZ1aSBhKXsKICAgICAgICBsbGkgYnN0Q29zdD1JTkY7CiAgICAgICAgY29uc3QgbGxpIG49KGxsaSlhLnNpemUoKTsKICAgICAgICBjb25zdCBsbGkgbGltPSgxTEw8PG4pOwoKICAgICAgICBmb3IobGxpIG1zaz0wO21zazxsaW07Kyttc2spCiAgICAgICAgewoKICAgICAgICAgICAgZm9yKGxsaSBpPTA7aTxuOysraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYobXNrJigxTEw8PGkpKQogICAgICAgICAgICAgICAgICAgIGFbaV09fmFbaV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGxpIGNvc3Q9MDsKCiAgICAgICAgICAgIGNvc3QrPUNvc3RDYWxjUHJlKGEpOwoKICAgICAgICAgICAgZm9yKGxsaSBpPTA7aTxuOysraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYobXNrJigxTEw8PGkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFbaV09fmFbaV07CiAgICAgICAgICAgICAgICAgICAgY29zdCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBic3RDb3N0PW1pbihic3RDb3N0LGNvc3QpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnN0Q29zdDsKICAgIH0KCiAgICBsbGkgZmluZENvc3QxKG1hcDxzdHJpbmcsdWxsaT4gc3QsdnVpICZhKQogICAgewogICAgICAgIHZpIGJpZD17MCwxLDJ9OwogICAgICAgIHBhaXI8bGxpLHZ1aT4gYnN0PXtJTkYsYX07CiAgICAgICAgZG97CiAgICAgICAgICAgIGxsaSBjb3N0PWNvc3RDYWxjKHthW2JpZFswXV1ec3RbcmdbMF1dLGFbYmlkWzFdXV5zdFtyZ1sxXV0sYVtiaWRbMl1dXnN0W3JnWzJdXX0pOwogICAgICAgICAgICBpZihic3QuWD5jb3N0KQogICAgICAgICAgICAgICAgYnN0PXtjb3N0LHthW2JpZFswXV0sYVtiaWRbMV1dLGFbYmlkWzJdXX19OwogICAgICAgIH13aGlsZShzdGQ6Om5leHRfcGVybXV0YXRpb24oYmlkLmJlZ2luKCksYmlkLmVuZCgpKSk7CiAgICAgICAgYT1ic3QuWTsKICAgICAgICByZXR1cm4gYnN0Llg7CiAgICB9CgogICAgbGxpIGZpbmRDb3N0MihtYXA8c3RyaW5nLHVsbGk+IHN0LHZ1aSAmYSkKICAgIHsKICAgICAgICBsbGkgYnN0Q29zdD1JTkY7CiAgICAgICAgZm9yKGxsaSBtc2s9MDttc2s8NDsrK21zaykKICAgICAgICB7CiAgICAgICAgICAgIGxsaSBjb3N0PTA7CgogICAgICAgICAgICBpZihtc2smMSkKICAgICAgICAgICAgICAgIGFbMV1ePWFbMF07CiAgICAgICAgICAgIGlmKG1zayYyKQogICAgICAgICAgICAgICAgYVsyXV49YVswXTsKCiAgICAgICAgICAgIGNvc3QrPWNvc3RDYWxjKHthWzBdXnN0W3JnWzBdXSxhWzFdXnN0W3JnWzFdXSxhWzJdXnN0W3JnWzJdXX0pOwoKICAgICAgICAgICAgaWYobXNrJjEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGFbMV1ePWFbMF07CiAgICAgICAgICAgICAgICBjb3N0Kys7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKG1zayYyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhWzJdXj1hWzBdOwogICAgICAgICAgICAgICAgY29zdCsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJzdENvc3Q9bWluKGJzdENvc3QsY29zdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBic3RDb3N0OwogICAgfQoKICAgIGxsaSBmaW5kQ29zdDUobWFwPHN0cmluZyx1bGxpPiBzdCx2dWkgJmEpCiAgICB7CiAgICAgICAgbGxpIGJzdENvc3Q9SU5GOwogICAgICAgIGNvbnN0IGxsaSBuPShsbGkpYS5zaXplKCk7CiAgICAgICAgZm9yKGxsaSBpPTA7aTxuOysraSkKICAgICAgICBmb3IobGxpIGo9MDtqPG47KytqKQogICAgICAgIHsKICAgICAgICAgICAgaWYoaT09aikKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBmb3IobGxpIG1zaz0wO21zazw0OysrbXNrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBsbGkgY29zdD0wOwoKICAgICAgICAgICAgICAgIGlmKG1zayYxKSAgICAgICAgICAgIGFbaV1ePWFbMy1pLWpdOwogICAgICAgICAgICAgICAgaWYobXNrJjIpICAgICAgICAgICAgYVtqXV49YVszLWktal07CgogICAgICAgICAgICAgICAgY29zdCs9Y29zdENhbGMoe2FbaV1ec3RbcmdbMV1dLGFbal1ec3RbcmdbMl1dfSk7CgogICAgICAgICAgICAgICAgaWYobXNrJjEpeyAgYVtpXV49YVszLWktal07ICAgICBjb3N0Kys7fQogICAgICAgICAgICAgICAgaWYobXNrJjIpeyAgYVtqXV49YVszLWktal07ICAgICBjb3N0Kys7fQoKICAgICAgICAgICAgICAgIGJzdENvc3Q9bWluKGJzdENvc3QsY29zdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJzdENvc3Q7CiAgICB9CgogICAgbGxpIGZpbmRDb3N0KGNvbnN0IG1hcDxzdHJpbmcsdWxsaT4gJnN0LHZ1aSAmYSxsbGkgZmwpCiAgICB7CiAgICAgICAgaWYoZmw9PTEpCiAgICAgICAgICAgIHJldHVybiBmaW5kQ29zdDEoc3QsYSk7CiAgICAgICAgaWYoZmw9PTIpCiAgICAgICAgICAgIHJldHVybiBmaW5kQ29zdDIoc3QsYSk7CiAgICAgICAgaWYoZmw9PTUpCiAgICAgICAgICAgIHJldHVybiBmaW5kQ29zdDUoc3QsYSk7CiAgICAgICAgYXNzZXJ0KGZhbHNlKTsKICAgIH0KCiAgICB2b2lkIGxvYWQxKG1hcDxzdHJpbmcsdWxsaT4gJnN0LHZ1aSBhLGxsaSBmc3RwbGFjZSkKICAgIHsKICAgICAgICBjb25zdCBpbnQgbj0zOwogICAgICAgIGZvcihpbnQgaT1mc3RwbGFjZTtpPG47KytpKQogICAgICAgICAgICBzdFtyZ1tpXV09YVtpXTsKICAgIH0KCiAgICB2b2lkIGxvYWQobWFwPHN0cmluZyx1bGxpPiAmc3QsdnVpIGEsbGxpIGZsKQogICAgewogICAgICAgIGlmKGZsPT0xfHxmbD09MikKICAgICAgICB7CiAgICAgICAgICAgIGxvYWQxKHN0LGEsMCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmKGZsPT01KQogICAgICAgIHsKICAgICAgICAgICAgbG9hZDEoc3QsYSwxKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgYXNzZXJ0KGZhbHNlKTsKICAgIH0KCiAgICBsbGkgZ2V0TmV4dChjb25zdCBtYXA8c3RyaW5nLHVsbGk+ICZzdCx2ZWN0b3I8dnVpPiAmYSxsbGkgZmwpCiAgICB7CiAgICAgICAgaWkgbnh0PW1wKDAsSU5GKTsKICAgICAgICBjb25zdCBsbGkgbj0obGxpKWEuc2l6ZSgpOwogICAgICAgIGZvcihsbGkgaT0wO2k8bjsrK2kpCiAgICAgICAgewogICAgICAgICAgICBpZih2aXNbaV0pCiAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIGxsaSBjb3N0PWZpbmRDb3N0KHN0LGFbaV0sZmwpOwogICAgICAgICAgICBpZihjb3N0PG54dC5ZKQogICAgICAgICAgICAgICAgbnh0PW1wKGksY29zdCk7CiAgICAgICAgfQoKICAgICAgICB2aXNbbnh0LlhdPXRydWU7CiAgICAgICAgcmV0dXJuIG54dC5YOwogICAgfQoKICAgIC8vIGlpIGdldE5leHQycGFpcihjb25zdCBtYXA8c3RyaW5nLHVsbGk+ICZzdCx2ZWN0b3I8dnVpPiAmYSxsbGkgZmwpCiAgICAvLyB7CiAgICAvLyAgICAgaWkgbnh0Mj1tcCgwLDApOwogICAgLy8gICAgIGxsaSBic3RDb3N0PUlORjsKICAgIC8vICAgICBjb25zdCBsbGkgbj0obGxpKWEuc2l6ZSgpOwogICAgLy8gICAgIGZvcihsbGkgaT0wO2k8bjsrK2kpCiAgICAvLyAgICAgZm9yKGxsaSBqPTA7ajxuOysraikKICAgIC8vICAgICB7CiAgICAvLyAgICAgICAgIGlmKHZpc1tpXXx8dmlzW2pdfHxpPT1qKQogICAgLy8gICAgICAgICAgICAgY29udGludWU7CgogICAgLy8gICAgICAgICBsbGkgY29zdD1maW5kQ29zdDJwYWlyKHN0LGFbaV0sYVtqXSxmbCk7CiAgICAvLyAgICAgICAgIGlmKGNvc3Q8YnN0Q29zdCkKICAgIC8vICAgICAgICAgewogICAgLy8gICAgICAgICAgICAgbnh0Mj1tcChpLGopOwogICAgLy8gICAgICAgICAgICAgYnN0Q29zdD1jb3N0OwogICAgLy8gICAgICAgICB9CiAgICAvLyAgICAgfQoKICAgIC8vICAgICB2aXNbbnh0Mi5YXT10cnVlOwogICAgLy8gICAgIHZpc1tueHQyLlldPXRydWU7CiAgICAvLyAgICAgcmV0dXJuIG54dDI7CiAgICAvLyB9CgogICAgdm9pZCBzb2x2ZSh2ZWN0b3I8dnVpPiBhLHZlY3Rvcjx2dWk+ICZhbnMsbGxpIGZsKQogICAgewogICAgICAgIGNvbnN0IGxsaSBuPShsbGkpYS5zaXplKCk7CiAgICAgICAgbGxpIGNudD0wOwogICAgICAgIHZpcy5jbGVhcigpO3Zpcy5yZXNpemUobixmYWxzZSk7CiAgICAgICAgYW5zLmNsZWFyKCk7CiAgICAgICAgbWFwPHN0cmluZyx1bGxpPiBzdDsKICAgICAgICB3aGlsZShjbnQ8bikKICAgICAgICB7CiAgICAgICAgICAgIGFucy5wYihhW2dldE5leHQoc3QsYSxmbCldKTsKICAgICAgICAgICAgbG9hZChzdCxhbnMuYmFjaygpLGZsKTsKICAgICAgICAgICAgY250Kys7CiAgICAgICAgfQogICAgfQoKICAgIC8vIHZvaWQgc29sdmUyKHZlY3Rvcjx2dWk+IGEsdmVjdG9yPHZ1aT4gJmFucyxsbGkgZmwpCiAgICAvLyB7CiAgICAvLyAgICAgY29uc3QgbGxpIG49KGxsaSlhLnNpemUoKTsKICAgIC8vICAgICBsbGkgY250PTA7CiAgICAvLyAgICAgdmlzLmNsZWFyKCk7dmlzLnJlc2l6ZShuLGZhbHNlKTsKICAgIC8vICAgICBhbnMuY2xlYXIoKTsKICAgIC8vICAgICBtYXA8c3RyaW5nLHVsbGk+IHN0OwogICAgLy8gICAgIHdoaWxlKGNudDxuKQogICAgLy8gICAgIHsKICAgIC8vICAgICAgICAgaWkgbnh0Mj1nZXROZXh0MnBhaXIoc3QsYSxmbCk7CiAgICAvLyAgICAgICAgIGFucy5wYihhW254dDIuWF0pOwogICAgLy8gICAgICAgICBhbnMucGIoYVtueHQyLlldKTsKICAgIC8vICAgICAgICAgbG9hZDJwYWlyKHN0LHthW254dDIuWF0sYVtueHQyLlldfSxmbCk7CiAgICAvLyAgICAgICAgIGNudCs9MjsKICAgIC8vICAgICB9CiAgICAvLyB9Cn07CgpuYW1lc3BhY2UgbWF0Y2hpbmd7CiAgICAvLyBSZWYgLSBodHRwczovL2cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLmIuY29tL0FzaGlzaGd1cDEvQ29tcGV0aXRpdmUtQ29kaW5nL2Jsb2IvbWFzdGVyL01pbiUyMENvc3QlMjBNYXglMjBGbG93JTIwLSUyMERpamtzdHJhLmNwcAoKICAgIC8vV29ya3MgZm9yIG5lZ2F0aXZlIGNvc3RzLCBidXQgZG9lcyBub3Qgd29yayBmb3IgbmVnYXRpdmUgY3ljbGVzCiAgICAvL0NvbXBsZXhpdHk6IE8obWluKEVeMiAqViBsb2cgViwgRSBsb2dWICogZmxvdykpCgogICAgc3RydWN0IGVkZ2UKICAgIHsKICAgICAgICBpbnQgdG8sIGZsb3csIGNhcCwgY29zdCwgcmV2OwogICAgfTsKCiAgICBzdHJ1Y3QgTWluQ29zdE1heEZsb3cKICAgIHsKICAgICAgICBpbnQgbm9kZXM7CiAgICAgICAgdmVjdG9yPGludD4gcHJpbywgY3VyZmxvdywgcHJldmVkZ2UsIHByZXZub2RlLCBxLCBwb3Q7CiAgICAgICAgdmVjdG9yPGJvb2w+IGlucXVldWU7CiAgICAgICAgdmVjdG9yPHZlY3RvcjxlZGdlPiA+IGdyYXBoOwogICAgICAgIE1pbkNvc3RNYXhGbG93KCkge30KCiAgICAgICAgTWluQ29zdE1heEZsb3coaW50IG4pOiBub2RlcyhuKSwgcHJpbyhuLCAwKSwgY3VyZmxvdyhuLCAwKSwKICAgICAgICBwcmV2ZWRnZShuLCAwKSwgcHJldm5vZGUobiwgMCksIHEobiwgMCksIHBvdChuLCAwKSwgaW5xdWV1ZShuLCAwKSwgZ3JhcGgobikge30KCiAgICAgICAgdm9pZCBhZGRFZGdlKGludCBzb3VyY2UsIGludCB0bywgaW50IGNhcGFjaXR5LCBpbnQgY29zdCkKICAgICAgICB7CiAgICAgICAgICAgIGVkZ2UgYSA9IHt0bywgMCwgY2FwYWNpdHksIGNvc3QsIChpbnQpZ3JhcGhbdG9dLnNpemUoKX07CiAgICAgICAgICAgIGVkZ2UgYiA9IHtzb3VyY2UsIDAsIDAsIC1jb3N0LCAoaW50KWdyYXBoW3NvdXJjZV0uc2l6ZSgpfTsKICAgICAgICAgICAgZ3JhcGhbc291cmNlXS5wdXNoX2JhY2soYSk7CiAgICAgICAgICAgIGdyYXBoW3RvXS5wdXNoX2JhY2soYik7CiAgICAgICAgfQoKICAgICAgICB2b2lkIGJlbGxtYW5fZm9yZChpbnQgc291cmNlLCB2ZWN0b3I8aW50PiAmZGlzdCkKICAgICAgICB7CiAgICAgICAgICAgIGZpbGwoZGlzdC5iZWdpbigpLCBkaXN0LmVuZCgpLCBJTlRfTUFYKTsKICAgICAgICAgICAgZGlzdFtzb3VyY2VdID0gMDsKICAgICAgICAgICAgaW50IHF0PTA7CiAgICAgICAgICAgIHFbcXQrK10gPSBzb3VyY2U7CiAgICAgICAgICAgIGZvcihpbnQgcWg9MDsocWgtcXQpJW5vZGVzIT0wO3FoKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCB1ID0gcVtxaCVub2Rlc107CiAgICAgICAgICAgICAgICBpbnF1ZXVlW3VdID0gZmFsc2U7CiAgICAgICAgICAgICAgICBmb3IoYXV0byAmZSA6IGdyYXBoW3VdKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmKGUuZmxvdyA+PSBlLmNhcCkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgaW50IHYgPSBlLnRvOwogICAgICAgICAgICAgICAgICAgIGludCBuZXdEaXN0ID0gZGlzdFt1XSArIGUuY29zdDsKICAgICAgICAgICAgICAgICAgICBpZihkaXN0W3ZdID4gbmV3RGlzdCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3Rbdl0gPSBuZXdEaXN0OwogICAgICAgICAgICAgICAgICAgICAgICBpZighaW5xdWV1ZVt2XSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5xdWV1ZVt2XSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxW3F0KysgJSBub2Rlc10gPSB2OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwYWlyPGludCwgaW50PiBtaW5Db3N0RmxvdyhpbnQgc291cmNlLCBpbnQgZGVzdCwgaW50IG1heGZsb3cpCiAgICAgICAgewogICAgICAgICAgICBiZWxsbWFuX2ZvcmQoc291cmNlLCBwb3QpOwogICAgICAgICAgICBpbnQgZmxvdyA9IDA7CiAgICAgICAgICAgIGludCBmbG93X2Nvc3QgPSAwOwogICAgICAgICAgICB3aGlsZShmbG93IDwgbWF4ZmxvdykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcHJpb3JpdHlfcXVldWU8cGFpcjxpbnQsIGludD4sIHZlY3RvcjxwYWlyPGludCwgaW50PiA+LCBncmVhdGVyPHBhaXI8aW50LCBpbnQ+ID4gPiBxOwogICAgICAgICAgICAgICAgcS5wdXNoKHswLCBzb3VyY2V9KTsKICAgICAgICAgICAgICAgIGZpbGwocHJpby5iZWdpbigpLCBwcmlvLmVuZCgpLCBJTlRfTUFYKTsKICAgICAgICAgICAgICAgIHByaW9bc291cmNlXSA9IDA7CiAgICAgICAgICAgICAgICBjdXJmbG93W3NvdXJjZV0gPSBJTlRfTUFYOwogICAgICAgICAgICAgICAgd2hpbGUoIXEuZW1wdHkoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgZCA9IHEudG9wKCkuZmlyc3Q7CiAgICAgICAgICAgICAgICAgICAgaW50IHUgPSBxLnRvcCgpLnNlY29uZDsKICAgICAgICAgICAgICAgICAgICBxLnBvcCgpOwogICAgICAgICAgICAgICAgICAgIGlmKGQgIT0gcHJpb1t1XSkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgZm9yKGludCBpPTA7aTxncmFwaFt1XS5zaXplKCk7aSsrKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWRnZSAmZT1ncmFwaFt1XVtpXTsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IHYgPSBlLnRvOwogICAgICAgICAgICAgICAgICAgICAgICBpZihlLmZsb3cgPj0gZS5jYXApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5ld1ByaW8gPSBwcmlvW3VdICsgZS5jb3N0ICsgcG90W3VdIC0gcG90W3ZdOwogICAgICAgICAgICAgICAgICAgICAgICBpZihwcmlvW3ZdID4gbmV3UHJpbykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb1t2XSA9IG5ld1ByaW87CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxLnB1c2goe25ld1ByaW8sIHZ9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZub2RlW3ZdID0gdTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZlZGdlW3ZdID0gaTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cmZsb3dbdl0gPSBtaW4oY3VyZmxvd1t1XSwgZS5jYXAgLSBlLmZsb3cpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYocHJpb1tkZXN0XSA9PSBJTlRfTUFYKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZm9yKGludCBpPTA7aTxub2RlcztpKyspCiAgICAgICAgICAgICAgICAgICAgcG90W2ldKz1wcmlvW2ldOwogICAgICAgICAgICAgICAgaW50IGRmID0gbWluKGN1cmZsb3dbZGVzdF0sIG1heGZsb3cgLSBmbG93KTsKICAgICAgICAgICAgICAgIGZsb3cgKz0gZGY7CiAgICAgICAgICAgICAgICBmb3IoaW50IHY9ZGVzdDt2IT1zb3VyY2U7dj1wcmV2bm9kZVt2XSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBlZGdlICZlID0gZ3JhcGhbcHJldm5vZGVbdl1dW3ByZXZlZGdlW3ZdXTsKICAgICAgICAgICAgICAgICAgICBlLmZsb3cgKz0gZGY7CiAgICAgICAgICAgICAgICAgICAgZ3JhcGhbdl1bZS5yZXZdLmZsb3cgLT0gZGY7CiAgICAgICAgICAgICAgICAgICAgZmxvd19jb3N0ICs9IGRmICogZS5jb3N0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB7ZmxvdywgZmxvd19jb3N0fTsKICAgICAgICB9CiAgICB9OwoKICAgIC8vUHJvYmxlbSAxOiBodHRwczovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLmouY29tL3Byb2JsZW1zL0dSRUVELwogICAgLy9Tb2x1dGlvbiAxOiBodHRwOi8vcC4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4ucC5maS9PRFJrCgogICAgLy9Qcm9ibGVtIDIgKERvdWJsZSBDb3N0KTogaHR0cHM6Ly9jLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5zLmNvbS9jb250ZXN0LzI3Ny9wcm9ibGVtL0UKICAgIC8vU29sdXRpb24gMjogaHR0cHM6Ly9jLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5zLmNvbS9jb250ZXN0LzI3Ny9zdWJtaXNzaW9uLzQzMTgwODQ1CgogICAgbGxpIGFycmFuZ2UoY29uc3QgdnVpICZhLHZ1aSAmYikKICAgIHsKICAgICAgICBjb25zdCBsbGkgbiA9IDM7CiAgICAgICAgTWluQ29zdE1heEZsb3cgYW5zKDIqbisyKTsKICAgICAgICBsbGkgaSxqOwogICAgICAgIHJlcEEoaSwxLG4pCiAgICAgICAgewogICAgICAgICAgICBhbnMuYWRkRWRnZSgwLGksMSwwKTsKICAgICAgICAgICAgYW5zLmFkZEVkZ2UobitpLDIqbisxLDEsMCk7CiAgICAgICAgfQoKICAgICAgICByZXBBKGksMSxuKQogICAgICAgIHJlcEEoaixuKzEsMipuKQogICAgICAgICAgICBhbnMuYWRkRWRnZShpLGosMSxsb2FkOjpiY250KGFbaS0xXV5iW2otbi0xXSkpOwoKICAgICAgICBsbGkgY29zdD1hbnMubWluQ29zdEZsb3coMCwyKm4rMSwzKS5ZOwoKICAgICAgICB2dWkgYzsKICAgICAgICByZXBBKGksMSxuKQogICAgICAgIHsKICAgICAgICAgICAgZm9yKGF1dG8geDphbnMuZ3JhcGhbaV0pCiAgICAgICAgICAgICAgICBpZih4LmZsb3c+MCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjLnBiKGJbeC50by1uLTFdKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGIuc3dhcChjKTsKICAgICAgICByZXR1cm4gY29zdDsKICAgICAgICAvLyBzb3J0KGIuYmVnaW4oKSxiLmVuZCgpKTsKICAgICAgICAvLyBzb3J0KGMuYmVnaW4oKSxjLmVuZCgpKTsKICAgICAgICAvLyBhc3NlcnQoYj09Yyk7CiAgICAgICAgLy8gZGJnKGIsYyk7CiAgICB9Cn07CgpuYW1lc3BhY2UgdHlwZTV7CiAgICB1bGxpIGs7CgogICAgYm9vbCBjaGsodmVjdG9yPHZ1aT4gYSkKICAgIHsKICAgICAgICBmb3IoYXV0byB2OmEpCiAgICAgICAgewogICAgICAgICAgICB1bGxpIGNudD0wOwogICAgICAgICAgICBmb3IoYXV0byB4OnYpCiAgICAgICAgICAgICAgICBjbnQrPXg7CiAgICAgICAgICAgIGlmKGNudCE9aykKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgdm9pZCBzaHVmZmxlKHZlY3Rvcjx2dWk+ICZhKQogICAgewogICAgICAgIHNodWZmbGUoYS5iZWdpbigpLGEuZW5kKCksIHJuZyk7CiAgICAgICAgZm9yKGF1dG8gJmM6YSkKICAgICAgICAgICAgc2h1ZmZsZShjLmJlZ2luKCksYy5lbmQoKSwgcm5nKTsKICAgICAgICBjb25zdCBsbGkgbj0obGxpKWEuc2l6ZSgpOwogICAgICAgIGZvcihsbGkgaT0xO2k8bjsrK2kpCiAgICAgICAgICAgIG1hdGNoaW5nOjphcnJhbmdlKGFbaS0xXSxhW2ldKTsKICAgIH0KCiAgICB2b2lkIGxvYWR2ZWN0b3Ioc29sbiAmYW5zLHZ1aSBhKQogICAgewogICAgICAgIHNvbG4gYnN0LGM7CiAgICAgICAgaW50IGNudD0wOwogICAgICAgIGNvbnN0IGxsaSBuPShsbGkpYS5zaXplKCk7CgogICAgICAgIGZvcihpbnQgaT0wO2k8bjsrK2kpCiAgICAgICAgZm9yKGludCBqPTA7ajxuOysraikKICAgICAgICB7CiAgICAgICAgICAgIGlmKGk9PWopCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgc29sbiBjOwogICAgICAgICAgICBjLnNldFN0YXRlcyhhbnMpOwogICAgICAgICAgICBsb2FkOjpsb2FkKGMse3thW2ldLHJnWzFdfSx7YVtqXSxyZ1syXX19KTsKICAgICAgICAgICAgaWYoKGk9PTAmJmo9PTEpfHxjLnNjcigpPGJzdC5zY3IoKSkKICAgICAgICAgICAgICAgIGJzdC5zd2FwKGMpOwogICAgICAgIH0KCiAgICAgICAgYW5zLm1lcmdlV2l0aFN0YXRlcyhic3QpOwoKICAgICAgICBhbnMucHJ0KCJzdWIgIityZ1swXSsiICIrcmdbMV0pOwogICAgICAgIGFucy5wcnQoInN1YiAiK3JnWzBdKyIgIityZ1syXSk7CiAgICAgICAgYW5zLnBydCgiYWRkICIrcmdbMF0rIiAiK3JnWzFdKTsKICAgICAgICBhbnMucHJ0KCJhZGQgIityZ1swXSsiICIrcmdbMl0pOwogICAgfQoKICAgIHNvbG4gcnVuT25jZSh2ZWN0b3I8dnVpPiBhKQogICAgewogICAgICAgIHNvbG4gYW5zOwoKICAgICAgICBsb2FkOjpsb2FkKGFucyx7e2sscmdbMF19fSk7CiAgICAgICAgZm9yKGF1dG8geDphKQogICAgICAgICAgICBsb2FkdmVjdG9yKGFucyx4KTsKCiAgICAgICAgcmV0dXJuIGFuczsKICAgIH0KCiAgICBzb2xuIHNvbHZlKHZlY3Rvcjx2dWk+IGEpCiAgICB7CiAgICAgICAgc29sbiBhbnM7CiAgICAgICAgaz1hWzBdWzBdK2FbMF1bMV0rYVswXVsyXTsKCiAgICAgICAgaWYoIWNoayhhKSkKICAgICAgICAgICAgcmV0dXJuIGFuczsKICAgICAgICBncmFwaDo6c29sdmUoYSxhLDUpOwogICAgICAgIGFucy5tYXgocnVuT25jZShhKSk7CgogICAgICAgIC8vIGZvcihpbnQgaT0wO2k8aXRuOysraSkKICAgICAgICAvLyB7CiAgICAgICAgICAgIC8vIGFucy5tYXgocnVuT25jZShhKSk7CiAgICAgICAgLy8gICAgIHNodWZmbGUoYSk7CiAgICAgICAgLy8gfQoKICAgICAgICBkYmcoInR5cGU1IDogIixhbnMuc2NyKCkpOwogICAgICAgIHJldHVybiBhbnM7CiAgICB9Cn07CgpuYW1lc3BhY2UgdHlwZTN7CgogICAgYm9vbCBjaGsodmVjdG9yPHZ1aT4gYSkKICAgIHsKICAgICAgICBjb25zdCBpbnQgbj0oaW50KWEuc2l6ZSgpLGJhdD04OwogICAgICAgIHVsbGkgZD0wOwogICAgICAgIGZvcihpbnQgaT0wO2k8bjsrK2kpCiAgICAgICAgewogICAgICAgICAgICBpZihpJWJhdD09MCkKICAgICAgICAgICAgICAgIGQ9YVtpXVsxXS1hW2ldWzBdOwogICAgICAgICAgICBpZihhW2ldWzFdLWFbaV1bMF0hPWR8fGFbaV1bMl0tYVtpXVsxXSE9ZCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgdm9pZCBzaHVmZmxlKHZlY3Rvcjx2dWk+ICZhKQogICAgewogICAgICAgIGNvbnN0IGludCBuPShpbnQpYS5zaXplKCksYmF0PTg7CiAgICAgICAgdmVjdG9yPHZ1aT4gYixjOwoKICAgICAgICBmb3IoaW50IGk9MDtpPG47KytpKQogICAgICAgIHsKICAgICAgICAgICAgYy5wYihhW2ldKTsKICAgICAgICAgICAgaWYoaT09bi0xfHwoaSsxKSViYXQ9PTApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNodWZmbGUoYy5iZWdpbigpLGMuZW5kKCksIHJuZyk7CiAgICAgICAgICAgICAgICBmb3IoYXV0byB4OmMpCiAgICAgICAgICAgICAgICAgICAgYi5wYih4KTsKICAgICAgICAgICAgICAgIGMuY2xlYXIoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgYS5zd2FwKGIpOwogICAgfQoKICAgIHNvbG4gcnVuT25jZSh2ZWN0b3I8dnVpPiBhKQogICAgewogICAgICAgIHNvbG4gYW5zOwogICAgICAgIGNvbnN0IGludCBuPShpbnQpYS5zaXplKCksYmF0PTg7CiAgICAgICAgdWxsaSBkPTA7CiAgICAgICAgZm9yKGludCBpPTA7aTxuO2krPTIpCiAgICAgICAgewogICAgICAgICAgICBhdXRvIHg9YVtpXSx5PWFbaSsxXTsKICAgICAgICAgICAgaWYoaSViYXQ9PTApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGQ9eFsxXS14WzBdOwogICAgICAgICAgICAgICAgbG9hZDo6bG9hZChhbnMse3t4WzBdLHJnWzFdfSx7ZCxyZ1swXX0se3lbMF0scmdbMl19fSk7CiAgICAgICAgICAgICAgICAvLyBkLGExLGEyLDA7CgogICAgICAgICAgICAgICAgYW5zLm1vdihyZ3ZbM10scmdbMF0pOwogICAgICAgICAgICAgICAgYW5zLmFkZChyZ3ZbM10scmd2WzNdKTsgLy9kLGExLGEyLDJkCgogICAgICAgICAgICAgICAgYW5zLmFkZChyZ1swXSxyZ1sxXSk7CiAgICAgICAgICAgICAgICBhbnMuYWRkKHJndlszXSxyZ1sxXSk7Ly9hMStkLGExLGEyLGExKzJkCiAgICAgICAgICAgICAgICBhbnMuc3ViKHJnWzBdLHJnWzFdKTsKICAgICAgICAgICAgICAgIGFucy5zdWIocmd2WzNdLHJnWzFdKTsvL2QsYTEsYTIsMmQKCiAgICAgICAgICAgICAgICBhbnMuYWRkKHJnWzBdLHJnWzJdKTsKICAgICAgICAgICAgICAgIGFucy5hZGQocmd2WzNdLHJnWzJdKTsvL2EyK2QsYTEsYTIsYTIrMmQKICAgICAgICAgICAgICAgIGFucy5zdWIocmdbMF0scmdbMl0pOwogICAgICAgICAgICAgICAgYW5zLnN1YihyZ3ZbM10scmdbMl0pOy8vZCxhMSxhMiwyZAoKICAgICAgICAgICAgICAgIGFucy5yc3Qocmd2WzNdKTsvL2ExLGQsYTIsMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vICosZCwqLDAKICAgICAgICAgICAgICAgIGxvYWQ6OmxvYWQoYW5zLHt7eFswXSxyZ1sxXX0se3lbMF0scmdbMl19fSk7CiAgICAgICAgICAgICAgICAvLyBhMSxkLGEyLDA7CgogICAgICAgICAgICAgICAgYW5zLm1vdihyZ3ZbM10scmdbMF0pOwogICAgICAgICAgICAgICAgYW5zLmFkZChyZ3ZbM10scmd2WzNdKTsgLy9kLGExLGEyLDJkCgogICAgICAgICAgICAgICAgYW5zLmFkZChyZ1swXSxyZ1sxXSk7CiAgICAgICAgICAgICAgICBhbnMuYWRkKHJndlszXSxyZ1sxXSk7Ly9hMStkLGExLGEyLGExKzJkCiAgICAgICAgICAgICAgICBhbnMuc3ViKHJnWzBdLHJnWzFdKTsKICAgICAgICAgICAgICAgIGFucy5zdWIocmd2WzNdLHJnWzFdKTsvL2QsYTEsYTIsMmQKCiAgICAgICAgICAgICAgICBhbnMuYWRkKHJnWzBdLHJnWzJdKTsKICAgICAgICAgICAgICAgIGFucy5hZGQocmd2WzNdLHJnWzJdKTsvL2EyK2QsYTEsYTIsYTIrMmQKICAgICAgICAgICAgICAgIGFucy5zdWIocmdbMF0scmdbMl0pOwogICAgICAgICAgICAgICAgYW5zLnN1YihyZ3ZbM10scmdbMl0pOy8vZCxhMSxhMiwyZAogICAgICAgICAgICAgICAgYW5zLnJzdChyZ3ZbM10pOy8vZCxhMSxhMiwwOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYW5zOwogICAgfQoKICAgIHNvbG4gc29sdmUodmVjdG9yPHZ1aT4gYSkKICAgIHsKICAgICAgICBzb2xuIGFuczsKICAgICAgICBpZighY2hrKGEpKQogICAgICAgICAgICByZXR1cm4gYW5zOwoKICAgICAgICBmb3IoaW50IGk9MDtpPGl0bjsrK2kpCiAgICAgICAgewogICAgICAgICAgICBhbnMubWF4KHJ1bk9uY2UoYSkpOwogICAgICAgICAgICBzaHVmZmxlKGEpOwogICAgICAgIH0KCiAgICAgICAgZGJnKCJ0eXBlMyA6ICIsYW5zLnNjcigpKTsKICAgICAgICByZXR1cm4gYW5zOwogICAgfQp9OwoKbmFtZXNwYWNlIHR5cGUyewoKICAgIGxsaSBiY250KHVsbGkgeCkKICAgIHsKICAgICAgICBsbGkgY250PTA7CiAgICAgICAgd2hpbGUoeCkKICAgICAgICB7CiAgICAgICAgICAgIGlmKHgmMSkKICAgICAgICAgICAgICAgIGNudCsrOwogICAgICAgICAgICB4Lz0yOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY250OwogICAgfQoKICAgIGJvb2wgY2hrKHZlY3Rvcjx2dWk+IGEpCiAgICB7CiAgICAgICAgZm9yKGF1dG8geDphKQogICAgICAgIHsKICAgICAgICAgICAgaWYoYmNudCh4WzBdXnhbMV0pPjJ8fGJjbnQoeFswXV54WzJdKT4yKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICB2b2lkIGxvYWR2ZWN0b3Ioc29sbiAmYW5zLHZ1aSBhKQogICAgewogICAgICAgIGFucy5yc3QocmdbMF0pO2Fucy5yc3QocmdbMV0pO2Fucy5yc3QocmdbMl0pOwogICAgICAgIHNvbG4gYnN0OwoKICAgICAgICBmb3IobGxpIG1zaz0wO21zazw0OysrbXNrKQogICAgICAgIHsKICAgICAgICAgICAgc29sbiBjOwogICAgICAgICAgICAvLyBjLnNldFN0YXRlcyhhbnMpOwogICAgICAgICAgICBpZihtc2smMSkKICAgICAgICAgICAgICAgIGFbMV1ePWFbMF07CiAgICAgICAgICAgIGlmKG1zayYyKQogICAgICAgICAgICAgICAgYVsyXV49YVswXTsKCiAgICAgICAgICAgIGxvYWQ6OmxvYWQoYyx7e2FbMF0scmdbMF19LHthWzFdLHJnWzFdfSx7YVsyXSxyZ1syXX19KTsKCiAgICAgICAgICAgIGlmKG1zayYxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhWzFdXj1hWzBdOwogICAgICAgICAgICAgICAgYy54cihyZ1sxXSxyZ1swXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKG1zayYyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhWzJdXj1hWzBdOwogICAgICAgICAgICAgICAgYy54cihyZ1syXSxyZ1swXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKG1zaykKICAgICAgICAgICAgICAgIGJzdC5tYXgoYyk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGJzdC5zd2FwKGMpOwogICAgICAgIH0KCiAgICAgICAgYW5zLm1lcmdlV2l0aFN0YXRlcyhic3QpOwogICAgICAgIC8vIGRiZyhhLGFucy5nZXRTdGF0ZXMoKSk7CiAgICB9CgogICAgc29sbiBydW5Tb3J0ZWQodmVjdG9yPHZ1aT4gYSkKICAgIHsKICAgICAgICBmb3IoYXV0byAmeDphKQogICAgICAgIHsKICAgICAgICAgICAgaWYoKHhbMV1eeFswXSk8KHhbMl1eeFswXSkpCiAgICAgICAgICAgICAgICBzd2FwKHhbMV0seFswXSk7CiAgICAgICAgfQoKICAgICAgICBzb3J0KGEuYmVnaW4oKSxhLmVuZCgpLFsmXShjb25zdCB2dWkgJmEsY29uc3QgdnVpICZiKXsKICAgICAgICAgICAgaWkgeD17YVsxXV5hWzBdLGFbMl1eYVswXX07CiAgICAgICAgICAgIGlpIHk9e2JbMV1eYlswXSxiWzJdXmJbMF19OwogICAgICAgICAgICByZXR1cm4geDx5OwogICAgICAgIH0pOwoKICAgICAgICBzdHJpbmcgcz1yZ1sxXTsKCiAgICAgICAgc29sbiBhbnM7CiAgICAgICAgYW5zLmluYyhzKTsKCiAgICAgICAgZm9yKGF1dG8geDphKQogICAgICAgIHsKICAgICAgICAgICAgd2hpbGUoYW5zLmJ0KHMpJiYoYW5zLmJ0KHMpJih4WzFdXnhbMF0pKT09MCkKICAgICAgICAgICAgICAgIGFucy5hZGQocyxzKTsKCiAgICAgICAgICAgIGxvYWQ6OmxvYWQoYW5zLHt7eFswXSxyZ1swXX0se3hbMV1eeFswXSxyZ1sxXX0se3hbMl1eeFswXSxyZ1syXX19KTsKICAgICAgICAgICAgYW5zLnhyKHJnWzJdLHJnWzBdKTsKICAgICAgICAgICAgYW5zLnhyKHJnWzFdLHJnWzBdKTsKCiAgICAgICAgICAgIGFucy54cihyZ1syXSxyZ1swXSk7CiAgICAgICAgICAgIGFucy54cihyZ1sxXSxyZ1swXSk7CiAgICAgICAgfQoKICAgICAgICBkYmcoInR5cGUyc3AgOiAiLGFucy5zY3IoKSk7CiAgICAgICAgcmV0dXJuIGFuczsKICAgIH0KCiAgICBzb2xuIHJ1bk9uY2UodmVjdG9yPHZ1aT4gYSkKICAgIHsKICAgICAgICBzb2xuIGFuczsKICAgICAgICBmb3IoYXV0byB4OmEpCiAgICAgICAgICAgIGxvYWR2ZWN0b3IoYW5zLHgpOwogICAgICAgIHJldHVybiBhbnM7CiAgICB9CgogICAgc29sbiBzb2x2ZSh2ZWN0b3I8dnVpPiBhKQogICAgewogICAgICAgIHNvbG4gYW5zOwogICAgICAgIGFucy5tYXgocnVuU29ydGVkKGEpKTsKICAgICAgICBncmFwaDo6c29sdmUoYSxhLDIpOwogICAgICAgIGFucy5tYXgocnVuT25jZShhKSk7CiAgICAgICAgZGJnKCJ0eXBlMiA6ICIsYW5zLnNjcigpKTsKICAgICAgICByZXR1cm4gYW5zOwogICAgfQp9OwoKbmFtZXNwYWNlIHR5cGUxewogICAgdm9pZCBsb2FkKHNvbG4gJmFucyx2dWkgYSkKICAgIHsKICAgICAgICAvLyBkYmcoYSk7CiAgICAgICAgbG9hZDo6bG9hZChhbnMse3thWzBdLHJnWzBdfSx7YVsxXSxyZ1sxXX0se2FbMl0scmdbMl19fSk7CiAgICB9CgogICAgc29sbiBydW5PbmNlKHZlY3Rvcjx2dWk+IGEpCiAgICB7CiAgICAgICAgc29sbiBhbnM7CiAgICAgICAgZm9yKGF1dG8geDphKQogICAgICAgICAgICBsb2FkKGFucyx4KTsKICAgICAgICByZXR1cm4gYW5zOwogICAgfQoKICAgIHZvaWQgc2h1ZmZsZSh2ZWN0b3I8dnVpPiAmYSkKICAgIHsKICAgICAgICBzaHVmZmxlKGEuYmVnaW4oKSxhLmVuZCgpLCBybmcpOwogICAgICAgIGZvcihhdXRvICZjOmEpCiAgICAgICAgICAgIHNodWZmbGUoYy5iZWdpbigpLGMuZW5kKCksIHJuZyk7CiAgICAgICAgY29uc3QgbGxpIG49KGxsaSlhLnNpemUoKTsKICAgICAgICBmb3IobGxpIGk9MTtpPG47KytpKQogICAgICAgICAgICBtYXRjaGluZzo6YXJyYW5nZShhW2ktMV0sYVtpXSk7CiAgICB9CgogICAgc29sbiBzb2x2ZSh2ZWN0b3I8dnVpPiBhKQogICAgewogICAgICAgIHNvbG4gYW5zOwogICAgICAgIGdyYXBoOjpzb2x2ZShhLGEsMSk7CiAgICAgICAgYW5zLm1heChydW5PbmNlKGEpKTsKICAgICAgICBkYmcoInR5cGUxIDogIixhbnMuc2NyKCkpOwogICAgICAgIHJldHVybiBhbnM7CiAgICB9Cn07CgpuYW1lc3BhY2Ugc29sdmV7CgogICAgc29sbiBzb2x2ZSh2ZWN0b3I8dnVpPiBhKQogICAgewogICAgICAgIHNvbG4gYW5zOwogICAgICAgIGFucy5tYXgodHlwZTE6OnNvbHZlKGEpKTsKICAgICAgICBhbnMubWF4KHR5cGU1Ojpzb2x2ZShhKSk7CiAgICAgICAgYW5zLm1heCh0eXBlMjo6c29sdmUoYSkpOwogICAgICAgIGFucy5tYXgodHlwZTM6OnNvbHZlKGEpKTsKICAgICAgICByZXR1cm4gYW5zOwogICAgfQp9OwoKbmFtZXNwYWNlIGNvbXBsZXRlewogICAgdm9pZCBydW4oKQogICAgewogICAgICAgIGNvbnN0IGxsaSBuPTY0OwogICAgICAgIGxsaSBzY3I9MCxjbnQ9MCxzY3J2PTA7CgogICAgICAgIC8vY250PXNvbHZlOjpzb2x2ZSh0ZXN0Y2FzZTo6dGVzdDEoKSkuc2NyKCk7c2NyKz1jbnQ7CiAgICAgICAgLy9kYmcoIiBUQyAxIFNjb3JlIDogIiwgY250LCBjbnQvbik7CgogICAgICAgIC8vY250PXNvbHZlOjpzb2x2ZSh0ZXN0Y2FzZTo6dGVzdDIoKSkuc2NyKCk7c2NyKz1jbnQ7c2Nydis9Y250OwogICAgICAgIC8vZGJnKCIgVEMgMiBTY29yZSA6ICIsIGNudCwgY250L24pOwoKICAgICAgICAvL2NudD1zb2x2ZTo6c29sdmUodGVzdGNhc2U6OnRlc3QzKCkpLnNjcigpO3Njcis9Y250O3NjcnYrPWNudDsKICAgICAgICAvL2RiZygiIFRDIDMgU2NvcmUgOiAiLCBjbnQsIGNudC9uKTsKCiAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IDEwMDsgKytpKXsKICAgICAgICAgICAgY250PXNvbHZlOjpzb2x2ZSh0ZXN0Y2FzZTo6dGVzdDQoKSkuc2NyKCk7c2NyKz1jbnQ7CiAgICAgICAgICAgIGRiZygiIFRDIDQgU2NvcmUgOiAiLCBjbnQsIGNudC9uKTsKICAgICAgICB9CgogICAgICAgIC8vY250PXNvbHZlOjpzb2x2ZSh0ZXN0Y2FzZTo6dGVzdDUoKSkuc2NyKCk7c2NyKz1jbnQ7c2Nydis9Y250OwogICAgICAgIC8vZGJnKCIgVEMgNSBTY29yZSA6ICIsIGNudCwgY250L24pOwoKICAgICAgICAvL2RiZyhzY3IsMypzY3IvNSxzY3J2KTsKICAgIH0KfTsKCmludCBtYWluKHZvaWQpIHsKICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpO2Npbi50aWUoTlVMTCk7Y291dC50aWUoTlVMTCk7CiAgICAvLyBmcmVvcGVuKCJ0eHQuaW4iLCAiciIsIHN0ZGluKTsKICAgIC8vIGZyZW9wZW4oInR4dC5vdXQiLCAidyIsIHN0ZG91dCk7Ci8vIGNvdXQ8PHN0ZDo6Zml4ZWQ8PHN0ZDo6c2V0cHJlY2lzaW9uKDM1KTsKCiAgICBsbGkgbjsKICAgIHVsbGkgeCx5LHo7CiAgICB2ZWN0b3I8dnVpPiBhOwoKI2lmZGVmIEFSWUFOQzQwMwoKICAgIGlmKGZhbHNlKQogICAgewogICAgICAgIGNvbXBsZXRlOjpydW4oKTsKICAgICAgICBkYmcoc2VlZCxzZWVkdGdlbik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgewogICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCAxMDA7ICsraSkKICAgICAgICAgICAgdGVzdGNhc2U6OnByaW50dGMoNCk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgYT10ZXN0Y2FzZTo6dGVzdDEoKTsKICAgIG49KGxsaSlhLnNpemUoKTsKI2Vsc2UKICAgICAgICBjaW4+Pm47CiAgICAgICAgYS5jbGVhcigpO2EucmVzZXJ2ZShuKTsKICAgICAgICBmb3IoaW50IGk9MDtpPG47KytpKQogICAgICAgIHsKICAgICAgICAgICAgY2luPj54Pj55Pj56OwogICAgICAgICAgICBhLnBiKHt4LHksen0pOwogICAgICAgIH0KI2VuZGlmCgogICAgc29sbiBhbnM7CiAgICBhbnMubWF4KHNvbHZlOjpzb2x2ZShhKSk7CiAgICAvLyBhbnMubWF4KHR5cGU1Ojpzb2x2ZShhKSk7CgojaWZkZWYgQVJZQU5DNDAzCiAgICBkYmcoYW5zLnNjcigpL24sYW5zLnNjcigpKTsKICAgIGRiZyhzZWVkLHNlZWR0Z2VuKTsKICAgIC8vIHByaW50YW5zKGFucyk7CiNlbHNlCiAgICBwcmludGFucyhhbnMpOwojZW5kaWYKCiAgICBhcnlhbmM0MDMoKTsKICAgIHJldHVybiAwOwp9Cg==