#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>
#include <time.h>
#include <string.h>
#include <assert.h>
using namespace std;
typedef long long ll;
template < class T> bool INRANGE( T x,T a,T b) { return a<= x&& x<= b; }
#define NG (-1)
#define BIG (123456789)
#define BIGBIG (123456789123456789LL)
#define SZ(a) ((int)(a).size())
// 最大流 Dinic O(EV^2)だけど、実際もっとはやい。
class Dinic
{
public :
Dinic( int input_maxv) : maxv( input_maxv)
{
G.resize ( input_maxv) ;
level.resize ( input_maxv) ;
iter.resize ( input_maxv) ;
}
void add_edge_both( int from, int to, ll cap)
{
if ( cap> 0 )
{
const int rev_from = SZ( G[ from] ) ;
const int rev_to = SZ( G[ to] ) ;
G[ from] .push_back ( edge( to,cap,rev_to) ) ;
G[ to] .push_back ( edge( from,cap,rev_from) ) ;
}
}
void add_edge( int from, int to, ll cap)
{
if ( cap> 0 )
{
const int rev_from = SZ( G[ from] ) ;
const int rev_to = SZ( G[ to] ) ;
G[ from] .push_back ( edge( to,cap,rev_to) ) ;
G[ to] .push_back ( edge( from,0 ,rev_from) ) ;
}
}
// sからtへの最大流を求める
ll max_flow( int s, int t)
{
ll flow = 0 ;
for ( ;; )
{
bfs( s) ;
if ( level[ t] < 0 ) break ;
fill( iter.begin ( ) ,iter.end ( ) ,0 ) ;
ll f;
while ( ( f= dfs( s,t,DINIC_INF) ) > 0 )
{
flow + = f;
}
}
return flow;
}
// ノードsから辿れる範囲を求める(これ以上流せないところcap=0は、リンクがなくなる)
// (流し終わったあとsourceからたどれる範囲が、最小カット時のs側。たどれない法がt側。その境界がカットするところ。)
vector < bool > get_nodes_in_group( int s)
{
vector < bool > ret( maxv) ;
queue< int > que;
que.push ( s) ;
while ( ! que.empty ( ) )
{
int v = que.front ( ) ;
que.pop ( ) ;
ret[ v] = true ;
for ( int i= 0 ; i< SZ( G[ v] ) ; i++ )
{
edge & e = G[ v] [ i] ;
if ( e.cap > 0 && ! ret[ e.to ] )
{
que.push ( e.to ) ;
}
}
}
return ret;
}
void disp( )
{
for ( int v = 0 ; v < maxv; v++ )
{
printf ( "%d:" ,v) ;
for ( int i= 0 ; i< SZ( G[ v] ) ; i++ )
{
if ( G[ v] [ i] .init_cap > 0 )
{
printf ( "->%d(%lld)," ,G[ v] [ i] .to ,G[ v] [ i] .init_cap ) ;
}
}
printf ( "\n " ) ;
}
}
private :
// sからの最短距離をBFSで計算する
void bfs( int s)
{
fill( level.begin ( ) ,level.end ( ) ,NG) ;
queue< int > que;
level[ s] = 0 ;
que.push ( s) ;
while ( ! que.empty ( ) )
{
int v = que.front ( ) ;
que.pop ( ) ;
for ( int i= 0 ; i< SZ( G[ v] ) ; i++ )
{
edge & e = G[ v] [ i] ;
if ( e.cap > 0 && level[ e.to ] < 0 )
{
level[ e.to ] = level[ v] + 1 ;
que.push ( e.to ) ;
}
}
}
}
// 増加パスをDFSで探す
ll dfs( int v, int t, ll f)
{
if ( v== t) return f;
for ( int & i= iter[ v] ; i< SZ( G[ v] ) ; i++ )
{
edge& e = G[ v] [ i] ;
if ( e.cap > 0 && level[ v] < level[ e.to ] )
{
ll d = dfs( e.to , t, min( f, e.cap ) ) ;
if ( d> 0 )
{
e.cap - = d;
G[ e.to ] [ e.rev ] .cap + = d;
return d;
}
}
}
return 0 ;
}
static const ll DINIC_INF = LLONG_MAX; // 容量をllにしたいときは、ここも変える
struct edge
{
edge( int input_to, ll input_cap, int input_rev) : to( input_to) , cap( input_cap) , rev( input_rev) , init_cap( input_cap) { }
int to; // 行先
ll cap; // 容量
int rev; // 逆辺
ll init_cap; // 初期容量(デバッグ用)
} ;
int maxv;
vector < vector < edge> > G; // グラフの隣接リスト
vector < int > level; // sからの距離
vector < int > iter; // どこまで調べ終わったか
} ;
class RabbitWorking {
public :
bool ok( ll a, ll b, const vector < string> & profit)
{
const int N = SZ( profit) ;
const int S = N+ N* ( N- 1 ) / 2 ;
const int T = S+ 1 ;
const int V = T+ 1 ;
Dinic* dinic = new Dinic( V) ;
ll ret = 0 ;
int v = 0 ;
for ( int i = 0 ; i < N; i++ )
{
dinic- > add_edge( S,i,199 * a) ;
v++ ;
}
for ( int i = 0 ; i < N; i++ )
{
for ( int j = i+ 1 ; j < N; j++ )
{
ll p = profit[ i] [ j] - '0' ;
ll cost = b* p+ 2 * a;
ret + = cost;
dinic- > add_edge( v,T,cost) ;
dinic- > add_edge( i,v,BIGBIG) ;
dinic- > add_edge( j,v,BIGBIG) ;
v++ ;
}
}
ret - = dinic- > max_flow( S,T) ;
delete dinic;
return ret> 0 ;
}
double getMaximum( vector < string> profit) {
ll b = ( ll) 1e12 ;
ll lo = 0 ;
ll hi = ( ll) b* 100 ;
while ( lo< hi)
{
ll mid = lo+ ( hi- lo) / 2LL;
if ( ! ok( mid,b,profit) )
{
hi= mid;
}
else
{
lo= mid+ 1 ;
}
}
return ( double ) lo/ b;
}
private :
template < typename T> string print_array( const vector< T> & V) { ostringstream os; os << "{ " ; for ( typename vector< T> :: const_iterator iter = V.begin ( ) ; iter ! = V.end ( ) ; ++ iter) os << '\" ' << * iter << "\" ," ; os << " }" ; return os.str ( ) ; }
void verify_case( int Case, const double & Expected, const double & Received) { cerr << "Test Case #" << Case << "..." ; if ( Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\t Expected: \" " << Expected << '\" ' << endl; cerr << "\t Received: \" " << Received << '\" ' << endl; } }
public :
void run_test( int Case) {
int n = 0 ;
// test_case_0
if ( ( Case == - 1 ) || ( Case == n) ) {
string Arr0[ ] = { "071" ,
"702" ,
"120" }
;
double Arg1 = 0.017676767676767676 ;
vector < string> Arg0( Arr0, Arr0 + ( sizeof ( Arr0) / sizeof ( Arr0[ 0 ] ) ) ) ;
verify_case( n, Arg1, getMaximum( Arg0) ) ;
}
n++ ;
// test_case_1
if ( ( Case == - 1 ) || ( Case == n) ) {
string Arr0[ ] = { "061" ,
"602" ,
"120" }
;
double Arg1 = 0.015228426395939087 ;
vector < string> Arg0( Arr0, Arr0 + ( sizeof ( Arr0) / sizeof ( Arr0[ 0 ] ) ) ) ;
verify_case( n, Arg1, getMaximum( Arg0) ) ;
}
n++ ;
// test_case_2
if ( ( Case == - 1 ) || ( Case == n) ) {
string Arr0[ ] = { "0" }
;
double Arg1 = 0.0 ;
vector < string> Arg0( Arr0, Arr0 + ( sizeof ( Arr0) / sizeof ( Arr0[ 0 ] ) ) ) ;
verify_case( n, Arg1, getMaximum( Arg0) ) ;
}
n++ ;
// test_case_3
if ( ( Case == - 1 ) || ( Case == n) ) {
string Arr0[ ] = { "013040" ,
"100010" ,
"300060" ,
"000008" ,
"416000" ,
"000800" }
;
double Arg1 = 0.021996615905245348 ;
vector < string> Arg0( Arr0, Arr0 + ( sizeof ( Arr0) / sizeof ( Arr0[ 0 ] ) ) ) ;
verify_case( n, Arg1, getMaximum( Arg0) ) ;
}
n++ ;
// test_case_4
if ( ( Case == - 1 ) || ( Case == n) ) {
string Arr0[ ] = { "06390061" ,
"60960062" ,
"39090270" ,
"96900262" ,
"00000212" ,
"00222026" ,
"66761201" ,
"12022610" }
;
double Arg1 = 0.06871794871794872 ;
vector < string> Arg0( Arr0, Arr0 + ( sizeof ( Arr0) / sizeof ( Arr0[ 0 ] ) ) ) ;
verify_case( n, Arg1, getMaximum( Arg0) ) ;
}
n++ ;
}
} ;
int main( ) {
RabbitWorking* ___test = new RabbitWorking( ) ;
___test- > run_test( - 1 ) ;
delete ___test;
}
I2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPGNzdGRsaWI+CiNpbmNsdWRlIDxjbWF0aD4KI2luY2x1ZGUgPGNsaW1pdHM+CiNpbmNsdWRlIDxjZmxvYXQ+CiNpbmNsdWRlIDxtYXA+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxtZW1vcnk+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgojaW5jbHVkZSA8c3N0cmVhbT4KI2luY2x1ZGUgPGNvbXBsZXg+CiNpbmNsdWRlIDxzdGFjaz4KI2luY2x1ZGUgPHF1ZXVlPgojaW5jbHVkZSA8bnVtZXJpYz4KI2luY2x1ZGUgPGxpc3Q+CiNpbmNsdWRlIDx0aW1lLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwp0eXBlZGVmIGxvbmcgbG9uZyBsbDsKCnRlbXBsYXRlPGNsYXNzIFQ+IGJvb2wgSU5SQU5HRShUIHgsVCBhLFQgYikgeyByZXR1cm4gYTw9eCYmeDw9YjsgfQojZGVmaW5lIE5HICgtMSkKI2RlZmluZSBCSUcgKDEyMzQ1Njc4OSkKI2RlZmluZSBCSUdCSUcgKDEyMzQ1Njc4OTEyMzQ1Njc4OUxMKQojZGVmaW5lIFNaKGEpICgoaW50KShhKS5zaXplKCkpIAoKLy8g5pyA5aSn5rWBIERpbmljIE8oRVZeMinjgaDjgZHjganjgIHlrp/pmpvjgoLjgaPjgajjga/jgoTjgYTjgIIKY2xhc3MgRGluaWMKewpwdWJsaWM6CglEaW5pYyhpbnQgaW5wdXRfbWF4dikgOiBtYXh2KGlucHV0X21heHYpCgl7CgkJRy5yZXNpemUoaW5wdXRfbWF4dik7CgkJbGV2ZWwucmVzaXplKGlucHV0X21heHYpOwoJCWl0ZXIucmVzaXplKGlucHV0X21heHYpOwoJfQoKCXZvaWQgYWRkX2VkZ2VfYm90aChpbnQgZnJvbSwgaW50IHRvLCBsbCBjYXApCgl7CgkJaWYoY2FwPjApCgkJewoJCQljb25zdCBpbnQgcmV2X2Zyb20JPSBTWihHW2Zyb21dKTsKCQkJY29uc3QgaW50IHJldl90bwk9IFNaKEdbdG9dKTsKCQkJR1tmcm9tXS5wdXNoX2JhY2soZWRnZSh0byxjYXAscmV2X3RvKSk7CgkJCUdbdG9dLnB1c2hfYmFjayhlZGdlKGZyb20sY2FwLHJldl9mcm9tKSk7CgkJfQoJfQoKCXZvaWQgYWRkX2VkZ2UoaW50IGZyb20sIGludCB0bywgbGwgY2FwKQoJewoJCWlmKGNhcD4wKQoJCXsKCQkJY29uc3QgaW50IHJldl9mcm9tCT0gU1ooR1tmcm9tXSk7CgkJCWNvbnN0IGludCByZXZfdG8JPSBTWihHW3RvXSk7CgkJCUdbZnJvbV0ucHVzaF9iYWNrKGVkZ2UodG8sY2FwLHJldl90bykpOwoJCQlHW3RvXS5wdXNoX2JhY2soZWRnZShmcm9tLDAscmV2X2Zyb20pKTsKCQl9Cgl9CgoJLy8gc+OBi+OCiXTjgbjjga7mnIDlpKfmtYHjgpLmsYLjgoHjgosKCWxsIG1heF9mbG93KGludCBzLCBpbnQgdCkKCXsKCQlsbCBmbG93ID0gMDsKCQlmb3IoOzspCgkJewoJCQliZnMocyk7CgkJCWlmKGxldmVsW3RdPDApIGJyZWFrOwoJCQlmaWxsKGl0ZXIuYmVnaW4oKSxpdGVyLmVuZCgpLDApOwoJCQlsbCBmOwoJCQl3aGlsZSggKGY9ZGZzKHMsdCxESU5JQ19JTkYpKT4wKQoJCQl7CgkJCQlmbG93ICs9IGY7CgkJCX0KCQl9CgoJCXJldHVybiBmbG93OwoJfQoKCS8vICDjg47jg7zjg4lz44GL44KJ6L6/44KM44KL56+E5Zuy44KS5rGC44KB44KL77yI44GT44KM5Lul5LiK5rWB44Gb44Gq44GE44Go44GT44KNY2FwPTDjga/jgIHjg6rjg7Pjgq/jgYzjgarjgY/jgarjgovvvIkKCS8vIO+8iOa1geOBl+e1guOCj+OBo+OBn+OBguOBqHNvdXJjZeOBi+OCieOBn+OBqeOCjOOCi+evhOWbsuOBjOOAgeacgOWwj+OCq+ODg+ODiOaZguOBrnPlgbTjgILjgZ/jganjgozjgarjgYTms5XjgYx05YG044CC44Gd44Gu5aKD55WM44GM44Kr44OD44OI44GZ44KL44Go44GT44KN44CC77yJCgl2ZWN0b3IgPGJvb2w+IGdldF9ub2Rlc19pbl9ncm91cChpbnQgcykKCXsKCQl2ZWN0b3IgPGJvb2w+IHJldChtYXh2KTsKCgkJcXVldWU8aW50PiBxdWU7CgkJcXVlLnB1c2gocyk7CgkJd2hpbGUoIXF1ZS5lbXB0eSgpKQoJCXsKCQkJaW50IHYgPSBxdWUuZnJvbnQoKTsKCQkJcXVlLnBvcCgpOwoJCQlyZXRbdl09dHJ1ZTsKCgkJCWZvcihpbnQgaT0wO2k8U1ooR1t2XSk7aSsrKQoJCQl7CgkJCQllZGdlICZlID0gR1t2XVtpXTsKCQkJCWlmKGUuY2FwPjAgJiYgIXJldFtlLnRvXSkKCQkJCXsKCQkJCQlxdWUucHVzaChlLnRvKTsKCQkJCX0KCQkJfQoJCX0KCQlyZXR1cm4gcmV0OwoJfQoKCXZvaWQgZGlzcCgpCgl7CgkJZm9yIChpbnQgdiA9IDA7IHYgPCBtYXh2OyB2KyspCgkJewoJCQlwcmludGYoIiVkOiIsdik7CgkJCWZvcihpbnQgaT0wO2k8U1ooR1t2XSk7aSsrKQoJCQl7CgkJCQlpZihHW3ZdW2ldLmluaXRfY2FwPjApCgkJCQl7CgkJCQkJcHJpbnRmKCItPiVkKCVsbGQpLCIsR1t2XVtpXS50byxHW3ZdW2ldLmluaXRfY2FwKTsKCQkJCX0KCQkJfQoJCQlwcmludGYoIlxuIik7CgkJfQoJfQoKcHJpdmF0ZToKCS8vIHPjgYvjgonjga7mnIDnn63ot53pm6LjgpJCRlPjgafoqIjnrpfjgZnjgosKCXZvaWQgYmZzKGludCBzKQoJewoJCWZpbGwobGV2ZWwuYmVnaW4oKSxsZXZlbC5lbmQoKSxORyk7CgkJcXVldWU8aW50PiBxdWU7CgkJbGV2ZWxbc109MDsKCQlxdWUucHVzaChzKTsKCQl3aGlsZSghcXVlLmVtcHR5KCkpCgkJewoJCQlpbnQgdiA9IHF1ZS5mcm9udCgpOwoJCQlxdWUucG9wKCk7CgkJCWZvcihpbnQgaT0wO2k8U1ooR1t2XSk7aSsrKQoJCQl7CgkJCQllZGdlICZlID0gR1t2XVtpXTsKCQkJCWlmKGUuY2FwPjAgJiYgbGV2ZWxbZS50b108MCkKCQkJCXsKCQkJCQlsZXZlbFtlLnRvXSA9IGxldmVsW3ZdICsgMTsKCQkJCQlxdWUucHVzaChlLnRvKTsKCQkJCX0KCQkJfQoJCX0KCX0KCgkvLyDlopfliqDjg5HjgrnjgpJERlPjgafmjqLjgZkKCWxsIGRmcyhpbnQgdiwgaW50IHQsIGxsIGYpCgl7CgkJaWYodj09dCkgcmV0dXJuIGY7CgkJZm9yIChpbnQgJmk9aXRlclt2XTtpPFNaKEdbdl0pO2krKykKCQl7CgkJCWVkZ2UmIGUgPSBHW3ZdW2ldOwoJCQlpZihlLmNhcD4wICYmIGxldmVsW3ZdPGxldmVsW2UudG9dKQoJCQl7CgkJCQlsbCBkID0gZGZzKGUudG8sIHQsIG1pbihmLCBlLmNhcCkpOwoJCQkJaWYoZD4wKQoJCQkJewoJCQkJCWUuY2FwIC09IGQ7CgkJCQkJR1tlLnRvXVtlLnJldl0uY2FwICs9IGQ7CgkJCQkJcmV0dXJuIGQ7CgkJCQl9CgkJCX0KCQl9CgkJcmV0dXJuIDA7Cgl9CgoJc3RhdGljIGNvbnN0IGxsIERJTklDX0lORiA9IExMT05HX01BWDsgLy8g5a656YeP44KSbGzjgavjgZfjgZ/jgYTjgajjgY3jga/jgIHjgZPjgZPjgoLlpInjgYjjgosKCglzdHJ1Y3QgZWRnZSAKCXsKCQllZGdlKGludCBpbnB1dF90bywgbGwgaW5wdXRfY2FwLCBpbnQgaW5wdXRfcmV2KSA6IHRvKGlucHV0X3RvKSwgY2FwKGlucHV0X2NhcCksIHJldihpbnB1dF9yZXYpLCBpbml0X2NhcChpbnB1dF9jYXApIHt9CgkJaW50IHRvOwkJLy8g6KGM5YWICgkJbGwgY2FwOwkvLyDlrrnph48KCQlpbnQgcmV2OwkvLyDpgIbovroKCQlsbCBpbml0X2NhcDsgLy8g5Yid5pyf5a656YeP77yI44OH44OQ44OD44Kw55So77yJCgl9OwoKCWludAltYXh2OwoJdmVjdG9yIDwgdmVjdG9yIDxlZGdlPiA+IEc7CS8vIOOCsOODqeODleOBrumao+aOpeODquOCueODiAoJdmVjdG9yIDwgaW50ID4gbGV2ZWw7CQkvLyBz44GL44KJ44Gu6Led6ZuiCgl2ZWN0b3IgPCBpbnQgPiBpdGVyOwkJLy8g44Gp44GT44G+44Gn6Kq/44G557WC44KP44Gj44Gf44GLCn07CgoKY2xhc3MgUmFiYml0V29ya2luZyB7CnB1YmxpYzoKCgkKCWJvb2wgb2sobGwgYSwgbGwgYiwgY29uc3QgdmVjdG9yIDxzdHJpbmc+JiBwcm9maXQpCgl7CgkJY29uc3QgaW50IE4gPSBTWihwcm9maXQpOwoJCWNvbnN0IGludCBTID0gTitOKihOLTEpLzI7CgkJY29uc3QgaW50IFQgPSBTKzE7CgkJY29uc3QgaW50IFYgPSBUKzE7CgkJRGluaWMqCWRpbmljID0gbmV3IERpbmljKFYpOwoKCQlsbCByZXQgPSAwOwoJCWludCB2ID0gMDsKCQlmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykKCQl7CgkJCWRpbmljLT5hZGRfZWRnZShTLGksMTk5KmEpOwoJCQl2Kys7CgkJfQoKCQlmb3IgKGludCBpID0gMDsgaSA8IE47IGkrKykKCQl7CgkJCWZvciAoaW50IGogPSBpKzE7IGogPCBOOyBqKyspCgkJCXsKCQkJCWxsIHAgPSBwcm9maXRbaV1bal0tJzAnOwoJCQkJbGwgY29zdCA9IGIqcCsyKmE7CgkJCQlyZXQgKz0gY29zdDsKCQkJCWRpbmljLT5hZGRfZWRnZSh2LFQsY29zdCk7CgkJCQlkaW5pYy0+YWRkX2VkZ2UoaSx2LEJJR0JJRyk7CgkJCQlkaW5pYy0+YWRkX2VkZ2Uoaix2LEJJR0JJRyk7CgkJCQl2Kys7CgkJCX0KCQl9CgoJCXJldCAtPSBkaW5pYy0+bWF4X2Zsb3coUyxUKTsKCQlkZWxldGUgZGluaWM7CgoJCXJldHVybiByZXQ+MDsKCX0KCglkb3VibGUgZ2V0TWF4aW11bSh2ZWN0b3IgPHN0cmluZz4gcHJvZml0KSB7CgoJCWxsIGIgPSAobGwpMWUxMjsKCQlsbCBsbyA9IDA7CgkJbGwgaGkgPSAobGwpYioxMDA7CgoJCXdoaWxlKGxvPGhpKQoJCXsKCQkJbGwgbWlkID0gbG8rKGhpLWxvKS8yTEw7CgkJCWlmKCFvayhtaWQsYixwcm9maXQpKQoJCQl7CgkJCQloaT1taWQ7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlsbz1taWQrMTsKCQkJfQoJCX0KCgkJcmV0dXJuIChkb3VibGUpbG8vYjsKCX0KCnByaXZhdGU6Cgl0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gc3RyaW5nIHByaW50X2FycmF5KGNvbnN0IHZlY3RvcjxUPiAmVikgeyBvc3RyaW5nc3RyZWFtIG9zOyBvcyA8PCAieyAiOyBmb3IgKHR5cGVuYW1lIHZlY3RvcjxUPjo6Y29uc3RfaXRlcmF0b3IgaXRlciA9IFYuYmVnaW4oKTsgaXRlciAhPSBWLmVuZCgpOyArK2l0ZXIpIG9zIDw8ICdcIicgPDwgKml0ZXIgPDwgIlwiLCI7IG9zIDw8ICIgfSI7IHJldHVybiBvcy5zdHIoKTsgfQoKCXZvaWQgdmVyaWZ5X2Nhc2UoaW50IENhc2UsIGNvbnN0IGRvdWJsZSAmRXhwZWN0ZWQsIGNvbnN0IGRvdWJsZSAmUmVjZWl2ZWQpIHsgY2VyciA8PCAiVGVzdCBDYXNlICMiIDw8IENhc2UgPDwgIi4uLiI7IGlmIChFeHBlY3RlZCA9PSBSZWNlaXZlZCkgY2VyciA8PCAiUEFTU0VEIiA8PCBlbmRsOyBlbHNlIHsgY2VyciA8PCAiRkFJTEVEIiA8PCBlbmRsOyBjZXJyIDw8ICJcdEV4cGVjdGVkOiBcIiIgPDwgRXhwZWN0ZWQgPDwgJ1wiJyA8PCBlbmRsOyBjZXJyIDw8ICJcdFJlY2VpdmVkOiBcIiIgPDwgUmVjZWl2ZWQgPDwgJ1wiJyA8PCBlbmRsOyB9IH0KCnB1YmxpYzoKCXZvaWQgcnVuX3Rlc3QoaW50IENhc2UpIHsgCgkJaW50IG4gPSAwOwoKCQkvLyB0ZXN0X2Nhc2VfMAoJCWlmICgoQ2FzZSA9PSAtMSkgfHwgKENhc2UgPT0gbikpewoJCQlzdHJpbmcgQXJyMFtdID0geyAiMDcxIiwgCiAgIjcwMiIsIAogICIxMjAiIH0KOwoJCQlkb3VibGUgQXJnMSA9IDAuMDE3Njc2NzY3Njc2NzY3Njc2OwoKCQkJdmVjdG9yIDxzdHJpbmc+IEFyZzAoQXJyMCwgQXJyMCArIChzaXplb2YoQXJyMCkgLyBzaXplb2YoQXJyMFswXSkpKTsKCQkJdmVyaWZ5X2Nhc2UobiwgQXJnMSwgZ2V0TWF4aW11bShBcmcwKSk7CgkJfQoJCW4rKzsKCgkJLy8gdGVzdF9jYXNlXzEKCQlpZiAoKENhc2UgPT0gLTEpIHx8IChDYXNlID09IG4pKXsKCQkJc3RyaW5nIEFycjBbXSA9IHsgIjA2MSIsIAogICI2MDIiLCAKICAiMTIwIiB9CjsKCQkJZG91YmxlIEFyZzEgPSAwLjAxNTIyODQyNjM5NTkzOTA4NzsKCgkJCXZlY3RvciA8c3RyaW5nPiBBcmcwKEFycjAsIEFycjAgKyAoc2l6ZW9mKEFycjApIC8gc2l6ZW9mKEFycjBbMF0pKSk7CgkJCXZlcmlmeV9jYXNlKG4sIEFyZzEsIGdldE1heGltdW0oQXJnMCkpOwoJCX0KCQluKys7CgoJCS8vIHRlc3RfY2FzZV8yCgkJaWYgKChDYXNlID09IC0xKSB8fCAoQ2FzZSA9PSBuKSl7CgkJCXN0cmluZyBBcnIwW10gPSB7ICIwIiB9CjsKCQkJZG91YmxlIEFyZzEgPSAwLjA7CgoJCQl2ZWN0b3IgPHN0cmluZz4gQXJnMChBcnIwLCBBcnIwICsgKHNpemVvZihBcnIwKSAvIHNpemVvZihBcnIwWzBdKSkpOwoJCQl2ZXJpZnlfY2FzZShuLCBBcmcxLCBnZXRNYXhpbXVtKEFyZzApKTsKCQl9CgkJbisrOwoKCQkvLyB0ZXN0X2Nhc2VfMwoJCWlmICgoQ2FzZSA9PSAtMSkgfHwgKENhc2UgPT0gbikpewoJCQlzdHJpbmcgQXJyMFtdID0geyAiMDEzMDQwIiwgCiAgIjEwMDAxMCIsIAogICIzMDAwNjAiLCAKICAiMDAwMDA4IiwgCiAgIjQxNjAwMCIsIAogICIwMDA4MDAiIH0KOwoJCQlkb3VibGUgQXJnMSA9IDAuMDIxOTk2NjE1OTA1MjQ1MzQ4OwoKCQkJdmVjdG9yIDxzdHJpbmc+IEFyZzAoQXJyMCwgQXJyMCArIChzaXplb2YoQXJyMCkgLyBzaXplb2YoQXJyMFswXSkpKTsKCQkJdmVyaWZ5X2Nhc2UobiwgQXJnMSwgZ2V0TWF4aW11bShBcmcwKSk7CgkJfQoJCW4rKzsKCgkJLy8gdGVzdF9jYXNlXzQKCQlpZiAoKENhc2UgPT0gLTEpIHx8IChDYXNlID09IG4pKXsKCQkJc3RyaW5nIEFycjBbXSA9IHsgIjA2MzkwMDYxIiwgCiAgIjYwOTYwMDYyIiwgCiAgIjM5MDkwMjcwIiwgCiAgIjk2OTAwMjYyIiwgCiAgIjAwMDAwMjEyIiwgCiAgIjAwMjIyMDI2IiwgCiAgIjY2NzYxMjAxIiwgCiAgIjEyMDIyNjEwIiB9CjsKCQkJZG91YmxlIEFyZzEgPSAwLjA2ODcxNzk0ODcxNzk0ODcyOwoKCQkJdmVjdG9yIDxzdHJpbmc+IEFyZzAoQXJyMCwgQXJyMCArIChzaXplb2YoQXJyMCkgLyBzaXplb2YoQXJyMFswXSkpKTsKCQkJdmVyaWZ5X2Nhc2UobiwgQXJnMSwgZ2V0TWF4aW11bShBcmcwKSk7CgkJfQoJCW4rKzsKCgl9Cgp9OwoKaW50IG1haW4oKSB7CglSYWJiaXRXb3JraW5nKiBfX190ZXN0ID0gbmV3IFJhYmJpdFdvcmtpbmcoKTsKCV9fX3Rlc3QtPnJ1bl90ZXN0KC0xKTsKCWRlbGV0ZSBfX190ZXN0Owp9Cgo=