#pragma GCC optimize("Ofast")
#include <cstring>
#include <numeric>
#include <set>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <memory>
#include <cassert>
#include <vector>
#include <utility>
#include <iostream>
#include <string>
//#define assert(x) ;
#define pb push_back
#define REP_ANY(type,i,l,r) for(type i = l; i <= r; ++i)
#define REP_INT(i,l,r) for(int i = l; i <= r; ++i)
#define GET_REP_MACRO(_1,_2,_3,_4,NAME,...) NAME
#define rep(...) GET_REP_MACRO(__VA_ARGS__,REP_ANY,REP_INT)(__VA_ARGS__)
#define all(v) (v).begin(), (v).end()
#define sz(v) ll(v.size())
#define watch(x) cerr << (#x) << " = " << x << '\n'
#define X first
#define Y second
#define T1 template<typename T> static
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<string> vs;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
bool saving = true;
const ll MOD = 1e9 + 7;
ll ipow(ll x, ll p, ll mod = MOD){
if(abs(x) >= mod)
x %= mod;
if(x < 0)
x += mod;
if(p == 0)
return 1;
if(p == 1)
return x;
return ipow(x * x % mod, p / 2, mod) * ipow(x, p % 2, mod) % mod;
}
T1 ostream& operator<<(ostream& stream, const vector<T>& t);
template <typename F, typename S> static
ostream& operator<<(ostream& stream, const pair<F, S>& t){
return stream << t.first << ' ' << t.second;
}
template <typename F, typename S> static
istream& operator>>(istream& stream, pair<F, S>& t){
return stream >> t.first >> t.second;
}
T1 vector<T> unique(vector<T>& arr){
sort(all(arr));
arr.erase(unique(all(arr)), arr.end());
return arr;
}
static string unique(string& s){
sort(all(s));
s.erase(unique(all(s)), s.end());
return s;
}
T1 istream& read(T, T, istream& = cin);
T1 istream& operator>>(istream& stream, vector<T>& t){
return read(all(t), stream);
}
T1 istream& read(T b, T e, istream& stream){
for(T it = b; it != e; ++it)
stream >> *it;
return stream;
}
struct DSU{
vi par;
int n;
DSU(int _n):n(_n){
par.resize(n + 1);
iota(all(par), 0);
}
int getpar(int u){
if(par[par[u]] == par[u])
return par[u];
return par[u] = getpar(par[u]);
}
bool unite(int u, int v){
u = getpar(u);
v = getpar(v);
if(u == v)
return false;
par[u] = v;
return true;
}
};
T1 T sum(vector<T>& arr){
T ans = 0;
for(auto x : arr)
ans += x;
return ans;
}
T1 T sum(vector<T>&& arr){
T ans = 0;
for(auto x : arr)
ans += x;
return ans;
}
template <typename COST_TYPE = ll>
struct MaxFlow{
const COST_TYPE COST_INF = numeric_limits<COST_TYPE>::max();
const ll FLOW_INF = 1e18;
bool needs_prep;
struct FlowTracker{
ll *cap, *rcap;
shared_ptr<ll> flow;
bool dir;
FlowTracker(){
dir = 0;
cap = rcap = NULL;
}
FlowTracker(ll *_cap, ll *_rcap, shared_ptr<ll> _flow, int _dir)
:cap(_cap), rcap(_rcap), flow(_flow), dir(_dir){
}
ll rem()const{
if(dir == 0){
return *cap - *flow;
}else{
return *rcap + *flow;
}
}
void add_flow(ll f){
if(dir == 0)
*flow += f;
else
*flow -= f;
assert(*flow <= *cap);
assert(-*flow <= *rcap);
}
operator ll()const{
return rem();
}
void clear(){
*flow = 0;
}
void operator-=(ll x){
add_flow(x);
}
void operator+=(ll x){
add_flow(-x);
}
};
struct Edge{
int u, v;
ll c, rc;
COST_TYPE cost;
FlowTracker flow;
Edge(){}
Edge(int _u, int _v, ll _c, COST_TYPE _cost = 0)
:u(_u), v(_v), c(_c), cost(_cost){
rc = 0;
}
void change_cap(ll _c, ll _rc = 0){
c = _c;
rc = _rc;
}
};
int source, sink, rt_source, rt_sink;
MaxFlow(int _source = numeric_limits<int>::min(), int _sink = numeric_limits<int>::min() + 1):source(_source), sink(_sink){
needs_prep = true;
}
vector<vector<int>> adj;
vector<vector<COST_TYPE>> cost;
vector<vector<FlowTracker>> cap;
vector<Edge> edges;
int add_edge(int u, int v, ll c, COST_TYPE cost = 0){
needs_prep = true;
edges.push_back(Edge(u, v, c, cost));
return sz(edges) - 1;
}
vector<int> now, lvl;
vector<COST_TYPE> pot;
vi indices;
void prep(){
if(!needs_prep){
for(auto &_ : edges)
_.flow.clear();
return;
}
needs_prep = false;
indices = vi{source,sink};
for(auto& edge : edges){
indices.push_back(edge.u);
indices.push_back(edge.v);
}
sort(indices.begin(), indices.end());
indices.erase(unique(indices.begin(), indices.end()), indices.end());
rt_source = lower_bound(indices.begin(), indices.end(), source) - indices.begin();
rt_sink = lower_bound(indices.begin(), indices.end(), sink) - indices.begin();
adj.clear();
cost.clear();
cap.clear();
now.clear();
lvl.clear();
pot.clear();
int max_id = sz(indices) - 1;
adj.resize(max_id + 1);
cost.resize(max_id + 1);
cap.resize(max_id + 1);
now.resize(max_id + 1);
lvl.resize(max_id + 1);
pot.resize(max_id + 1);
vi ordering(sz(edges));
iota(all(ordering),0);
random_shuffle(all(ordering));
for(int id : ordering){
auto &edge = edges[id];
int u = lower_bound(indices.begin(), indices.end(), edge.u) - indices.begin();
int v = lower_bound(indices.begin(), indices.end(), edge.v) - indices.begin();
auto flow = make_shared<ll>(0);
adj[u].push_back(v);
cost[u].push_back(edge.cost);
cap[u].push_back(FlowTracker(&edge.c, &edge.rc, flow, 0));
if(u != v){
adj[v].push_back(u);
cost[v].push_back(-edge.cost);
cap[v].push_back(FlowTracker(&edge.c, &edge.rc, flow, 1));
}
assert(cap[u].back() == edge.c);
edge.flow = cap[v].back();
}
}
int get_name(int x){
auto it = lower_bound(all(indices),x);
if(it == indices.end() || *it != x){
indices.pb(x);
unique(indices);
needs_prep = true;
it = lower_bound(all(indices),x);
}
assert(*it == x);
return it-indices.begin();
}
void set_source(int _source){
if(source == _source) return;
source = _source;
rt_source = get_name(source);
}
void set_sink(int _sink){
if(sink == _sink) return;
sink = _sink;
rt_sink = get_name(sink);
}
void bellman_ford(){
vector<COST_TYPE> dist(sz(adj), COST_INF);
dist[rt_source] = 0;
//for(int times = 0; times < sz(dist); ++times){
while(true){
bool changes = false;
for(int u = 0; u < sz(adj); ++u)
for(int i = 0; i < sz(adj[u]); ++i){
int v = adj[u][i];
if(dist[u] != COST_INF && cap[u][i]){
if(dist[v] > dist[u] + cost[u][i]){
changes = true;
dist[v] = dist[u] + cost[u][i];
}
}
}
if(!changes)
break;
}
pot = dist;
}
ll dijkstra(vector<COST_TYPE>& dist, vector<int>& last_node, vector<int>& last_index){
dist[rt_source] = 0;
vector<ll> flow(sz(dist));
flow[rt_source] = FLOW_INF;
vector<bool> visited(sz(dist));
priority_queue<pair<COST_TYPE, int>> pq;
pq.push({0, rt_source});
while(!pq.empty()){
int u = pq.top().second;
pq.pop();
if(visited[u])
continue;
visited[u] = true;
assert(dist[u] != COST_INF);
for(int i = 0; i < sz(adj[u]); ++i){
int v = adj[u][i];
if(!visited[v] && cap[u][i])
if(dist[u] + cost[u][i] + pot[u] - pot[v] < dist[v]){
dist[v] = dist[u] + cost[u][i] + pot[u] - pot[v];
last_node[v] = u;
last_index[v] = i;
flow[v] = min(flow[u], (ll)cap[u][i]);
pq.push({-dist[v], v});
}
}
}
return flow[rt_sink];
}
pair<ll, COST_TYPE> min_cost_flow(int _source, int _sink){
set_source(_source);
set_sink(_sink);
prep();
bool has_negative = false;
for(auto& edge : edges)
if(edge.cost < 0)
has_negative = true;
if(has_negative)
bellman_ford();
ll total_flow = 0;
COST_TYPE total_cost = 0;
while(true){
vector<COST_TYPE> dist(sz(adj), COST_INF);
vector<int> last_node(sz(dist)), last_index(sz(dist));
ll flow = dijkstra(dist, last_node, last_index);
if(flow == 0)
break;
for(int u = rt_sink; u != rt_source; u = last_node[u])
cap[last_node[u]][last_index[u]] -= flow;
for(int i = 0; i < sz(adj); ++i)
pot[i] = pot[i] + dist[i];
total_flow += flow;
total_cost += pot[rt_sink] * flow;
}
return {total_flow, total_cost};
}
pair<ll, COST_TYPE> min_cost_flow(){
return min_cost_flow(source, sink);
}
};
T1 T max(const vector<T> arr){
assert(!arr.empty());
T ans = arr[0];
for(auto& cur : arr)
ans = max(ans, cur);
return ans;
}
T1 T min(const vector<T>& arr){
assert(!arr.empty());
T ans = arr[0];
for(auto& cur : arr)
ans = min(ans, cur);
return ans;
}
T1 T max(const set<T>& s){
assert(!s.empty());
return *--s.end();
}
T1 T min(const set<T>& s){
assert(!s.empty());
return *s.begin();
}
T1 void print(T x, string end = "\n"){
cout << x << end;
}
T1 void print(vector<vector<T>> arr){
for(int i = 0; i < sz(arr); ++i){
cout << "[" << arr[i] << "]";
if(i + 1 < sz(arr))
cout << ", ";
}
cout << '\n';
}
T1 ostream& print(T b, T e, string sep = " ", ostream& stream = cout){
for(T it = b; it != e; ++it){
stream << *it;
if(it + 1 != e)
stream << sep;
}
return stream;
}
T1 ostream& operator<<(ostream& stream, const vector<T>& t){
for(int i = 0; i < sz(t); ++i){
stream << t[i];
if(i+1 < sz(t))
stream << ' ';
}
return stream;
}
T1 void print(vector<T> arr, string sep = " "){
if(arr.empty()){
return;
}
print(arr.begin(), arr.end(), sep);
cout << '\n';
}
typedef vector<ull> vull;
typedef vector<vull> vvull;
int n,type;
vvull a;
int dist[64][64];
vs description;
string last_oper;
ull rx[4];
#define REG string(1,'a'+pos)
#define OPER if(saving){last_oper = string(__func__).substr(1)+last_oper;}
ull *l64(int pos){
string tmp = " r"+REG+"x";
if(saving)
last_oper = tmp+last_oper;
return &rx[pos];
}
uint *l32(int pos){
string tmp = " e"+REG+"x";
if(saving)
last_oper = tmp+last_oper;
uint *a = reinterpret_cast<uint*>(&rx[pos]);
return &a[0];
}
ushort *l16(int pos){
string tmp = " "+REG+"x";
if(saving)
last_oper = tmp+last_oper;
ushort *a = reinterpret_cast<ushort*>(&rx[pos]);
return &a[0];
}
uchar *l8(int pos){
string tmp = " "+REG+"l";
if(saving)
last_oper = tmp+last_oper;
uchar *a = reinterpret_cast<uchar*>(&rx[pos]);
return &a[0];
}
uchar *u8(int pos){
string tmp = " "+REG+"h";
if(saving)
last_oper = tmp+last_oper;
uchar *a = reinterpret_cast<uchar*>(&rx[pos]);
return &a[1];
}
T1 void _inc(T *a){
*a += 1;
OPER;
}
T1 void _dec(T *a){
*a -= 1;
OPER;
}
T1 void _not(T *a){
*a = ~*a;
if(saving)
last_oper = "not"+last_oper;
}
T1 void _and(T *a, T *b){
*a = (*a) & (*b);
OPER;
}
T1 void _or(T *a, T *b){
*a = (*a) | (*b);
OPER;
}
T1 void _xor(T *a, T *b){
*a = (*a) ^ (*b);
OPER;
}
T1 void _shl(T *a, T *b){
*a = (*a) << (*b);
OPER;
}
T1 void _shr(T *a, T *b){
*a = (*a) >> (*b);
OPER;
}
T1 void _add(T *a, T *b){
*a = (*a) + (*b);
OPER;
}
T1 void _sub(T *a, T *b){
*a = (*a) - (*b);
OPER;
}
T1 void _mul(T *a, T *b){
*a = (*a) * (*b);
OPER;
}
T1 void _div(T *a, T *b){
//assert(b);
*a = (*a) / (*b);
OPER;
}
T1 void _mod(T *a, T *b){
//assert(b);
*a = (*a) % (*b);
OPER;
}
T1 void _mov(T *a, T *b){
*a = *b;
OPER;
}
vvull all_visited;
int cnt_op;
template<typename T = ull*>
void f(void (*oper)(T,T), int i, int j, T (*type)(int) = l64){
++cnt_op;
oper(type(i),type(j));
if(saving){
description.pb(last_oper);
all_visited.pb(vull(rx,rx+4));
last_oper = "";
}
}
void f(void (*oper)(uchar*,uchar*), int i, int j, uchar* (*typei)(int), uchar* (*typej)(int)){
++cnt_op;
oper(typei(i),typej(j));
if(saving){
description.pb(last_oper);
all_visited.pb(vull(rx,rx+4));
last_oper = "";
}
}
template<typename T = ull*>
void f(void (*oper)(T), int i, T (*type)(int) = l64){
++cnt_op;
oper(type(i));
if(saving){
description.pb(last_oper);
all_visited.pb(vull(rx,rx+4));
last_oper = "";
}
}
template<typename T = ull*>
ull g(void (*oper)(T,T), int i, int j, T (*type)(int) = l64){
ull old = rx[i];
oper(type(i),type(j));
last_oper = "";
ull nxt = rx[i];
rx[i] = old;
return nxt;
}
ull g(void (*oper)(uchar*,uchar*), int i, int j, uchar* (*typei)(int), uchar* (*typej)(int)){
ull old = rx[i];
oper(typei(i),typej(j));
last_oper = "";
ull nxt = rx[i];
rx[i] = old;
return nxt;
}
template<typename T = ull*>
ull g(void (*oper)(T), int i, T (*type)(int) = l64){
ull old = rx[i];
oper(type(i));
last_oper = "";
ull nxt = rx[i];
rx[i] = old;
return nxt;
}
bool match(vull a, vull b){
if(a.empty())
return true;
sort(all(a));
sort(all(b));
if(a.back() == b.back()){
a.pop_back();
b.pop_back();
return match(a,b);
}
else{
b.pop_back();
return a == b;
}
}
void check(vvull a){
set<vull> seen;
for(auto _ : a){
sort(all(_));
seen.insert(_);
}
for(auto _ : all_visited){
sort(all(_));
rep(i,0,3){
vull tmp;
rep(j,0,3)
if(i != j)
tmp.pb(_[j]);
seen.erase(tmp);
}
}
assert(seen.empty());
}
int bits(ll x){
return __builtin_popcountll(x);
}
int get_type(){
int evidence_3 = 0;
set<ull> sums;
set<ull> vals;
for(auto _ : a){
if(_[2]-_[1] == _[1]-_[0]){
++evidence_3;
}
sums.insert(sum(_));
vals.insert(_[0]);
vals.insert(_[1]);
vals.insert(_[2]);
}
if(evidence_3 >= n) return 3;
if(sz(sums) == 1) return 5;
if(sz(vals) <= 3*n-10) return 4;
bool can_2 = true;
for(auto _ : a){
if(bits(_[0]^_[1]) > 4)
can_2 = false;
if(bits(_[0]^_[2]) > 4)
can_2 = false;
}
if(can_2)
return 2;
return 1;
}
string B(ull x){
string ans;
rep(i,0,63){
if(i && i%8 == 0)
ans.pb(' ');
ans.pb(x%2+'0');
x >>= 1;
}
return ans;
}
vull sx;
void save_state(){
assert(sx.empty());
sx = vull(rx,rx+4);
}
void load_state(){
assert(!sx.empty());
rep(i,0,3)
rx[i] = sx[i];
sx.clear();
}
vull get_state(){
return vull(rx,rx+4);
}
void set_state(vull _state){
rep(i,0,sz(_state)-1)
rx[i] = _state[i];
}
ull choose(ull x, ull g){
ull m = (ull(1)<<48)+(ull(1)<<32)+(ull(1)<<16);
rep(t,0,1){
rep(i,0,7)
if((((x*m)^g)>>(48+i))%2)
x ^= ull(1)<<i;
rep(i,8,15)
if((((x*m)^g)>>(16+i))%2)
x ^= ull(1)<<i;
rep(i,24,31)
if((((x*m)^g)>>(16+i))%2)
x ^= ull(1)<<i;
rep(i,40,47)
if((((x*m)^g)>>(16+i))%2)
x ^= ull(1)<<i;
}
ull mask = (-1ull)^((ull(1)<<40)-1)^((ull(1)<<32)-1)^((ull(1)<<24)-1);
if((((x*m)^g)&mask))
throw 1;
return x;
}
ull fbin(string s){
ull ans = 0;
reverse(all(s));
for(char c : s){
ans <<= 1;
ans += c-'0';
}
return ans;
}
void make_rx3_rem(){
ull rem = 0;
rem ^= 1ull<<32;
rem ^= 1ull<<16;
if((rx[3]&rx[0])==rem)
f(_and,3,0);
else if((rx[3]&rx[1])==rem)
f(_and,3,1);
else if((rx[3]&rx[2])==rem)
f(_and,3,2);
else if((rx[3]&~rx[0])==rem){
f(_not,0);
f(_and,3,0);
f(_not,0);
}
else if((rx[3]&~rx[1])==rem){
f(_not,1);
f(_and,3,1);
f(_not,1);
}
else if((rx[3]&~rx[2])==rem){
f(_not,2);
f(_and,3,2);
f(_not,2);
}
else if((rx[3]&(rx[0]^rx[1]))==rem){
f(_xor,0,1);
f(_and,3,0);
f(_xor,0,1);
}
else if((rx[3]&(rx[2]^rx[1]))==rem){
f(_xor,2,1);
f(_and,3,2);
f(_xor,2,1);
}
else if((rx[3]&(rx[2]^rx[0]))==rem){
f(_xor,2,0);
f(_and,3,2);
f(_xor,2,0);
}
else if((rx[3]&(~rx[0]^rx[1]))==rem){
f(_not,0);
f(_xor,0,1);
f(_and,3,0);
f(_xor,0,1);
f(_not,0);
}
else if((rx[3]&(~rx[2]^rx[1]))==rem){
f(_not,2);
f(_xor,2,1);
f(_and,3,2);
f(_xor,2,1);
f(_not,2);
}
else if((rx[3]&(~rx[2]^rx[0]))==rem){
f(_not,2);
f(_xor,2,0);
f(_and,3,2);
f(_xor,2,0);
f(_not,2);
}
else if((rx[3]&(rx[0]^rx[1]^rx[2]))==rem){
f(_xor,0,1);
f(_xor,0,2);
f(_and,3,0);
f(_xor,0,1);
f(_xor,0,2);
}
else{
f(_sub,3,3); //0
f(_inc,3,u8); //8
f(_mul,3,3); //16
f(_mul,3,3); //32
f(_inc,3,u8); //32,8
f(_mul,3,3,l32); //32,16
assert(rx[3]==rem);
}
}
void inner16(vull goal){
vull intermediate(3);
ull m = (ull(1)<<48)+(ull(1)<<32)+(ull(1)<<16);
rep(i,0,2){
try{
intermediate[i] = choose(rx[i],goal[i]);
}catch(...){
f(_sub,i,i);
intermediate[i] = choose(rx[i],goal[i]);
}
}
rep(i,0,7){
rep(j,0,2)
if((rx[j]^intermediate[j]) & (1ull<<(40+i)))
f(_xor,j,3);
rep(j,0,2)
if((rx[j]^intermediate[j]) & (1ull<<(24+i)))
f(_xor,j,3,l32);
rep(j,0,2)
if((rx[j]^intermediate[j]) & (1ull<<(8+i)))
f(_xor,j,3,u8,u8);
rep(j,0,2)
if((rx[j]^intermediate[j]) & (1ull<<(i)))
f(_xor,j,3,l8,u8);
f(_add,3,3);
}
assert(rx[3] == m);
rep(j,0,2)
f(_mul,j,3);
make_rx3_rem();
f(_inc,3);
rep(i,0,7){
rep(j,0,2)
if((rx[j]^goal[j]) & (1ull<<(32+i)))
f(_xor,j,3);
rep(j,0,2)
if((rx[j]^goal[j]) & (1ull<<(16+i)))
f(_xor,j,3,l32);
rep(j,0,2)
if((rx[j]^goal[j]) & (1ull<<(8+i)))
f(_xor,j,3,u8,l8);
rep(j,0,2)
if((rx[j]^goal[j]) & (1ull<<(i)))
f(_xor,j,3,l8,l8);
f(_add,3,3);
}
}
ll mock(void (*to_test)(vull), vull initial, vull goal){
auto old_saving = saving;
saving = false;
int old_op = cnt_op;
save_state();
rep(i,0,sz(initial)-1)
rx[i] = initial[i];
to_test(goal);
load_state();
saving = old_saving;
int ans = cnt_op-old_op;
cnt_op = old_op;
return ans;
}
template<typename T>
ll mock(void (*to_test)(T), T goals){
saving = false;
int old_op = cnt_op;
vull _state = get_state();
to_test(goals);
set_state(_state);
saving = true;
int ans = cnt_op-old_op;
cnt_op = old_op;
return ans;
}
vull best_permute(void (*)(vull), vull);
vvull rand_permute(void (*)(vvull), vvull, int);
void tsp_permute(void (*)(vull), vvull&);
void outer16(vvull goals){
rep(t,0,n-1){
vull goal = best_permute(inner16,goals[t]);
inner16(goal);
rep(j,0,2) assert((rx[j]^goal[j])==0);
}
}
void calc_dist(void (*to_test)(vull), vvull goals){
vull state = get_state();
rep(i,0,sz(goals)-1)
rep(j,0,sz(goals)-1){
set_state(goals[i]);
dist[i][j] = mock(to_test,get_state(),best_permute(to_test,goals[j]));
}
set_state(state);
}
bool visited[64];
vi path;
int cost = 0;
void dfs(int u, int sz){
visited[u] = true;
path.pb(u);
if(sz(path) == sz)
return;
vpii best_cont;
rep(v,0,sz-1)
if(!visited[v])
best_cont.pb({dist[u][v],v});
sort(all(best_cont));
for(auto _ : best_cont){
if(sz(path) < 50 && rand()%15 == 0) continue;
cost += _.X;
dfs(_.Y,sz);
if(sz(path) == sz)
return;
cost -= _.X;
}
if(sz(path) == sz)
return;
visited[u] = false;
path.pop_back();
return;
}
vi mst_order(int sz = 64){
vvi edges;
rep(i,0,sz-1)
rep(j,i+1,sz-1)
edges.pb({dist[i][j],i,j});
DSU dsu(sz);
vi deg(sz);
vvi adj(sz);
ll cost = 0;
for(auto _ : edges){
int u = _[1];
int v = _[2];
if(deg[u] <= 1 && deg[v] <= 1 && dsu.unite(u,v)){
++deg[u];
++deg[v];
adj[u].pb(v);
adj[v].pb(u);
cost += _[0];
}
}
int start = 0;
while(deg[start] != 1)
++start;
vi ans(1,start);
rep(i,0,sz(ans)-1){
int u = ans[i];
for(int v : adj[u]){
if(deg[v] != 0){
ans.pb(v);
deg[u]--;
deg[v]--;
}
}
}
watch(cost);
watch(sz(ans));
return ans;
}
vi mf_order(int sz = 64){
vvi edges;
rep(i,0,sz-1)
rep(j,i+1,sz-1)
edges.pb({dist[i][j],i,j});
DSU dsu(sz);
vi deg(sz);
ll cost = 0;
ll icost = 0;
vi ls,rs;
for(auto _ : edges){
int u = _[1];
int v = _[2];
if(deg[u] <= 0 && deg[v] <= 0 && dsu.unite(u,v)){
++deg[u];
++deg[v];
icost += _[0];
ls.pb(u);
rs.pb(v);
}
}
ll tcost = MOD;
rep(times,0,1000){
cost = icost;
rep(i,0,31)
if(rand()%2)
swap(ls[i],rs[i]);
MaxFlow<int> mf;
vvi edge_indices(32,vi(32));
rep(i,0,31)
rep(j,0,31)
edge_indices[i][j] = mf.add_edge(ls[i],rs[j],1,dist[ls[i]][rs[j]]);
int ts = -1;
rep(i,0,31)
mf.add_edge(ts,ls[i],1,0);
rep(j,0,31)
mf.add_edge(rs[j],mf.sink,1,0);
mf.add_edge(mf.source,ts,31,0);
cost += mf.min_cost_flow().Y;
tcost = min(tcost,cost);
}
watch(tcost);
return {};
}
vi decent_order(int sz = 64){
vi best_path;
int best_cost = MOD;
rep(start,0,30*(sz-1)){
cost = 0;
path.clear();
memset(visited,0,sizeof visited);
dfs(start%sz,sz);
if(cost < best_cost){
best_path = path;
best_cost = cost;
}
}
return best_path;
}
void set_order(vvull &goals, vi order){
vvull b(sz(goals));
rep(i,0,sz(goals)-1)
b[i] = goals[order[i]];
goals = b;
}
void solve16(){
f(_inc,3,u8); //8
f(_mov,0,3);
f(_mul,3,3); //16
f(_mul,3,3); //32
f(_inc,3,u8); //32,8
f(_mul,3,3,l32); //32,16
f(_inc,3); //32,16,0
f(_mul,3,0); //40,24,8
vvull goals = a;
tsp_permute(inner16,goals);
outer16(goals);
}
void inner56(int t, vull goal){
if(t > 0){
f(_add,2,0);
f(_add,2,1);
}
{
int endp = 1+(t==0);
vull intermediate(3);
ull m = (ull(1)<<48)+(ull(1)<<32)+(ull(1)<<16);
rep(i,0,endp){
try{
intermediate[i] = choose(rx[i],goal[i]);
}catch(...){
f(_sub,i,i);
intermediate[i] = choose(rx[i],goal[i]);
}
}
rep(i,0,7){
rep(j,0,endp)
if((rx[j]^intermediate[j]) & (1ull<<(40+i)))
f(_xor,j,3);
rep(j,0,endp)
if((rx[j]^intermediate[j]) & (1ull<<(24+i)))
f(_xor,j,3,l32);
rep(j,0,endp){
if((rx[j]^intermediate[j]) & (1ull<<(8+i)))
f(_xor,j,3,u8,u8);
}
rep(j,0,endp)
if((rx[j]^intermediate[j]) & (1ull<<(i)))
f(_xor,j,3,l8,u8);
f(_add,3,3);
}
assert(rx[3] == m);
rep(j,0,endp)
f(_mul,j,3);
make_rx3_rem();
f(_inc,3);
rep(i,0,7){
rep(j,0,endp)
if((rx[j]^goal[j]) & (1ull<<(32+i)))
f(_xor,j,3);
rep(j,0,endp)
if((rx[j]^goal[j]) & (1ull<<(16+i)))
f(_xor,j,3,l32);
rep(j,0,endp)
if((rx[j]^goal[j]) & (1ull<<(8+i)))
f(_xor,j,3,u8,l8);
rep(j,0,endp)
if((rx[j]^goal[j]) & (1ull<<(i)))
f(_xor,j,3,l8,l8);
f(_add,3,3);
}
if(t > 0){
f(_sub,2,0);
f(_sub,2,1);
}
}
}
void inner56_init(vull goal){
inner56(0,goal);
}
void inner56_normal(vull goal){
inner56(1,goal);
}
void outer56(vvull goals){
rep(t,0,n-1){
auto func = t == 0 ? inner56_init : inner56_normal;
vull goal = goals[t];
goal = best_permute(func,goals[t]);
func(goal);
rep(j,0,2) assert((rx[j]^goal[j])==0);
}
}
void solve56(){
f(_inc,3,u8); //8
f(_mov,0,3);
f(_mul,3,3); //16
f(_mul,3,3); //32
f(_inc,3,u8); //32,8
f(_mul,3,3,l32); //32,16
f(_inc,3); //32,16,0
f(_mul,3,0); //40,24,8
vvull goals = a;
tsp_permute(inner56_normal,goals);
outer56(goals);
}
void inner4(vull goal){
rep(times,0,3){
if(times > 2){
if(goal[0]>>32 != rx[0]>>32){
if(goal[0]>>32 == g(_add,0,1)>>32) f(_add, 0,1);
else if(goal[0]>>32 == g(_xor,0,1)>>32) f(_xor, 0,1);
else if(goal[0]>>32 == g(_sub,0,1)>>32) f(_sub, 0,1);
else if(goal[0]>>32 == g(_and,0,1)>>32) f(_and, 0,1);
else if(goal[0]>>32 == g(_or, 0,1)>>32) f(_or, 0,1);
else if(goal[0]>>32 == g(_add,0,2)>>32) f(_add, 0,2);
else if(goal[0]>>32 == g(_xor,0,2)>>32) f(_xor, 0,2);
else if(goal[0]>>32 == g(_sub,0,2)>>32) f(_sub, 0,2);
else if(goal[0]>>32 == g(_and,0,2)>>32) f(_and, 0,2);
else if(goal[0]>>32 == g(_or, 0,2)>>32) f(_or, 0,2);
else if(times>1 && goal[0]>>32 == g(_mov,0,1)>>32) f(_mov, 0,1);
else if(times>1 && goal[0]>>32 == g(_mov,0,2)>>32) f(_mov, 0,2);
}
if(goal[1]>>32 != rx[1]>>32){
if(goal[1]>>32 == g(_add,1,0)>>32) f(_add, 1,0);
else if(goal[1]>>32 == g(_xor,1,0)>>32) f(_xor, 1,0);
else if(goal[1]>>32 == g(_sub,1,0)>>32) f(_sub, 1,0);
else if(goal[1]>>32 == g(_and,1,0)>>32) f(_and, 1,0);
else if(goal[1]>>32 == g(_or, 1,0)>>32) f(_or, 1,0);
else if(goal[1]>>32 == g(_add,1,2)>>32) f(_add, 1,2);
else if(goal[1]>>32 == g(_xor,1,2)>>32) f(_xor, 1,2);
else if(goal[1]>>32 == g(_sub,1,2)>>32) f(_sub, 1,2);
else if(goal[1]>>32 == g(_and,1,2)>>32) f(_and, 1,2);
else if(goal[1]>>32 == g(_or, 1,2)>>32) f(_or, 1,2);
else if(times > 1 && goal[1]>>32 == g(_mov,1,0)>>32) f(_mov, 1,0);
else if(times > 1 && goal[1]>>32 == g(_mov,1,2)>>32) f(_mov, 1,2);
}
if(goal[0]>>32 != rx[0]>>32){
if(goal[2]>>32 == g(_add,2,1)>>32) f(_add, 2,1);
else if(goal[2]>>32 == g(_xor,2,1)>>32) f(_xor, 2,1);
else if(goal[2]>>32 == g(_sub,2,1)>>32) f(_sub, 2,1);
else if(goal[2]>>32 == g(_and,2,1)>>32) f(_and, 2,1);
else if(goal[2]>>32 == g(_or, 2,1)>>32) f(_or, 2,1);
else if(goal[2]>>32 == g(_add,2,0)>>32) f(_add, 2,0);
else if(goal[2]>>32 == g(_xor,2,0)>>32) f(_xor, 2,0);
else if(goal[2]>>32 == g(_sub,2,0)>>32) f(_sub, 2,0);
else if(goal[2]>>32 == g(_and,2,0)>>32) f(_and, 2,0);
else if(goal[2]>>32 == g(_or, 2,0)>>32) f(_or, 2,0);
else if(times > 1 && goal[2]>>32 == g(_mov,2,1)>>32) f(_mov, 2,1);
else if(times > 1 && goal[2]>>32 == g(_mov,2,0)>>32) f(_mov, 2,0);
}
}
if(goal[0] != rx[0]){
if(goal[0] == g(_add,0,1)) f(_add, 0,1);
else if(goal[0] == g(_xor,0,1)) f(_xor, 0,1);
else if(goal[0] == g(_sub,0,1)) f(_sub, 0,1);
else if(goal[0] == g(_and,0,1)) f(_and, 0,1);
else if(goal[0] == g(_or, 0,1)) f(_or, 0,1);
else if(goal[0] == g(_add,0,1,l32)) f(_add,0,1,l32);
else if(goal[0] == g(_xor,0,1,l32)) f(_xor,0,1,l32);
else if(goal[0] == g(_sub,0,1,l32)) f(_sub,0,1,l32);
else if(goal[0] == g(_and,0,1,l32)) f(_and,0,1,l32);
else if(goal[0] == g(_or, 0,1,l32)) f(_or, 0,1,l32);
else if(goal[0] == g(_add,0,2)) f(_add, 0,2);
else if(goal[0] == g(_xor,0,2)) f(_xor, 0,2);
else if(goal[0] == g(_sub,0,2)) f(_sub, 0,2);
else if(goal[0] == g(_and,0,2)) f(_and, 0,2);
else if(goal[0] == g(_or, 0,2)) f(_or, 0,2);
else if(goal[0] == g(_add,0,2,l32)) f(_add,0,2,l32);
else if(goal[0] == g(_xor,0,2,l32)) f(_xor,0,2,l32);
else if(goal[0] == g(_sub,0,2,l32)) f(_sub,0,2,l32);
else if(goal[0] == g(_and,0,2,l32)) f(_and,0,2,l32);
else if(goal[0] == g(_or, 0,2,l32)) f(_or, 0,2,l32);
else if(times > 0 && goal[0] == g(_mov,0,1)) f(_mov, 0,1);
else if(times > 0 && goal[0] == g(_mov,0,2)) f(_mov, 0,2);
else if(times > 0 && goal[0] == g(_mov,0,1,l32)) f(_mov,0,1,l32);
else if(times > 0 && goal[0] == g(_mov,0,2,l32)) f(_mov,0,2,l32);
}
if(goal[1] != rx[1]){
if(goal[1] == g(_add,1,0)) f(_add, 1,0);
else if(goal[1] == g(_xor,1,0)) f(_xor, 1,0);
else if(goal[1] == g(_sub,1,0)) f(_sub, 1,0);
else if(goal[1] == g(_and,1,0)) f(_and, 1,0);
else if(goal[1] == g(_or, 1,0)) f(_or, 1,0);
else if(goal[1] == g(_add,1,0,l32)) f(_add,1,0,l32);
else if(goal[1] == g(_xor,1,0,l32)) f(_xor,1,0,l32);
else if(goal[1] == g(_sub,1,0,l32)) f(_sub,1,0,l32);
else if(goal[1] == g(_and,1,0,l32)) f(_and,1,0,l32);
else if(goal[1] == g(_or, 1,0,l32)) f(_or, 1,0,l32);
else if(goal[1] == g(_add,1,2)) f(_add, 1,2);
else if(goal[1] == g(_xor,1,2)) f(_xor, 1,2);
else if(goal[1] == g(_sub,1,2)) f(_sub, 1,2);
else if(goal[1] == g(_and,1,2)) f(_and, 1,2);
else if(goal[1] == g(_or, 1,2)) f(_or, 1,2);
else if(goal[1] == g(_add,1,2,l32)) f(_add,1,2,l32);
else if(goal[1] == g(_xor,1,2,l32)) f(_xor,1,2,l32);
else if(goal[1] == g(_sub,1,2,l32)) f(_sub,1,2,l32);
else if(goal[1] == g(_and,1,2,l32)) f(_and,1,2,l32);
else if(goal[1] == g(_or, 1,2,l32)) f(_or, 1,2,l32);
else if(times > 0 && goal[1] == g(_mov,1,0)) f(_mov, 1,0);
else if(times > 0 && goal[1] == g(_mov,1,2)) f(_mov, 1,2);
else if(times > 0 && goal[1] == g(_mov,1,0,l32)) f(_mov,1,0,l32);
else if(times > 0 && goal[1] == g(_mov,1,2,l32)) f(_mov,1,2,l32);
}
if(goal[2] != rx[2]){
if(goal[2] == g(_add,2,0)) f(_add, 2,0);
else if(goal[2] == g(_xor,2,0)) f(_xor, 2,0);
else if(goal[2] == g(_sub,2,0)) f(_sub, 2,0);
else if(goal[2] == g(_and,2,0)) f(_and, 2,0);
else if(goal[2] == g(_or, 2,0)) f(_or, 2,0);
else if(goal[2] == g(_add,2,0,l32)) f(_add,2,0,l32);
else if(goal[2] == g(_xor,2,0,l32)) f(_xor,2,0,l32);
else if(goal[2] == g(_sub,2,0,l32)) f(_sub,2,0,l32);
else if(goal[2] == g(_and,2,0,l32)) f(_and,2,0,l32);
else if(goal[2] == g(_or, 2,0,l32)) f(_or, 2,0,l32);
else if(goal[2] == g(_add,2,1)) f(_add, 2,1);
else if(goal[2] == g(_xor,2,1)) f(_xor, 2,1);
else if(goal[2] == g(_sub,2,1)) f(_sub, 2,1);
else if(goal[2] == g(_and,2,1)) f(_and, 2,1);
else if(goal[2] == g(_or, 2,1)) f(_or, 2,1);
else if(goal[2] == g(_add,2,1,l32)) f(_add,2,1,l32);
else if(goal[2] == g(_xor,2,1,l32)) f(_xor,2,1,l32);
else if(goal[2] == g(_sub,2,1,l32)) f(_sub,2,1,l32);
else if(goal[2] == g(_and,2,1,l32)) f(_and,2,1,l32);
else if(goal[2] == g(_or, 2,1,l32)) f(_or, 2,1,l32);
else if(times > 0 && goal[2] == g(_mov,2,0)) f(_mov, 2,0);
else if(times > 0 && goal[2] == g(_mov,2,1)) f(_mov, 2,1);
else if(times > 0 && goal[2] == g(_mov,2,0,l32)) f(_mov,2,0,l32);
else if(times > 0 && goal[2] == g(_mov,2,1,l32)) f(_mov,2,1,l32);
}
}
vull t64(3);
vull t32(3);
rep(j,0,2){
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
rep(j,0,2){
if(bits(t64[j]) > 16){
f(_not,j);
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
if(bits(t32[j]) > 16){
f(_not,j,l32);
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
if(bits(t32[j]&0xffff) > 8 && bits(t32[j]&0x00ff) > 4 && bits(t32[j]&0xff00) > 4){
f(_not,j,l16);
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
if(bits(t32[j]&0x00ff) > 4){
f(_not,j,l8);
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
if(bits(t32[j]&0xff00) > 4){
f(_not,j,u8);
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
}
if(vull(rx,rx+3) == goal) return;
f(_inc,3); //32,1
rep(i,0,31){
rep(j,0,2){
if(t64[j]&rx[3]) f(_xor,j,3);
if(t32[j]&rx[3]) f(_xor,j,3,l32);
}
f(_add,3,3);
}
rep(j,0,2)
assert(rx[j] == goal[j]);
}
void outer4(vvull goals){
rep(t,0,n-1){
vull goal = goals[t];
goal = best_permute(inner4,goals[t]);
inner4(goal);
}
}
//void solve4(){
//f(_inc,3,u8); //8
//f(_mul,3,3); //16
//f(_mul,3,3); //32
//vvull goals = a;
//tsp_permute(inner4,goals);
//outer4(goals);
//}
vull apply_oper(bool keep_changes, int bm){
vull old_vals(rx,rx+3);
if(!keep_changes)
saving = false;
rep(j,0,2){
int p1 = bm%3; bm /= 3;
int p2 = bm%2; bm /= 2;
if(p2 == p1) p2 = 2;
int op_index, nr_bits;
op_index = bm%5; bm /= 5;
nr_bits = bm%2; bm /= 2;
if(nr_bits == 0){
if(op_index == 0) f(_add,p1,p2);
if(op_index == 1) f(_xor,p1,p2);
if(op_index == 2) f(_and,p1,p2);
if(op_index == 3) f(_or,p1,p2);
if(op_index == 4) f(_sub,p1,p2);
}
else{
if(op_index == 0) f(_add,p1,p2,l32);
if(op_index == 1) f(_xor,p1,p2,l32);
if(op_index == 2) f(_and,p1,p2,l32);
if(op_index == 3) f(_or,p1,p2,l32);
if(op_index == 4) f(_sub,p1,p2,l32);
}
}
vull ret(rx,rx+3);
if(!keep_changes){
saving = true;
rep(j,0,2)
rx[j] = old_vals[j];
}
sort(all(ret));
return ret;
}
void solve4(){
f(_inc,3);
rep(i,0,63){
rep(j,0,2)
if(a[0][j]&(1LL<<i))
f(_xor,j,3);
f(_add,3,3);
}
rep(i,1,n-1){
sort(all(a[i]));
saving = false;
vull old_vals(rx,rx+3);
//assert(old_vals == a[i-1]);
int correct_mask = -1;
rep(bm,0,ipow(60,3))
if(apply_oper(false,bm) == a[i]){
correct_mask = bm;
break;
}
assert(correct_mask != -1);
apply_oper(true,correct_mask);
set<ull> tmp(rx,rx+4);
rep(j,0,2) assert(tmp.count(a[i][j]));
}
}
void inner2(vull goal){
goal[2] ^= goal[0];
goal[1] ^= goal[0];
f(_inc,3); //32,1
if(rx[1] != 0) f(_sub,1,1);
if(rx[2] != 0) f(_sub,2,2);
vull t64(3);
vull t32(3);
rep(j,0,2){
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
rep(j,0,2){
if(bits(t64[j]) > 16){
f(_not,j);
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
if(bits(t32[j]) > 16){
f(_not,j,l32);
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
int types = 0;
if(bits(t32[j]&0x00ff) > 4) types ^= 1;
if(bits(t32[j]&0xff00) > 4) types ^= 2;
if((types&3)==3){
f(_not,j,l16);
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
else if(types&1){
f(_not,j,l8);
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
else if(types&2){
f(_not,j,u8);
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
goal[j] ^= t64[j];
}
}
rep(i,0,31){
rep(j,0,2){
if(t64[j]&rx[3]) f(_xor,j,3);
if(t32[j]&rx[3]) f(_xor,j,3,l32);
}
f(_add,3,3);
}
f(_xor,1,0);
f(_xor,2,0);
}
void outer2(vvull goals){
rep(t,0,n-1){
vull goal = best_permute(inner2,goals[t]);
inner2(goal);
}
}
void solve2(){
f(_inc,3,u8); //8
f(_mul,3,3); //16
f(_mul,3,3); //32
vvull goals = a;
tsp_permute(inner2,goals);
outer2(goals);
}
void solve26(){
f(_inc,3,u8); //8
f(_mov,0,3);
f(_mul,3,3); //16
f(_mul,3,3); //32
f(_inc,3,u8); //32,8
f(_mul,3,3,l32); //32,16
f(_inc,3); //32,16,0
f(_mul,3,0); //40,24,8
rep(t,0,n-1){
if(t > 0){
f(_sub,1,1);
f(_sub,2,2);
}
vull goal = a[t];
goal[1] ^= goal[0];
goal[2] ^= goal[0];
{
vull intermediate(3);
ull m = (ull(1)<<48)+(ull(1)<<32)+(ull(1)<<16);
rep(i,0,2){
try{
intermediate[i] = choose(rx[i],goal[i]);
}catch(...){
f(_sub,i,i);
intermediate[i] = choose(rx[i],goal[i]);
}
}
rep(i,0,7){
rep(j,0,2)
if((rx[j]^intermediate[j]) & (1ull<<(40+i)))
f(_xor,j,3);
rep(j,0,2)
if((rx[j]^intermediate[j]) & (1ull<<(24+i)))
f(_xor,j,3,l32);
rep(j,0,2)
if((rx[j]^intermediate[j]) & (1ull<<(8+i)))
f(_xor,j,3,u8,u8);
rep(j,0,2)
if((rx[j]^intermediate[j]) & (1ull<<(i)))
f(_xor,j,3,l8,u8);
f(_add,3,3);
}
assert(rx[3] == m);
rep(j,0,2)
f(_mul,j,3);
make_rx3_rem();
f(_inc,3);
rep(i,0,7){
rep(j,0,2)
if((rx[j]^goal[j]) & (1ull<<(32+i)))
f(_xor,j,3);
rep(j,0,2)
if((rx[j]^goal[j]) & (1ull<<(16+i)))
f(_xor,j,3,l32);
rep(j,0,2)
if((rx[j]^goal[j]) & (1ull<<(8+i)))
f(_xor,j,3,u8,l8);
rep(j,0,2)
if((rx[j]^goal[j]) & (1ull<<(i)))
f(_xor,j,3,l8,l8);
f(_add,3,3);
}
rep(j,0,2) assert((rx[j]^goal[j])==0);
}
f(_xor,1,0);
f(_xor,2,0);
}
}
void solve5(){
f(_inc,3,u8); //8
f(_mul,3,3); //16
f(_mul,3,3); //32
rep(t,0,n-1){
if(t > 0){
f(_add,2,0);
f(_add,2,1);
}
f(_inc,3); //32,1
vull goal = a[t];
vull t64(3);
vull t32(3);
rep(j,0,2){
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
}
rep(i,0,31){
rep(j,0,1+(t==0)){
if(t64[j]&rx[3]) f(_xor,j,3);
if(t32[j]&rx[3]) f(_xor,j,3,l32);
}
f(_add,3,3);
}
if(t > 0){
f(_sub,2,0);
f(_sub,2,1);
}
}
}
bool comp(const vull &a, const vull &b){
return a[1]-a[0] < b[1]-b[0];
}
void solve3(){
sort(all(a),comp);
f(_inc,3,u8); //8
f(_mul,3,3); //16
f(_mul,3,3); //32
rep(t,0,n-1){
f(_inc,3); //32,1
vull goal = a[t];
vull t64(3);
vull t32(3);
if(t%8)
f(_sub,2,1);
rep(j,0,2){
t64[j] = (goal[j]^rx[j])>>32;
goal[j] ^= t64[j];
t32[j] = ((goal[j]^rx[j])<<32)>>32;
}
rep(i,0,31){
rep(j,0,2*(t%8 == 0)){
if(t64[j]&rx[3]) f(_xor,j,3);
if(t32[j]&rx[3]) f(_xor,j,3,l32);
}
f(_add,3,3);
}
if(t%8){
f(_mov,1,0);
f(_add,1,2);
f(_add,2,1);
}
}
}
void inner36_8(vull goal, int t2){
sort(all(goal));
if(t2)
f(_sub,2,1);
{
int endp = 0+2*(t2 == 0);
vull intermediate(3);
ull m = (ull(1)<<48)+(ull(1)<<32)+(ull(1)<<16);
rep(i,0,endp){
try{
intermediate[i] = choose(rx[i],goal[i]);
}catch(...){
f(_sub,i,i);
intermediate[i] = choose(rx[i],goal[i]);
}
}
rep(i,0,7){
rep(j,0,endp)
if((rx[j]^intermediate[j]) & (1ull<<(40+i)))
f(_xor,j,3);
rep(j,0,endp)
if((rx[j]^intermediate[j]) & (1ull<<(24+i)))
f(_xor,j,3,l32);
rep(j,0,endp)
if((rx[j]^intermediate[j]) & (1ull<<(8+i)))
f(_xor,j,3,u8,u8);
rep(j,0,endp)
if((rx[j]^intermediate[j]) & (1ull<<(i)))
f(_xor,j,3,l8,u8);
f(_add,3,3);
}
assert(rx[3] == m);
rep(j,0,endp)
f(_mul,j,3);
make_rx3_rem();
f(_inc,3);
rep(i,0,7){
rep(j,0,endp)
if((rx[j]^goal[j]) & (1ull<<(32+i)))
f(_xor,j,3);
rep(j,0,endp)
if((rx[j]^goal[j]) & (1ull<<(16+i)))
f(_xor,j,3,l32);
rep(j,0,endp)
if((rx[j]^goal[j]) & (1ull<<(8+i)))
f(_xor,j,3,u8,l8);
rep(j,0,endp)
if((rx[j]^goal[j]) & (1ull<<(i)))
f(_xor,j,3,l8,l8);
f(_add,3,3);
}
if(t2){
f(_mov,1,0);
f(_add,1,2);
f(_add,2,1);
}
rep(j,0,2) assert((rx[j]^goal[j])==0);
}
}
void inner36_8_0(vull goal){
inner36_8(goal,0);
}
void inner36_8_1(vull goal){
inner36_8(goal,1);
}
void outer36(vvull goals){
rep(t2,0,7){
if(t2 == 0){
goals[t2] = best_permute(inner36_8_0,goals[t2]);
inner36_8_0(goals[t2]);
}
else{
goals[t2] = best_permute(inner36_8_1,goals[t2]);
inner36_8_1(goals[t2]);
}
}
}
void far_out36(vector<vvull> goals){
rep(i,0,7)
outer36(goals[i]);
}
void solve36(){
sort(all(a),comp);
f(_inc,3,u8); //8
f(_mov,0,3);
f(_mul,3,3); //16
f(_mul,3,3); //32
f(_inc,3,u8); //32,8
f(_mul,3,3,l32); //32,16
f(_inc,3); //32,16,0
f(_mul,3,0); //40,24,8
vvull goals = a;
vector<vvull> buckets(8),best;
rep(i,0,7){
buckets[i] = vvull(goals.begin()+i*8,goals.begin()+(i+1)*8);
tsp_permute(inner36_8_1,buckets[i]);
}
best = buckets;
int best_cost = MOD;
rep(attempts,0,400){
ll cur_cost = mock(far_out36,buckets);
if(cur_cost < best_cost){
best_cost = cur_cost;
best = buckets;
}
random_shuffle(all(buckets));
}
far_out36(buckets);
}
//if(!keep_changes)
//if(!keep_changes){
void _(){
ll total = 0;
ll display = 0;
int cnt = 0;
while(cin >> n){
++cnt;
if(cnt > 5)
break;
a = vvull(n,vull(3)); cin >> a;
type = get_type();
if(type != 4){
for(auto &_ : a)
sort(all(_));
sort(all(a));
}
//if(type != 2) continue;
if(type == 4)
solve4();
else if(type == 2)
solve2();
else if(type == 3)
solve36();
else if(type == 5)
solve56();
else
solve16();
check(a);
//assert(type != 1);
if(type == 1){
}
cerr << type << ' ' << sz(description) << '\n';;
print(sz(description));
print(description,"\n");
total += sz(description);
if(type == 2 || type == 4 || type == 5)
display += sz(description);
description.clear();
memset(rx,0,sizeof rx);
}
watch(total);
watch(display/2);
}
void tsp_permute(void (*to_test)(vull), vvull &goals){
calc_dist(to_test,goals);
vi order;
if(sz(goals) > 8){
order = decent_order(sz(goals));
}
else{
vi ans(8);
iota(all(ans),0);
vi best;
int best_cost = MOD;
do{
ll cur_cost = 0;
rep(i,1,7)
cur_cost += dist[ans[i-1]][ans[i]];
if(cur_cost < best_cost){
best_cost = cur_cost;
best = ans;
}
}while(next_permutation(all(ans)));
order = best;
}
set_order(goals,order);
}
vvull rand_permute(void (*to_test)(vvull), vvull goals, int rand_times){
sort(all(goals));
vvull best = goals;
int best_cost = MOD;
rep(attempts,0,rand_times){
int cur_cost = mock(to_test,goals);
if(cur_cost < best_cost){
best_cost = cur_cost;
best = goals;
}
random_shuffle(all(goals));
}
return best;
}
vull best_permute(void (*to_test)(vull), vull goal){
sort(all(goal));
vull best = goal;
int best_cost = MOD;
do{
int cur_cost = mock(to_test,get_state(),goal);
if(cur_cost < best_cost){
best_cost = cur_cost;
best = goal;
}
}while(next_permutation(all(goal)));
return best;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout << fixed << setprecision(15);
_();
}
I3ByYWdtYSBHQ0Mgb3B0aW1pemUoIk9mYXN0IikKI2luY2x1ZGUgPGNzdHJpbmc+CiNpbmNsdWRlIDxudW1lcmljPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPHF1ZXVlPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8Y2Fzc2VydD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHN0cmluZz4KLy8jZGVmaW5lIGFzc2VydCh4KSA7CiNkZWZpbmUgcGIgcHVzaF9iYWNrCiNkZWZpbmUgUkVQX0FOWSh0eXBlLGksbCxyKSBmb3IodHlwZSBpID0gbDsgaSA8PSByOyArK2kpCiNkZWZpbmUgUkVQX0lOVChpLGwscikgZm9yKGludCBpID0gbDsgaSA8PSByOyArK2kpCiNkZWZpbmUgR0VUX1JFUF9NQUNSTyhfMSxfMixfMyxfNCxOQU1FLC4uLikgTkFNRQojZGVmaW5lIHJlcCguLi4pIEdFVF9SRVBfTUFDUk8oX19WQV9BUkdTX18sUkVQX0FOWSxSRVBfSU5UKShfX1ZBX0FSR1NfXykKI2RlZmluZSBhbGwodikgKHYpLmJlZ2luKCksICh2KS5lbmQoKQojZGVmaW5lIHN6KHYpIGxsKHYuc2l6ZSgpKQojZGVmaW5lIHdhdGNoKHgpIGNlcnIgPDwgKCN4KSA8PCAiID0gIiA8PCB4IDw8ICdcbicKI2RlZmluZSBYIGZpcnN0CiNkZWZpbmUgWSBzZWNvbmQKI2RlZmluZSBUMSB0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBzdGF0aWMKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdHlwZWRlZiBsb25nIGxvbmcgbGw7CnR5cGVkZWYgdW5zaWduZWQgaW50IHVpbnQ7CnR5cGVkZWYgdW5zaWduZWQgY2hhciB1Y2hhcjsKdHlwZWRlZiB1bnNpZ25lZCBsb25nIGxvbmcgdWxsOwp0eXBlZGVmIHZlY3RvcjxpbnQ+IHZpOwp0eXBlZGVmIHZlY3RvcjxzdHJpbmc+IHZzOwp0eXBlZGVmIHZlY3Rvcjx2aT4gdnZpOwp0eXBlZGVmIHBhaXI8aW50LCBpbnQ+IHBpaTsKdHlwZWRlZiB2ZWN0b3I8cGlpPiB2cGlpOwpib29sIHNhdmluZyA9IHRydWU7CgoKY29uc3QgbGwgTU9EID0gMWU5ICsgNzsKCmxsIGlwb3cobGwgeCwgbGwgcCwgbGwgbW9kID0gTU9EKXsKICAgIGlmKGFicyh4KSA+PSBtb2QpCiAgICAgICAgeCAlPSBtb2Q7CiAgICBpZih4IDwgMCkKICAgICAgICB4ICs9IG1vZDsKICAgIGlmKHAgPT0gMCkKICAgICAgICByZXR1cm4gMTsKICAgIGlmKHAgPT0gMSkKICAgICAgICByZXR1cm4geDsKICAgIHJldHVybiBpcG93KHggKiB4ICUgbW9kLCBwIC8gMiwgbW9kKSAqIGlwb3coeCwgcCAlIDIsIG1vZCkgJSBtb2Q7Cn0KVDEgb3N0cmVhbSYgb3BlcmF0b3I8PChvc3RyZWFtJiBzdHJlYW0sIGNvbnN0IHZlY3RvcjxUPiYgdCk7CnRlbXBsYXRlIDx0eXBlbmFtZSBGLCB0eXBlbmFtZSBTPiBzdGF0aWMKb3N0cmVhbSYgb3BlcmF0b3I8PChvc3RyZWFtJiBzdHJlYW0sIGNvbnN0IHBhaXI8RiwgUz4mIHQpewogICAgcmV0dXJuIHN0cmVhbSA8PCB0LmZpcnN0IDw8ICcgJyA8PCB0LnNlY29uZDsKfQp0ZW1wbGF0ZSA8dHlwZW5hbWUgRiwgdHlwZW5hbWUgUz4gc3RhdGljCmlzdHJlYW0mIG9wZXJhdG9yPj4oaXN0cmVhbSYgc3RyZWFtLCBwYWlyPEYsIFM+JiB0KXsKICAgIHJldHVybiBzdHJlYW0gPj4gdC5maXJzdCA+PiB0LnNlY29uZDsKfQpUMSB2ZWN0b3I8VD4gdW5pcXVlKHZlY3RvcjxUPiYgYXJyKXsKICAgIHNvcnQoYWxsKGFycikpOwogICAgYXJyLmVyYXNlKHVuaXF1ZShhbGwoYXJyKSksIGFyci5lbmQoKSk7CiAgICByZXR1cm4gYXJyOwp9CnN0YXRpYyBzdHJpbmcgdW5pcXVlKHN0cmluZyYgcyl7CiAgICBzb3J0KGFsbChzKSk7CiAgICBzLmVyYXNlKHVuaXF1ZShhbGwocykpLCBzLmVuZCgpKTsKICAgIHJldHVybiBzOwp9ClQxIGlzdHJlYW0mIHJlYWQoVCwgVCwgaXN0cmVhbSYgPSBjaW4pOwpUMSBpc3RyZWFtJiBvcGVyYXRvcj4+KGlzdHJlYW0mIHN0cmVhbSwgdmVjdG9yPFQ+JiB0KXsKICAgIHJldHVybiByZWFkKGFsbCh0KSwgc3RyZWFtKTsKfQpUMSBpc3RyZWFtJiByZWFkKFQgYiwgVCBlLCBpc3RyZWFtJiBzdHJlYW0pewogICAgZm9yKFQgaXQgPSBiOyBpdCAhPSBlOyArK2l0KQogICAgICAgIHN0cmVhbSA+PiAqaXQ7CiAgICByZXR1cm4gc3RyZWFtOwp9CnN0cnVjdCBEU1V7CiAgICB2aSBwYXI7CiAgICBpbnQgbjsKICAgIERTVShpbnQgX24pOm4oX24pewogICAgICAgIHBhci5yZXNpemUobiArIDEpOwogICAgICAgIGlvdGEoYWxsKHBhciksIDApOwogICAgfQogICAgaW50IGdldHBhcihpbnQgdSl7CiAgICAgICAgaWYocGFyW3Bhclt1XV0gPT0gcGFyW3VdKQogICAgICAgICAgICByZXR1cm4gcGFyW3VdOwogICAgICAgIHJldHVybiBwYXJbdV0gPSBnZXRwYXIocGFyW3VdKTsKICAgIH0KICAgIGJvb2wgdW5pdGUoaW50IHUsIGludCB2KXsKICAgICAgICB1ID0gZ2V0cGFyKHUpOwogICAgICAgIHYgPSBnZXRwYXIodik7CiAgICAgICAgaWYodSA9PSB2KQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgcGFyW3VdID0gdjsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfTsKVDEgVCBzdW0odmVjdG9yPFQ+JiBhcnIpewogICAgVCBhbnMgPSAwOwogICAgZm9yKGF1dG8geCA6IGFycikKICAgICAgICBhbnMgKz0geDsKICAgIHJldHVybiBhbnM7Cn0KVDEgVCBzdW0odmVjdG9yPFQ+JiYgYXJyKXsKICAgIFQgYW5zID0gMDsKICAgIGZvcihhdXRvIHggOiBhcnIpCiAgICAgICAgYW5zICs9IHg7CiAgICByZXR1cm4gYW5zOwp9CnRlbXBsYXRlIDx0eXBlbmFtZSBDT1NUX1RZUEUgPSBsbD4Kc3RydWN0IE1heEZsb3d7CiAgICBjb25zdCBDT1NUX1RZUEUgQ09TVF9JTkYgPSBudW1lcmljX2xpbWl0czxDT1NUX1RZUEU+OjptYXgoKTsKICAgIGNvbnN0IGxsIEZMT1dfSU5GID0gMWUxODsKICAgIGJvb2wgbmVlZHNfcHJlcDsKICAgIHN0cnVjdCBGbG93VHJhY2tlcnsKICAgICAgICBsbCAqY2FwLCAqcmNhcDsKICAgICAgICBzaGFyZWRfcHRyPGxsPiBmbG93OwogICAgICAgIGJvb2wgZGlyOwogICAgICAgIEZsb3dUcmFja2VyKCl7CiAgICAgICAgICAgIGRpciA9IDA7CiAgICAgICAgICAgIGNhcCA9IHJjYXAgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBGbG93VHJhY2tlcihsbCAqX2NhcCwgbGwgKl9yY2FwLCBzaGFyZWRfcHRyPGxsPiBfZmxvdywgaW50IF9kaXIpCiAgICAgICAgICAgIDpjYXAoX2NhcCksIHJjYXAoX3JjYXApLCBmbG93KF9mbG93KSwgZGlyKF9kaXIpewogICAgICAgICAgICB9CiAgICAgICAgbGwgcmVtKCljb25zdHsKICAgICAgICAgICAgaWYoZGlyID09IDApewogICAgICAgICAgICAgICAgcmV0dXJuICpjYXAgLSAqZmxvdzsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICByZXR1cm4gKnJjYXAgKyAqZmxvdzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB2b2lkIGFkZF9mbG93KGxsIGYpewogICAgICAgICAgICBpZihkaXIgPT0gMCkKICAgICAgICAgICAgICAgICpmbG93ICs9IGY7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICpmbG93IC09IGY7CiAgICAgICAgICAgIGFzc2VydCgqZmxvdyA8PSAqY2FwKTsKICAgICAgICAgICAgYXNzZXJ0KC0qZmxvdyA8PSAqcmNhcCk7CiAgICAgICAgfQogICAgICAgIG9wZXJhdG9yIGxsKCljb25zdHsKICAgICAgICAgICAgcmV0dXJuIHJlbSgpOwogICAgICAgIH0KICAgICAgICB2b2lkIGNsZWFyKCl7CiAgICAgICAgICAgICpmbG93ID0gMDsKICAgICAgICB9CiAgICAgICAgdm9pZCBvcGVyYXRvci09KGxsIHgpewogICAgICAgICAgICBhZGRfZmxvdyh4KTsKICAgICAgICB9CiAgICAgICAgdm9pZCBvcGVyYXRvcis9KGxsIHgpewogICAgICAgICAgICBhZGRfZmxvdygteCk7CiAgICAgICAgfQogICAgfTsKICAgIHN0cnVjdCBFZGdlewogICAgICAgIGludCB1LCB2OwogICAgICAgIGxsIGMsIHJjOwogICAgICAgIENPU1RfVFlQRSBjb3N0OwogICAgICAgIEZsb3dUcmFja2VyIGZsb3c7CiAgICAgICAgRWRnZSgpe30KICAgICAgICBFZGdlKGludCBfdSwgaW50IF92LCBsbCBfYywgQ09TVF9UWVBFIF9jb3N0ID0gMCkKICAgICAgICAgICAgOnUoX3UpLCB2KF92KSwgYyhfYyksIGNvc3QoX2Nvc3QpewogICAgICAgICAgICAgICAgcmMgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgdm9pZCBjaGFuZ2VfY2FwKGxsIF9jLCBsbCBfcmMgPSAwKXsKICAgICAgICAgICAgYyA9IF9jOwogICAgICAgICAgICByYyA9IF9yYzsKICAgICAgICB9CiAgICB9OwogICAgaW50IHNvdXJjZSwgc2luaywgcnRfc291cmNlLCBydF9zaW5rOwogICAgTWF4RmxvdyhpbnQgX3NvdXJjZSA9IG51bWVyaWNfbGltaXRzPGludD46Om1pbigpLCBpbnQgX3NpbmsgPSBudW1lcmljX2xpbWl0czxpbnQ+OjptaW4oKSArIDEpOnNvdXJjZShfc291cmNlKSwgc2luayhfc2luayl7CiAgICAgICAgbmVlZHNfcHJlcCA9IHRydWU7CiAgICB9CiAgICB2ZWN0b3I8dmVjdG9yPGludD4+IGFkajsKICAgIHZlY3Rvcjx2ZWN0b3I8Q09TVF9UWVBFPj4gY29zdDsKICAgIHZlY3Rvcjx2ZWN0b3I8Rmxvd1RyYWNrZXI+PiBjYXA7CiAgICB2ZWN0b3I8RWRnZT4gZWRnZXM7CiAgICBpbnQgYWRkX2VkZ2UoaW50IHUsIGludCB2LCBsbCBjLCBDT1NUX1RZUEUgY29zdCA9IDApewogICAgICAgIG5lZWRzX3ByZXAgPSB0cnVlOwogICAgICAgIGVkZ2VzLnB1c2hfYmFjayhFZGdlKHUsIHYsIGMsIGNvc3QpKTsKICAgICAgICByZXR1cm4gc3ooZWRnZXMpIC0gMTsKICAgIH0KICAgIHZlY3RvcjxpbnQ+IG5vdywgbHZsOwogICAgdmVjdG9yPENPU1RfVFlQRT4gcG90OwogICAgdmkgaW5kaWNlczsKICAgIHZvaWQgcHJlcCgpewogICAgICAgIGlmKCFuZWVkc19wcmVwKXsKICAgICAgICAgICAgZm9yKGF1dG8gJl8gOiBlZGdlcykKICAgICAgICAgICAgICAgIF8uZmxvdy5jbGVhcigpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIG5lZWRzX3ByZXAgPSBmYWxzZTsKICAgICAgICBpbmRpY2VzID0gdml7c291cmNlLHNpbmt9OwogICAgICAgIGZvcihhdXRvJiBlZGdlIDogZWRnZXMpewogICAgICAgICAgICBpbmRpY2VzLnB1c2hfYmFjayhlZGdlLnUpOwogICAgICAgICAgICBpbmRpY2VzLnB1c2hfYmFjayhlZGdlLnYpOwogICAgICAgIH0KICAgICAgICBzb3J0KGluZGljZXMuYmVnaW4oKSwgaW5kaWNlcy5lbmQoKSk7CiAgICAgICAgaW5kaWNlcy5lcmFzZSh1bmlxdWUoaW5kaWNlcy5iZWdpbigpLCBpbmRpY2VzLmVuZCgpKSwgaW5kaWNlcy5lbmQoKSk7CiAgICAgICAgcnRfc291cmNlID0gbG93ZXJfYm91bmQoaW5kaWNlcy5iZWdpbigpLCBpbmRpY2VzLmVuZCgpLCBzb3VyY2UpIC0gaW5kaWNlcy5iZWdpbigpOwogICAgICAgIHJ0X3NpbmsgPSBsb3dlcl9ib3VuZChpbmRpY2VzLmJlZ2luKCksIGluZGljZXMuZW5kKCksIHNpbmspIC0gaW5kaWNlcy5iZWdpbigpOwogICAgICAgIGFkai5jbGVhcigpOwogICAgICAgIGNvc3QuY2xlYXIoKTsKICAgICAgICBjYXAuY2xlYXIoKTsKICAgICAgICBub3cuY2xlYXIoKTsKICAgICAgICBsdmwuY2xlYXIoKTsKICAgICAgICBwb3QuY2xlYXIoKTsKICAgICAgICBpbnQgbWF4X2lkID0gc3ooaW5kaWNlcykgLSAxOwogICAgICAgIGFkai5yZXNpemUobWF4X2lkICsgMSk7CiAgICAgICAgY29zdC5yZXNpemUobWF4X2lkICsgMSk7CiAgICAgICAgY2FwLnJlc2l6ZShtYXhfaWQgKyAxKTsKICAgICAgICBub3cucmVzaXplKG1heF9pZCArIDEpOwogICAgICAgIGx2bC5yZXNpemUobWF4X2lkICsgMSk7CiAgICAgICAgcG90LnJlc2l6ZShtYXhfaWQgKyAxKTsKCiAgICAgICAgdmkgb3JkZXJpbmcoc3ooZWRnZXMpKTsKICAgICAgICBpb3RhKGFsbChvcmRlcmluZyksMCk7CiAgICAgICAgcmFuZG9tX3NodWZmbGUoYWxsKG9yZGVyaW5nKSk7CgogICAgICAgIGZvcihpbnQgaWQgOiBvcmRlcmluZyl7CiAgICAgICAgICAgIGF1dG8gJmVkZ2UgPSBlZGdlc1tpZF07CiAgICAgICAgICAgIGludCB1ID0gbG93ZXJfYm91bmQoaW5kaWNlcy5iZWdpbigpLCBpbmRpY2VzLmVuZCgpLCBlZGdlLnUpIC0gaW5kaWNlcy5iZWdpbigpOwogICAgICAgICAgICBpbnQgdiA9IGxvd2VyX2JvdW5kKGluZGljZXMuYmVnaW4oKSwgaW5kaWNlcy5lbmQoKSwgZWRnZS52KSAtIGluZGljZXMuYmVnaW4oKTsKICAgICAgICAgICAgYXV0byBmbG93ID0gbWFrZV9zaGFyZWQ8bGw+KDApOwogICAgICAgICAgICBhZGpbdV0ucHVzaF9iYWNrKHYpOwogICAgICAgICAgICBjb3N0W3VdLnB1c2hfYmFjayhlZGdlLmNvc3QpOwogICAgICAgICAgICBjYXBbdV0ucHVzaF9iYWNrKEZsb3dUcmFja2VyKCZlZGdlLmMsICZlZGdlLnJjLCBmbG93LCAwKSk7CiAgICAgICAgICAgIGlmKHUgIT0gdil7CiAgICAgICAgICAgICAgICBhZGpbdl0ucHVzaF9iYWNrKHUpOwogICAgICAgICAgICAgICAgY29zdFt2XS5wdXNoX2JhY2soLWVkZ2UuY29zdCk7CiAgICAgICAgICAgICAgICBjYXBbdl0ucHVzaF9iYWNrKEZsb3dUcmFja2VyKCZlZGdlLmMsICZlZGdlLnJjLCBmbG93LCAxKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYXNzZXJ0KGNhcFt1XS5iYWNrKCkgPT0gZWRnZS5jKTsKICAgICAgICAgICAgZWRnZS5mbG93ID0gY2FwW3ZdLmJhY2soKTsKICAgICAgICB9CiAgICB9CiAgICBpbnQgZ2V0X25hbWUoaW50IHgpewogICAgICAgIGF1dG8gaXQgPSBsb3dlcl9ib3VuZChhbGwoaW5kaWNlcykseCk7CiAgICAgICAgaWYoaXQgPT0gaW5kaWNlcy5lbmQoKSB8fCAqaXQgIT0geCl7CiAgICAgICAgICAgIGluZGljZXMucGIoeCk7CiAgICAgICAgICAgIHVuaXF1ZShpbmRpY2VzKTsKICAgICAgICAgICAgbmVlZHNfcHJlcCA9IHRydWU7CiAgICAgICAgICAgIGl0ID0gbG93ZXJfYm91bmQoYWxsKGluZGljZXMpLHgpOwogICAgICAgIH0KICAgICAgICBhc3NlcnQoKml0ID09IHgpOwogICAgICAgIHJldHVybiBpdC1pbmRpY2VzLmJlZ2luKCk7CiAgICB9CiAgICB2b2lkIHNldF9zb3VyY2UoaW50IF9zb3VyY2UpewogICAgICAgIGlmKHNvdXJjZSA9PSBfc291cmNlKSByZXR1cm47CiAgICAgICAgc291cmNlID0gX3NvdXJjZTsKICAgICAgICBydF9zb3VyY2UgPSBnZXRfbmFtZShzb3VyY2UpOwogICAgfQogICAgdm9pZCBzZXRfc2luayhpbnQgX3NpbmspewogICAgICAgIGlmKHNpbmsgPT0gX3NpbmspIHJldHVybjsKICAgICAgICBzaW5rID0gX3Npbms7CiAgICAgICAgcnRfc2luayA9IGdldF9uYW1lKHNpbmspOwogICAgfQogICAgdm9pZCBiZWxsbWFuX2ZvcmQoKXsKICAgICAgICB2ZWN0b3I8Q09TVF9UWVBFPiBkaXN0KHN6KGFkaiksIENPU1RfSU5GKTsKICAgICAgICBkaXN0W3J0X3NvdXJjZV0gPSAwOwogICAgICAgIC8vZm9yKGludCB0aW1lcyA9IDA7IHRpbWVzIDwgc3ooZGlzdCk7ICsrdGltZXMpewogICAgICAgIHdoaWxlKHRydWUpewogICAgICAgICAgICBib29sIGNoYW5nZXMgPSBmYWxzZTsKICAgICAgICAgICAgZm9yKGludCB1ID0gMDsgdSA8IHN6KGFkaik7ICsrdSkKICAgICAgICAgICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBzeihhZGpbdV0pOyArK2kpewogICAgICAgICAgICAgICAgICAgIGludCB2ID0gYWRqW3VdW2ldOwogICAgICAgICAgICAgICAgICAgIGlmKGRpc3RbdV0gIT0gQ09TVF9JTkYgJiYgY2FwW3VdW2ldKXsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoZGlzdFt2XSA+IGRpc3RbdV0gKyBjb3N0W3VdW2ldKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZXMgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzdFt2XSA9IGRpc3RbdV0gKyBjb3N0W3VdW2ldOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBpZighY2hhbmdlcykKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBwb3QgPSBkaXN0OwogICAgfQogICAgbGwgZGlqa3N0cmEodmVjdG9yPENPU1RfVFlQRT4mIGRpc3QsIHZlY3RvcjxpbnQ+JiBsYXN0X25vZGUsIHZlY3RvcjxpbnQ+JiBsYXN0X2luZGV4KXsKICAgICAgICBkaXN0W3J0X3NvdXJjZV0gPSAwOwogICAgICAgIHZlY3RvcjxsbD4gZmxvdyhzeihkaXN0KSk7CiAgICAgICAgZmxvd1tydF9zb3VyY2VdID0gRkxPV19JTkY7CiAgICAgICAgdmVjdG9yPGJvb2w+IHZpc2l0ZWQoc3ooZGlzdCkpOwogICAgICAgIHByaW9yaXR5X3F1ZXVlPHBhaXI8Q09TVF9UWVBFLCBpbnQ+PiBwcTsKICAgICAgICBwcS5wdXNoKHswLCBydF9zb3VyY2V9KTsKICAgICAgICB3aGlsZSghcHEuZW1wdHkoKSl7CiAgICAgICAgICAgIGludCB1ID0gcHEudG9wKCkuc2Vjb25kOwogICAgICAgICAgICBwcS5wb3AoKTsKICAgICAgICAgICAgaWYodmlzaXRlZFt1XSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB2aXNpdGVkW3VdID0gdHJ1ZTsKICAgICAgICAgICAgYXNzZXJ0KGRpc3RbdV0gIT0gQ09TVF9JTkYpOwogICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgc3ooYWRqW3VdKTsgKytpKXsKICAgICAgICAgICAgICAgIGludCB2ID0gYWRqW3VdW2ldOwogICAgICAgICAgICAgICAgaWYoIXZpc2l0ZWRbdl0gJiYgY2FwW3VdW2ldKQogICAgICAgICAgICAgICAgICAgIGlmKGRpc3RbdV0gKyBjb3N0W3VdW2ldICsgcG90W3VdIC0gcG90W3ZdIDwgZGlzdFt2XSl7CiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3Rbdl0gPSBkaXN0W3VdICsgY29zdFt1XVtpXSArIHBvdFt1XSAtIHBvdFt2XTsKICAgICAgICAgICAgICAgICAgICAgICAgbGFzdF9ub2RlW3ZdID0gdTsKICAgICAgICAgICAgICAgICAgICAgICAgbGFzdF9pbmRleFt2XSA9IGk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZsb3dbdl0gPSBtaW4oZmxvd1t1XSwgKGxsKWNhcFt1XVtpXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHBxLnB1c2goey1kaXN0W3ZdLCB2fSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmbG93W3J0X3NpbmtdOwogICAgfQogICAgcGFpcjxsbCwgQ09TVF9UWVBFPiBtaW5fY29zdF9mbG93KGludCBfc291cmNlLCBpbnQgX3NpbmspewogICAgICAgIHNldF9zb3VyY2UoX3NvdXJjZSk7CiAgICAgICAgc2V0X3NpbmsoX3NpbmspOwogICAgICAgIHByZXAoKTsKICAgICAgICBib29sIGhhc19uZWdhdGl2ZSA9IGZhbHNlOwogICAgICAgIGZvcihhdXRvJiBlZGdlIDogZWRnZXMpCiAgICAgICAgICAgIGlmKGVkZ2UuY29zdCA8IDApCiAgICAgICAgICAgICAgICBoYXNfbmVnYXRpdmUgPSB0cnVlOwogICAgICAgIGlmKGhhc19uZWdhdGl2ZSkKICAgICAgICAgICAgYmVsbG1hbl9mb3JkKCk7CiAgICAgICAgbGwgdG90YWxfZmxvdyA9IDA7CiAgICAgICAgQ09TVF9UWVBFIHRvdGFsX2Nvc3QgPSAwOwogICAgICAgIHdoaWxlKHRydWUpewogICAgICAgICAgICB2ZWN0b3I8Q09TVF9UWVBFPiBkaXN0KHN6KGFkaiksIENPU1RfSU5GKTsKICAgICAgICAgICAgdmVjdG9yPGludD4gbGFzdF9ub2RlKHN6KGRpc3QpKSwgbGFzdF9pbmRleChzeihkaXN0KSk7CiAgICAgICAgICAgIGxsIGZsb3cgPSBkaWprc3RyYShkaXN0LCBsYXN0X25vZGUsIGxhc3RfaW5kZXgpOwogICAgICAgICAgICBpZihmbG93ID09IDApCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZm9yKGludCB1ID0gcnRfc2luazsgdSAhPSBydF9zb3VyY2U7IHUgPSBsYXN0X25vZGVbdV0pCiAgICAgICAgICAgICAgICBjYXBbbGFzdF9ub2RlW3VdXVtsYXN0X2luZGV4W3VdXSAtPSBmbG93OwogICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgc3ooYWRqKTsgKytpKQogICAgICAgICAgICAgICAgcG90W2ldID0gcG90W2ldICsgZGlzdFtpXTsKICAgICAgICAgICAgdG90YWxfZmxvdyArPSBmbG93OwogICAgICAgICAgICB0b3RhbF9jb3N0ICs9IHBvdFtydF9zaW5rXSAqIGZsb3c7CiAgICAgICAgfQogICAgICAgIHJldHVybiB7dG90YWxfZmxvdywgdG90YWxfY29zdH07CiAgICB9CiAgICBwYWlyPGxsLCBDT1NUX1RZUEU+IG1pbl9jb3N0X2Zsb3coKXsKICAgICAgICByZXR1cm4gbWluX2Nvc3RfZmxvdyhzb3VyY2UsIHNpbmspOwogICAgfQp9OwpUMSBUIG1heChjb25zdCB2ZWN0b3I8VD4gYXJyKXsKICAgIGFzc2VydCghYXJyLmVtcHR5KCkpOwogICAgVCBhbnMgPSBhcnJbMF07CiAgICBmb3IoYXV0byYgY3VyIDogYXJyKQogICAgICAgIGFucyA9IG1heChhbnMsIGN1cik7CiAgICByZXR1cm4gYW5zOwp9ClQxIFQgbWluKGNvbnN0IHZlY3RvcjxUPiYgYXJyKXsKICAgIGFzc2VydCghYXJyLmVtcHR5KCkpOwogICAgVCBhbnMgPSBhcnJbMF07CiAgICBmb3IoYXV0byYgY3VyIDogYXJyKQogICAgICAgIGFucyA9IG1pbihhbnMsIGN1cik7CiAgICByZXR1cm4gYW5zOwp9ClQxIFQgbWF4KGNvbnN0IHNldDxUPiYgcyl7CiAgICBhc3NlcnQoIXMuZW1wdHkoKSk7CiAgICByZXR1cm4gKi0tcy5lbmQoKTsKfQpUMSBUIG1pbihjb25zdCBzZXQ8VD4mIHMpewogICAgYXNzZXJ0KCFzLmVtcHR5KCkpOwogICAgcmV0dXJuICpzLmJlZ2luKCk7Cn0KVDEgdm9pZCBwcmludChUIHgsIHN0cmluZyBlbmQgPSAiXG4iKXsKICAgIGNvdXQgPDwgeCA8PCBlbmQ7Cn0KVDEgdm9pZCBwcmludCh2ZWN0b3I8dmVjdG9yPFQ+PiBhcnIpewogICAgZm9yKGludCBpID0gMDsgaSA8IHN6KGFycik7ICsraSl7CiAgICAgICAgY291dCA8PCAiWyIgPDwgYXJyW2ldIDw8ICJdIjsKICAgICAgICBpZihpICsgMSA8IHN6KGFycikpCiAgICAgICAgICAgIGNvdXQgPDwgIiwgIjsKICAgIH0KICAgIGNvdXQgPDwgJ1xuJzsKfQpUMSBvc3RyZWFtJiBwcmludChUIGIsIFQgZSwgc3RyaW5nIHNlcCA9ICIgIiwgb3N0cmVhbSYgc3RyZWFtID0gY291dCl7CiAgICBmb3IoVCBpdCA9IGI7IGl0ICE9IGU7ICsraXQpewogICAgICAgIHN0cmVhbSA8PCAqaXQ7CiAgICAgICAgaWYoaXQgKyAxICE9IGUpCiAgICAgICAgICAgIHN0cmVhbSA8PCBzZXA7CiAgICB9CiAgICByZXR1cm4gc3RyZWFtOwp9ClQxIG9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSYgc3RyZWFtLCBjb25zdCB2ZWN0b3I8VD4mIHQpewogICAgZm9yKGludCBpID0gMDsgaSA8IHN6KHQpOyArK2kpewogICAgICAgIHN0cmVhbSA8PCB0W2ldOwogICAgICAgIGlmKGkrMSA8IHN6KHQpKQogICAgICAgICAgICBzdHJlYW0gPDwgJyAnOwogICAgfQogICAgcmV0dXJuIHN0cmVhbTsKfQpUMSB2b2lkIHByaW50KHZlY3RvcjxUPiBhcnIsIHN0cmluZyBzZXAgPSAiICIpewogICAgaWYoYXJyLmVtcHR5KCkpewogICAgICAgIHJldHVybjsKICAgIH0KICAgIHByaW50KGFyci5iZWdpbigpLCBhcnIuZW5kKCksIHNlcCk7CiAgICBjb3V0IDw8ICdcbic7Cn0KdHlwZWRlZiB2ZWN0b3I8dWxsPiB2dWxsOwp0eXBlZGVmIHZlY3Rvcjx2dWxsPiB2dnVsbDsKaW50IG4sdHlwZTsKdnZ1bGwgYTsKaW50IGRpc3RbNjRdWzY0XTsKdnMgZGVzY3JpcHRpb247CnN0cmluZyBsYXN0X29wZXI7CnVsbCByeFs0XTsKI2RlZmluZSBSRUcgc3RyaW5nKDEsJ2EnK3BvcykKI2RlZmluZSBPUEVSIGlmKHNhdmluZyl7bGFzdF9vcGVyID0gc3RyaW5nKF9fZnVuY19fKS5zdWJzdHIoMSkrbGFzdF9vcGVyO30KdWxsICpsNjQoaW50IHBvcyl7CiAgICBzdHJpbmcgdG1wID0gIiByIitSRUcrIngiOwogICAgaWYoc2F2aW5nKQogICAgICAgIGxhc3Rfb3BlciA9IHRtcCtsYXN0X29wZXI7CiAgICByZXR1cm4gJnJ4W3Bvc107Cn0KdWludCAqbDMyKGludCBwb3MpewogICAgc3RyaW5nIHRtcCA9ICIgZSIrUkVHKyJ4IjsKICAgIGlmKHNhdmluZykKICAgICAgICBsYXN0X29wZXIgPSB0bXArbGFzdF9vcGVyOwogICAgdWludCAqYSA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWludCo+KCZyeFtwb3NdKTsKICAgIHJldHVybiAmYVswXTsKfQp1c2hvcnQgKmwxNihpbnQgcG9zKXsKICAgIHN0cmluZyB0bXAgPSAiICIrUkVHKyJ4IjsKICAgIGlmKHNhdmluZykKICAgICAgICBsYXN0X29wZXIgPSB0bXArbGFzdF9vcGVyOwogICAgdXNob3J0ICphID0gcmVpbnRlcnByZXRfY2FzdDx1c2hvcnQqPigmcnhbcG9zXSk7CiAgICByZXR1cm4gJmFbMF07Cn0KdWNoYXIgKmw4KGludCBwb3MpewogICAgc3RyaW5nIHRtcCA9ICIgIitSRUcrImwiOwogICAgaWYoc2F2aW5nKQogICAgICAgIGxhc3Rfb3BlciA9IHRtcCtsYXN0X29wZXI7CiAgICB1Y2hhciAqYSA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWNoYXIqPigmcnhbcG9zXSk7CiAgICByZXR1cm4gJmFbMF07Cn0KdWNoYXIgKnU4KGludCBwb3MpewogICAgc3RyaW5nIHRtcCA9ICIgIitSRUcrImgiOwogICAgaWYoc2F2aW5nKQogICAgICAgIGxhc3Rfb3BlciA9IHRtcCtsYXN0X29wZXI7CiAgICB1Y2hhciAqYSA9IHJlaW50ZXJwcmV0X2Nhc3Q8dWNoYXIqPigmcnhbcG9zXSk7CiAgICByZXR1cm4gJmFbMV07Cn0KVDEgdm9pZCBfaW5jKFQgKmEpewogICAgKmEgKz0gMTsKICAgIE9QRVI7Cn0KVDEgdm9pZCBfZGVjKFQgKmEpewogICAgKmEgLT0gMTsKICAgIE9QRVI7Cn0KVDEgdm9pZCBfbm90KFQgKmEpewogICAgKmEgPSB+KmE7CiAgICBpZihzYXZpbmcpCiAgICAgICAgbGFzdF9vcGVyID0gIm5vdCIrbGFzdF9vcGVyOwp9ClQxIHZvaWQgX2FuZChUICphLCBUICpiKXsKICAgICphID0gKCphKSAmICgqYik7CiAgICBPUEVSOwp9ClQxIHZvaWQgX29yKFQgKmEsIFQgKmIpewogICAgKmEgPSAoKmEpIHwgKCpiKTsKICAgIE9QRVI7Cn0KVDEgdm9pZCBfeG9yKFQgKmEsIFQgKmIpewogICAgKmEgPSAoKmEpIF4gKCpiKTsKICAgIE9QRVI7Cn0KVDEgdm9pZCBfc2hsKFQgKmEsIFQgKmIpewogICAgKmEgPSAoKmEpIDw8ICgqYik7CiAgICBPUEVSOwp9ClQxIHZvaWQgX3NocihUICphLCBUICpiKXsKICAgICphID0gKCphKSA+PiAoKmIpOwogICAgT1BFUjsKfQpUMSB2b2lkIF9hZGQoVCAqYSwgVCAqYil7CiAgICAqYSA9ICgqYSkgKyAoKmIpOwogICAgT1BFUjsKfQpUMSB2b2lkIF9zdWIoVCAqYSwgVCAqYil7CiAgICAqYSA9ICgqYSkgLSAoKmIpOwogICAgT1BFUjsKfQpUMSB2b2lkIF9tdWwoVCAqYSwgVCAqYil7CiAgICAqYSA9ICgqYSkgKiAoKmIpOwogICAgT1BFUjsKfQpUMSB2b2lkIF9kaXYoVCAqYSwgVCAqYil7CiAgICAvL2Fzc2VydChiKTsKICAgICphID0gKCphKSAvICgqYik7CiAgICBPUEVSOwp9ClQxIHZvaWQgX21vZChUICphLCBUICpiKXsKICAgIC8vYXNzZXJ0KGIpOwogICAgKmEgPSAoKmEpICUgKCpiKTsKICAgIE9QRVI7Cn0KVDEgdm9pZCBfbW92KFQgKmEsIFQgKmIpewogICAgKmEgPSAqYjsKICAgIE9QRVI7Cn0KdnZ1bGwgYWxsX3Zpc2l0ZWQ7CmludCBjbnRfb3A7CnRlbXBsYXRlPHR5cGVuYW1lIFQgPSB1bGwqPgp2b2lkIGYodm9pZCAoKm9wZXIpKFQsVCksIGludCBpLCBpbnQgaiwgVCAoKnR5cGUpKGludCkgPSBsNjQpewogICAgKytjbnRfb3A7CiAgICBvcGVyKHR5cGUoaSksdHlwZShqKSk7CiAgICBpZihzYXZpbmcpewogICAgICAgIGRlc2NyaXB0aW9uLnBiKGxhc3Rfb3Blcik7CiAgICAgICAgYWxsX3Zpc2l0ZWQucGIodnVsbChyeCxyeCs0KSk7CiAgICAgICAgbGFzdF9vcGVyID0gIiI7CiAgICB9Cn0Kdm9pZCBmKHZvaWQgKCpvcGVyKSh1Y2hhciosdWNoYXIqKSwgaW50IGksIGludCBqLCB1Y2hhciogKCp0eXBlaSkoaW50KSwgdWNoYXIqICgqdHlwZWopKGludCkpewogICAgKytjbnRfb3A7CiAgICBvcGVyKHR5cGVpKGkpLHR5cGVqKGopKTsKICAgIGlmKHNhdmluZyl7CiAgICAgICAgZGVzY3JpcHRpb24ucGIobGFzdF9vcGVyKTsKICAgICAgICBhbGxfdmlzaXRlZC5wYih2dWxsKHJ4LHJ4KzQpKTsKICAgICAgICBsYXN0X29wZXIgPSAiIjsKICAgIH0KfQp0ZW1wbGF0ZTx0eXBlbmFtZSBUID0gdWxsKj4Kdm9pZCBmKHZvaWQgKCpvcGVyKShUKSwgaW50IGksIFQgKCp0eXBlKShpbnQpID0gbDY0KXsKICAgICsrY250X29wOwogICAgb3Blcih0eXBlKGkpKTsKICAgIGlmKHNhdmluZyl7CiAgICAgICAgZGVzY3JpcHRpb24ucGIobGFzdF9vcGVyKTsKICAgICAgICBhbGxfdmlzaXRlZC5wYih2dWxsKHJ4LHJ4KzQpKTsKICAgICAgICBsYXN0X29wZXIgPSAiIjsKICAgIH0KfQoKdGVtcGxhdGU8dHlwZW5hbWUgVCA9IHVsbCo+CnVsbCBnKHZvaWQgKCpvcGVyKShULFQpLCBpbnQgaSwgaW50IGosIFQgKCp0eXBlKShpbnQpID0gbDY0KXsKICAgIHVsbCBvbGQgPSByeFtpXTsKICAgIG9wZXIodHlwZShpKSx0eXBlKGopKTsKICAgIGxhc3Rfb3BlciA9ICIiOwogICAgdWxsIG54dCA9IHJ4W2ldOwogICAgcnhbaV0gPSBvbGQ7CiAgICByZXR1cm4gbnh0Owp9CnVsbCBnKHZvaWQgKCpvcGVyKSh1Y2hhciosdWNoYXIqKSwgaW50IGksIGludCBqLCB1Y2hhciogKCp0eXBlaSkoaW50KSwgdWNoYXIqICgqdHlwZWopKGludCkpewogICAgdWxsIG9sZCA9IHJ4W2ldOwogICAgb3Blcih0eXBlaShpKSx0eXBlaihqKSk7CiAgICBsYXN0X29wZXIgPSAiIjsKICAgIHVsbCBueHQgPSByeFtpXTsKICAgIHJ4W2ldID0gb2xkOwogICAgcmV0dXJuIG54dDsKfQp0ZW1wbGF0ZTx0eXBlbmFtZSBUID0gdWxsKj4KdWxsIGcodm9pZCAoKm9wZXIpKFQpLCBpbnQgaSwgVCAoKnR5cGUpKGludCkgPSBsNjQpewogICAgdWxsIG9sZCA9IHJ4W2ldOwogICAgb3Blcih0eXBlKGkpKTsKICAgIGxhc3Rfb3BlciA9ICIiOwogICAgdWxsIG54dCA9IHJ4W2ldOwogICAgcnhbaV0gPSBvbGQ7CiAgICByZXR1cm4gbnh0Owp9CmJvb2wgbWF0Y2godnVsbCBhLCB2dWxsIGIpewogICAgaWYoYS5lbXB0eSgpKQogICAgICAgIHJldHVybiB0cnVlOwogICAgc29ydChhbGwoYSkpOwogICAgc29ydChhbGwoYikpOwogICAgaWYoYS5iYWNrKCkgPT0gYi5iYWNrKCkpewogICAgICAgIGEucG9wX2JhY2soKTsKICAgICAgICBiLnBvcF9iYWNrKCk7CiAgICAgICAgcmV0dXJuIG1hdGNoKGEsYik7CiAgICB9CiAgICBlbHNlewogICAgICAgIGIucG9wX2JhY2soKTsKICAgICAgICByZXR1cm4gYSA9PSBiOwogICAgfQp9CnZvaWQgY2hlY2sodnZ1bGwgYSl7CiAgICBzZXQ8dnVsbD4gc2VlbjsKICAgIGZvcihhdXRvIF8gOiBhKXsKICAgICAgICBzb3J0KGFsbChfKSk7CiAgICAgICAgc2Vlbi5pbnNlcnQoXyk7CiAgICB9CiAgICBmb3IoYXV0byBfIDogYWxsX3Zpc2l0ZWQpewogICAgICAgIHNvcnQoYWxsKF8pKTsKICAgICAgICByZXAoaSwwLDMpewogICAgICAgICAgICB2dWxsIHRtcDsKICAgICAgICAgICAgcmVwKGosMCwzKQogICAgICAgICAgICAgICAgaWYoaSAhPSBqKQogICAgICAgICAgICAgICAgICAgIHRtcC5wYihfW2pdKTsKICAgICAgICAgICAgc2Vlbi5lcmFzZSh0bXApOwogICAgICAgIH0KICAgIH0KICAgIGFzc2VydChzZWVuLmVtcHR5KCkpOwp9CmludCBiaXRzKGxsIHgpewogICAgcmV0dXJuIF9fYnVpbHRpbl9wb3Bjb3VudGxsKHgpOwp9CmludCBnZXRfdHlwZSgpewogICAgaW50IGV2aWRlbmNlXzMgPSAwOwogICAgc2V0PHVsbD4gc3VtczsKICAgIHNldDx1bGw+IHZhbHM7CiAgICBmb3IoYXV0byBfIDogYSl7CiAgICAgICAgaWYoX1syXS1fWzFdID09IF9bMV0tX1swXSl7CiAgICAgICAgICAgICsrZXZpZGVuY2VfMzsKICAgICAgICB9CiAgICAgICAgc3Vtcy5pbnNlcnQoc3VtKF8pKTsKICAgICAgICB2YWxzLmluc2VydChfWzBdKTsKICAgICAgICB2YWxzLmluc2VydChfWzFdKTsKICAgICAgICB2YWxzLmluc2VydChfWzJdKTsKICAgIH0KICAgIGlmKGV2aWRlbmNlXzMgPj0gbikgcmV0dXJuIDM7CiAgICBpZihzeihzdW1zKSA9PSAxKSByZXR1cm4gNTsKICAgIGlmKHN6KHZhbHMpIDw9IDMqbi0xMCkgcmV0dXJuIDQ7CiAgICBib29sIGNhbl8yID0gdHJ1ZTsKICAgIGZvcihhdXRvIF8gOiBhKXsKICAgICAgICBpZihiaXRzKF9bMF1eX1sxXSkgPiA0KQogICAgICAgICAgICBjYW5fMiA9IGZhbHNlOwogICAgICAgIGlmKGJpdHMoX1swXV5fWzJdKSA+IDQpCiAgICAgICAgICAgIGNhbl8yID0gZmFsc2U7CiAgICB9CiAgICBpZihjYW5fMikKICAgICAgICByZXR1cm4gMjsKICAgIHJldHVybiAxOwp9CnN0cmluZyBCKHVsbCB4KXsKICAgIHN0cmluZyBhbnM7CiAgICByZXAoaSwwLDYzKXsKICAgICAgICBpZihpICYmIGklOCA9PSAwKQogICAgICAgICAgICBhbnMucGIoJyAnKTsKICAgICAgICBhbnMucGIoeCUyKycwJyk7CiAgICAgICAgeCA+Pj0gMTsKICAgIH0KICAgIHJldHVybiBhbnM7Cn0KdnVsbCBzeDsKdm9pZCBzYXZlX3N0YXRlKCl7CiAgICBhc3NlcnQoc3guZW1wdHkoKSk7CiAgICBzeCA9IHZ1bGwocngscngrNCk7Cn0Kdm9pZCBsb2FkX3N0YXRlKCl7CiAgICBhc3NlcnQoIXN4LmVtcHR5KCkpOwogICAgcmVwKGksMCwzKQogICAgICAgIHJ4W2ldID0gc3hbaV07CiAgICBzeC5jbGVhcigpOwp9CnZ1bGwgZ2V0X3N0YXRlKCl7CiAgICByZXR1cm4gdnVsbChyeCxyeCs0KTsKfQp2b2lkIHNldF9zdGF0ZSh2dWxsIF9zdGF0ZSl7CiAgICByZXAoaSwwLHN6KF9zdGF0ZSktMSkKICAgICAgICByeFtpXSA9IF9zdGF0ZVtpXTsKfQp1bGwgY2hvb3NlKHVsbCB4LCB1bGwgZyl7CiAgICB1bGwgbSA9ICh1bGwoMSk8PDQ4KSsodWxsKDEpPDwzMikrKHVsbCgxKTw8MTYpOwogICAgcmVwKHQsMCwxKXsKICAgICAgICByZXAoaSwwLDcpCiAgICAgICAgICAgIGlmKCgoKHgqbSleZyk+Pig0OCtpKSklMikKICAgICAgICAgICAgICAgIHggXj0gdWxsKDEpPDxpOwogICAgICAgIHJlcChpLDgsMTUpCiAgICAgICAgICAgIGlmKCgoKHgqbSleZyk+PigxNitpKSklMikKICAgICAgICAgICAgICAgIHggXj0gdWxsKDEpPDxpOwogICAgICAgIHJlcChpLDI0LDMxKQogICAgICAgICAgICBpZigoKCh4Km0pXmcpPj4oMTYraSkpJTIpCiAgICAgICAgICAgICAgICB4IF49IHVsbCgxKTw8aTsKCiAgICAgICAgcmVwKGksNDAsNDcpCiAgICAgICAgICAgIGlmKCgoKHgqbSleZyk+PigxNitpKSklMikKICAgICAgICAgICAgICAgIHggXj0gdWxsKDEpPDxpOwogICAgfQoKICAgIHVsbCBtYXNrID0gKC0xdWxsKV4oKHVsbCgxKTw8NDApLTEpXigodWxsKDEpPDwzMiktMSleKCh1bGwoMSk8PDI0KS0xKTsKICAgIGlmKCgoKHgqbSleZykmbWFzaykpCiAgICAgICAgdGhyb3cgMTsKICAgIHJldHVybiB4Owp9CnVsbCBmYmluKHN0cmluZyBzKXsKICAgIHVsbCBhbnMgPSAwOwogICAgcmV2ZXJzZShhbGwocykpOwogICAgZm9yKGNoYXIgYyA6IHMpewogICAgICAgIGFucyA8PD0gMTsKICAgICAgICBhbnMgKz0gYy0nMCc7CiAgICB9CiAgICByZXR1cm4gYW5zOwp9CnZvaWQgbWFrZV9yeDNfcmVtKCl7CiAgICB1bGwgcmVtID0gMDsKICAgIHJlbSBePSAxdWxsPDwzMjsKICAgIHJlbSBePSAxdWxsPDwxNjsKICAgIGlmKChyeFszXSZyeFswXSk9PXJlbSkKICAgICAgICBmKF9hbmQsMywwKTsKICAgIGVsc2UgaWYoKHJ4WzNdJnJ4WzFdKT09cmVtKQogICAgICAgIGYoX2FuZCwzLDEpOwogICAgZWxzZSBpZigocnhbM10mcnhbMl0pPT1yZW0pCiAgICAgICAgZihfYW5kLDMsMik7CiAgICBlbHNlIGlmKChyeFszXSZ+cnhbMF0pPT1yZW0pewogICAgICAgIGYoX25vdCwwKTsKICAgICAgICBmKF9hbmQsMywwKTsKICAgICAgICBmKF9ub3QsMCk7CiAgICB9CiAgICBlbHNlIGlmKChyeFszXSZ+cnhbMV0pPT1yZW0pewogICAgICAgIGYoX25vdCwxKTsKICAgICAgICBmKF9hbmQsMywxKTsKICAgICAgICBmKF9ub3QsMSk7CiAgICB9CiAgICBlbHNlIGlmKChyeFszXSZ+cnhbMl0pPT1yZW0pewogICAgICAgIGYoX25vdCwyKTsKICAgICAgICBmKF9hbmQsMywyKTsKICAgICAgICBmKF9ub3QsMik7CiAgICB9CiAgICBlbHNlIGlmKChyeFszXSYocnhbMF1ecnhbMV0pKT09cmVtKXsKICAgICAgICBmKF94b3IsMCwxKTsKICAgICAgICBmKF9hbmQsMywwKTsKICAgICAgICBmKF94b3IsMCwxKTsKICAgIH0KICAgIGVsc2UgaWYoKHJ4WzNdJihyeFsyXV5yeFsxXSkpPT1yZW0pewogICAgICAgIGYoX3hvciwyLDEpOwogICAgICAgIGYoX2FuZCwzLDIpOwogICAgICAgIGYoX3hvciwyLDEpOwogICAgfQogICAgZWxzZSBpZigocnhbM10mKHJ4WzJdXnJ4WzBdKSk9PXJlbSl7CiAgICAgICAgZihfeG9yLDIsMCk7CiAgICAgICAgZihfYW5kLDMsMik7CiAgICAgICAgZihfeG9yLDIsMCk7CiAgICB9CiAgICBlbHNlIGlmKChyeFszXSYofnJ4WzBdXnJ4WzFdKSk9PXJlbSl7CiAgICAgICAgZihfbm90LDApOwogICAgICAgIGYoX3hvciwwLDEpOwogICAgICAgIGYoX2FuZCwzLDApOwogICAgICAgIGYoX3hvciwwLDEpOwogICAgICAgIGYoX25vdCwwKTsKICAgIH0KICAgIGVsc2UgaWYoKHJ4WzNdJih+cnhbMl1ecnhbMV0pKT09cmVtKXsKICAgICAgICBmKF9ub3QsMik7CiAgICAgICAgZihfeG9yLDIsMSk7CiAgICAgICAgZihfYW5kLDMsMik7CiAgICAgICAgZihfeG9yLDIsMSk7CiAgICAgICAgZihfbm90LDIpOwogICAgfQogICAgZWxzZSBpZigocnhbM10mKH5yeFsyXV5yeFswXSkpPT1yZW0pewogICAgICAgIGYoX25vdCwyKTsKICAgICAgICBmKF94b3IsMiwwKTsKICAgICAgICBmKF9hbmQsMywyKTsKICAgICAgICBmKF94b3IsMiwwKTsKICAgICAgICBmKF9ub3QsMik7CiAgICB9CiAgICBlbHNlIGlmKChyeFszXSYocnhbMF1ecnhbMV1ecnhbMl0pKT09cmVtKXsKICAgICAgICBmKF94b3IsMCwxKTsKICAgICAgICBmKF94b3IsMCwyKTsKICAgICAgICBmKF9hbmQsMywwKTsKICAgICAgICBmKF94b3IsMCwxKTsKICAgICAgICBmKF94b3IsMCwyKTsKICAgIH0KICAgIGVsc2V7CiAgICAgICAgZihfc3ViLDMsMyk7IC8vMAogICAgICAgIGYoX2luYywzLHU4KTsgLy84CiAgICAgICAgZihfbXVsLDMsMyk7IC8vMTYKICAgICAgICBmKF9tdWwsMywzKTsgLy8zMgogICAgICAgIGYoX2luYywzLHU4KTsgLy8zMiw4CiAgICAgICAgZihfbXVsLDMsMyxsMzIpOyAvLzMyLDE2CiAgICAgICAgYXNzZXJ0KHJ4WzNdPT1yZW0pOwogICAgfQp9CnZvaWQgaW5uZXIxNih2dWxsIGdvYWwpewogICAgdnVsbCBpbnRlcm1lZGlhdGUoMyk7CiAgICB1bGwgbSA9ICh1bGwoMSk8PDQ4KSsodWxsKDEpPDwzMikrKHVsbCgxKTw8MTYpOwogICAgcmVwKGksMCwyKXsKICAgICAgICB0cnl7CiAgICAgICAgICAgIGludGVybWVkaWF0ZVtpXSA9IGNob29zZShyeFtpXSxnb2FsW2ldKTsKICAgICAgICB9Y2F0Y2goLi4uKXsKICAgICAgICAgICAgZihfc3ViLGksaSk7CiAgICAgICAgICAgIGludGVybWVkaWF0ZVtpXSA9IGNob29zZShyeFtpXSxnb2FsW2ldKTsKICAgICAgICB9CiAgICB9CiAgICByZXAoaSwwLDcpewogICAgICAgIHJlcChqLDAsMikKICAgICAgICAgICAgaWYoKHJ4W2pdXmludGVybWVkaWF0ZVtqXSkgJiAoMXVsbDw8KDQwK2kpKSkKICAgICAgICAgICAgICAgIGYoX3hvcixqLDMpOwogICAgICAgIHJlcChqLDAsMikKICAgICAgICAgICAgaWYoKHJ4W2pdXmludGVybWVkaWF0ZVtqXSkgJiAoMXVsbDw8KDI0K2kpKSkKICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsbDMyKTsKICAgICAgICByZXAoaiwwLDIpCiAgICAgICAgICAgIGlmKChyeFtqXV5pbnRlcm1lZGlhdGVbal0pICYgKDF1bGw8PCg4K2kpKSkKICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsdTgsdTgpOwogICAgICAgIHJlcChqLDAsMikKICAgICAgICAgICAgaWYoKHJ4W2pdXmludGVybWVkaWF0ZVtqXSkgJiAoMXVsbDw8KGkpKSkKICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsbDgsdTgpOwogICAgICAgIGYoX2FkZCwzLDMpOwogICAgfQogICAgYXNzZXJ0KHJ4WzNdID09IG0pOwogICAgcmVwKGosMCwyKQogICAgICAgIGYoX211bCxqLDMpOwogICAgbWFrZV9yeDNfcmVtKCk7CiAgICBmKF9pbmMsMyk7CiAgICByZXAoaSwwLDcpewogICAgICAgIHJlcChqLDAsMikKICAgICAgICAgICAgaWYoKHJ4W2pdXmdvYWxbal0pICYgKDF1bGw8PCgzMitpKSkpCiAgICAgICAgICAgICAgICBmKF94b3IsaiwzKTsKICAgICAgICByZXAoaiwwLDIpCiAgICAgICAgICAgIGlmKChyeFtqXV5nb2FsW2pdKSAmICgxdWxsPDwoMTYraSkpKQogICAgICAgICAgICAgICAgZihfeG9yLGosMyxsMzIpOwogICAgICAgIHJlcChqLDAsMikKICAgICAgICAgICAgaWYoKHJ4W2pdXmdvYWxbal0pICYgKDF1bGw8PCg4K2kpKSkKICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsdTgsbDgpOwogICAgICAgIHJlcChqLDAsMikKICAgICAgICAgICAgaWYoKHJ4W2pdXmdvYWxbal0pICYgKDF1bGw8PChpKSkpCiAgICAgICAgICAgICAgICBmKF94b3IsaiwzLGw4LGw4KTsKICAgICAgICBmKF9hZGQsMywzKTsKICAgIH0KfQpsbCBtb2NrKHZvaWQgKCp0b190ZXN0KSh2dWxsKSwgdnVsbCBpbml0aWFsLCB2dWxsIGdvYWwpewogICAgYXV0byBvbGRfc2F2aW5nID0gc2F2aW5nOwogICAgc2F2aW5nID0gZmFsc2U7CiAgICBpbnQgb2xkX29wID0gY250X29wOwogICAgc2F2ZV9zdGF0ZSgpOwogICAgcmVwKGksMCxzeihpbml0aWFsKS0xKQogICAgICAgIHJ4W2ldID0gaW5pdGlhbFtpXTsKICAgIHRvX3Rlc3QoZ29hbCk7CiAgICBsb2FkX3N0YXRlKCk7CiAgICBzYXZpbmcgPSBvbGRfc2F2aW5nOwogICAgaW50IGFucyA9IGNudF9vcC1vbGRfb3A7CiAgICBjbnRfb3AgPSBvbGRfb3A7CiAgICByZXR1cm4gYW5zOwp9CnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmxsIG1vY2sodm9pZCAoKnRvX3Rlc3QpKFQpLCBUIGdvYWxzKXsKICAgIHNhdmluZyA9IGZhbHNlOwoKICAgIGludCBvbGRfb3AgPSBjbnRfb3A7CiAgICB2dWxsIF9zdGF0ZSA9IGdldF9zdGF0ZSgpOwogICAgdG9fdGVzdChnb2Fscyk7CiAgICBzZXRfc3RhdGUoX3N0YXRlKTsKICAgIHNhdmluZyA9IHRydWU7CiAgICBpbnQgYW5zID0gY250X29wLW9sZF9vcDsKICAgIGNudF9vcCA9IG9sZF9vcDsKICAgIHJldHVybiBhbnM7Cn0KdnVsbCBiZXN0X3Blcm11dGUodm9pZCAoKikodnVsbCksIHZ1bGwpOwp2dnVsbCByYW5kX3Blcm11dGUodm9pZCAoKikodnZ1bGwpLCB2dnVsbCwgaW50KTsKdm9pZCB0c3BfcGVybXV0ZSh2b2lkICgqKSh2dWxsKSwgdnZ1bGwmKTsKdm9pZCBvdXRlcjE2KHZ2dWxsIGdvYWxzKXsKICAgIHJlcCh0LDAsbi0xKXsKICAgICAgICB2dWxsIGdvYWwgPSBiZXN0X3Blcm11dGUoaW5uZXIxNixnb2Fsc1t0XSk7CiAgICAgICAgaW5uZXIxNihnb2FsKTsKICAgICAgICByZXAoaiwwLDIpIGFzc2VydCgocnhbal1eZ29hbFtqXSk9PTApOwogICAgfQp9CnZvaWQgY2FsY19kaXN0KHZvaWQgKCp0b190ZXN0KSh2dWxsKSwgdnZ1bGwgZ29hbHMpewogICAgdnVsbCBzdGF0ZSA9IGdldF9zdGF0ZSgpOwogICAgcmVwKGksMCxzeihnb2FscyktMSkKICAgICAgICByZXAoaiwwLHN6KGdvYWxzKS0xKXsKICAgICAgICAgICAgc2V0X3N0YXRlKGdvYWxzW2ldKTsKICAgICAgICAgICAgZGlzdFtpXVtqXSA9IG1vY2sodG9fdGVzdCxnZXRfc3RhdGUoKSxiZXN0X3Blcm11dGUodG9fdGVzdCxnb2Fsc1tqXSkpOwogICAgICAgIH0KICAgIHNldF9zdGF0ZShzdGF0ZSk7Cn0KYm9vbCB2aXNpdGVkWzY0XTsKdmkgcGF0aDsKaW50IGNvc3QgPSAwOwp2b2lkIGRmcyhpbnQgdSwgaW50IHN6KXsKICAgIHZpc2l0ZWRbdV0gPSB0cnVlOwogICAgcGF0aC5wYih1KTsKICAgIGlmKHN6KHBhdGgpID09IHN6KQogICAgICAgIHJldHVybjsKICAgIHZwaWkgYmVzdF9jb250OwogICAgcmVwKHYsMCxzei0xKQogICAgICAgIGlmKCF2aXNpdGVkW3ZdKQogICAgICAgICAgICBiZXN0X2NvbnQucGIoe2Rpc3RbdV1bdl0sdn0pOwogICAgc29ydChhbGwoYmVzdF9jb250KSk7CiAgICBmb3IoYXV0byBfIDogYmVzdF9jb250KXsKICAgICAgICBpZihzeihwYXRoKSA8IDUwICYmIHJhbmQoKSUxNSA9PSAwKSBjb250aW51ZTsKICAgICAgICBjb3N0ICs9IF8uWDsKICAgICAgICBkZnMoXy5ZLHN6KTsKICAgICAgICBpZihzeihwYXRoKSA9PSBzeikKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIGNvc3QgLT0gXy5YOwogICAgfQogICAgaWYoc3oocGF0aCkgPT0gc3opCiAgICAgICAgcmV0dXJuOwogICAgdmlzaXRlZFt1XSA9IGZhbHNlOwogICAgcGF0aC5wb3BfYmFjaygpOwogICAgcmV0dXJuOwp9CnZpIG1zdF9vcmRlcihpbnQgc3ogPSA2NCl7CiAgICB2dmkgZWRnZXM7CiAgICByZXAoaSwwLHN6LTEpCiAgICAgICAgcmVwKGosaSsxLHN6LTEpCiAgICAgICAgICAgIGVkZ2VzLnBiKHtkaXN0W2ldW2pdLGksan0pOwogICAgRFNVIGRzdShzeik7CiAgICB2aSBkZWcoc3opOwogICAgdnZpIGFkaihzeik7CiAgICBsbCBjb3N0ID0gMDsKICAgIGZvcihhdXRvIF8gOiBlZGdlcyl7CiAgICAgICAgaW50IHUgPSBfWzFdOwogICAgICAgIGludCB2ID0gX1syXTsKICAgICAgICBpZihkZWdbdV0gPD0gMSAmJiBkZWdbdl0gPD0gMSAmJiBkc3UudW5pdGUodSx2KSl7CiAgICAgICAgICAgICsrZGVnW3VdOwogICAgICAgICAgICArK2RlZ1t2XTsKICAgICAgICAgICAgYWRqW3VdLnBiKHYpOwogICAgICAgICAgICBhZGpbdl0ucGIodSk7CiAgICAgICAgICAgIGNvc3QgKz0gX1swXTsKICAgICAgICB9CiAgICB9CiAgICBpbnQgc3RhcnQgPSAwOwogICAgd2hpbGUoZGVnW3N0YXJ0XSAhPSAxKQogICAgICAgICsrc3RhcnQ7CiAgICB2aSBhbnMoMSxzdGFydCk7CiAgICByZXAoaSwwLHN6KGFucyktMSl7CiAgICAgICAgaW50IHUgPSBhbnNbaV07CiAgICAgICAgZm9yKGludCB2IDogYWRqW3VdKXsKICAgICAgICAgICAgaWYoZGVnW3ZdICE9IDApewogICAgICAgICAgICAgICAgYW5zLnBiKHYpOwogICAgICAgICAgICAgICAgZGVnW3VdLS07CiAgICAgICAgICAgICAgICBkZWdbdl0tLTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHdhdGNoKGNvc3QpOwogICAgd2F0Y2goc3ooYW5zKSk7CiAgICByZXR1cm4gYW5zOwoKfQp2aSBtZl9vcmRlcihpbnQgc3ogPSA2NCl7CiAgICB2dmkgZWRnZXM7CiAgICByZXAoaSwwLHN6LTEpCiAgICAgICAgcmVwKGosaSsxLHN6LTEpCiAgICAgICAgICAgIGVkZ2VzLnBiKHtkaXN0W2ldW2pdLGksan0pOwogICAgRFNVIGRzdShzeik7CiAgICB2aSBkZWcoc3opOwogICAgbGwgY29zdCA9IDA7CiAgICBsbCBpY29zdCA9IDA7CiAgICB2aSBscyxyczsKICAgIGZvcihhdXRvIF8gOiBlZGdlcyl7CiAgICAgICAgaW50IHUgPSBfWzFdOwogICAgICAgIGludCB2ID0gX1syXTsKICAgICAgICBpZihkZWdbdV0gPD0gMCAmJiBkZWdbdl0gPD0gMCAmJiBkc3UudW5pdGUodSx2KSl7CiAgICAgICAgICAgICsrZGVnW3VdOwogICAgICAgICAgICArK2RlZ1t2XTsKICAgICAgICAgICAgaWNvc3QgKz0gX1swXTsKICAgICAgICAgICAgbHMucGIodSk7CiAgICAgICAgICAgIHJzLnBiKHYpOwogICAgICAgIH0KICAgIH0KICAgIGxsIHRjb3N0ID0gTU9EOwogICAgcmVwKHRpbWVzLDAsMTAwMCl7CiAgICAgICAgY29zdCA9IGljb3N0OwogICAgICAgIHJlcChpLDAsMzEpCiAgICAgICAgICAgIGlmKHJhbmQoKSUyKQogICAgICAgICAgICAgICAgc3dhcChsc1tpXSxyc1tpXSk7CiAgICAgICAgTWF4RmxvdzxpbnQ+IG1mOwogICAgICAgIHZ2aSBlZGdlX2luZGljZXMoMzIsdmkoMzIpKTsKICAgICAgICByZXAoaSwwLDMxKQogICAgICAgICAgICByZXAoaiwwLDMxKQogICAgICAgICAgICAgICAgZWRnZV9pbmRpY2VzW2ldW2pdID0gbWYuYWRkX2VkZ2UobHNbaV0scnNbal0sMSxkaXN0W2xzW2ldXVtyc1tqXV0pOwogICAgICAgIGludCB0cyA9IC0xOwogICAgICAgIHJlcChpLDAsMzEpCiAgICAgICAgICAgIG1mLmFkZF9lZGdlKHRzLGxzW2ldLDEsMCk7CiAgICAgICAgcmVwKGosMCwzMSkKICAgICAgICAgICAgbWYuYWRkX2VkZ2UocnNbal0sbWYuc2luaywxLDApOwogICAgICAgIG1mLmFkZF9lZGdlKG1mLnNvdXJjZSx0cywzMSwwKTsKICAgICAgICBjb3N0ICs9IG1mLm1pbl9jb3N0X2Zsb3coKS5ZOwogICAgICAgIHRjb3N0ID0gbWluKHRjb3N0LGNvc3QpOwogICAgfQogICAgd2F0Y2godGNvc3QpOwogICAgcmV0dXJuIHt9Owp9CnZpIGRlY2VudF9vcmRlcihpbnQgc3ogPSA2NCl7CiAgICB2aSBiZXN0X3BhdGg7IAogICAgaW50IGJlc3RfY29zdCA9IE1PRDsKICAgIHJlcChzdGFydCwwLDMwKihzei0xKSl7CiAgICAgICAgY29zdCA9IDA7CiAgICAgICAgcGF0aC5jbGVhcigpOwogICAgICAgIG1lbXNldCh2aXNpdGVkLDAsc2l6ZW9mIHZpc2l0ZWQpOwogICAgICAgIGRmcyhzdGFydCVzeixzeik7CiAgICAgICAgaWYoY29zdCA8IGJlc3RfY29zdCl7CiAgICAgICAgICAgIGJlc3RfcGF0aCA9IHBhdGg7CiAgICAgICAgICAgIGJlc3RfY29zdCA9IGNvc3Q7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGJlc3RfcGF0aDsKfQp2b2lkIHNldF9vcmRlcih2dnVsbCAmZ29hbHMsIHZpIG9yZGVyKXsKICAgIHZ2dWxsIGIoc3ooZ29hbHMpKTsKICAgIHJlcChpLDAsc3ooZ29hbHMpLTEpCiAgICAgICAgYltpXSA9IGdvYWxzW29yZGVyW2ldXTsKICAgIGdvYWxzID0gYjsKfQp2b2lkIHNvbHZlMTYoKXsKICAgIGYoX2luYywzLHU4KTsgLy84CiAgICBmKF9tb3YsMCwzKTsKICAgIGYoX211bCwzLDMpOyAvLzE2CiAgICBmKF9tdWwsMywzKTsgLy8zMgogICAgZihfaW5jLDMsdTgpOyAvLzMyLDgKICAgIGYoX211bCwzLDMsbDMyKTsgLy8zMiwxNgogICAgZihfaW5jLDMpOyAvLzMyLDE2LDAKICAgIGYoX211bCwzLDApOyAvLzQwLDI0LDgKICAgIHZ2dWxsIGdvYWxzID0gYTsKICAgIHRzcF9wZXJtdXRlKGlubmVyMTYsZ29hbHMpOwoKICAgIG91dGVyMTYoZ29hbHMpOwp9Cgp2b2lkIGlubmVyNTYoaW50IHQsIHZ1bGwgZ29hbCl7CiAgICBpZih0ID4gMCl7CiAgICAgICAgZihfYWRkLDIsMCk7CiAgICAgICAgZihfYWRkLDIsMSk7CiAgICB9CiAgICB7CiAgICAgICAgaW50IGVuZHAgPSAxKyh0PT0wKTsKICAgICAgICB2dWxsIGludGVybWVkaWF0ZSgzKTsKICAgICAgICB1bGwgbSA9ICh1bGwoMSk8PDQ4KSsodWxsKDEpPDwzMikrKHVsbCgxKTw8MTYpOwogICAgICAgIHJlcChpLDAsZW5kcCl7CiAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgIGludGVybWVkaWF0ZVtpXSA9IGNob29zZShyeFtpXSxnb2FsW2ldKTsKICAgICAgICAgICAgfWNhdGNoKC4uLil7CiAgICAgICAgICAgICAgICBmKF9zdWIsaSxpKTsKICAgICAgICAgICAgICAgIGludGVybWVkaWF0ZVtpXSA9IGNob29zZShyeFtpXSxnb2FsW2ldKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXAoaSwwLDcpewogICAgICAgICAgICByZXAoaiwwLGVuZHApCiAgICAgICAgICAgICAgICBpZigocnhbal1eaW50ZXJtZWRpYXRlW2pdKSAmICgxdWxsPDwoNDAraSkpKQogICAgICAgICAgICAgICAgICAgIGYoX3hvcixqLDMpOwogICAgICAgICAgICByZXAoaiwwLGVuZHApCiAgICAgICAgICAgICAgICBpZigocnhbal1eaW50ZXJtZWRpYXRlW2pdKSAmICgxdWxsPDwoMjQraSkpKQogICAgICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsbDMyKTsKICAgICAgICAgICAgcmVwKGosMCxlbmRwKXsKICAgICAgICAgICAgICAgIGlmKChyeFtqXV5pbnRlcm1lZGlhdGVbal0pICYgKDF1bGw8PCg4K2kpKSkKICAgICAgICAgICAgICAgICAgICBmKF94b3IsaiwzLHU4LHU4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXAoaiwwLGVuZHApCiAgICAgICAgICAgICAgICBpZigocnhbal1eaW50ZXJtZWRpYXRlW2pdKSAmICgxdWxsPDwoaSkpKQogICAgICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsbDgsdTgpOwogICAgICAgICAgICBmKF9hZGQsMywzKTsKICAgICAgICB9CiAgICAgICAgYXNzZXJ0KHJ4WzNdID09IG0pOwogICAgICAgIHJlcChqLDAsZW5kcCkKICAgICAgICAgICAgZihfbXVsLGosMyk7CiAgICAgICAgbWFrZV9yeDNfcmVtKCk7CiAgICAgICAgZihfaW5jLDMpOwogICAgICAgIHJlcChpLDAsNyl7CiAgICAgICAgICAgIHJlcChqLDAsZW5kcCkKICAgICAgICAgICAgICAgIGlmKChyeFtqXV5nb2FsW2pdKSAmICgxdWxsPDwoMzIraSkpKQogICAgICAgICAgICAgICAgICAgIGYoX3hvcixqLDMpOwogICAgICAgICAgICByZXAoaiwwLGVuZHApCiAgICAgICAgICAgICAgICBpZigocnhbal1eZ29hbFtqXSkgJiAoMXVsbDw8KDE2K2kpKSkKICAgICAgICAgICAgICAgICAgICBmKF94b3IsaiwzLGwzMik7CiAgICAgICAgICAgIHJlcChqLDAsZW5kcCkKICAgICAgICAgICAgICAgIGlmKChyeFtqXV5nb2FsW2pdKSAmICgxdWxsPDwoOCtpKSkpCiAgICAgICAgICAgICAgICAgICAgZihfeG9yLGosMyx1OCxsOCk7CiAgICAgICAgICAgIHJlcChqLDAsZW5kcCkKICAgICAgICAgICAgICAgIGlmKChyeFtqXV5nb2FsW2pdKSAmICgxdWxsPDwoaSkpKQogICAgICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsbDgsbDgpOwogICAgICAgICAgICBmKF9hZGQsMywzKTsKICAgICAgICB9CiAgICAgICAgaWYodCA+IDApewogICAgICAgICAgICBmKF9zdWIsMiwwKTsKICAgICAgICAgICAgZihfc3ViLDIsMSk7CiAgICAgICAgfQogICAgfQp9CnZvaWQgaW5uZXI1Nl9pbml0KHZ1bGwgZ29hbCl7CiAgICBpbm5lcjU2KDAsZ29hbCk7Cn0Kdm9pZCBpbm5lcjU2X25vcm1hbCh2dWxsIGdvYWwpewogICAgaW5uZXI1NigxLGdvYWwpOwp9CnZvaWQgb3V0ZXI1Nih2dnVsbCBnb2Fscyl7CiAgICByZXAodCwwLG4tMSl7CiAgICAgICAgYXV0byBmdW5jID0gdCA9PSAwID8gaW5uZXI1Nl9pbml0IDogaW5uZXI1Nl9ub3JtYWw7CiAgICAgICAgdnVsbCBnb2FsID0gZ29hbHNbdF07CiAgICAgICAgZ29hbCA9IGJlc3RfcGVybXV0ZShmdW5jLGdvYWxzW3RdKTsKICAgICAgICBmdW5jKGdvYWwpOwogICAgICAgIHJlcChqLDAsMikgYXNzZXJ0KChyeFtqXV5nb2FsW2pdKT09MCk7CiAgICB9Cn0Kdm9pZCBzb2x2ZTU2KCl7CiAgICBmKF9pbmMsMyx1OCk7IC8vOAogICAgZihfbW92LDAsMyk7CiAgICBmKF9tdWwsMywzKTsgLy8xNgogICAgZihfbXVsLDMsMyk7IC8vMzIKICAgIGYoX2luYywzLHU4KTsgLy8zMiw4CiAgICBmKF9tdWwsMywzLGwzMik7IC8vMzIsMTYKICAgIGYoX2luYywzKTsgLy8zMiwxNiwwCiAgICBmKF9tdWwsMywwKTsgLy80MCwyNCw4CiAgICB2dnVsbCBnb2FscyA9IGE7CiAgICB0c3BfcGVybXV0ZShpbm5lcjU2X25vcm1hbCxnb2Fscyk7CiAgICBvdXRlcjU2KGdvYWxzKTsKfQp2b2lkIGlubmVyNCh2dWxsIGdvYWwpewogICAgcmVwKHRpbWVzLDAsMyl7CiAgICAgICAgaWYodGltZXMgPiAyKXsKICAgICAgICAgICAgaWYoZ29hbFswXT4+MzIgIT0gcnhbMF0+PjMyKXsKICAgICAgICAgICAgICAgICAgICAgaWYoZ29hbFswXT4+MzIgPT0gZyhfYWRkLDAsMSk+PjMyKSBmKF9hZGQsICAgIDAsMSk7CiAgICAgICAgICAgICAgICBlbHNlIGlmKGdvYWxbMF0+PjMyID09IGcoX3hvciwwLDEpPj4zMikgZihfeG9yLCAgICAwLDEpOwogICAgICAgICAgICAgICAgZWxzZSBpZihnb2FsWzBdPj4zMiA9PSBnKF9zdWIsMCwxKT4+MzIpIGYoX3N1YiwgICAgMCwxKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYoZ29hbFswXT4+MzIgPT0gZyhfYW5kLDAsMSk+PjMyKSBmKF9hbmQsICAgIDAsMSk7CiAgICAgICAgICAgICAgICBlbHNlIGlmKGdvYWxbMF0+PjMyID09IGcoX29yLCAwLDEpPj4zMikgZihfb3IsICAgICAwLDEpOwogICAgICAgICAgICAgICAgZWxzZSBpZihnb2FsWzBdPj4zMiA9PSBnKF9hZGQsMCwyKT4+MzIpIGYoX2FkZCwgICAgMCwyKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYoZ29hbFswXT4+MzIgPT0gZyhfeG9yLDAsMik+PjMyKSBmKF94b3IsICAgIDAsMik7CiAgICAgICAgICAgICAgICBlbHNlIGlmKGdvYWxbMF0+PjMyID09IGcoX3N1YiwwLDIpPj4zMikgZihfc3ViLCAgICAwLDIpOwogICAgICAgICAgICAgICAgZWxzZSBpZihnb2FsWzBdPj4zMiA9PSBnKF9hbmQsMCwyKT4+MzIpIGYoX2FuZCwgICAgMCwyKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYoZ29hbFswXT4+MzIgPT0gZyhfb3IsIDAsMik+PjMyKSBmKF9vciwgICAgIDAsMik7CiAgICAgICAgICAgICAgICBlbHNlIGlmKHRpbWVzPjEgJiYgZ29hbFswXT4+MzIgPT0gZyhfbW92LDAsMSk+PjMyKSBmKF9tb3YsICAgIDAsMSk7CiAgICAgICAgICAgICAgICBlbHNlIGlmKHRpbWVzPjEgJiYgZ29hbFswXT4+MzIgPT0gZyhfbW92LDAsMik+PjMyKSBmKF9tb3YsICAgIDAsMik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoZ29hbFsxXT4+MzIgIT0gcnhbMV0+PjMyKXsKICAgICAgICAgICAgICAgICAgICAgaWYoZ29hbFsxXT4+MzIgPT0gZyhfYWRkLDEsMCk+PjMyKSBmKF9hZGQsICAgIDEsMCk7CiAgICAgICAgICAgICAgICBlbHNlIGlmKGdvYWxbMV0+PjMyID09IGcoX3hvciwxLDApPj4zMikgZihfeG9yLCAgICAxLDApOwogICAgICAgICAgICAgICAgZWxzZSBpZihnb2FsWzFdPj4zMiA9PSBnKF9zdWIsMSwwKT4+MzIpIGYoX3N1YiwgICAgMSwwKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsxXT4+MzIgPT0gZyhfYW5kLDEsMCk+PjMyKSBmKF9hbmQsICAgIDEsMCk7CiAgICAgICAgICAgICAgICBlbHNlIGlmKGdvYWxbMV0+PjMyID09IGcoX29yLCAxLDApPj4zMikgZihfb3IsICAgICAxLDApOwogICAgICAgICAgICAgICAgZWxzZSBpZihnb2FsWzFdPj4zMiA9PSBnKF9hZGQsMSwyKT4+MzIpIGYoX2FkZCwgICAgMSwyKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsxXT4+MzIgPT0gZyhfeG9yLDEsMik+PjMyKSBmKF94b3IsICAgIDEsMik7CiAgICAgICAgICAgICAgICBlbHNlIGlmKGdvYWxbMV0+PjMyID09IGcoX3N1YiwxLDIpPj4zMikgZihfc3ViLCAgICAxLDIpOwogICAgICAgICAgICAgICAgZWxzZSBpZihnb2FsWzFdPj4zMiA9PSBnKF9hbmQsMSwyKT4+MzIpIGYoX2FuZCwgICAgMSwyKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsxXT4+MzIgPT0gZyhfb3IsIDEsMik+PjMyKSBmKF9vciwgICAgIDEsMik7CiAgICAgICAgICAgICAgICBlbHNlIGlmKHRpbWVzID4gMSAmJiBnb2FsWzFdPj4zMiA9PSBnKF9tb3YsMSwwKT4+MzIpIGYoX21vdiwgICAgMSwwKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYodGltZXMgPiAxICYmIGdvYWxbMV0+PjMyID09IGcoX21vdiwxLDIpPj4zMikgZihfbW92LCAgICAxLDIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGdvYWxbMF0+PjMyICE9IHJ4WzBdPj4zMil7CiAgICAgICAgICAgICAgICAgICAgIGlmKGdvYWxbMl0+PjMyID09IGcoX2FkZCwyLDEpPj4zMikgZihfYWRkLCAgICAyLDEpOwogICAgICAgICAgICAgICAgZWxzZSBpZihnb2FsWzJdPj4zMiA9PSBnKF94b3IsMiwxKT4+MzIpIGYoX3hvciwgICAgMiwxKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsyXT4+MzIgPT0gZyhfc3ViLDIsMSk+PjMyKSBmKF9zdWIsICAgIDIsMSk7CiAgICAgICAgICAgICAgICBlbHNlIGlmKGdvYWxbMl0+PjMyID09IGcoX2FuZCwyLDEpPj4zMikgZihfYW5kLCAgICAyLDEpOwogICAgICAgICAgICAgICAgZWxzZSBpZihnb2FsWzJdPj4zMiA9PSBnKF9vciwgMiwxKT4+MzIpIGYoX29yLCAgICAgMiwxKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsyXT4+MzIgPT0gZyhfYWRkLDIsMCk+PjMyKSBmKF9hZGQsICAgIDIsMCk7CiAgICAgICAgICAgICAgICBlbHNlIGlmKGdvYWxbMl0+PjMyID09IGcoX3hvciwyLDApPj4zMikgZihfeG9yLCAgICAyLDApOwogICAgICAgICAgICAgICAgZWxzZSBpZihnb2FsWzJdPj4zMiA9PSBnKF9zdWIsMiwwKT4+MzIpIGYoX3N1YiwgICAgMiwwKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsyXT4+MzIgPT0gZyhfYW5kLDIsMCk+PjMyKSBmKF9hbmQsICAgIDIsMCk7CiAgICAgICAgICAgICAgICBlbHNlIGlmKGdvYWxbMl0+PjMyID09IGcoX29yLCAyLDApPj4zMikgZihfb3IsICAgICAyLDApOwogICAgICAgICAgICAgICAgZWxzZSBpZih0aW1lcyA+IDEgJiYgZ29hbFsyXT4+MzIgPT0gZyhfbW92LDIsMSk+PjMyKSBmKF9tb3YsICAgIDIsMSk7CiAgICAgICAgICAgICAgICBlbHNlIGlmKHRpbWVzID4gMSAmJiBnb2FsWzJdPj4zMiA9PSBnKF9tb3YsMiwwKT4+MzIpIGYoX21vdiwgICAgMiwwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZihnb2FsWzBdICE9IHJ4WzBdKXsKICAgICAgICAgICAgaWYoZ29hbFswXSA9PSBnKF9hZGQsMCwxKSkgZihfYWRkLCAgICAwLDEpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMF0gPT0gZyhfeG9yLDAsMSkpIGYoX3hvciwgICAgMCwxKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzBdID09IGcoX3N1YiwwLDEpKSBmKF9zdWIsICAgIDAsMSk7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFswXSA9PSBnKF9hbmQsMCwxKSkgZihfYW5kLCAgICAwLDEpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMF0gPT0gZyhfb3IsIDAsMSkpIGYoX29yLCAgICAgMCwxKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzBdID09IGcoX2FkZCwwLDEsbDMyKSkgZihfYWRkLDAsMSxsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMF0gPT0gZyhfeG9yLDAsMSxsMzIpKSBmKF94b3IsMCwxLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFswXSA9PSBnKF9zdWIsMCwxLGwzMikpIGYoX3N1YiwwLDEsbDMyKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzBdID09IGcoX2FuZCwwLDEsbDMyKSkgZihfYW5kLDAsMSxsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMF0gPT0gZyhfb3IsIDAsMSxsMzIpKSBmKF9vciwgMCwxLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFswXSA9PSBnKF9hZGQsMCwyKSkgZihfYWRkLCAgICAwLDIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMF0gPT0gZyhfeG9yLDAsMikpIGYoX3hvciwgICAgMCwyKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzBdID09IGcoX3N1YiwwLDIpKSBmKF9zdWIsICAgIDAsMik7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFswXSA9PSBnKF9hbmQsMCwyKSkgZihfYW5kLCAgICAwLDIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMF0gPT0gZyhfb3IsIDAsMikpIGYoX29yLCAgICAgMCwyKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzBdID09IGcoX2FkZCwwLDIsbDMyKSkgZihfYWRkLDAsMixsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMF0gPT0gZyhfeG9yLDAsMixsMzIpKSBmKF94b3IsMCwyLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFswXSA9PSBnKF9zdWIsMCwyLGwzMikpIGYoX3N1YiwwLDIsbDMyKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzBdID09IGcoX2FuZCwwLDIsbDMyKSkgZihfYW5kLDAsMixsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMF0gPT0gZyhfb3IsIDAsMixsMzIpKSBmKF9vciwgMCwyLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYodGltZXMgPiAwICYmIGdvYWxbMF0gPT0gZyhfbW92LDAsMSkpIGYoX21vdiwgICAgMCwxKTsKICAgICAgICAgICAgZWxzZSBpZih0aW1lcyA+IDAgJiYgZ29hbFswXSA9PSBnKF9tb3YsMCwyKSkgZihfbW92LCAgICAwLDIpOwogICAgICAgICAgICBlbHNlIGlmKHRpbWVzID4gMCAmJiBnb2FsWzBdID09IGcoX21vdiwwLDEsbDMyKSkgZihfbW92LDAsMSxsMzIpOwogICAgICAgICAgICBlbHNlIGlmKHRpbWVzID4gMCAmJiBnb2FsWzBdID09IGcoX21vdiwwLDIsbDMyKSkgZihfbW92LDAsMixsMzIpOwogICAgICAgIH0KICAgICAgICBpZihnb2FsWzFdICE9IHJ4WzFdKXsKICAgICAgICAgICAgaWYoZ29hbFsxXSA9PSBnKF9hZGQsMSwwKSkgZihfYWRkLCAgICAxLDApOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMV0gPT0gZyhfeG9yLDEsMCkpIGYoX3hvciwgICAgMSwwKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzFdID09IGcoX3N1YiwxLDApKSBmKF9zdWIsICAgIDEsMCk7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsxXSA9PSBnKF9hbmQsMSwwKSkgZihfYW5kLCAgICAxLDApOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMV0gPT0gZyhfb3IsIDEsMCkpIGYoX29yLCAgICAgMSwwKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzFdID09IGcoX2FkZCwxLDAsbDMyKSkgZihfYWRkLDEsMCxsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMV0gPT0gZyhfeG9yLDEsMCxsMzIpKSBmKF94b3IsMSwwLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsxXSA9PSBnKF9zdWIsMSwwLGwzMikpIGYoX3N1YiwxLDAsbDMyKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzFdID09IGcoX2FuZCwxLDAsbDMyKSkgZihfYW5kLDEsMCxsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMV0gPT0gZyhfb3IsIDEsMCxsMzIpKSBmKF9vciwgMSwwLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsxXSA9PSBnKF9hZGQsMSwyKSkgZihfYWRkLCAgICAxLDIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMV0gPT0gZyhfeG9yLDEsMikpIGYoX3hvciwgICAgMSwyKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzFdID09IGcoX3N1YiwxLDIpKSBmKF9zdWIsICAgIDEsMik7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsxXSA9PSBnKF9hbmQsMSwyKSkgZihfYW5kLCAgICAxLDIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMV0gPT0gZyhfb3IsIDEsMikpIGYoX29yLCAgICAgMSwyKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzFdID09IGcoX2FkZCwxLDIsbDMyKSkgZihfYWRkLDEsMixsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMV0gPT0gZyhfeG9yLDEsMixsMzIpKSBmKF94b3IsMSwyLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsxXSA9PSBnKF9zdWIsMSwyLGwzMikpIGYoX3N1YiwxLDIsbDMyKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzFdID09IGcoX2FuZCwxLDIsbDMyKSkgZihfYW5kLDEsMixsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMV0gPT0gZyhfb3IsIDEsMixsMzIpKSBmKF9vciwgMSwyLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYodGltZXMgPiAwICYmIGdvYWxbMV0gPT0gZyhfbW92LDEsMCkpIGYoX21vdiwgICAgMSwwKTsKICAgICAgICAgICAgZWxzZSBpZih0aW1lcyA+IDAgJiYgZ29hbFsxXSA9PSBnKF9tb3YsMSwyKSkgZihfbW92LCAgICAxLDIpOwogICAgICAgICAgICBlbHNlIGlmKHRpbWVzID4gMCAmJiBnb2FsWzFdID09IGcoX21vdiwxLDAsbDMyKSkgZihfbW92LDEsMCxsMzIpOwogICAgICAgICAgICBlbHNlIGlmKHRpbWVzID4gMCAmJiBnb2FsWzFdID09IGcoX21vdiwxLDIsbDMyKSkgZihfbW92LDEsMixsMzIpOwogICAgICAgIH0KICAgICAgICBpZihnb2FsWzJdICE9IHJ4WzJdKXsKICAgICAgICAgICAgaWYoZ29hbFsyXSA9PSBnKF9hZGQsMiwwKSkgZihfYWRkLCAgICAyLDApOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMl0gPT0gZyhfeG9yLDIsMCkpIGYoX3hvciwgICAgMiwwKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzJdID09IGcoX3N1YiwyLDApKSBmKF9zdWIsICAgIDIsMCk7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsyXSA9PSBnKF9hbmQsMiwwKSkgZihfYW5kLCAgICAyLDApOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMl0gPT0gZyhfb3IsIDIsMCkpIGYoX29yLCAgICAgMiwwKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzJdID09IGcoX2FkZCwyLDAsbDMyKSkgZihfYWRkLDIsMCxsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMl0gPT0gZyhfeG9yLDIsMCxsMzIpKSBmKF94b3IsMiwwLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsyXSA9PSBnKF9zdWIsMiwwLGwzMikpIGYoX3N1YiwyLDAsbDMyKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzJdID09IGcoX2FuZCwyLDAsbDMyKSkgZihfYW5kLDIsMCxsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMl0gPT0gZyhfb3IsIDIsMCxsMzIpKSBmKF9vciwgMiwwLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsyXSA9PSBnKF9hZGQsMiwxKSkgZihfYWRkLCAgICAyLDEpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMl0gPT0gZyhfeG9yLDIsMSkpIGYoX3hvciwgICAgMiwxKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzJdID09IGcoX3N1YiwyLDEpKSBmKF9zdWIsICAgIDIsMSk7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsyXSA9PSBnKF9hbmQsMiwxKSkgZihfYW5kLCAgICAyLDEpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMl0gPT0gZyhfb3IsIDIsMSkpIGYoX29yLCAgICAgMiwxKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzJdID09IGcoX2FkZCwyLDEsbDMyKSkgZihfYWRkLDIsMSxsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMl0gPT0gZyhfeG9yLDIsMSxsMzIpKSBmKF94b3IsMiwxLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYoZ29hbFsyXSA9PSBnKF9zdWIsMiwxLGwzMikpIGYoX3N1YiwyLDEsbDMyKTsKICAgICAgICAgICAgZWxzZSBpZihnb2FsWzJdID09IGcoX2FuZCwyLDEsbDMyKSkgZihfYW5kLDIsMSxsMzIpOwogICAgICAgICAgICBlbHNlIGlmKGdvYWxbMl0gPT0gZyhfb3IsIDIsMSxsMzIpKSBmKF9vciwgMiwxLGwzMik7CiAgICAgICAgICAgIGVsc2UgaWYodGltZXMgPiAwICYmIGdvYWxbMl0gPT0gZyhfbW92LDIsMCkpIGYoX21vdiwgICAgMiwwKTsKICAgICAgICAgICAgZWxzZSBpZih0aW1lcyA+IDAgJiYgZ29hbFsyXSA9PSBnKF9tb3YsMiwxKSkgZihfbW92LCAgICAyLDEpOwogICAgICAgICAgICBlbHNlIGlmKHRpbWVzID4gMCAmJiBnb2FsWzJdID09IGcoX21vdiwyLDAsbDMyKSkgZihfbW92LDIsMCxsMzIpOwogICAgICAgICAgICBlbHNlIGlmKHRpbWVzID4gMCAmJiBnb2FsWzJdID09IGcoX21vdiwyLDEsbDMyKSkgZihfbW92LDIsMSxsMzIpOwogICAgICAgIH0KICAgIH0KICAgIHZ1bGwgdDY0KDMpOwogICAgdnVsbCB0MzIoMyk7CiAgICByZXAoaiwwLDIpewogICAgICAgIHQ2NFtqXSA9IChnb2FsW2pdXnJ4W2pdKT4+MzI7CiAgICAgICAgZ29hbFtqXSBePSB0NjRbal07CiAgICAgICAgdDMyW2pdID0gKChnb2FsW2pdXnJ4W2pdKTw8MzIpPj4zMjsKICAgICAgICBnb2FsW2pdIF49IHQ2NFtqXTsKICAgIH0KICAgIHJlcChqLDAsMil7CiAgICAgICAgaWYoYml0cyh0NjRbal0pID4gMTYpewogICAgICAgICAgICBmKF9ub3Qsaik7CiAgICAgICAgICAgIHQ2NFtqXSA9IChnb2FsW2pdXnJ4W2pdKT4+MzI7CiAgICAgICAgICAgIGdvYWxbal0gXj0gdDY0W2pdOwogICAgICAgICAgICB0MzJbal0gPSAoKGdvYWxbal1ecnhbal0pPDwzMik+PjMyOwogICAgICAgICAgICBnb2FsW2pdIF49IHQ2NFtqXTsKICAgICAgICB9CiAgICAgICAgaWYoYml0cyh0MzJbal0pID4gMTYpewogICAgICAgICAgICBmKF9ub3QsaixsMzIpOwogICAgICAgICAgICB0NjRbal0gPSAoZ29hbFtqXV5yeFtqXSk+PjMyOwogICAgICAgICAgICBnb2FsW2pdIF49IHQ2NFtqXTsKICAgICAgICAgICAgdDMyW2pdID0gKChnb2FsW2pdXnJ4W2pdKTw8MzIpPj4zMjsKICAgICAgICAgICAgZ29hbFtqXSBePSB0NjRbal07CiAgICAgICAgfQogICAgICAgIGlmKGJpdHModDMyW2pdJjB4ZmZmZikgPiA4ICYmIGJpdHModDMyW2pdJjB4MDBmZikgPiA0ICYmIGJpdHModDMyW2pdJjB4ZmYwMCkgPiA0KXsKICAgICAgICAgICAgZihfbm90LGosbDE2KTsKICAgICAgICAgICAgdDY0W2pdID0gKGdvYWxbal1ecnhbal0pPj4zMjsKICAgICAgICAgICAgZ29hbFtqXSBePSB0NjRbal07CiAgICAgICAgICAgIHQzMltqXSA9ICgoZ29hbFtqXV5yeFtqXSk8PDMyKT4+MzI7CiAgICAgICAgICAgIGdvYWxbal0gXj0gdDY0W2pdOwogICAgICAgIH0KICAgICAgICBpZihiaXRzKHQzMltqXSYweDAwZmYpID4gNCl7CiAgICAgICAgICAgIGYoX25vdCxqLGw4KTsKICAgICAgICAgICAgdDY0W2pdID0gKGdvYWxbal1ecnhbal0pPj4zMjsKICAgICAgICAgICAgZ29hbFtqXSBePSB0NjRbal07CiAgICAgICAgICAgIHQzMltqXSA9ICgoZ29hbFtqXV5yeFtqXSk8PDMyKT4+MzI7CiAgICAgICAgICAgIGdvYWxbal0gXj0gdDY0W2pdOwogICAgICAgIH0KICAgICAgICBpZihiaXRzKHQzMltqXSYweGZmMDApID4gNCl7CiAgICAgICAgICAgIGYoX25vdCxqLHU4KTsKICAgICAgICAgICAgdDY0W2pdID0gKGdvYWxbal1ecnhbal0pPj4zMjsKICAgICAgICAgICAgZ29hbFtqXSBePSB0NjRbal07CiAgICAgICAgICAgIHQzMltqXSA9ICgoZ29hbFtqXV5yeFtqXSk8PDMyKT4+MzI7CiAgICAgICAgICAgIGdvYWxbal0gXj0gdDY0W2pdOwogICAgICAgIH0KICAgIH0KICAgIGlmKHZ1bGwocngscngrMykgPT0gZ29hbCkgcmV0dXJuOwogICAgZihfaW5jLDMpOyAvLzMyLDEKICAgIHJlcChpLDAsMzEpewogICAgICAgIHJlcChqLDAsMil7CiAgICAgICAgICAgIGlmKHQ2NFtqXSZyeFszXSkgZihfeG9yLGosMyk7CiAgICAgICAgICAgIGlmKHQzMltqXSZyeFszXSkgZihfeG9yLGosMyxsMzIpOwogICAgICAgIH0KICAgICAgICBmKF9hZGQsMywzKTsKICAgIH0KICAgIHJlcChqLDAsMikKICAgICAgICBhc3NlcnQocnhbal0gPT0gZ29hbFtqXSk7Cn0Kdm9pZCBvdXRlcjQodnZ1bGwgZ29hbHMpewogICAgcmVwKHQsMCxuLTEpewogICAgICAgIHZ1bGwgZ29hbCA9IGdvYWxzW3RdOwogICAgICAgIGdvYWwgPSBiZXN0X3Blcm11dGUoaW5uZXI0LGdvYWxzW3RdKTsKICAgICAgICBpbm5lcjQoZ29hbCk7CiAgICB9Cn0KLy92b2lkIHNvbHZlNCgpewogICAgLy9mKF9pbmMsMyx1OCk7IC8vOAogICAgLy9mKF9tdWwsMywzKTsgLy8xNgogICAgLy9mKF9tdWwsMywzKTsgLy8zMgogICAgLy92dnVsbCBnb2FscyA9IGE7CiAgICAvL3RzcF9wZXJtdXRlKGlubmVyNCxnb2Fscyk7CiAgICAvL291dGVyNChnb2Fscyk7Ci8vfQoKCnZ1bGwgYXBwbHlfb3Blcihib29sIGtlZXBfY2hhbmdlcywgaW50IGJtKXsKICAgIHZ1bGwgb2xkX3ZhbHMocngscngrMyk7CiAgICBpZigha2VlcF9jaGFuZ2VzKQogICAgICAgIHNhdmluZyA9IGZhbHNlOwogICAgcmVwKGosMCwyKXsKICAgICAgICBpbnQgcDEgPSBibSUzOyBibSAvPSAzOwogICAgICAgIGludCBwMiA9IGJtJTI7IGJtIC89IDI7CiAgICAgICAgaWYocDIgPT0gcDEpIHAyID0gMjsKICAgICAgICBpbnQgb3BfaW5kZXgsIG5yX2JpdHM7CiAgICAgICAgb3BfaW5kZXggPSBibSU1OyBibSAvPSA1OwogICAgICAgIG5yX2JpdHMgPSBibSUyOyBibSAvPSAyOwogICAgICAgIGlmKG5yX2JpdHMgPT0gMCl7CiAgICAgICAgICAgIGlmKG9wX2luZGV4ID09IDApIGYoX2FkZCxwMSxwMik7CiAgICAgICAgICAgIGlmKG9wX2luZGV4ID09IDEpIGYoX3hvcixwMSxwMik7CiAgICAgICAgICAgIGlmKG9wX2luZGV4ID09IDIpIGYoX2FuZCxwMSxwMik7CiAgICAgICAgICAgIGlmKG9wX2luZGV4ID09IDMpIGYoX29yLHAxLHAyKTsKICAgICAgICAgICAgaWYob3BfaW5kZXggPT0gNCkgZihfc3ViLHAxLHAyKTsKICAgICAgICB9CiAgICAgICAgZWxzZXsKICAgICAgICAgICAgaWYob3BfaW5kZXggPT0gMCkgZihfYWRkLHAxLHAyLGwzMik7CiAgICAgICAgICAgIGlmKG9wX2luZGV4ID09IDEpIGYoX3hvcixwMSxwMixsMzIpOwogICAgICAgICAgICBpZihvcF9pbmRleCA9PSAyKSBmKF9hbmQscDEscDIsbDMyKTsKICAgICAgICAgICAgaWYob3BfaW5kZXggPT0gMykgZihfb3IscDEscDIsbDMyKTsKICAgICAgICAgICAgaWYob3BfaW5kZXggPT0gNCkgZihfc3ViLHAxLHAyLGwzMik7CiAgICAgICAgfQoKICAgIH0KICAgIHZ1bGwgcmV0KHJ4LHJ4KzMpOwogICAgaWYoIWtlZXBfY2hhbmdlcyl7CiAgICAgICAgc2F2aW5nID0gdHJ1ZTsKICAgICAgICByZXAoaiwwLDIpCiAgICAgICAgICAgIHJ4W2pdID0gb2xkX3ZhbHNbal07CiAgICB9CiAgICBzb3J0KGFsbChyZXQpKTsKICAgIHJldHVybiByZXQ7Cn0Kdm9pZCBzb2x2ZTQoKXsKICAgIGYoX2luYywzKTsKICAgIHJlcChpLDAsNjMpewogICAgICAgIHJlcChqLDAsMikKICAgICAgICAgICAgaWYoYVswXVtqXSYoMUxMPDxpKSkKICAgICAgICAgICAgICAgIGYoX3hvcixqLDMpOwogICAgICAgIGYoX2FkZCwzLDMpOwogICAgfQogICAgcmVwKGksMSxuLTEpewogICAgICAgIHNvcnQoYWxsKGFbaV0pKTsKICAgICAgICBzYXZpbmcgPSBmYWxzZTsKICAgICAgICB2dWxsIG9sZF92YWxzKHJ4LHJ4KzMpOwogICAgICAgIC8vYXNzZXJ0KG9sZF92YWxzID09IGFbaS0xXSk7CiAgICAgICAgaW50IGNvcnJlY3RfbWFzayA9IC0xOwogICAgICAgIHJlcChibSwwLGlwb3coNjAsMykpCiAgICAgICAgICAgIGlmKGFwcGx5X29wZXIoZmFsc2UsYm0pID09IGFbaV0pewogICAgICAgICAgICAgICAgY29ycmVjdF9tYXNrID0gYm07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGFzc2VydChjb3JyZWN0X21hc2sgIT0gLTEpOwogICAgICAgIGFwcGx5X29wZXIodHJ1ZSxjb3JyZWN0X21hc2spOwogICAgICAgIHNldDx1bGw+IHRtcChyeCxyeCs0KTsKICAgICAgICByZXAoaiwwLDIpIGFzc2VydCh0bXAuY291bnQoYVtpXVtqXSkpOwogICAgfQp9CnZvaWQgaW5uZXIyKHZ1bGwgZ29hbCl7CiAgICBnb2FsWzJdIF49IGdvYWxbMF07CiAgICBnb2FsWzFdIF49IGdvYWxbMF07CiAgICBmKF9pbmMsMyk7IC8vMzIsMQogICAgaWYocnhbMV0gIT0gMCkgZihfc3ViLDEsMSk7CiAgICBpZihyeFsyXSAhPSAwKSBmKF9zdWIsMiwyKTsKICAgIHZ1bGwgdDY0KDMpOwogICAgdnVsbCB0MzIoMyk7CiAgICByZXAoaiwwLDIpewogICAgICAgIHQ2NFtqXSA9IChnb2FsW2pdXnJ4W2pdKT4+MzI7CiAgICAgICAgZ29hbFtqXSBePSB0NjRbal07CiAgICAgICAgdDMyW2pdID0gKChnb2FsW2pdXnJ4W2pdKTw8MzIpPj4zMjsKICAgICAgICBnb2FsW2pdIF49IHQ2NFtqXTsKICAgIH0KICAgIHJlcChqLDAsMil7CiAgICAgICAgaWYoYml0cyh0NjRbal0pID4gMTYpewogICAgICAgICAgICBmKF9ub3Qsaik7CiAgICAgICAgICAgIHQ2NFtqXSA9IChnb2FsW2pdXnJ4W2pdKT4+MzI7CiAgICAgICAgICAgIGdvYWxbal0gXj0gdDY0W2pdOwogICAgICAgICAgICB0MzJbal0gPSAoKGdvYWxbal1ecnhbal0pPDwzMik+PjMyOwogICAgICAgICAgICBnb2FsW2pdIF49IHQ2NFtqXTsKICAgICAgICB9CiAgICAgICAgaWYoYml0cyh0MzJbal0pID4gMTYpewogICAgICAgICAgICBmKF9ub3QsaixsMzIpOwogICAgICAgICAgICB0NjRbal0gPSAoZ29hbFtqXV5yeFtqXSk+PjMyOwogICAgICAgICAgICBnb2FsW2pdIF49IHQ2NFtqXTsKICAgICAgICAgICAgdDMyW2pdID0gKChnb2FsW2pdXnJ4W2pdKTw8MzIpPj4zMjsKICAgICAgICAgICAgZ29hbFtqXSBePSB0NjRbal07CiAgICAgICAgfQoKICAgICAgICBpbnQgdHlwZXMgPSAwOwogICAgICAgIGlmKGJpdHModDMyW2pdJjB4MDBmZikgPiA0KSB0eXBlcyBePSAxOwogICAgICAgIGlmKGJpdHModDMyW2pdJjB4ZmYwMCkgPiA0KSB0eXBlcyBePSAyOwogICAgICAgIGlmKCh0eXBlcyYzKT09Myl7CiAgICAgICAgICAgIGYoX25vdCxqLGwxNik7CiAgICAgICAgICAgIHQ2NFtqXSA9IChnb2FsW2pdXnJ4W2pdKT4+MzI7CiAgICAgICAgICAgIGdvYWxbal0gXj0gdDY0W2pdOwogICAgICAgICAgICB0MzJbal0gPSAoKGdvYWxbal1ecnhbal0pPDwzMik+PjMyOwogICAgICAgICAgICBnb2FsW2pdIF49IHQ2NFtqXTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZih0eXBlcyYxKXsKICAgICAgICAgICAgZihfbm90LGosbDgpOwogICAgICAgICAgICB0NjRbal0gPSAoZ29hbFtqXV5yeFtqXSk+PjMyOwogICAgICAgICAgICBnb2FsW2pdIF49IHQ2NFtqXTsKICAgICAgICAgICAgdDMyW2pdID0gKChnb2FsW2pdXnJ4W2pdKTw8MzIpPj4zMjsKICAgICAgICAgICAgZ29hbFtqXSBePSB0NjRbal07CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYodHlwZXMmMil7CiAgICAgICAgICAgIGYoX25vdCxqLHU4KTsKICAgICAgICAgICAgdDY0W2pdID0gKGdvYWxbal1ecnhbal0pPj4zMjsKICAgICAgICAgICAgZ29hbFtqXSBePSB0NjRbal07CiAgICAgICAgICAgIHQzMltqXSA9ICgoZ29hbFtqXV5yeFtqXSk8PDMyKT4+MzI7CiAgICAgICAgICAgIGdvYWxbal0gXj0gdDY0W2pdOwogICAgICAgIH0KICAgIH0KICAgIHJlcChpLDAsMzEpewogICAgICAgIHJlcChqLDAsMil7CiAgICAgICAgICAgIGlmKHQ2NFtqXSZyeFszXSkgZihfeG9yLGosMyk7CiAgICAgICAgICAgIGlmKHQzMltqXSZyeFszXSkgZihfeG9yLGosMyxsMzIpOwogICAgICAgIH0KICAgICAgICBmKF9hZGQsMywzKTsKICAgIH0KICAgIGYoX3hvciwxLDApOwogICAgZihfeG9yLDIsMCk7Cn0Kdm9pZCBvdXRlcjIodnZ1bGwgZ29hbHMpewogICAgcmVwKHQsMCxuLTEpewogICAgICAgIHZ1bGwgZ29hbCA9IGJlc3RfcGVybXV0ZShpbm5lcjIsZ29hbHNbdF0pOwogICAgICAgIGlubmVyMihnb2FsKTsKICAgIH0KfQp2b2lkIHNvbHZlMigpewogICAgZihfaW5jLDMsdTgpOyAvLzgKICAgIGYoX211bCwzLDMpOyAvLzE2CiAgICBmKF9tdWwsMywzKTsgLy8zMgogICAgdnZ1bGwgZ29hbHMgPSBhOwogICAgdHNwX3Blcm11dGUoaW5uZXIyLGdvYWxzKTsKICAgIG91dGVyMihnb2Fscyk7Cn0Kdm9pZCBzb2x2ZTI2KCl7CiAgICBmKF9pbmMsMyx1OCk7IC8vOAogICAgZihfbW92LDAsMyk7CiAgICBmKF9tdWwsMywzKTsgLy8xNgogICAgZihfbXVsLDMsMyk7IC8vMzIKICAgIGYoX2luYywzLHU4KTsgLy8zMiw4CiAgICBmKF9tdWwsMywzLGwzMik7IC8vMzIsMTYKICAgIGYoX2luYywzKTsgLy8zMiwxNiwwCiAgICBmKF9tdWwsMywwKTsgLy80MCwyNCw4CiAgICByZXAodCwwLG4tMSl7CiAgICAgICAgaWYodCA+IDApewogICAgICAgICAgICBmKF9zdWIsMSwxKTsKICAgICAgICAgICAgZihfc3ViLDIsMik7CiAgICAgICAgfQogICAgICAgIHZ1bGwgZ29hbCA9IGFbdF07CiAgICAgICAgZ29hbFsxXSBePSBnb2FsWzBdOwogICAgICAgIGdvYWxbMl0gXj0gZ29hbFswXTsKICAgICAgICB7CiAgICAgICAgICAgIHZ1bGwgaW50ZXJtZWRpYXRlKDMpOwogICAgICAgICAgICB1bGwgbSA9ICh1bGwoMSk8PDQ4KSsodWxsKDEpPDwzMikrKHVsbCgxKTw8MTYpOwogICAgICAgICAgICByZXAoaSwwLDIpewogICAgICAgICAgICAgICAgdHJ5ewogICAgICAgICAgICAgICAgICAgIGludGVybWVkaWF0ZVtpXSA9IGNob29zZShyeFtpXSxnb2FsW2ldKTsKICAgICAgICAgICAgICAgIH1jYXRjaCguLi4pewogICAgICAgICAgICAgICAgICAgIGYoX3N1YixpLGkpOwogICAgICAgICAgICAgICAgICAgIGludGVybWVkaWF0ZVtpXSA9IGNob29zZShyeFtpXSxnb2FsW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXAoaSwwLDcpewogICAgICAgICAgICAgICAgcmVwKGosMCwyKQogICAgICAgICAgICAgICAgICAgIGlmKChyeFtqXV5pbnRlcm1lZGlhdGVbal0pICYgKDF1bGw8PCg0MCtpKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIGYoX3hvcixqLDMpOwogICAgICAgICAgICAgICAgcmVwKGosMCwyKQogICAgICAgICAgICAgICAgICAgIGlmKChyeFtqXV5pbnRlcm1lZGlhdGVbal0pICYgKDF1bGw8PCgyNCtpKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsbDMyKTsKICAgICAgICAgICAgICAgIHJlcChqLDAsMikKICAgICAgICAgICAgICAgICAgICBpZigocnhbal1eaW50ZXJtZWRpYXRlW2pdKSAmICgxdWxsPDwoOCtpKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsdTgsdTgpOwogICAgICAgICAgICAgICAgcmVwKGosMCwyKQogICAgICAgICAgICAgICAgICAgIGlmKChyeFtqXV5pbnRlcm1lZGlhdGVbal0pICYgKDF1bGw8PChpKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsbDgsdTgpOwogICAgICAgICAgICAgICAgZihfYWRkLDMsMyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYXNzZXJ0KHJ4WzNdID09IG0pOwogICAgICAgICAgICByZXAoaiwwLDIpCiAgICAgICAgICAgICAgICBmKF9tdWwsaiwzKTsKICAgICAgICAgICAgbWFrZV9yeDNfcmVtKCk7CiAgICAgICAgICAgIGYoX2luYywzKTsKICAgICAgICAgICAgcmVwKGksMCw3KXsKICAgICAgICAgICAgICAgIHJlcChqLDAsMikKICAgICAgICAgICAgICAgICAgICBpZigocnhbal1eZ29hbFtqXSkgJiAoMXVsbDw8KDMyK2kpKSkKICAgICAgICAgICAgICAgICAgICAgICAgZihfeG9yLGosMyk7CiAgICAgICAgICAgICAgICByZXAoaiwwLDIpCiAgICAgICAgICAgICAgICAgICAgaWYoKHJ4W2pdXmdvYWxbal0pICYgKDF1bGw8PCgxNitpKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsbDMyKTsKICAgICAgICAgICAgICAgIHJlcChqLDAsMikKICAgICAgICAgICAgICAgICAgICBpZigocnhbal1eZ29hbFtqXSkgJiAoMXVsbDw8KDgraSkpKQogICAgICAgICAgICAgICAgICAgICAgICBmKF94b3IsaiwzLHU4LGw4KTsKICAgICAgICAgICAgICAgIHJlcChqLDAsMikKICAgICAgICAgICAgICAgICAgICBpZigocnhbal1eZ29hbFtqXSkgJiAoMXVsbDw8KGkpKSkKICAgICAgICAgICAgICAgICAgICAgICAgZihfeG9yLGosMyxsOCxsOCk7CiAgICAgICAgICAgICAgICBmKF9hZGQsMywzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXAoaiwwLDIpIGFzc2VydCgocnhbal1eZ29hbFtqXSk9PTApOwogICAgICAgIH0KICAgICAgICBmKF94b3IsMSwwKTsKICAgICAgICBmKF94b3IsMiwwKTsKICAgIH0KfQp2b2lkIHNvbHZlNSgpewogICAgZihfaW5jLDMsdTgpOyAvLzgKICAgIGYoX211bCwzLDMpOyAvLzE2CiAgICBmKF9tdWwsMywzKTsgLy8zMgogICAgcmVwKHQsMCxuLTEpewogICAgICAgIGlmKHQgPiAwKXsKICAgICAgICAgICAgZihfYWRkLDIsMCk7CiAgICAgICAgICAgIGYoX2FkZCwyLDEpOwogICAgICAgIH0KICAgICAgICBmKF9pbmMsMyk7IC8vMzIsMQogICAgICAgIHZ1bGwgZ29hbCA9IGFbdF07CiAgICAgICAgdnVsbCB0NjQoMyk7CiAgICAgICAgdnVsbCB0MzIoMyk7CiAgICAgICAgcmVwKGosMCwyKXsKICAgICAgICAgICAgdDY0W2pdID0gKGdvYWxbal1ecnhbal0pPj4zMjsKICAgICAgICAgICAgZ29hbFtqXSBePSB0NjRbal07CiAgICAgICAgICAgIHQzMltqXSA9ICgoZ29hbFtqXV5yeFtqXSk8PDMyKT4+MzI7CiAgICAgICAgfQogICAgICAgIHJlcChpLDAsMzEpewogICAgICAgICAgICByZXAoaiwwLDErKHQ9PTApKXsKICAgICAgICAgICAgICAgIGlmKHQ2NFtqXSZyeFszXSkgZihfeG9yLGosMyk7CiAgICAgICAgICAgICAgICBpZih0MzJbal0mcnhbM10pIGYoX3hvcixqLDMsbDMyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmKF9hZGQsMywzKTsKICAgICAgICB9CgogICAgICAgIGlmKHQgPiAwKXsKICAgICAgICAgICAgZihfc3ViLDIsMCk7CiAgICAgICAgICAgIGYoX3N1YiwyLDEpOwogICAgICAgIH0KICAgIH0KfQpib29sIGNvbXAoY29uc3QgdnVsbCAmYSwgY29uc3QgdnVsbCAmYil7CiAgICByZXR1cm4gYVsxXS1hWzBdIDwgYlsxXS1iWzBdOwp9CnZvaWQgc29sdmUzKCl7CiAgICBzb3J0KGFsbChhKSxjb21wKTsKICAgIGYoX2luYywzLHU4KTsgLy84CiAgICBmKF9tdWwsMywzKTsgLy8xNgogICAgZihfbXVsLDMsMyk7IC8vMzIKICAgIHJlcCh0LDAsbi0xKXsKICAgICAgICBmKF9pbmMsMyk7IC8vMzIsMQogICAgICAgIHZ1bGwgZ29hbCA9IGFbdF07CiAgICAgICAgdnVsbCB0NjQoMyk7CiAgICAgICAgdnVsbCB0MzIoMyk7CiAgICAgICAgaWYodCU4KQogICAgICAgICAgICBmKF9zdWIsMiwxKTsKICAgICAgICByZXAoaiwwLDIpewogICAgICAgICAgICB0NjRbal0gPSAoZ29hbFtqXV5yeFtqXSk+PjMyOwogICAgICAgICAgICBnb2FsW2pdIF49IHQ2NFtqXTsKICAgICAgICAgICAgdDMyW2pdID0gKChnb2FsW2pdXnJ4W2pdKTw8MzIpPj4zMjsKICAgICAgICB9CiAgICAgICAgcmVwKGksMCwzMSl7CiAgICAgICAgICAgIHJlcChqLDAsMioodCU4ID09IDApKXsKICAgICAgICAgICAgICAgIGlmKHQ2NFtqXSZyeFszXSkgZihfeG9yLGosMyk7CiAgICAgICAgICAgICAgICBpZih0MzJbal0mcnhbM10pIGYoX3hvcixqLDMsbDMyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmKF9hZGQsMywzKTsKICAgICAgICB9CiAgICAgICAgaWYodCU4KXsKICAgICAgICAgICAgZihfbW92LDEsMCk7CiAgICAgICAgICAgIGYoX2FkZCwxLDIpOwogICAgICAgICAgICBmKF9hZGQsMiwxKTsKICAgICAgICB9CiAgICB9Cn0Kdm9pZCBpbm5lcjM2XzgodnVsbCBnb2FsLCBpbnQgdDIpewogICAgc29ydChhbGwoZ29hbCkpOwogICAgaWYodDIpCiAgICAgICAgZihfc3ViLDIsMSk7CiAgICB7CiAgICAgICAgaW50IGVuZHAgPSAwKzIqKHQyID09IDApOwogICAgICAgIHZ1bGwgaW50ZXJtZWRpYXRlKDMpOwogICAgICAgIHVsbCBtID0gKHVsbCgxKTw8NDgpKyh1bGwoMSk8PDMyKSsodWxsKDEpPDwxNik7CiAgICAgICAgcmVwKGksMCxlbmRwKXsKICAgICAgICAgICAgdHJ5ewogICAgICAgICAgICAgICAgaW50ZXJtZWRpYXRlW2ldID0gY2hvb3NlKHJ4W2ldLGdvYWxbaV0pOwogICAgICAgICAgICB9Y2F0Y2goLi4uKXsKICAgICAgICAgICAgICAgIGYoX3N1YixpLGkpOwogICAgICAgICAgICAgICAgaW50ZXJtZWRpYXRlW2ldID0gY2hvb3NlKHJ4W2ldLGdvYWxbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJlcChpLDAsNyl7CiAgICAgICAgICAgIHJlcChqLDAsZW5kcCkKICAgICAgICAgICAgICAgIGlmKChyeFtqXV5pbnRlcm1lZGlhdGVbal0pICYgKDF1bGw8PCg0MCtpKSkpCiAgICAgICAgICAgICAgICAgICAgZihfeG9yLGosMyk7CiAgICAgICAgICAgIHJlcChqLDAsZW5kcCkKICAgICAgICAgICAgICAgIGlmKChyeFtqXV5pbnRlcm1lZGlhdGVbal0pICYgKDF1bGw8PCgyNCtpKSkpCiAgICAgICAgICAgICAgICAgICAgZihfeG9yLGosMyxsMzIpOwogICAgICAgICAgICByZXAoaiwwLGVuZHApCiAgICAgICAgICAgICAgICBpZigocnhbal1eaW50ZXJtZWRpYXRlW2pdKSAmICgxdWxsPDwoOCtpKSkpCiAgICAgICAgICAgICAgICAgICAgZihfeG9yLGosMyx1OCx1OCk7CiAgICAgICAgICAgIHJlcChqLDAsZW5kcCkKICAgICAgICAgICAgICAgIGlmKChyeFtqXV5pbnRlcm1lZGlhdGVbal0pICYgKDF1bGw8PChpKSkpCiAgICAgICAgICAgICAgICAgICAgZihfeG9yLGosMyxsOCx1OCk7CiAgICAgICAgICAgIGYoX2FkZCwzLDMpOwogICAgICAgIH0KICAgICAgICBhc3NlcnQocnhbM10gPT0gbSk7CiAgICAgICAgcmVwKGosMCxlbmRwKQogICAgICAgICAgICBmKF9tdWwsaiwzKTsKICAgICAgICBtYWtlX3J4M19yZW0oKTsKICAgICAgICBmKF9pbmMsMyk7CiAgICAgICAgcmVwKGksMCw3KXsKICAgICAgICAgICAgcmVwKGosMCxlbmRwKQogICAgICAgICAgICAgICAgaWYoKHJ4W2pdXmdvYWxbal0pICYgKDF1bGw8PCgzMitpKSkpCiAgICAgICAgICAgICAgICAgICAgZihfeG9yLGosMyk7CiAgICAgICAgICAgIHJlcChqLDAsZW5kcCkKICAgICAgICAgICAgICAgIGlmKChyeFtqXV5nb2FsW2pdKSAmICgxdWxsPDwoMTYraSkpKQogICAgICAgICAgICAgICAgICAgIGYoX3hvcixqLDMsbDMyKTsKICAgICAgICAgICAgcmVwKGosMCxlbmRwKQogICAgICAgICAgICAgICAgaWYoKHJ4W2pdXmdvYWxbal0pICYgKDF1bGw8PCg4K2kpKSkKICAgICAgICAgICAgICAgICAgICBmKF94b3IsaiwzLHU4LGw4KTsKICAgICAgICAgICAgcmVwKGosMCxlbmRwKQogICAgICAgICAgICAgICAgaWYoKHJ4W2pdXmdvYWxbal0pICYgKDF1bGw8PChpKSkpCiAgICAgICAgICAgICAgICAgICAgZihfeG9yLGosMyxsOCxsOCk7CiAgICAgICAgICAgIGYoX2FkZCwzLDMpOwogICAgICAgIH0KCiAgICAgICAgaWYodDIpewogICAgICAgICAgICBmKF9tb3YsMSwwKTsKICAgICAgICAgICAgZihfYWRkLDEsMik7CiAgICAgICAgICAgIGYoX2FkZCwyLDEpOwogICAgICAgIH0KICAgICAgICByZXAoaiwwLDIpIGFzc2VydCgocnhbal1eZ29hbFtqXSk9PTApOwogICAgfQp9CnZvaWQgaW5uZXIzNl84XzAodnVsbCBnb2FsKXsKICAgIGlubmVyMzZfOChnb2FsLDApOwp9CnZvaWQgaW5uZXIzNl84XzEodnVsbCBnb2FsKXsKICAgIGlubmVyMzZfOChnb2FsLDEpOwp9CnZvaWQgb3V0ZXIzNih2dnVsbCBnb2Fscyl7CiAgICByZXAodDIsMCw3KXsKICAgICAgICBpZih0MiA9PSAwKXsKICAgICAgICAgICAgZ29hbHNbdDJdID0gYmVzdF9wZXJtdXRlKGlubmVyMzZfOF8wLGdvYWxzW3QyXSk7CiAgICAgICAgICAgIGlubmVyMzZfOF8wKGdvYWxzW3QyXSk7CiAgICAgICAgfQogICAgICAgIGVsc2V7CiAgICAgICAgICAgIGdvYWxzW3QyXSA9IGJlc3RfcGVybXV0ZShpbm5lcjM2XzhfMSxnb2Fsc1t0Ml0pOwogICAgICAgICAgICBpbm5lcjM2XzhfMShnb2Fsc1t0Ml0pOwogICAgICAgIH0KICAgIH0KfQp2b2lkIGZhcl9vdXQzNih2ZWN0b3I8dnZ1bGw+IGdvYWxzKXsKICAgIHJlcChpLDAsNykKICAgICAgICBvdXRlcjM2KGdvYWxzW2ldKTsKfQp2b2lkIHNvbHZlMzYoKXsKICAgIHNvcnQoYWxsKGEpLGNvbXApOwogICAgZihfaW5jLDMsdTgpOyAvLzgKICAgIGYoX21vdiwwLDMpOwogICAgZihfbXVsLDMsMyk7IC8vMTYKICAgIGYoX211bCwzLDMpOyAvLzMyCiAgICBmKF9pbmMsMyx1OCk7IC8vMzIsOAogICAgZihfbXVsLDMsMyxsMzIpOyAvLzMyLDE2CiAgICBmKF9pbmMsMyk7IC8vMzIsMTYsMAogICAgZihfbXVsLDMsMCk7IC8vNDAsMjQsOAogICAgdnZ1bGwgZ29hbHMgPSBhOwogICAgdmVjdG9yPHZ2dWxsPiBidWNrZXRzKDgpLGJlc3Q7CiAgICByZXAoaSwwLDcpewogICAgICAgIGJ1Y2tldHNbaV0gPSB2dnVsbChnb2Fscy5iZWdpbigpK2kqOCxnb2Fscy5iZWdpbigpKyhpKzEpKjgpOwogICAgICAgIHRzcF9wZXJtdXRlKGlubmVyMzZfOF8xLGJ1Y2tldHNbaV0pOwogICAgfQogICAgYmVzdCA9IGJ1Y2tldHM7CiAgICBpbnQgYmVzdF9jb3N0ID0gTU9EOwogICAgcmVwKGF0dGVtcHRzLDAsNDAwKXsKICAgICAgICBsbCBjdXJfY29zdCA9IG1vY2soZmFyX291dDM2LGJ1Y2tldHMpOwogICAgICAgIGlmKGN1cl9jb3N0IDwgYmVzdF9jb3N0KXsKICAgICAgICAgICAgYmVzdF9jb3N0ID0gY3VyX2Nvc3Q7CiAgICAgICAgICAgIGJlc3QgPSBidWNrZXRzOwogICAgICAgIH0KICAgICAgICByYW5kb21fc2h1ZmZsZShhbGwoYnVja2V0cykpOwogICAgfQogICAgZmFyX291dDM2KGJ1Y2tldHMpOwp9CiAgICAvL2lmKCFrZWVwX2NoYW5nZXMpCgogICAgLy9pZigha2VlcF9jaGFuZ2VzKXsKdm9pZCBfKCl7CiAgICBsbCB0b3RhbCA9IDA7CiAgICBsbCBkaXNwbGF5ID0gMDsKICAgIGludCBjbnQgPSAwOwogICAgd2hpbGUoY2luID4+IG4pewogICAgICAgICsrY250OwogICAgICAgIGlmKGNudCA+IDUpCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGEgPSB2dnVsbChuLHZ1bGwoMykpOyBjaW4gPj4gYTsKICAgICAgICB0eXBlID0gZ2V0X3R5cGUoKTsKICAgICAgICBpZih0eXBlICE9IDQpewogICAgICAgICAgICBmb3IoYXV0byAmXyA6IGEpCiAgICAgICAgICAgICAgICBzb3J0KGFsbChfKSk7CiAgICAgICAgICAgIHNvcnQoYWxsKGEpKTsKICAgICAgICB9CiAgICAgICAgLy9pZih0eXBlICE9IDIpIGNvbnRpbnVlOwogICAgICAgIGlmKHR5cGUgPT0gNCkKICAgICAgICAgICAgc29sdmU0KCk7CiAgICAgICAgZWxzZSBpZih0eXBlID09IDIpCiAgICAgICAgICAgIHNvbHZlMigpOwogICAgICAgIGVsc2UgaWYodHlwZSA9PSAzKQogICAgICAgICAgICBzb2x2ZTM2KCk7CiAgICAgICAgZWxzZSBpZih0eXBlID09IDUpCiAgICAgICAgICAgIHNvbHZlNTYoKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHNvbHZlMTYoKTsKICAgICAgICBjaGVjayhhKTsKICAgICAgICAvL2Fzc2VydCh0eXBlICE9IDEpOwogICAgICAgIGlmKHR5cGUgPT0gMSl7CiAgICAgICAgfQogICAgICAgIGNlcnIgPDwgdHlwZSA8PCAnICcgPDwgc3ooZGVzY3JpcHRpb24pIDw8ICdcbic7OwogICAgICAgIHByaW50KHN6KGRlc2NyaXB0aW9uKSk7CiAgICAgICAgcHJpbnQoZGVzY3JpcHRpb24sIlxuIik7CiAgICAgICAgdG90YWwgKz0gc3ooZGVzY3JpcHRpb24pOwogICAgICAgIGlmKHR5cGUgPT0gMiB8fCB0eXBlID09IDQgfHwgdHlwZSA9PSA1KQogICAgICAgICAgICBkaXNwbGF5ICs9IHN6KGRlc2NyaXB0aW9uKTsKICAgICAgICBkZXNjcmlwdGlvbi5jbGVhcigpOwogICAgICAgIG1lbXNldChyeCwwLHNpemVvZiByeCk7CiAgICB9CiAgICB3YXRjaCh0b3RhbCk7CiAgICB3YXRjaChkaXNwbGF5LzIpOwp9CnZvaWQgdHNwX3Blcm11dGUodm9pZCAoKnRvX3Rlc3QpKHZ1bGwpLCB2dnVsbCAmZ29hbHMpewogICAgY2FsY19kaXN0KHRvX3Rlc3QsZ29hbHMpOwogICAgdmkgb3JkZXI7CiAgICBpZihzeihnb2FscykgPiA4KXsKICAgICAgICBvcmRlciA9IGRlY2VudF9vcmRlcihzeihnb2FscykpOwogICAgfQogICAgZWxzZXsKICAgICAgICB2aSBhbnMoOCk7CiAgICAgICAgaW90YShhbGwoYW5zKSwwKTsKICAgICAgICB2aSBiZXN0OwogICAgICAgIGludCBiZXN0X2Nvc3QgPSBNT0Q7CiAgICAgICAgZG97CiAgICAgICAgICAgIGxsIGN1cl9jb3N0ID0gMDsKICAgICAgICAgICAgcmVwKGksMSw3KQogICAgICAgICAgICAgICAgY3VyX2Nvc3QgKz0gZGlzdFthbnNbaS0xXV1bYW5zW2ldXTsKICAgICAgICAgICAgaWYoY3VyX2Nvc3QgPCBiZXN0X2Nvc3QpewogICAgICAgICAgICAgICAgYmVzdF9jb3N0ID0gY3VyX2Nvc3Q7CiAgICAgICAgICAgICAgICBiZXN0ID0gYW5zOwogICAgICAgICAgICB9CiAgICAgICAgfXdoaWxlKG5leHRfcGVybXV0YXRpb24oYWxsKGFucykpKTsKICAgICAgICBvcmRlciA9IGJlc3Q7CiAgICB9CiAgICBzZXRfb3JkZXIoZ29hbHMsb3JkZXIpOwp9CnZ2dWxsIHJhbmRfcGVybXV0ZSh2b2lkICgqdG9fdGVzdCkodnZ1bGwpLCB2dnVsbCBnb2FscywgaW50IHJhbmRfdGltZXMpewogICAgc29ydChhbGwoZ29hbHMpKTsKICAgIHZ2dWxsIGJlc3QgPSBnb2FsczsKICAgIGludCBiZXN0X2Nvc3QgPSBNT0Q7CiAgICByZXAoYXR0ZW1wdHMsMCxyYW5kX3RpbWVzKXsKICAgICAgICBpbnQgY3VyX2Nvc3QgPSBtb2NrKHRvX3Rlc3QsZ29hbHMpOwogICAgICAgIGlmKGN1cl9jb3N0IDwgYmVzdF9jb3N0KXsKICAgICAgICAgICAgYmVzdF9jb3N0ID0gY3VyX2Nvc3Q7CiAgICAgICAgICAgIGJlc3QgPSBnb2FsczsKICAgICAgICB9CiAgICAgICAgcmFuZG9tX3NodWZmbGUoYWxsKGdvYWxzKSk7CiAgICB9CiAgICByZXR1cm4gYmVzdDsKfQp2dWxsIGJlc3RfcGVybXV0ZSh2b2lkICgqdG9fdGVzdCkodnVsbCksIHZ1bGwgZ29hbCl7CiAgICBzb3J0KGFsbChnb2FsKSk7CiAgICB2dWxsIGJlc3QgPSBnb2FsOwogICAgaW50IGJlc3RfY29zdCA9IE1PRDsKICAgIGRvewogICAgICAgIGludCBjdXJfY29zdCA9IG1vY2sodG9fdGVzdCxnZXRfc3RhdGUoKSxnb2FsKTsKICAgICAgICBpZihjdXJfY29zdCA8IGJlc3RfY29zdCl7CiAgICAgICAgICAgIGJlc3RfY29zdCA9IGN1cl9jb3N0OwogICAgICAgICAgICBiZXN0ID0gZ29hbDsKICAgICAgICB9CiAgICB9d2hpbGUobmV4dF9wZXJtdXRhdGlvbihhbGwoZ29hbCkpKTsKICAgIHJldHVybiBiZXN0Owp9CmludCBtYWluKCl7CiAgICBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsKICAgIGNpbi50aWUobnVsbHB0cik7CiAgICBjb3V0IDw8IGZpeGVkIDw8IHNldHByZWNpc2lvbigxNSk7CiAgICAgICAgXygpOwp9Cg==