#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned int uint;
typedef unsigned short ushort;
typedef pair<int, int> PII;
#define MAX_INT (int)0x7fffffff
#define MIN_INT (int)0x80000000
#define MAX_UINT (uint)0xffffffff
#define TTi template<typename T> inline
TTi T SQR(T x) { return x * x; }
#define CONCAT3_NX(x, y, z) x ## y ## z
#define CONCAT3(x, y, z) CONCAT3_NX(x, y, z)
#define VAR(name) CONCAT3(__tmpvar__, name, __LINE__)
#define TYPE(x) __typeof(x)
#define FOR(i, s, n) for (TYPE(n) i=(s), VAR(end)=(n); i < VAR(end); i++)
#define RFOR(i, s, n) for (TYPE(n) i=(n)-1, VAR(end)=(s); i >= VAR(end); i--)
#define FORN(i, n) FOR(i, 0, n)
#define RFORN(i, n) RFOR(i, 0, n)
#define FOREACH(i, v) for (auto& i: v)
#define SC() scanf("\n")
#define SC1(fmt, a) scanf(fmt, &a)
#define SC2(fmt, a, b) scanf(fmt, &a, &b)
#define SC3(fmt, a, b, c) scanf(fmt, &a, &b, &c)
#define SCi(a) scanf("%d", &a)
#define SCii(a,b) scanf("%d%d", &a, &b)
#define SCiii(a,b,c) scanf("%d%d%d", &a, &b, &c)
#define fLL "%lld"
#define SCl(a) scanf(fLL, &a)
#define SCll(a,b) scanf(fLL fLL, &a, &b)
#define SClll(a,b,c) scanf(fLL fLL fLL, &a, &b, &c)
#define SCs(s, n) {scanf("%s", s); n = strlen(s);}
#define SCc(s) scanf("%c", &c)
#define MP make_pair
#define PB push_back
#define WHOLE(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define POPST(stack) (stack).top();(stack).pop();
#define POPQ(queue) (queue).front();(queue).pop();
#define CONTAINS(v, x) (find(WHOLE(v), (x)) != v.end())
#define SORT(v) (sort(WHOLE(v)))
#define LIMIT(x, lim) {if (x > lim) x = lim;}
TTi T MIN(T x, T y) { return (x < y) ? x : y; }
TTi T MAX(T x, T y) { return (x > y) ? x : y; }
TTi T ABS(T x) { return (x > 0) ? x : -x; }
TTi void UPDATE_MIN(T &x, T y) {if (y < x) {x = y;}}
TTi void UPDATE_MAX(T &x, T y) {if (x < y) {x = y;}}
TTi int ARGMAX(T cont) { return max_element(cont.begin(), cont.end()) - cont.begin(); }
TTi int ARGMIN(T cont) { return min_element(cont.begin(), cont.end()) - cont.begin(); }
vector<string> split(const string& s, char c) {
vector<string> v; stringstream ss(s); string x;
while (getline(ss, x, c)) v.emplace_back(x); return move(v);
}
template<typename T, typename... Args>
inline string arrStr(T arr, int n) {
stringstream s;
s << "[";
FORN(i, n - 1) s << arr[i] << ",";
s << arr[n - 1] << "]";
return s.str();
}
// #ifndef ONLINE_JUDGE
#ifdef JUDGE_LOCAL
#define EPR(args...) if (DEBUG) {fprintf(stderr, args);}
#define EARR(arr, n) if (DEBUG) {FORN(i, n) fprintf(stderr, "%d, ", arr[i]);}
#define EVEC(arr) if (DEBUG) {FORN(i, arr.size()) fprintf(stderr, "%d, ", arr[i]);}
#define EVARS(args...) if (DEBUG) { __evars_begin(__LINE__); __evars(split(#args, ',').begin(), args);}
inline void __evars_begin(int line) { cerr << "#" << line << ": "; }
inline void __evars(vector<string>::iterator it) {cerr << endl;}
TTi void __evars_out_var(vector<T> val) {
cerr << arrStr(val, val.size());
}
TTi void __evars_out_var(T* val) {
cerr << arrStr(val, 10);
}
TTi void __evars_out_var(T val) {
cerr << val;
}
template<typename T, typename... Args>
inline void __evars(vector<string>::iterator it, T a, Args... args) {
cerr << it->substr((*it)[0] == ' ', it->length()) << "=";
__evars_out_var(a);
cerr << "; ";
__evars(++it, args...);
}
#else
#define EPR(args...) 1
#define EARR(args...) 1
#define EVEC(args...) 1
#define EVARS(args...) 1
#endif
template<class T> inline string TOSTR(const T & x) { stringstream ss; ss << x; return ss.str(); }
#define DIE(args...) {printf(args);exit(0);}
inline void PR(void) {}
inline void PR(int x) {printf("%d", x);}
inline void PR(LL x) {printf("%lld", x);}
inline void PR(char * s) {printf("%s", s);}
inline void PR(const char * s) {printf("%s", s);}
inline void PR(double f) {printf("%.10lf", f);}
inline void PR(long double f) {printf("%.10llf", f);}
inline void PR(vector<int> &vec) {for(auto x: vec){PR(x);putc(0x20,stdout);}}
TTi void PRS(T x) {PR(x);putc(0x20,stdout);}
TTi void PRN(T x) {PR(x);putc(0x0a,stdout);}
void PRN(void) {putc(0x0a,stdout);}
inline int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
inline LL gcd(LL a, LL b) { return a ? gcd(b % a, a) : b; }
inline LL powmod(LL a, LL p, LL m) { LL r = 1; while (p) { if (p & 1) r = r*a%m; p>>=1; a=a*a%m; } return r; }
struct pairhash {
template <typename T, typename U>
std::size_t operator() (const std::pair<T, U> &x) const {
return std::hash<T>()(x.first) ^ std::hash<U>()(x.second);
}
};
template <typename K, typename V>
V GetWithDef(const std::map<K,V> & m, const K & key, const V & defval ) {
auto it = m.find(key);
return (it == m.end()) ? defval : it->second;
}
template <typename K, typename V>
void SetDef(std::map<K,V> & m, const K & key, const V & defval ) {
auto it = m.find(key);
if (it == m.end()) m[key] = defval;
}
template <typename K, typename V>
V GetWithDef(const std::unordered_map<K,V> & m, const K & key, const V & defval ) {
auto it = m.find(key);
return (it == m.end()) ? defval : it->second;
}
template <typename K, typename V>
void SetDef(std::unordered_map<K,V> & m, const K & key, const V & defval ) {
auto it = m.find(key);
if (it == m.end()) m[key] = defval;
}
const int MOD = 1000 * 1000 * 1000 + 7;
const double PI = 3.1415926535897932384626433832795l;
inline void addto(int &a, int b) {
a += b;
if (a >= MOD) a -= MOD;
}
inline int add(int a, int b) {
a += b;
if (a >= MOD) a -= MOD;
return a;
}
inline void subto(int &a, int b) {
a -= b;
if (a < 0) a += MOD;
if (a >= MOD) a -= MOD;
}
inline int sub(int a, int b) {
a -= b;
if (a < 0) a += MOD;
if (a >= MOD) a -= MOD;
return a;
}
inline void multo(int &a, int b) {
a = (long long)a * b % MOD;
}
inline int mul(int a, int b) {
return (long long)a * b % MOD;
}
inline int mulmod(int a, int b, int mod) {
return (long long)a * b % mod;
}
inline int powmod(int a, int e, int mod) {
int x;
for(x = 1; e > 0; e >>= 1) {
if (e & 1)
x = mulmod(x, a, mod);
a = mulmod(a, a, mod);
}
return x;
}
inline int invmod_prime(int a, int mod) {
return powmod(a, mod - 2, mod);
}
inline LL invmod_LL(LL p){
LL q=p;
for(LL a=p*p;a!=1;a*=a) q*=a;
return q;
}
// -----------------------------------------------------------------
// CODE
// -----------------------------------------------------------------
#define DEBUG 1
int N, M, K, L, E, Q;
double pwin[100][100];
bool visited[1 << 18] = {};
double cache[1 << 18] = {};
double solve(int mask) {
if (!(mask & 1)) return 0.0;
if (mask == 1) return 1.0;
if (!visited[mask]) {
double res = 0;
int bestI = -1, bestJ = -1;
FORN(i, N) {
if ( !(mask & (1 << i)) ) continue;
FOR(j, 1, N) {
if (i == j) continue;
if ( !(mask & (1 << j)) ) continue;
int mask1 = mask ^ (1 << i);
double prob1 = pwin[j][i];
int mask2 = mask ^ (1 << j);
double prob2 = pwin[i][j];
double t = prob1 * solve(mask1) + prob2 * solve(mask2);
if (t > res) {
res = t;
bestI = i;
bestJ = j;
}
}
}
cout << "for mask " << mask << ": " << bestI + 1 << " " << bestJ + 1 << endl;
cache[mask] = res;
visited[mask] = 1;
}
return cache[mask];
}
int main() {
ios_base::sync_with_stdio(0);
SCi(N);
FORN(i, N) {
FORN(j, N) {
scanf("%lf", &pwin[i][j]);
EVARS(pwin[i][j]);
}}
int mask = (1 << N) - 1;
double ans = solve(mask);
for (int i = 0; i < (1 << N); i++) {
cout << i << " " << cache[i] << endl;
}
PRN(ans);
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdHlwZWRlZiBsb25nIGxvbmcgTEw7CnR5cGVkZWYgdW5zaWduZWQgbG9uZyBsb25nIFVMTDsKdHlwZWRlZiB1bnNpZ25lZCBpbnQgdWludDsKdHlwZWRlZiB1bnNpZ25lZCBzaG9ydCB1c2hvcnQ7CnR5cGVkZWYgcGFpcjxpbnQsIGludD4gUElJOwoKI2RlZmluZSBNQVhfSU5UIChpbnQpMHg3ZmZmZmZmZgojZGVmaW5lIE1JTl9JTlQgKGludCkweDgwMDAwMDAwCiNkZWZpbmUgTUFYX1VJTlQgKHVpbnQpMHhmZmZmZmZmZgoKI2RlZmluZSBUVGkgdGVtcGxhdGU8dHlwZW5hbWUgVD4gaW5saW5lClRUaSBUIFNRUihUIHgpIHsgcmV0dXJuIHggKiB4OyB9CgojZGVmaW5lIENPTkNBVDNfTlgoeCwgeSwgeikgeCAjIyB5ICMjIHoKI2RlZmluZSBDT05DQVQzKHgsIHksIHopIENPTkNBVDNfTlgoeCwgeSwgeikKI2RlZmluZSBWQVIobmFtZSkgQ09OQ0FUMyhfX3RtcHZhcl9fLCBuYW1lLCBfX0xJTkVfXykKI2RlZmluZSBUWVBFKHgpIF9fdHlwZW9mKHgpCgojZGVmaW5lIEZPUihpLCBzLCBuKSAgZm9yIChUWVBFKG4pIGk9KHMpLCAgIFZBUihlbmQpPShuKTsgIGkgPCAgVkFSKGVuZCk7ICBpKyspCiNkZWZpbmUgUkZPUihpLCBzLCBuKSBmb3IgKFRZUEUobikgaT0obiktMSwgVkFSKGVuZCk9KHMpOyAgaSA+PSBWQVIoZW5kKTsgIGktLSkKI2RlZmluZSBGT1JOKGksIG4pICAgIEZPUihpLCAwLCBuKQojZGVmaW5lIFJGT1JOKGksIG4pICAgUkZPUihpLCAwLCBuKQojZGVmaW5lIEZPUkVBQ0goaSwgdikgZm9yIChhdXRvJiBpOiB2KQoKI2RlZmluZSBTQygpIHNjYW5mKCJcbiIpCiNkZWZpbmUgU0MxKGZtdCwgYSkgc2NhbmYoZm10LCAmYSkKI2RlZmluZSBTQzIoZm10LCBhLCBiKSBzY2FuZihmbXQsICZhLCAmYikKI2RlZmluZSBTQzMoZm10LCBhLCBiLCBjKSBzY2FuZihmbXQsICZhLCAmYiwgJmMpCiNkZWZpbmUgU0NpKGEpIHNjYW5mKCIlZCIsICZhKQojZGVmaW5lIFNDaWkoYSxiKSBzY2FuZigiJWQlZCIsICZhLCAmYikKI2RlZmluZSBTQ2lpaShhLGIsYykgc2NhbmYoIiVkJWQlZCIsICZhLCAmYiwgJmMpCiNkZWZpbmUgZkxMICIlbGxkIgojZGVmaW5lIFNDbChhKSBzY2FuZihmTEwsICZhKQojZGVmaW5lIFNDbGwoYSxiKSBzY2FuZihmTEwgZkxMLCAmYSwgJmIpCiNkZWZpbmUgU0NsbGwoYSxiLGMpIHNjYW5mKGZMTCBmTEwgZkxMLCAmYSwgJmIsICZjKQojZGVmaW5lIFNDcyhzLCBuKSB7c2NhbmYoIiVzIiwgcyk7IG4gPSBzdHJsZW4ocyk7fQojZGVmaW5lIFNDYyhzKSBzY2FuZigiJWMiLCAmYykKCiNkZWZpbmUgTVAgbWFrZV9wYWlyCiNkZWZpbmUgUEIgcHVzaF9iYWNrCiNkZWZpbmUgV0hPTEUoeCkgKHgpLmJlZ2luKCksKHgpLmVuZCgpCiNkZWZpbmUgU1ooeCkgKChpbnQpKHgpLnNpemUoKSkKI2RlZmluZSBQT1BTVChzdGFjaykgKHN0YWNrKS50b3AoKTsoc3RhY2spLnBvcCgpOwojZGVmaW5lIFBPUFEocXVldWUpIChxdWV1ZSkuZnJvbnQoKTsocXVldWUpLnBvcCgpOwojZGVmaW5lIENPTlRBSU5TKHYsIHgpIChmaW5kKFdIT0xFKHYpLCAoeCkpICE9IHYuZW5kKCkpCiNkZWZpbmUgU09SVCh2KSAoc29ydChXSE9MRSh2KSkpCgojZGVmaW5lIExJTUlUKHgsIGxpbSkge2lmICh4ID4gbGltKSB4ID0gbGltO30KVFRpIFQgTUlOKFQgeCwgVCB5KSB7IHJldHVybiAoeCA8IHkpID8geCA6IHk7IH0KVFRpIFQgTUFYKFQgeCwgVCB5KSB7IHJldHVybiAoeCA+IHkpID8geCA6IHk7IH0KVFRpIFQgQUJTKFQgeCkgeyByZXR1cm4gKHggPiAwKSA/IHggOiAteDsgfQpUVGkgdm9pZCBVUERBVEVfTUlOKFQgJngsIFQgeSkge2lmICh5IDwgeCkge3ggPSB5O319ClRUaSB2b2lkIFVQREFURV9NQVgoVCAmeCwgVCB5KSB7aWYgKHggPCB5KSB7eCA9IHk7fX0KVFRpIGludCBBUkdNQVgoVCBjb250KSB7IHJldHVybiBtYXhfZWxlbWVudChjb250LmJlZ2luKCksIGNvbnQuZW5kKCkpIC0gY29udC5iZWdpbigpOyB9ClRUaSBpbnQgQVJHTUlOKFQgY29udCkgeyByZXR1cm4gbWluX2VsZW1lbnQoY29udC5iZWdpbigpLCBjb250LmVuZCgpKSAtIGNvbnQuYmVnaW4oKTsgfQoKdmVjdG9yPHN0cmluZz4gc3BsaXQoY29uc3Qgc3RyaW5nJiBzLCBjaGFyIGMpIHsKICAgIHZlY3RvcjxzdHJpbmc+IHY7IHN0cmluZ3N0cmVhbSBzcyhzKTsgc3RyaW5nIHg7CiAgICB3aGlsZSAoZ2V0bGluZShzcywgeCwgYykpIHYuZW1wbGFjZV9iYWNrKHgpOyByZXR1cm4gbW92ZSh2KTsKfQp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBBcmdzPgppbmxpbmUgc3RyaW5nIGFyclN0cihUIGFyciwgaW50IG4pIHsKICAgIHN0cmluZ3N0cmVhbSBzOwogICAgcyA8PCAiWyI7CiAgICBGT1JOKGksIG4gLSAxKSBzIDw8IGFycltpXSA8PCAiLCI7CiAgICBzIDw8IGFycltuIC0gMV0gPDwgIl0iOwogICAgcmV0dXJuIHMuc3RyKCk7Cn0KCi8vICNpZm5kZWYgT05MSU5FX0pVREdFCiNpZmRlZiBKVURHRV9MT0NBTAogICAgI2RlZmluZSBFUFIoYXJncy4uLikgICBpZiAoREVCVUcpIHtmcHJpbnRmKHN0ZGVyciwgYXJncyk7fQogICAgI2RlZmluZSBFQVJSKGFyciwgbikgICBpZiAoREVCVUcpIHtGT1JOKGksIG4pIGZwcmludGYoc3RkZXJyLCAiJWQsICIsIGFycltpXSk7fQogICAgI2RlZmluZSBFVkVDKGFycikgICAgICBpZiAoREVCVUcpIHtGT1JOKGksIGFyci5zaXplKCkpIGZwcmludGYoc3RkZXJyLCAiJWQsICIsIGFycltpXSk7fQogICAgI2RlZmluZSBFVkFSUyhhcmdzLi4uKSBpZiAoREVCVUcpIHsgX19ldmFyc19iZWdpbihfX0xJTkVfXyk7IF9fZXZhcnMoc3BsaXQoI2FyZ3MsICcsJykuYmVnaW4oKSwgYXJncyk7fQoKICAgIGlubGluZSB2b2lkIF9fZXZhcnNfYmVnaW4oaW50IGxpbmUpIHsgY2VyciA8PCAiIyIgPDwgbGluZSA8PCAiOiAiOyB9CiAgICBpbmxpbmUgdm9pZCBfX2V2YXJzKHZlY3RvcjxzdHJpbmc+OjppdGVyYXRvciBpdCkge2NlcnIgPDwgZW5kbDt9CgogICAgVFRpIHZvaWQgX19ldmFyc19vdXRfdmFyKHZlY3RvcjxUPiB2YWwpIHsKICAgICAgICBjZXJyIDw8IGFyclN0cih2YWwsIHZhbC5zaXplKCkpOwogICAgfQogICAgVFRpIHZvaWQgX19ldmFyc19vdXRfdmFyKFQqIHZhbCkgewogICAgICAgIGNlcnIgPDwgYXJyU3RyKHZhbCwgMTApOwogICAgfQogICAgVFRpIHZvaWQgX19ldmFyc19vdXRfdmFyKFQgdmFsKSB7CiAgICAgICAgY2VyciA8PCB2YWw7CiAgICB9CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBBcmdzPgogICAgaW5saW5lIHZvaWQgX19ldmFycyh2ZWN0b3I8c3RyaW5nPjo6aXRlcmF0b3IgaXQsIFQgYSwgQXJncy4uLiBhcmdzKSB7CiAgICAgICAgY2VyciA8PCBpdC0+c3Vic3RyKCgqaXQpWzBdID09ICcgJywgaXQtPmxlbmd0aCgpKSA8PCAiPSI7CiAgICAgICAgX19ldmFyc19vdXRfdmFyKGEpOwogICAgICAgIGNlcnIgPDwgIjsgIjsKICAgICAgICBfX2V2YXJzKCsraXQsIGFyZ3MuLi4pOwogICAgfQojZWxzZQogICAgI2RlZmluZSBFUFIoYXJncy4uLikgMQogICAgI2RlZmluZSBFQVJSKGFyZ3MuLi4pIDEKICAgICNkZWZpbmUgRVZFQyhhcmdzLi4uKSAxCiAgICAjZGVmaW5lIEVWQVJTKGFyZ3MuLi4pIDEKI2VuZGlmCgp0ZW1wbGF0ZTxjbGFzcyBUPiBpbmxpbmUgc3RyaW5nIFRPU1RSKGNvbnN0IFQgJiB4KSB7IHN0cmluZ3N0cmVhbSBzczsgc3MgPDwgeDsgcmV0dXJuIHNzLnN0cigpOyB9CiNkZWZpbmUgRElFKGFyZ3MuLi4pIHtwcmludGYoYXJncyk7ZXhpdCgwKTt9CmlubGluZSB2b2lkIFBSKHZvaWQpIHt9CmlubGluZSB2b2lkIFBSKGludCB4KSB7cHJpbnRmKCIlZCIsIHgpO30KaW5saW5lIHZvaWQgUFIoTEwgeCkge3ByaW50ZigiJWxsZCIsIHgpO30KaW5saW5lIHZvaWQgUFIoY2hhciAqIHMpIHtwcmludGYoIiVzIiwgcyk7fQppbmxpbmUgdm9pZCBQUihjb25zdCBjaGFyICogcykge3ByaW50ZigiJXMiLCBzKTt9CmlubGluZSB2b2lkIFBSKGRvdWJsZSBmKSB7cHJpbnRmKCIlLjEwbGYiLCBmKTt9CmlubGluZSB2b2lkIFBSKGxvbmcgZG91YmxlIGYpIHtwcmludGYoIiUuMTBsbGYiLCBmKTt9CmlubGluZSB2b2lkIFBSKHZlY3RvcjxpbnQ+ICZ2ZWMpIHtmb3IoYXV0byB4OiB2ZWMpe1BSKHgpO3B1dGMoMHgyMCxzdGRvdXQpO319ClRUaSB2b2lkIFBSUyhUIHgpIHtQUih4KTtwdXRjKDB4MjAsc3Rkb3V0KTt9ClRUaSB2b2lkIFBSTihUIHgpIHtQUih4KTtwdXRjKDB4MGEsc3Rkb3V0KTt9CnZvaWQgUFJOKHZvaWQpIHtwdXRjKDB4MGEsc3Rkb3V0KTt9CgppbmxpbmUgaW50IGdjZChpbnQgYSwgaW50IGIpIHsgcmV0dXJuIGEgPyBnY2QoYiAlIGEsIGEpIDogYjsgfQppbmxpbmUgTEwgZ2NkKExMIGEsIExMIGIpIHsgcmV0dXJuIGEgPyBnY2QoYiAlIGEsIGEpIDogYjsgfQppbmxpbmUgTEwgcG93bW9kKExMIGEsIExMIHAsIExMIG0pIHsgTEwgciA9IDE7IHdoaWxlIChwKSB7IGlmIChwICYgMSkgciA9IHIqYSVtOyBwPj49MTsgYT1hKmElbTsgfSByZXR1cm4gcjsgfQoKc3RydWN0IHBhaXJoYXNoIHsKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBVPgogICAgc3RkOjpzaXplX3Qgb3BlcmF0b3IoKSAoY29uc3Qgc3RkOjpwYWlyPFQsIFU+ICZ4KSBjb25zdCB7CiAgICAgICAgcmV0dXJuIHN0ZDo6aGFzaDxUPigpKHguZmlyc3QpIF4gc3RkOjpoYXNoPFU+KCkoeC5zZWNvbmQpOwogICAgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEssIHR5cGVuYW1lIFY+ClYgR2V0V2l0aERlZihjb25zdCBzdGQ6Om1hcDxLLFY+ICYgbSwgY29uc3QgSyAmIGtleSwgY29uc3QgViAmIGRlZnZhbCApIHsKICAgIGF1dG8gaXQgPSBtLmZpbmQoa2V5KTsKICAgIHJldHVybiAoaXQgPT0gbS5lbmQoKSkgPyBkZWZ2YWwgOiBpdC0+c2Vjb25kOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgSywgdHlwZW5hbWUgVj4Kdm9pZCBTZXREZWYoc3RkOjptYXA8SyxWPiAmIG0sIGNvbnN0IEsgJiBrZXksIGNvbnN0IFYgJiBkZWZ2YWwgKSB7CiAgICBhdXRvIGl0ID0gbS5maW5kKGtleSk7CiAgICBpZiAoaXQgPT0gbS5lbmQoKSkgbVtrZXldID0gZGVmdmFsOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgSywgdHlwZW5hbWUgVj4KViBHZXRXaXRoRGVmKGNvbnN0IHN0ZDo6dW5vcmRlcmVkX21hcDxLLFY+ICYgbSwgY29uc3QgSyAmIGtleSwgY29uc3QgViAmIGRlZnZhbCApIHsKICAgIGF1dG8gaXQgPSBtLmZpbmQoa2V5KTsKICAgIHJldHVybiAoaXQgPT0gbS5lbmQoKSkgPyBkZWZ2YWwgOiBpdC0+c2Vjb25kOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgSywgdHlwZW5hbWUgVj4Kdm9pZCBTZXREZWYoc3RkOjp1bm9yZGVyZWRfbWFwPEssVj4gJiBtLCBjb25zdCBLICYga2V5LCBjb25zdCBWICYgZGVmdmFsICkgewogICAgYXV0byBpdCA9IG0uZmluZChrZXkpOwogICAgaWYgKGl0ID09IG0uZW5kKCkpIG1ba2V5XSA9IGRlZnZhbDsKfQoKY29uc3QgaW50IE1PRCA9IDEwMDAgKiAxMDAwICogMTAwMCArIDc7CmNvbnN0IGRvdWJsZSBQSSA9IDMuMTQxNTkyNjUzNTg5NzkzMjM4NDYyNjQzMzgzMjc5NWw7CgppbmxpbmUgdm9pZCBhZGR0byhpbnQgJmEsIGludCBiKSB7CiAgICBhICs9IGI7CiAgICBpZiAoYSA+PSBNT0QpIGEgLT0gTU9EOwp9CmlubGluZSBpbnQgYWRkKGludCBhLCBpbnQgYikgewogICAgYSArPSBiOwogICAgaWYgKGEgPj0gTU9EKSBhIC09IE1PRDsKICAgIHJldHVybiBhOwp9CmlubGluZSB2b2lkIHN1YnRvKGludCAmYSwgaW50IGIpIHsKICAgIGEgLT0gYjsKICAgIGlmIChhIDwgMCkgYSArPSBNT0Q7CiAgICBpZiAoYSA+PSBNT0QpIGEgLT0gTU9EOwp9CmlubGluZSBpbnQgc3ViKGludCBhLCBpbnQgYikgewogICAgYSAtPSBiOwogICAgaWYgKGEgPCAwKSBhICs9IE1PRDsKICAgIGlmIChhID49IE1PRCkgYSAtPSBNT0Q7CiAgICByZXR1cm4gYTsKfQppbmxpbmUgdm9pZCBtdWx0byhpbnQgJmEsIGludCBiKSB7CiAgICBhID0gKGxvbmcgbG9uZylhICogYiAlIE1PRDsKfQppbmxpbmUgaW50IG11bChpbnQgYSwgaW50IGIpIHsKICAgIHJldHVybiAobG9uZyBsb25nKWEgKiBiICUgTU9EOwp9CmlubGluZSBpbnQgbXVsbW9kKGludCBhLCBpbnQgYiwgaW50IG1vZCkgewogICAgcmV0dXJuIChsb25nIGxvbmcpYSAqIGIgJSBtb2Q7Cn0KaW5saW5lIGludCBwb3dtb2QoaW50IGEsIGludCBlLCBpbnQgbW9kKSB7CiAgICBpbnQgeDsKICAgIGZvcih4ID0gMTsgZSA+IDA7IGUgPj49IDEpIHsKICAgICAgICBpZiAoZSAmIDEpCiAgICAgICAgICAgIHggPSBtdWxtb2QoeCwgYSwgbW9kKTsKICAgICAgICBhID0gbXVsbW9kKGEsIGEsIG1vZCk7CiAgICB9CiAgICByZXR1cm4geDsKfQppbmxpbmUgaW50IGludm1vZF9wcmltZShpbnQgYSwgaW50IG1vZCkgewogICAgcmV0dXJuIHBvd21vZChhLCBtb2QgLSAyLCBtb2QpOwp9CmlubGluZSBMTCBpbnZtb2RfTEwoTEwgcCl7CiAgICBMTCBxPXA7CiAgICBmb3IoTEwgYT1wKnA7YSE9MTthKj1hKSBxKj1hOwogICAgcmV0dXJuIHE7Cn0KCgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gQ09ERQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKI2RlZmluZSBERUJVRyAxCgppbnQgTiwgTSwgSywgTCwgRSwgUTsKZG91YmxlIHB3aW5bMTAwXVsxMDBdOwoKYm9vbCB2aXNpdGVkWzEgPDwgMThdID0ge307CmRvdWJsZSBjYWNoZVsxIDw8IDE4XSA9IHt9OwoKZG91YmxlIHNvbHZlKGludCBtYXNrKSB7CiAgICBpZiAoIShtYXNrICYgMSkpIHJldHVybiAwLjA7CiAgICBpZiAobWFzayA9PSAxKSByZXR1cm4gMS4wOwoKICAgIGlmICghdmlzaXRlZFttYXNrXSkgewogICAgICAgIGRvdWJsZSByZXMgPSAwOwogICAgICAgIGludCBiZXN0SSA9IC0xLCBiZXN0SiA9IC0xOwogICAgICAgIEZPUk4oaSwgTikgewogICAgICAgICAgICBpZiAoICEobWFzayAmICgxIDw8IGkpKSApIGNvbnRpbnVlOwogICAgICAgICAgICBGT1IoaiwgMSwgTikgewogICAgICAgICAgICAgICAgaWYgKGkgPT0gaikgY29udGludWU7CiAgICAgICAgICAgICAgICBpZiAoICEobWFzayAmICgxIDw8IGopKSApIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaW50IG1hc2sxID0gbWFzayBeICgxIDw8IGkpOwogICAgICAgICAgICAgICAgZG91YmxlIHByb2IxID0gcHdpbltqXVtpXTsKICAgICAgICAgICAgICAgIGludCBtYXNrMiA9IG1hc2sgXiAoMSA8PCBqKTsKICAgICAgICAgICAgICAgIGRvdWJsZSBwcm9iMiA9IHB3aW5baV1bal07CiAgICAgICAgICAgICAgICBkb3VibGUgdCA9IHByb2IxICogc29sdmUobWFzazEpICsgcHJvYjIgKiBzb2x2ZShtYXNrMik7CiAgICAgICAgICAgICAgICBpZiAodCA+IHJlcykgewogICAgICAgICAgICAgICAgICAgIHJlcyA9IHQ7CiAgICAgICAgICAgICAgICAgICAgYmVzdEkgPSBpOwogICAgICAgICAgICAgICAgICAgIGJlc3RKID0gajsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb3V0IDw8ICJmb3IgbWFzayAiIDw8IG1hc2sgPDwgIjogIiA8PCBiZXN0SSArIDEgPDwgIiAiIDw8IGJlc3RKICsgMSA8PCBlbmRsOwogICAgICAgIGNhY2hlW21hc2tdID0gcmVzOwogICAgICAgIHZpc2l0ZWRbbWFza10gPSAxOwogICAgfQogICAgcmV0dXJuIGNhY2hlW21hc2tdOwp9CgppbnQgbWFpbigpIHsKICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oMCk7CgogICAgU0NpKE4pOwogICAgRk9STihpLCBOKSB7CiAgICBGT1JOKGosIE4pIHsKICAgICAgICBzY2FuZigiJWxmIiwgJnB3aW5baV1bal0pOwogICAgICAgIEVWQVJTKHB3aW5baV1bal0pOwogICAgfX0KCiAgICBpbnQgbWFzayA9ICgxIDw8IE4pIC0gMTsKICAgIGRvdWJsZSBhbnMgPSBzb2x2ZShtYXNrKTsKICAgIAogICAgZm9yIChpbnQgaSA9IDA7IGkgPCAoMSA8PCBOKTsgaSsrKSB7CiAgICAgICAgY291dCA8PCBpIDw8ICIgIiA8PCBjYWNoZVtpXSA8PCBlbmRsOwogICAgfQogICAgCiAgICBQUk4oYW5zKTsKICAgIHJldHVybiAwOwp9