#include <bits/stdc++.h>
using namespace std;
mt19937_64 rd( chrono:: steady_clock :: now ( ) .time_since_epoch ( ) .count ( ) ) ;
#define rf if(fopen(name".inp", "r")) {freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout);}
#define rd ({int x = 0; int c = getchar(), n = 0; for(; !isdigit(c); c = getchar()) n = (c == '-'); for(; isdigit(c); c = getchar()) x = x * 10 + c - '0'; n ? -x : x;})
#define bit(i, mask) (((mask) >> (i)) & 1)
#define on(i, mask) ((mask) | (1LL << (i)))
#define off(i, mask) ((mask) & (~(1LL << (i))))
#define ll long long
#define fi first
#define se second
#define pii pair<int, int>
#define vii vector<int>
#define all(a) (a).begin(), (a).end()
#define len(x) ((int)(x).size())
#define pb push_back
#define endl '\n'
#define TIME (1.0 * clock() / CLOCKS_PER_SEC)
#define name ""
template < typename T1, typename T2> bool mini( T1 & a, T2 b)
{ if ( a > b) a = b; else return 0 ; return 1 ; }
template < typename T1, typename T2> bool maxi( T1 & a, T2 b)
{ if ( a < b) a = b; else return 0 ; return 1 ; }
const int mod = 1e9 + 7 ;
const int inf = 1e9 + 9 ;
const ll oo = 1e18l+ 7 ;
const int M = 5e5 + 6 ;
const int N = 2468 ;
const int LOG = 31 - __builtin_clz( N) ;
int n, m, s[ N] [ N] ;
struct Edge{
int v, flow, cap;
} ;
struct Dinic{
int n, s, t, work[ N] , d[ N] ;
vector< Edge> e;
vii a[ N] ;
Dinic( int _n, int _s, int _t) {
n = _n, s = _s, t = _t;
}
void Add( int u, int v, int c) {
e.pb ( { v, 0 , c} ) ;
a[ u] .pb ( e.size ( ) - 1 ) ;
e.pb ( { u, 0 , 0 } ) ;
a[ v] .pb ( e.size ( ) - 1 ) ;
}
bool bfs( ) {
for ( int i = 1 ; i <= n; i++ ) d[ i] = 0 ;
d[ s] = 1 ;
queue< int > q;
q.push ( s) ;
while ( ! q.empty ( ) ) {
int k = q.front ( ) ;
q.pop ( ) ;
for ( int u : a[ k] ) {
int v = e[ u] .v ;
if ( e[ u] .cap > e[ u] .flow && d[ v] == 0 ) {
d[ v] = d[ k] + 1 ;
q.push ( v) ;
}
}
}
return d[ t] > 0 ;
}
int dfs( int u, int flow) {
if ( u == t) return flow;
for ( int & z = work[ u] ; z < ( int ) a[ u] .size ( ) ; z++ ) {
int i = a[ u] [ z] ;
int v = e[ i] .v ;
if ( e[ i] .cap > e[ i] .flow && d[ v] == d[ u] + 1 ) {
int tmp = dfs( v, min( flow, e[ i] .cap - e[ i] .flow ) ) ;
if ( tmp) {
e[ i] .flow + = tmp;
e[ i ^ 1 ] .flow - = tmp;
return tmp;
}
}
}
return 0 ;
}
int getFlow( ) {
int res = 0 ;
while ( bfs( ) ) {
for ( int i = 1 ; i <= n; i++ ) work[ i] = 0 ;
while ( int delta = dfs( s, inf) ) res + = delta;
}
//for(int i = 0; i < e.size(); i += 2) cout << e[i].flow << endl;
return res;
}
} ;
void in( ) {
cin >> n >> m;
for ( int i = 1 ; i <= n; i++ ) {
for ( int j = 1 ; j <= m; j++ ) cin >> s[ i] [ j] ;
}
}
namespace subtask1{
int dp[ 15 ] [ 1 << 12 ] , trace[ 15 ] [ 1 << 12 ] , cost[ 15 ] [ 1 << 12 ] ;
void solve( ) {
for ( int i = 1 ; i <= n; i++ ) {
for ( int mask = 0 ; mask < ( 1 << m) ; mask++ ) {
for ( int j = 0 ; j < m; j++ ) if ( bit( j, mask) ) cost[ i] [ mask] + = s[ i] [ j + 1 ] ;
}
}
memset ( dp, - 1 , sizeof dp) ;
dp[ 0 ] [ 0 ] = inf;
for ( int mask = 0 ; mask < ( 1 << m) ; mask++ ) {
for ( int i = 0 ; i < n; i++ ) {
if ( dp[ i] [ mask] == - 1 ) continue ;
int tmp = ( ( 1 << m) - 1 ) ^ mask;
for ( int submask = tmp; submask > 0 ; submask = ( submask - 1 ) & tmp) {
if ( maxi( dp[ i + 1 ] [ mask ^ submask] , min( cost[ i + 1 ] [ submask] , dp[ i] [ mask] ) ) )
trace[ i + 1 ] [ mask ^ submask] = submask;
}
}
}
vii ans;
int mask = ( 1 << m) - 1 ;
while ( n > 0 ) {
ans.pb ( trace[ n] [ mask] ) ;
mask ^ = trace[ n] [ mask] ;
n-- ;
}
reverse( all( ans) ) ;
for ( int it : ans) {
cout << __builtin_popcount( it) << " " ;
for ( int i = 1 ; i <= m; i++ ) if ( bit( i - 1 , it) ) cout << i << " " ;
cout << endl;
}
}
}
namespace subtask2{
int dp[ 2 ] [ 100005 ] , trace[ 1234 ] [ 100005 ] ;
// dp[i][j]: maxi 1, j la delta 1 va 2 => max = dp - j
// y tuong tu bai treasure (th tre)
void solve( ) {
memset ( dp[ 0 ] , - 0x3f , sizeof dp) ;
int w = 50000 ;
dp[ 0 ] [ w] = 0 ;
for ( int i = 1 ; i <= m; i++ ) {
int cur = i & 1 , pre = cur ^ 1 ;
for ( int j = - w; j <= w; j++ ) dp[ cur] [ j + w] = - inf;
for ( int j = - w; j <= w; j++ ) {
if ( dp[ pre] [ j + w] == - inf) continue ;
if ( j + s[ 1 ] [ i] <= w && maxi( dp[ cur] [ j + w + s[ 1 ] [ i] ] , dp[ pre] [ j + w] + s[ 1 ] [ i] ) )
trace[ i] [ j + w + s[ 1 ] [ i] ] = 1 ;
if ( j - s[ 2 ] [ i] >= - w && maxi( dp[ cur] [ j + w - s[ 2 ] [ i] ] , dp[ pre] [ j + w] ) )
trace[ i] [ j + w - s[ 2 ] [ i] ] = 2 ;
}
}
int val = 0 , id = 0 ;
for ( int i = - w; i <= w; i++ ) {
if ( dp[ m & 1 ] [ i + w] == - inf) continue ;
if ( maxi( val, dp[ m & 1 ] [ i + w] - ( i > 0 ? i : 0 ) ) ) id = i + w;
}
vii va, vb;
while ( m) {
if ( trace[ m] [ id] == 1 ) {
va.pb ( m) ;
id - = s[ 1 ] [ m] ;
}
else {
vb.pb ( m) ;
id + = s[ 2 ] [ m] ;
}
m-- ;
}
reverse( all( va) ) ; reverse( all( vb) ) ;
cout << len( va) << ' ' ;
for ( int it : va) cout << it << ' ' ;
cout << endl;
cout << len( vb) << ' ' ;
for ( int it : vb) cout << it << ' ' ;
}
}
namespace subtask3{
int st, en, cnt, ng[ N] , gift[ N] ;
bool check( int x) {
Dinic mxFlow( cnt, st, en) ;
for ( int i = 1 ; i <= n; i++ ) {
for ( int j = 1 ; j <= m; j++ ) if ( s[ i] [ j] >= x) mxFlow.Add ( ng[ i] , gift[ j] , 1 ) ;
}
for ( int i = 1 ; i <= n; i++ ) mxFlow.Add ( st, ng[ i] , 1 ) ;
for ( int i = 1 ; i <= m; i++ ) mxFlow.Add ( gift[ i] , en, 1 ) ;
return ( mxFlow.getFlow ( ) == n) ;
}
void output( int x) {
Dinic mxFlow( cnt, st, en) ;
for ( int i = 1 ; i <= n; i++ ) {
for ( int j = 1 ; j <= m; j++ ) if ( s[ i] [ j] >= x) mxFlow.Add ( ng[ i] , gift[ j] , 1 ) ;
}
for ( int i = 1 ; i <= n; i++ ) mxFlow.Add ( st, ng[ i] , 1 ) ;
for ( int i = 1 ; i <= m; i++ ) mxFlow.Add ( gift[ i] , en, 1 ) ;
mxFlow.getFlow ( ) ;
for ( int i = 1 ; i <= n; i++ ) {
int u = ng[ i] ;
for ( auto it : mxFlow.a [ u] ) {
int v = mxFlow.e [ it] .v ;
if ( mxFlow.e [ it] .flow == 1 ) {
cout << 1 << ' ' << v - n << endl;
break ;
}
}
}
}
void solve( ) {
for ( int i = 1 ; i <= n; i++ ) ng[ i] = ++ cnt;
for ( int i = 1 ; i <= m; i++ ) gift[ i] = ++ cnt;
st = ++ cnt, en = ++ cnt;
int l = 1 , r = 1000 , res = 1 ;
while ( l <= r) {
int mid = ( l + r) >> 1 ;
if ( check( mid) ) {
res = mid;
l = mid + 1 ;
}
else r = mid - 1 ;
}
output( res) ;
}
}
void proc( ) {
if ( n <= 12 && m <= 12 ) {
subtask1:: solve ( ) ;
return ;
}
if ( n == 2 ) {
subtask2:: solve ( ) ;
return ;
}
subtask3:: solve ( ) ;
}
int main( ) {
cin .tie ( nullptr) - > sync_with_stdio( false ) ;
rf
int test = 1 ;
//cin >> test;
while ( test-- ) {
in( ) ;
proc( ) ;
}
cerr << "Time elapsed: " << TIME << "s" << endl;
return 0 ;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKbXQxOTkzN182NCByZChjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCkudGltZV9zaW5jZV9lcG9jaCgpLmNvdW50KCkpOwoKI2RlZmluZSByZiBpZihmb3BlbihuYW1lIi5pbnAiLCAiciIpKSB7ZnJlb3BlbihuYW1lIi5pbnAiLCAiciIsIHN0ZGluKTsgZnJlb3BlbihuYW1lIi5vdXQiLCAidyIsIHN0ZG91dCk7fQojZGVmaW5lIHJkICh7aW50IHggPSAwOyBpbnQgYyA9IGdldGNoYXIoKSwgbiA9IDA7IGZvcig7ICFpc2RpZ2l0KGMpOyBjID0gZ2V0Y2hhcigpKSBuID0gKGMgPT0gJy0nKTsgZm9yKDsgaXNkaWdpdChjKTsgYyA9IGdldGNoYXIoKSkgeCA9IHggKiAxMCArIGMgLSAnMCc7IG4gPyAteCA6IHg7fSkKCiNkZWZpbmUgYml0KGksIG1hc2spICgoKG1hc2spID4+IChpKSkgJiAxKQojZGVmaW5lIG9uKGksIG1hc2spICgobWFzaykgfCAoMUxMIDw8IChpKSkpCiNkZWZpbmUgb2ZmKGksIG1hc2spICgobWFzaykgJiAofigxTEwgPDwgKGkpKSkpCgojZGVmaW5lIGxsIGxvbmcgbG9uZwojZGVmaW5lIGZpIGZpcnN0CiNkZWZpbmUgc2Ugc2Vjb25kCiNkZWZpbmUgcGlpIHBhaXI8aW50LCBpbnQ+CiNkZWZpbmUgdmlpIHZlY3RvcjxpbnQ+CiNkZWZpbmUgYWxsKGEpIChhKS5iZWdpbigpLCAoYSkuZW5kKCkKI2RlZmluZSBsZW4oeCkgKChpbnQpKHgpLnNpemUoKSkKI2RlZmluZSBwYiBwdXNoX2JhY2sKI2RlZmluZSBlbmRsICdcbicKI2RlZmluZSBUSU1FICgxLjAgKiBjbG9jaygpIC8gQ0xPQ0tTX1BFUl9TRUMpCgojZGVmaW5lIG5hbWUgIiIKCnRlbXBsYXRlPHR5cGVuYW1lIFQxLCB0eXBlbmFtZSBUMj4gYm9vbCBtaW5pKFQxICZhLCBUMiBiKQogICAge2lmKGEgPiBiKSBhID0gYjsgZWxzZSByZXR1cm4gMDsgcmV0dXJuIDE7fQp0ZW1wbGF0ZTx0eXBlbmFtZSBUMSwgdHlwZW5hbWUgVDI+IGJvb2wgbWF4aShUMSAmYSwgVDIgYikKICAgIHtpZihhIDwgYikgYSA9IGI7IGVsc2UgcmV0dXJuIDA7IHJldHVybiAxO30KCmNvbnN0IGludCBtb2QgPSAxZTkrNzsKY29uc3QgaW50IGluZiA9IDFlOSs5Owpjb25zdCBsbCBvbyA9IDFlMThsKzc7CmNvbnN0IGludCBNID0gNWU1KzY7CmNvbnN0IGludCBOID0gMjQ2ODsKY29uc3QgaW50IExPRyA9IDMxIC0gX19idWlsdGluX2NseihOKTsKCmludCBuLCBtLCBzW05dW05dOwoKc3RydWN0IEVkZ2V7CiAgICBpbnQgdiwgZmxvdywgY2FwOwp9OwoKc3RydWN0IERpbmljewogICAgaW50IG4sIHMsIHQsIHdvcmtbTl0sIGRbTl07CiAgICB2ZWN0b3I8RWRnZT4gZTsKICAgIHZpaSBhW05dOwogICAgRGluaWMoaW50IF9uLCBpbnQgX3MsIGludCBfdCl7CiAgICAgICAgbiA9IF9uLCBzID0gX3MsIHQgPSBfdDsKICAgIH0KCiAgICB2b2lkIEFkZChpbnQgdSwgaW50IHYsIGludCBjKXsKICAgICAgICBlLnBiKHt2LCAwLCBjfSk7CiAgICAgICAgYVt1XS5wYihlLnNpemUoKSAtIDEpOwogICAgICAgIGUucGIoe3UsIDAsIDB9KTsKICAgICAgICBhW3ZdLnBiKGUuc2l6ZSgpIC0gMSk7CiAgICB9CgogICAgYm9vbCBiZnMoKXsKICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDw9IG47IGkrKykgZFtpXSA9IDA7CiAgICAgICAgZFtzXSA9IDE7CiAgICAgICAgcXVldWU8aW50PiBxOwogICAgICAgIHEucHVzaChzKTsKICAgICAgICB3aGlsZSghcS5lbXB0eSgpKXsKICAgICAgICAgICAgaW50IGsgPSBxLmZyb250KCk7CiAgICAgICAgICAgIHEucG9wKCk7CiAgICAgICAgICAgIGZvcihpbnQgdSA6IGFba10pewogICAgICAgICAgICAgICAgaW50IHYgPSBlW3VdLnY7CiAgICAgICAgICAgICAgICBpZihlW3VdLmNhcCA+IGVbdV0uZmxvdyAmJiBkW3ZdID09IDApewogICAgICAgICAgICAgICAgICAgIGRbdl0gPSBkW2tdICsgMTsKICAgICAgICAgICAgICAgICAgICBxLnB1c2godik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGRbdF0gPiAwOwogICAgfQoKICAgIGludCBkZnMoaW50IHUsIGludCBmbG93KXsKICAgICAgICBpZih1ID09IHQpIHJldHVybiBmbG93OwogICAgICAgIGZvcihpbnQgJnogPSB3b3JrW3VdOyB6IDwgKGludClhW3VdLnNpemUoKTsgeisrKXsKICAgICAgICAgICAgaW50IGkgPSBhW3VdW3pdOwogICAgICAgICAgICBpbnQgdiA9IGVbaV0udjsKICAgICAgICAgICAgaWYoZVtpXS5jYXAgPiBlW2ldLmZsb3cgJiYgZFt2XSA9PSBkW3VdICsgMSl7CiAgICAgICAgICAgICAgICBpbnQgdG1wID0gZGZzKHYsIG1pbihmbG93LCBlW2ldLmNhcCAtIGVbaV0uZmxvdykpOwogICAgICAgICAgICAgICAgaWYodG1wKXsKICAgICAgICAgICAgICAgICAgICBlW2ldLmZsb3cgKz0gdG1wOwogICAgICAgICAgICAgICAgICAgIGVbaSBeIDFdLmZsb3cgLT0gdG1wOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB0bXA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaW50IGdldEZsb3coKXsKICAgICAgICBpbnQgcmVzID0gMDsKICAgICAgICB3aGlsZShiZnMoKSl7CiAgICAgICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPD0gbjsgaSsrKSB3b3JrW2ldID0gMDsKICAgICAgICAgICAgd2hpbGUoaW50IGRlbHRhID0gZGZzKHMsIGluZikpIHJlcyArPSBkZWx0YTsKICAgICAgICB9CiAgICAgICAgLy9mb3IoaW50IGkgPSAwOyBpIDwgZS5zaXplKCk7IGkgKz0gMikgY291dCA8PCBlW2ldLmZsb3cgPDwgZW5kbDsKICAgICAgICByZXR1cm4gcmVzOwogICAgfQp9OwoKdm9pZCBpbigpewogICAgY2luID4+IG4gPj4gbTsKICAgIGZvcihpbnQgaSA9IDE7IGkgPD0gbjsgaSsrKXsKICAgICAgICBmb3IoaW50IGogPSAxOyBqIDw9IG07IGorKykgY2luID4+IHNbaV1bal07CiAgICB9Cn0KCm5hbWVzcGFjZSBzdWJ0YXNrMXsKICAgIGludCBkcFsxNV1bMSA8PCAxMl0sIHRyYWNlWzE1XVsxIDw8IDEyXSwgY29zdFsxNV1bMSA8PCAxMl07CgogICAgdm9pZCBzb2x2ZSgpewogICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPD0gbjsgaSsrKXsKICAgICAgICAgICAgZm9yKGludCBtYXNrID0gMDsgbWFzayA8ICgxIDw8IG0pOyBtYXNrKyspewogICAgICAgICAgICAgICAgZm9yKGludCBqID0gMDsgaiA8IG07IGorKykgaWYoYml0KGosIG1hc2spKSBjb3N0W2ldW21hc2tdICs9IHNbaV1baiArIDFdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG1lbXNldChkcCwgLTEsIHNpemVvZiBkcCk7CiAgICAgICAgZHBbMF1bMF0gPSBpbmY7CiAgICAgICAgZm9yKGludCBtYXNrID0gMDsgbWFzayA8ICgxIDw8IG0pOyBtYXNrKyspewogICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbjsgaSsrKXsKICAgICAgICAgICAgICAgIGlmKGRwW2ldW21hc2tdID09IC0xKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIGludCB0bXAgPSAoKDEgPDwgbSkgLSAxKSBeIG1hc2s7CiAgICAgICAgICAgICAgICBmb3IoaW50IHN1Ym1hc2sgPSB0bXA7IHN1Ym1hc2sgPiAwOyBzdWJtYXNrID0gKHN1Ym1hc2sgLSAxKSAmIHRtcCl7CiAgICAgICAgICAgICAgICAgICAgaWYobWF4aShkcFtpICsgMV1bbWFzayBeIHN1Ym1hc2tdLCBtaW4oY29zdFtpICsgMV1bc3VibWFza10sIGRwW2ldW21hc2tdKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNlW2kgKyAxXVttYXNrIF4gc3VibWFza10gPSBzdWJtYXNrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHZpaSBhbnM7CiAgICAgICAgaW50IG1hc2sgPSAoMSA8PCBtKSAtIDE7CiAgICAgICAgd2hpbGUobiA+IDApewogICAgICAgICAgICBhbnMucGIodHJhY2Vbbl1bbWFza10pOwogICAgICAgICAgICBtYXNrIF49IHRyYWNlW25dW21hc2tdOwogICAgICAgICAgICBuLS07CiAgICAgICAgfQogICAgICAgIHJldmVyc2UoYWxsKGFucykpOwogICAgICAgIGZvcihpbnQgaXQgOiBhbnMpewogICAgICAgICAgICBjb3V0IDw8IF9fYnVpbHRpbl9wb3Bjb3VudChpdCkgPDwgIiAiOwogICAgICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDw9IG07IGkrKykgaWYoYml0KGkgLSAxLCBpdCkpIGNvdXQgPDwgaSA8PCAiICI7CiAgICAgICAgICAgIGNvdXQgPDwgZW5kbDsKICAgICAgICB9CiAgICB9Cn0KCm5hbWVzcGFjZSBzdWJ0YXNrMnsKICAgIGludCBkcFsyXVsxMDAwMDVdLCB0cmFjZVsxMjM0XVsxMDAwMDVdOwogICAgLy8gZHBbaV1bal06IG1heGkgMSwgaiBsYSBkZWx0YSAxIHZhIDIgPT4gbWF4ID0gZHAgLSBqCiAgICAvLyB5IHR1b25nIHR1IGJhaSB0cmVhc3VyZSAodGggdHJlKQoKICAgIHZvaWQgc29sdmUoKXsKICAgICAgICBtZW1zZXQoZHBbMF0sIC0weDNmLCBzaXplb2YgZHApOwogICAgICAgIGludCB3ID0gNTAwMDA7CiAgICAgICAgZHBbMF1bd10gPSAwOwogICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPD0gbTsgaSsrKXsKICAgICAgICAgICAgaW50IGN1ciA9IGkgJiAxLCBwcmUgPSBjdXIgXiAxOwogICAgICAgICAgICBmb3IoaW50IGogPSAtdzsgaiA8PSB3OyBqKyspIGRwW2N1cl1baiArIHddID0gLWluZjsKICAgICAgICAgICAgZm9yKGludCBqID0gLXc7IGogPD0gdzsgaisrKXsKICAgICAgICAgICAgICAgIGlmKGRwW3ByZV1baiArIHddID09IC1pbmYpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaWYoaiArIHNbMV1baV0gPD0gdyAmJiBtYXhpKGRwW2N1cl1baiArIHcgKyBzWzFdW2ldXSwgZHBbcHJlXVtqICsgd10gKyBzWzFdW2ldKSkKICAgICAgICAgICAgICAgICAgICB0cmFjZVtpXVtqICsgdyArIHNbMV1baV1dID0gMTsKICAgICAgICAgICAgICAgIGlmKGogLSBzWzJdW2ldID49IC13ICYmIG1heGkoZHBbY3VyXVtqICsgdyAtIHNbMl1baV1dLCBkcFtwcmVdW2ogKyB3XSkpCiAgICAgICAgICAgICAgICAgICAgdHJhY2VbaV1baiArIHcgLSBzWzJdW2ldXSA9IDI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGludCB2YWwgPSAwLCBpZCA9IDA7CiAgICAgICAgZm9yKGludCBpID0gLXc7IGkgPD0gdzsgaSsrKXsKICAgICAgICAgICAgaWYoZHBbbSAmIDFdW2kgKyB3XSA9PSAtaW5mKSBjb250aW51ZTsKICAgICAgICAgICAgaWYobWF4aSh2YWwsIGRwW20gJiAxXVtpICsgd10gLSAoaSA+IDAgPyBpIDogMCkpKSBpZCA9IGkgKyB3OwogICAgICAgIH0KCiAgICAgICAgdmlpIHZhLCB2YjsKICAgICAgICB3aGlsZShtKXsKICAgICAgICAgICAgaWYodHJhY2VbbV1baWRdID09IDEpewogICAgICAgICAgICAgICAgdmEucGIobSk7CiAgICAgICAgICAgICAgICBpZCAtPSBzWzFdW21dOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICB2Yi5wYihtKTsKICAgICAgICAgICAgICAgIGlkICs9IHNbMl1bbV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbS0tOwogICAgICAgIH0KICAgICAgICByZXZlcnNlKGFsbCh2YSkpOyByZXZlcnNlKGFsbCh2YikpOwogICAgICAgIGNvdXQgPDwgbGVuKHZhKSA8PCAnICc7CiAgICAgICAgZm9yKGludCBpdCA6IHZhKSBjb3V0IDw8IGl0IDw8ICcgJzsKICAgICAgICBjb3V0IDw8IGVuZGw7CiAgICAgICAgY291dCA8PCBsZW4odmIpIDw8ICcgJzsKICAgICAgICBmb3IoaW50IGl0IDogdmIpIGNvdXQgPDwgaXQgPDwgJyAnOwogICAgfQp9CgpuYW1lc3BhY2Ugc3VidGFzazN7CiAgICBpbnQgc3QsIGVuLCBjbnQsIG5nW05dLCBnaWZ0W05dOwoKICAgIGJvb2wgY2hlY2soaW50IHgpewogICAgICAgIERpbmljIG14RmxvdyhjbnQsIHN0LCBlbik7CiAgICAgICAgZm9yKGludCBpID0gMTsgaSA8PSBuOyBpKyspewogICAgICAgICAgICBmb3IoaW50IGogPSAxOyBqIDw9IG07IGorKykgaWYoc1tpXVtqXSA+PSB4KSBteEZsb3cuQWRkKG5nW2ldLCBnaWZ0W2pdLCAxKTsKICAgICAgICB9CiAgICAgICAgZm9yKGludCBpID0gMTsgaSA8PSBuOyBpKyspIG14Rmxvdy5BZGQoc3QsIG5nW2ldLCAxKTsKICAgICAgICBmb3IoaW50IGkgPSAxOyBpIDw9IG07IGkrKykgbXhGbG93LkFkZChnaWZ0W2ldLCBlbiwgMSk7CiAgICAgICAgcmV0dXJuIChteEZsb3cuZ2V0RmxvdygpID09IG4pOwogICAgfQoKICAgIHZvaWQgb3V0cHV0KGludCB4KXsKICAgICAgICBEaW5pYyBteEZsb3coY250LCBzdCwgZW4pOwogICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPD0gbjsgaSsrKXsKICAgICAgICAgICAgZm9yKGludCBqID0gMTsgaiA8PSBtOyBqKyspIGlmKHNbaV1bal0gPj0geCkgbXhGbG93LkFkZChuZ1tpXSwgZ2lmdFtqXSwgMSk7CiAgICAgICAgfQogICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPD0gbjsgaSsrKSBteEZsb3cuQWRkKHN0LCBuZ1tpXSwgMSk7CiAgICAgICAgZm9yKGludCBpID0gMTsgaSA8PSBtOyBpKyspIG14Rmxvdy5BZGQoZ2lmdFtpXSwgZW4sIDEpOwogICAgICAgIG14Rmxvdy5nZXRGbG93KCk7CiAgICAgICAgZm9yKGludCBpID0gMTsgaSA8PSBuOyBpKyspewogICAgICAgICAgICBpbnQgdSA9IG5nW2ldOwogICAgICAgICAgICBmb3IoYXV0byBpdCA6IG14Rmxvdy5hW3VdKXsKICAgICAgICAgICAgICAgIGludCB2ID0gbXhGbG93LmVbaXRdLnY7CiAgICAgICAgICAgICAgICBpZihteEZsb3cuZVtpdF0uZmxvdyA9PSAxKXsKICAgICAgICAgICAgICAgICAgICBjb3V0IDw8IDEgPDwgJyAnIDw8IHYgLSBuIDw8IGVuZGw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgdm9pZCBzb2x2ZSgpewogICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPD0gbjsgaSsrKSBuZ1tpXSA9ICsrY250OwogICAgICAgIGZvcihpbnQgaSA9IDE7IGkgPD0gbTsgaSsrKSBnaWZ0W2ldID0gKytjbnQ7CiAgICAgICAgc3QgPSArK2NudCwgZW4gPSArK2NudDsKICAgICAgICBpbnQgbCA9IDEsIHIgPSAxMDAwLCByZXMgPSAxOwogICAgICAgIHdoaWxlKGwgPD0gcil7CiAgICAgICAgICAgIGludCBtaWQgPSAobCArIHIpID4+IDE7CiAgICAgICAgICAgIGlmKGNoZWNrKG1pZCkpewogICAgICAgICAgICAgICAgcmVzID0gbWlkOwogICAgICAgICAgICAgICAgbCA9IG1pZCArIDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSByID0gbWlkIC0gMTsKICAgICAgICB9CiAgICAgICAgb3V0cHV0KHJlcyk7CiAgICB9Cn0KCnZvaWQgcHJvYygpewogICAgaWYobiA8PSAxMiAmJiBtIDw9IDEyKXsKICAgICAgICBzdWJ0YXNrMTo6c29sdmUoKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZihuID09IDIpewogICAgICAgIHN1YnRhc2syOjpzb2x2ZSgpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHN1YnRhc2szOjpzb2x2ZSgpOwp9CgppbnQgbWFpbigpewogICAgY2luLnRpZShudWxscHRyKS0+c3luY193aXRoX3N0ZGlvKGZhbHNlKTsKCiAgICByZgoKICAgIGludCB0ZXN0ID0gMTsKICAgIC8vY2luID4+IHRlc3Q7CgogICAgd2hpbGUodGVzdC0tKXsKICAgICAgICBpbigpOwogICAgICAgIHByb2MoKTsKICAgIH0KCiAgICBjZXJyIDw8ICJUaW1lIGVsYXBzZWQ6ICIgPDwgVElNRSA8PCAicyIgPDwgZW5kbDsKICAgIHJldHVybiAwOwp9Cg==