#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
void * wmem;
char memarr[ 96000000 ] ;
template < class S, class T> inline S min_L( S a,T b) {
return a<= b? a: b;
}
template < class S, class T> inline S max_L( S a,T b) {
return a>= b? a: b;
}
template < class T> inline void walloc1d( T ** arr, int x, void ** mem = & wmem) {
static int skip[ 16 ] = { 0 , 15 , 14 , 13 , 12 , 11 , 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 } ;
( * mem) = ( void * ) ( ( ( char * ) ( * mem) ) + skip[ ( ( unsigned long long ) ( * mem) ) & 15 ] ) ;
( * arr) = ( T* ) ( * mem) ;
( * mem) = ( ( * arr) + x) ;
}
template < class T> void malloc2d( T *** arr, int x, int y) {
int i;
( * arr) = ( T** ) malloc ( x* sizeof ( T* ) ) ;
( * arr) [ 0 ] = ( T* ) malloc ( x* y* sizeof ( T) ) ;
int jZyWAPpY = x;
for ( i= ( 1 ) ; i< ( jZyWAPpY) ; i++ ) {
( * arr) [ i] = ( * arr) [ i- 1 ] + y;
}
}
template < class T> void free2d( T ** arr) {
free ( arr[ 0 ] ) ;
free ( arr) ;
}
template < class T> struct DijkstraHeap{
int * hp;
int * place;
int size;
char * visited;
T * val;
void malloc ( int N) {
hp = ( int * ) std:: malloc ( N* sizeof ( int ) ) ;
place = ( int * ) std:: malloc ( N* sizeof ( int ) ) ;
visited = ( char * ) std:: malloc ( N* sizeof ( char ) ) ;
val = ( T* ) std:: malloc ( N* sizeof ( T) ) ;
}
void free ( ) {
std:: free ( hp) ;
std:: free ( place) ;
std:: free ( visited) ;
std:: free ( val) ;
}
void walloc( int N, void ** mem= & wmem) {
walloc1d( & hp, N, mem) ;
walloc1d( & place, N, mem) ;
walloc1d( & visited, N, mem) ;
walloc1d( & val, N, mem) ;
}
void init( int N) {
int i;
size = 0 ;
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
place[ i] = - 1 ;
}
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
visited[ i] = 0 ;
}
}
void up( int n) {
int m;
while ( n) {
m= ( n- 1 ) / 2 ;
if ( val[ hp[ m] ] <= val[ hp[ n] ] ) {
break ;
}
swap( hp[ m] ,hp[ n] ) ;
swap( place[ hp[ m] ] ,place[ hp[ n] ] ) ;
n= m;
}
}
void down( int n) {
int m;
for ( ;; ) {
m= 2 * n+ 1 ;
if ( m>= size) {
break ;
}
if ( m+ 1 < size&& val[ hp[ m] ] > val[ hp[ m+ 1 ] ] ) {
m++ ;
}
if ( val[ hp[ m] ] >= val[ hp[ n] ] ) {
break ;
}
swap( hp[ m] ,hp[ n] ) ;
swap( place[ hp[ m] ] ,place[ hp[ n] ] ) ;
n= m;
}
}
void change( int n, T v) {
if ( visited[ n] || ( place[ n] >= 0 && val[ n] <= v) ) {
return ;
}
val[ n] = v;
if ( place[ n] == - 1 ) {
place[ n] = size;
hp[ size++ ] = n;
up( place[ n] ) ;
}
else {
up( place[ n] ) ;
}
}
int pop( void ) {
int res= hp[ 0 ] ;
place[ res] = - 1 ;
size-- ;
if ( size) {
hp[ 0 ] = hp[ size] ;
place[ hp[ 0 ] ] = 0 ;
down( 0 ) ;
}
visited[ res] = 1 ;
return res;
}
}
;
template < class T> struct Grid2d{
int r;
int c;
T ** d;
int set_s;
int set_d;
T ** d_s;
int ** up;
int ** dw;
int ** lf;
int ** rg;
void malloc ( const int rr, const int cc) {
r = rr;
c = cc;
set_s = 0 ;
set_d = 0 ;
malloc2d( & d, r, c) ;
}
void free ( void ) {
free2d( d) ;
if ( set_s) {
free2d( d_s) ;
}
if ( set_d) {
free2d( up) ;
free2d( dw) ;
free2d( lf) ;
free2d( rg) ;
}
}
T* operator[ ] ( int a) {
return d[ a] ;
}
void setSum( void ) {
int i;
int j;
if ( set_s == 0 ) {
set_s = 1 ;
malloc2d( & d_s, r+ 1 , c+ 1 ) ;
}
for ( i= ( 0 ) ; i< ( r+ 1 ) ; i++ ) {
d_s[ i] [ 0 ] = 0 ;
}
for ( j= ( 0 ) ; j< ( c+ 1 ) ; j++ ) {
d_s[ 0 ] [ j] = 0 ;
}
for ( i= ( 0 ) ; i< ( r) ; i++ ) {
for ( j= ( 0 ) ; j< ( c) ; j++ ) {
d_s[ i+ 1 ] [ j+ 1 ] = d_s[ i] [ j+ 1 ] + d_s[ i+ 1 ] [ j] - d_s[ i] [ j] + d[ i] [ j] ;
}
}
}
void setDir( void ) {
int i;
int j;
if ( set_d == 0 ) {
set_d = 1 ;
malloc2d( & up, r, c) ;
malloc2d( & dw, r, c) ;
malloc2d( & lf, r, c) ;
malloc2d( & rg, r, c) ;
}
for ( j= ( 0 ) ; j< ( c) ; j++ ) {
up[ 0 ] [ j] = 1 ;
}
for ( i= ( 1 ) ; i< ( r) ; i++ ) {
for ( j= ( 0 ) ; j< ( c) ; j++ ) {
if ( d[ i] [ j] == d[ i- 1 ] [ j] ) {
up[ i] [ j] = 1 + up[ i- 1 ] [ j] ;
}
else {
up[ i] [ j] = 1 ;
}
}
}
for ( j= ( 0 ) ; j< ( c) ; j++ ) {
dw[ r- 1 ] [ j] = 1 ;
}
for ( i= r- 2 ; i>= 0 ; i-- ) {
for ( j= ( 0 ) ; j< ( c) ; j++ ) {
if ( d[ i] [ j] == d[ i+ 1 ] [ j] ) {
dw[ i] [ j] = 1 + dw[ i+ 1 ] [ j] ;
}
else {
dw[ i] [ j] = 1 ;
}
}
}
for ( i= ( 0 ) ; i< ( r) ; i++ ) {
lf[ i] [ 0 ] = 1 ;
for ( j= ( 1 ) ; j< ( c) ; j++ ) {
if ( d[ i] [ j] == d[ i] [ j- 1 ] ) {
lf[ i] [ j] = 1 + lf[ i] [ j- 1 ] ;
}
else {
lf[ i] [ j] = 1 ;
}
}
}
for ( i= ( 0 ) ; i< ( r) ; i++ ) {
rg[ i] [ c- 1 ] = 1 ;
for ( j= c- 2 ; j>= 0 ; j-- ) {
if ( d[ i] [ j] == d[ i] [ j+ 1 ] ) {
rg[ i] [ j] = 1 + rg[ i] [ j+ 1 ] ;
}
else {
rg[ i] [ j] = 1 ;
}
}
}
}
void setDirMatch( const T v) {
int i;
int j;
if ( set_d == 0 ) {
set_d = 1 ;
malloc2d( & up, r, c) ;
malloc2d( & dw, r, c) ;
malloc2d( & lf, r, c) ;
malloc2d( & rg, r, c) ;
}
for ( j= ( 0 ) ; j< ( c) ; j++ ) {
if ( d[ 0 ] [ j] == v) {
up[ 0 ] [ j] = 1 ;
}
else {
up[ 0 ] [ j] = 0 ;
}
}
for ( i= ( 1 ) ; i< ( r) ; i++ ) {
for ( j= ( 0 ) ; j< ( c) ; j++ ) {
if ( d[ i] [ j] == v) {
up[ i] [ j] = 1 + up[ i- 1 ] [ j] ;
}
else {
up[ i] [ j] = 0 ;
}
}
}
for ( j= ( 0 ) ; j< ( c) ; j++ ) {
if ( d[ r- 1 ] [ j] == v) {
dw[ r- 1 ] [ j] = 1 ;
}
else {
dw[ r- 1 ] [ j] = 0 ;
}
}
for ( i= r- 2 ; i>= 0 ; i-- ) {
for ( j= ( 0 ) ; j< ( c) ; j++ ) {
if ( d[ i] [ j] == v) {
dw[ i] [ j] = 1 + dw[ i+ 1 ] [ j] ;
}
else {
dw[ i] [ j] = 0 ;
}
}
}
for ( i= ( 0 ) ; i< ( r) ; i++ ) {
if ( d[ i] [ 0 ] == v) {
lf[ i] [ 0 ] = 1 ;
}
else {
lf[ i] [ 0 ] = 0 ;
}
for ( j= ( 1 ) ; j< ( c) ; j++ ) {
if ( d[ i] [ j] == v) {
lf[ i] [ j] = 1 + lf[ i] [ j- 1 ] ;
}
else {
lf[ i] [ j] = 0 ;
}
}
}
for ( i= ( 0 ) ; i< ( r) ; i++ ) {
if ( d[ i] [ c- 1 ] == v) {
rg[ i] [ c- 1 ] = 1 ;
}
else {
rg[ i] [ c- 1 ] = 0 ;
}
for ( j= c- 2 ; j>= 0 ; j-- ) {
if ( d[ i] [ j] == v) {
rg[ i] [ j] = 1 + rg[ i] [ j+ 1 ] ;
}
else {
rg[ i] [ j] = 0 ;
}
}
}
}
inline T getSum( const int r1, const int c1, const int r2, const int c2) {
return d_s[ r2+ 1 ] [ c2+ 1 ] - d_s[ r1] [ c2+ 1 ] - d_s[ r2+ 1 ] [ c1] + d_s[ r1] [ c1] ;
}
template < class S> inline void getDist4( int sr, int sc, S ** res, void * mem = wmem) {
int i;
int j;
int k;
DijkstraHeap< S> hp;
hp.walloc ( r* c) ;
hp.init ( r* c) ;
if ( d[ sr] [ sc] >= 0 ) {
hp.change ( sr* c+ sc, d[ sr] [ sc] ) ;
}
while ( hp.size ) {
k = hp.pop ( ) ;
i = k / c;
j = k % c;
if ( i- 1 >= 0 && d[ i- 1 ] [ j] >= 0 ) {
hp.change ( ( i- 1 ) * c+ j, hp.val [ k] + d[ i- 1 ] [ j] ) ;
}
if ( i+ 1 < r && d[ i+ 1 ] [ j] >= 0 ) {
hp.change ( ( i+ 1 ) * c+ j, hp.val [ k] + d[ i+ 1 ] [ j] ) ;
}
if ( j- 1 >= 0 && d[ i] [ j- 1 ] >= 0 ) {
hp.change ( i* c+ ( j- 1 ) , hp.val [ k] + d[ i] [ j- 1 ] ) ;
}
if ( j+ 1 < c && d[ i] [ j+ 1 ] >= 0 ) {
hp.change ( i* c+ ( j+ 1 ) , hp.val [ k] + d[ i] [ j+ 1 ] ) ;
}
}
for ( i= ( 0 ) ; i< ( r) ; i++ ) {
for ( j= ( 0 ) ; j< ( c) ; j++ ) {
if ( hp.visited [ i* c+ j] ) {
res[ i] [ j] = hp.val [ i* c+ j] ;
}
else {
res[ i] [ j] = - 1 ;
}
}
}
}
}
;
#define main dummy_main
int main( ) {
wmem = memarr;
return 0 ;
}
#undef main
int x;
int y;
Grid2d< int > g;
class Solution{
public :
vector< vector< int >> matrixBlockSum( vector< vector< int >> & mat, int K) {
int cTE1_r3A, i, xr20shxY;
vector< vector< int >> res;
vector< int > tmp;
dummy_main( ) ;
x = mat.size ( ) ;
y = mat[ 0 ] .size ( ) ;
g.malloc ( x,y) ;
for ( i= ( 0 ) ; i< ( x) ; i++ ) {
int j;
for ( j= ( 0 ) ; j< ( y) ; j++ ) {
g[ i] [ j] = mat[ i] [ j] ;
}
}
g.setSum ( ) ;
for ( cTE1_r3A= ( 0 ) ; cTE1_r3A< ( y) ; cTE1_r3A++ ) {
tmp.push_back ( 0 ) ;
}
for ( xr20shxY= ( 0 ) ; xr20shxY< ( x) ; xr20shxY++ ) {
res.push_back ( tmp) ;
}
for ( i= ( 0 ) ; i< ( x) ; i++ ) {
int j;
for ( j= ( 0 ) ; j< ( y) ; j++ ) {
res[ i] [ j] = g.getSum ( max_L( 0 , i- K) ,max_L( 0 , j- K) ,min_L( x- 1 , i+ K) ,min_L( y- 1 , j+ K) ) ;
}
}
g.free ( ) ;
return res;
}
}
;
// cLay varsion 20200112-1
// --- original code ---
// #define main dummy_main
// {}
// #undef main
//
// int x, y;
// Grid2d<int> g;
//
// class Solution {
// public:
// vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int K) {
// vector<vector<int>> res;
// vector<int> tmp;
// dummy_main();
// x = mat.size();
// y = mat[0].size();
// g.malloc(x,y);
// rep(i,x) rep(j,y) g[i][j] = mat[i][j];
// g.setSum();
//
// rep(y) tmp.push_back(0);
// rep(x) res.push_back(tmp);
//
// rep(i,x) rep(j,y) res[i][j] = g.getSum(max(0,i-K), max(0,j-K), min(x-1,i+K), min(y-1,j+K));
//
// g.free();
// return res;
// }
// };
I3ByYWdtYSBHQ0Mgb3B0aW1pemUgKCJPZmFzdCIpCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnZvaWQgKndtZW07CmNoYXIgbWVtYXJyWzk2MDAwMDAwXTsKdGVtcGxhdGU8Y2xhc3MgUywgY2xhc3MgVD4gaW5saW5lIFMgbWluX0woUyBhLFQgYil7CiAgcmV0dXJuIGE8PWI/YTpiOwp9CnRlbXBsYXRlPGNsYXNzIFMsIGNsYXNzIFQ+IGlubGluZSBTIG1heF9MKFMgYSxUIGIpewogIHJldHVybiBhPj1iP2E6YjsKfQp0ZW1wbGF0ZTxjbGFzcyBUPiBpbmxpbmUgdm9pZCB3YWxsb2MxZChUICoqYXJyLCBpbnQgeCwgdm9pZCAqKm1lbSA9ICZ3bWVtKXsKICBzdGF0aWMgaW50IHNraXBbMTZdID0gezAsIDE1LCAxNCwgMTMsIDEyLCAxMSwgMTAsIDksIDgsIDcsIDYsIDUsIDQsIDMsIDIsIDF9OwogICgqbWVtKSA9ICh2b2lkKikoICgoY2hhciopKCptZW0pKSArIHNraXBbKCh1bnNpZ25lZCBsb25nIGxvbmcpKCptZW0pKSAmIDE1XSApOwogICgqYXJyKT0oVCopKCptZW0pOwogICgqbWVtKT0oKCphcnIpK3gpOwp9CnRlbXBsYXRlPGNsYXNzIFQ+IHZvaWQgbWFsbG9jMmQoVCAqKiphcnIsIGludCB4LCBpbnQgeSl7CiAgaW50IGk7CiAgKCphcnIpID0gKFQqKiltYWxsb2MoeCpzaXplb2YoVCopKTsKICAoKmFycilbMF0gPSAoVCopbWFsbG9jKHgqeSpzaXplb2YoVCkpOwogIGludCBqWnlXQVBwWSA9IHg7CiAgZm9yKGk9KDEpO2k8KGpaeVdBUHBZKTtpKyspewogICAgKCphcnIpW2ldPSgqYXJyKVtpLTFdK3k7CiAgfQp9CnRlbXBsYXRlPGNsYXNzIFQ+IHZvaWQgZnJlZTJkKFQgKiphcnIpewogIGZyZWUoYXJyWzBdKTsKICBmcmVlKGFycik7Cn0KdGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBEaWprc3RyYUhlYXB7CiAgaW50ICpocDsKICBpbnQgKnBsYWNlOwogIGludCBzaXplOwogIGNoYXIgKnZpc2l0ZWQ7CiAgVCAqdmFsOwogIHZvaWQgbWFsbG9jKGludCBOKXsKICAgIGhwID0gKGludCopc3RkOjptYWxsb2MoTipzaXplb2YoaW50KSk7CiAgICBwbGFjZSA9IChpbnQqKXN0ZDo6bWFsbG9jKE4qc2l6ZW9mKGludCkpOwogICAgdmlzaXRlZCA9IChjaGFyKilzdGQ6Om1hbGxvYyhOKnNpemVvZihjaGFyKSk7CiAgICB2YWwgPSAoVCopc3RkOjptYWxsb2MoTipzaXplb2YoVCkpOwogIH0KICB2b2lkIGZyZWUoKXsKICAgIHN0ZDo6ZnJlZShocCk7CiAgICBzdGQ6OmZyZWUocGxhY2UpOwogICAgc3RkOjpmcmVlKHZpc2l0ZWQpOwogICAgc3RkOjpmcmVlKHZhbCk7CiAgfQogIHZvaWQgd2FsbG9jKGludCBOLCB2b2lkICoqbWVtPSZ3bWVtKXsKICAgIHdhbGxvYzFkKCZocCwgTiwgbWVtKTsKICAgIHdhbGxvYzFkKCZwbGFjZSwgTiwgbWVtKTsKICAgIHdhbGxvYzFkKCZ2aXNpdGVkLCBOLCBtZW0pOwogICAgd2FsbG9jMWQoJnZhbCwgTiwgbWVtKTsKICB9CiAgdm9pZCBpbml0KGludCBOKXsKICAgIGludCBpOwogICAgc2l6ZSA9IDA7CiAgICBmb3IoaT0oMCk7aTwoTik7aSsrKXsKICAgICAgcGxhY2VbaV09LTE7CiAgICB9CiAgICBmb3IoaT0oMCk7aTwoTik7aSsrKXsKICAgICAgdmlzaXRlZFtpXT0wOwogICAgfQogIH0KICB2b2lkIHVwKGludCBuKXsKICAgIGludCBtOwogICAgd2hpbGUobil7CiAgICAgIG09KG4tMSkvMjsKICAgICAgaWYodmFsW2hwW21dXTw9dmFsW2hwW25dXSl7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgc3dhcChocFttXSxocFtuXSk7CiAgICAgIHN3YXAocGxhY2VbaHBbbV1dLHBsYWNlW2hwW25dXSk7CiAgICAgIG49bTsKICAgIH0KICB9CiAgdm9pZCBkb3duKGludCBuKXsKICAgIGludCBtOwogICAgZm9yKDs7KXsKICAgICAgbT0yKm4rMTsKICAgICAgaWYobT49c2l6ZSl7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgaWYobSsxPHNpemUmJnZhbFtocFttXV0+dmFsW2hwW20rMV1dKXsKICAgICAgICBtKys7CiAgICAgIH0KICAgICAgaWYodmFsW2hwW21dXT49dmFsW2hwW25dXSl7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgc3dhcChocFttXSxocFtuXSk7CiAgICAgIHN3YXAocGxhY2VbaHBbbV1dLHBsYWNlW2hwW25dXSk7CiAgICAgIG49bTsKICAgIH0KICB9CiAgdm9pZCBjaGFuZ2UoaW50IG4sIFQgdil7CiAgICBpZih2aXNpdGVkW25dfHwocGxhY2Vbbl0+PTAmJnZhbFtuXTw9dikpewogICAgICByZXR1cm47CiAgICB9CiAgICB2YWxbbl09djsKICAgIGlmKHBsYWNlW25dPT0tMSl7CiAgICAgIHBsYWNlW25dPXNpemU7CiAgICAgIGhwW3NpemUrK109bjsKICAgICAgdXAocGxhY2Vbbl0pOwogICAgfQogICAgZWxzZXsKICAgICAgdXAocGxhY2Vbbl0pOwogICAgfQogIH0KICBpbnQgcG9wKHZvaWQpewogICAgaW50IHJlcz1ocFswXTsKICAgIHBsYWNlW3Jlc109LTE7CiAgICBzaXplLS07CiAgICBpZihzaXplKXsKICAgICAgaHBbMF09aHBbc2l6ZV07CiAgICAgIHBsYWNlW2hwWzBdXT0wOwogICAgICBkb3duKDApOwogICAgfQogICAgdmlzaXRlZFtyZXNdPTE7CiAgICByZXR1cm4gcmVzOwogIH0KfQo7CnRlbXBsYXRlPGNsYXNzIFQ+IHN0cnVjdCBHcmlkMmR7CiAgaW50IHI7CiAgaW50IGM7CiAgVCAqKmQ7CiAgaW50IHNldF9zOwogIGludCBzZXRfZDsKICBUICoqZF9zOwogIGludCAqKnVwOwogIGludCAqKmR3OwogIGludCAqKmxmOwogIGludCAqKnJnOwogIHZvaWQgbWFsbG9jKGNvbnN0IGludCByciwgY29uc3QgaW50IGNjKXsKICAgIHIgPSBycjsKICAgIGMgPSBjYzsKICAgIHNldF9zID0gMDsKICAgIHNldF9kID0gMDsKICAgIG1hbGxvYzJkKCZkLCByLCBjKTsKICB9CiAgdm9pZCBmcmVlKHZvaWQpewogICAgZnJlZTJkKGQpOwogICAgaWYoc2V0X3MpewogICAgICBmcmVlMmQoZF9zKTsKICAgIH0KICAgIGlmKHNldF9kKXsKICAgICAgZnJlZTJkKHVwKTsKICAgICAgZnJlZTJkKGR3KTsKICAgICAgZnJlZTJkKGxmKTsKICAgICAgZnJlZTJkKHJnKTsKICAgIH0KICB9CiAgVCpvcGVyYXRvcltdKGludCBhKXsKICAgIHJldHVybiBkW2FdOwogIH0KICB2b2lkIHNldFN1bSh2b2lkKXsKICAgIGludCBpOwogICAgaW50IGo7CiAgICBpZihzZXRfcyA9PSAwKXsKICAgICAgc2V0X3MgPSAxOwogICAgICBtYWxsb2MyZCgmZF9zLCByKzEsIGMrMSk7CiAgICB9CiAgICBmb3IoaT0oMCk7aTwocisxKTtpKyspewogICAgICBkX3NbaV1bMF0gPSAwOwogICAgfQogICAgZm9yKGo9KDApO2o8KGMrMSk7aisrKXsKICAgICAgZF9zWzBdW2pdID0gMDsKICAgIH0KICAgIGZvcihpPSgwKTtpPChyKTtpKyspewogICAgICBmb3Ioaj0oMCk7ajwoYyk7aisrKXsKICAgICAgICBkX3NbaSsxXVtqKzFdID0gZF9zW2ldW2orMV0gKyBkX3NbaSsxXVtqXSAtIGRfc1tpXVtqXSArIGRbaV1bal07CiAgICAgIH0KICAgIH0KICB9CiAgdm9pZCBzZXREaXIodm9pZCl7CiAgICBpbnQgaTsKICAgIGludCBqOwogICAgaWYoc2V0X2QgPT0gMCl7CiAgICAgIHNldF9kID0gMTsKICAgICAgbWFsbG9jMmQoJnVwLCByLCBjKTsKICAgICAgbWFsbG9jMmQoJmR3LCByLCBjKTsKICAgICAgbWFsbG9jMmQoJmxmLCByLCBjKTsKICAgICAgbWFsbG9jMmQoJnJnLCByLCBjKTsKICAgIH0KICAgIGZvcihqPSgwKTtqPChjKTtqKyspewogICAgICB1cFswXVtqXSA9IDE7CiAgICB9CiAgICBmb3IoaT0oMSk7aTwocik7aSsrKXsKICAgICAgZm9yKGo9KDApO2o8KGMpO2orKyl7CiAgICAgICAgaWYoZFtpXVtqXT09ZFtpLTFdW2pdKXsKICAgICAgICAgIHVwW2ldW2pdID0gMSArIHVwW2ktMV1bal07CiAgICAgICAgfQogICAgICAgIGVsc2V7CiAgICAgICAgICB1cFtpXVtqXSA9IDEgOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgZm9yKGo9KDApO2o8KGMpO2orKyl7CiAgICAgIGR3W3ItMV1bal0gPSAxOwogICAgfQogICAgZm9yKGk9ci0yO2k+PTA7aS0tKXsKICAgICAgZm9yKGo9KDApO2o8KGMpO2orKyl7CiAgICAgICAgaWYoZFtpXVtqXT09ZFtpKzFdW2pdKXsKICAgICAgICAgIGR3W2ldW2pdID0gMSArIGR3W2krMV1bal07CiAgICAgICAgfQogICAgICAgIGVsc2V7CiAgICAgICAgICBkd1tpXVtqXSA9IDEgOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgZm9yKGk9KDApO2k8KHIpO2krKyl7CiAgICAgIGxmW2ldWzBdID0gMTsKICAgICAgZm9yKGo9KDEpO2o8KGMpO2orKyl7CiAgICAgICAgaWYoZFtpXVtqXT09ZFtpXVtqLTFdKXsKICAgICAgICAgIGxmW2ldW2pdID0gMSArIGxmW2ldW2otMV07CiAgICAgICAgfQogICAgICAgIGVsc2V7CiAgICAgICAgICBsZltpXVtqXSA9IDEgOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgZm9yKGk9KDApO2k8KHIpO2krKyl7CiAgICAgIHJnW2ldW2MtMV0gPSAxOwogICAgICBmb3Ioaj1jLTI7aj49MDtqLS0pewogICAgICAgIGlmKGRbaV1bal09PWRbaV1baisxXSl7CiAgICAgICAgICByZ1tpXVtqXSA9IDEgKyByZ1tpXVtqKzFdOwogICAgICAgIH0KICAgICAgICBlbHNlewogICAgICAgICAgcmdbaV1bal0gPSAxIDsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CiAgdm9pZCBzZXREaXJNYXRjaChjb25zdCBUIHYpewogICAgaW50IGk7CiAgICBpbnQgajsKICAgIGlmKHNldF9kID09IDApewogICAgICBzZXRfZCA9IDE7CiAgICAgIG1hbGxvYzJkKCZ1cCwgciwgYyk7CiAgICAgIG1hbGxvYzJkKCZkdywgciwgYyk7CiAgICAgIG1hbGxvYzJkKCZsZiwgciwgYyk7CiAgICAgIG1hbGxvYzJkKCZyZywgciwgYyk7CiAgICB9CiAgICBmb3Ioaj0oMCk7ajwoYyk7aisrKXsKICAgICAgaWYoZFswXVtqXT09dil7CiAgICAgICAgdXBbMF1bal0gPTE7CiAgICAgIH0KICAgICAgZWxzZXsKICAgICAgICB1cFswXVtqXSA9MDsKICAgICAgfQogICAgfQogICAgZm9yKGk9KDEpO2k8KHIpO2krKyl7CiAgICAgIGZvcihqPSgwKTtqPChjKTtqKyspewogICAgICAgIGlmKGRbaV1bal09PXYpewogICAgICAgICAgdXBbaV1bal0gPTEgKyB1cFtpLTFdW2pdOwogICAgICAgIH0KICAgICAgICBlbHNlewogICAgICAgICAgdXBbaV1bal0gPTA7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBmb3Ioaj0oMCk7ajwoYyk7aisrKXsKICAgICAgaWYoZFtyLTFdW2pdPT12KXsKICAgICAgICBkd1tyLTFdW2pdID0xOwogICAgICB9CiAgICAgIGVsc2V7CiAgICAgICAgZHdbci0xXVtqXSA9MDsKICAgICAgfQogICAgfQogICAgZm9yKGk9ci0yO2k+PTA7aS0tKXsKICAgICAgZm9yKGo9KDApO2o8KGMpO2orKyl7CiAgICAgICAgaWYoZFtpXVtqXT09dil7CiAgICAgICAgICBkd1tpXVtqXSA9MSArIGR3W2krMV1bal07CiAgICAgICAgfQogICAgICAgIGVsc2V7CiAgICAgICAgICBkd1tpXVtqXSA9MDsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvcihpPSgwKTtpPChyKTtpKyspewogICAgICBpZihkW2ldWzBdPT12KXsKICAgICAgICBsZltpXVswXSA9MTsKICAgICAgfQogICAgICBlbHNlewogICAgICAgIGxmW2ldWzBdID0wOwogICAgICB9CiAgICAgIGZvcihqPSgxKTtqPChjKTtqKyspewogICAgICAgIGlmKGRbaV1bal09PXYpewogICAgICAgICAgbGZbaV1bal0gPTEgKyBsZltpXVtqLTFdOwogICAgICAgIH0KICAgICAgICBlbHNlewogICAgICAgICAgbGZbaV1bal0gPTA7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBmb3IoaT0oMCk7aTwocik7aSsrKXsKICAgICAgaWYoZFtpXVtjLTFdPT12KXsKICAgICAgICByZ1tpXVtjLTFdID0xOwogICAgICB9CiAgICAgIGVsc2V7CiAgICAgICAgcmdbaV1bYy0xXSA9MDsKICAgICAgfQogICAgICBmb3Ioaj1jLTI7aj49MDtqLS0pewogICAgICAgIGlmKGRbaV1bal09PXYpewogICAgICAgICAgcmdbaV1bal0gPTEgKyByZ1tpXVtqKzFdOwogICAgICAgIH0KICAgICAgICBlbHNlewogICAgICAgICAgcmdbaV1bal0gPTA7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQogIGlubGluZSBUIGdldFN1bShjb25zdCBpbnQgcjEsIGNvbnN0IGludCBjMSwgY29uc3QgaW50IHIyLCBjb25zdCBpbnQgYzIpewogICAgcmV0dXJuIGRfc1tyMisxXVtjMisxXSAtIGRfc1tyMV1bYzIrMV0gLSBkX3NbcjIrMV1bYzFdICsgZF9zW3IxXVtjMV07CiAgfQogIHRlbXBsYXRlPGNsYXNzIFM+IGlubGluZSB2b2lkIGdldERpc3Q0KGludCBzciwgaW50IHNjLCBTICoqcmVzLCB2b2lkICptZW0gPSB3bWVtKXsKICAgIGludCBpOwogICAgaW50IGo7CiAgICBpbnQgazsKICAgIERpamtzdHJhSGVhcDxTPiBocDsKICAgIGhwLndhbGxvYyhyKmMpOwogICAgaHAuaW5pdChyKmMpOwogICAgaWYoZFtzcl1bc2NdID49IDApewogICAgICBocC5jaGFuZ2Uoc3IqYytzYywgZFtzcl1bc2NdKTsKICAgIH0KICAgIHdoaWxlKGhwLnNpemUpewogICAgICBrID0gaHAucG9wKCk7CiAgICAgIGkgPSBrIC8gYzsKICAgICAgaiA9IGsgJSBjOwogICAgICBpZihpLTEgPj0gMCAmJiBkW2ktMV1bal0gPj0gMCl7CiAgICAgICAgaHAuY2hhbmdlKChpLTEpKmMraiwgaHAudmFsW2tdK2RbaS0xXVtqXSk7CiAgICAgIH0KICAgICAgaWYoaSsxIDwgIHIgJiYgZFtpKzFdW2pdID49IDApewogICAgICAgIGhwLmNoYW5nZSgoaSsxKSpjK2osIGhwLnZhbFtrXStkW2krMV1bal0pOwogICAgICB9CiAgICAgIGlmKGotMSA+PSAwICYmIGRbaV1bai0xXSA+PSAwKXsKICAgICAgICBocC5jaGFuZ2UoaSpjKyhqLTEpLCBocC52YWxba10rZFtpXVtqLTFdKTsKICAgICAgfQogICAgICBpZihqKzEgPCAgYyAmJiBkW2ldW2orMV0gPj0gMCl7CiAgICAgICAgaHAuY2hhbmdlKGkqYysoaisxKSwgaHAudmFsW2tdK2RbaV1baisxXSk7CiAgICAgIH0KICAgIH0KICAgIGZvcihpPSgwKTtpPChyKTtpKyspewogICAgICBmb3Ioaj0oMCk7ajwoYyk7aisrKXsKICAgICAgICBpZihocC52aXNpdGVkW2kqYytqXSl7CiAgICAgICAgICByZXNbaV1bal0gPWhwLnZhbFtpKmMral07CiAgICAgICAgfQogICAgICAgIGVsc2V7CiAgICAgICAgICByZXNbaV1bal0gPS0xOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfQo7CiNkZWZpbmUgbWFpbiBkdW1teV9tYWluCmludCBtYWluKCl7CiAgd21lbSA9IG1lbWFycjsKICByZXR1cm4gMDsKfQojdW5kZWYgbWFpbgppbnQgeDsKaW50IHk7CkdyaWQyZDxpbnQ+IGc7CmNsYXNzIFNvbHV0aW9uewogIHB1YmxpYzoKICB2ZWN0b3I8dmVjdG9yPGludD4+IG1hdHJpeEJsb2NrU3VtKHZlY3Rvcjx2ZWN0b3I8aW50Pj4mIG1hdCwgaW50IEspewogICAgaW50IGNURTFfcjNBLCBpLCB4cjIwc2h4WTsKICAgIHZlY3Rvcjx2ZWN0b3I8aW50Pj4gcmVzOwogICAgdmVjdG9yPGludD4gdG1wOwogICAgZHVtbXlfbWFpbigpOwogICAgeCA9IG1hdC5zaXplKCk7CiAgICB5ID0gbWF0WzBdLnNpemUoKTsKICAgIGcubWFsbG9jKHgseSk7CiAgICBmb3IoaT0oMCk7aTwoeCk7aSsrKXsKICAgICAgaW50IGo7CiAgICAgIGZvcihqPSgwKTtqPCh5KTtqKyspewogICAgICAgIGdbaV1bal0gPSBtYXRbaV1bal07CiAgICAgIH0KICAgIH0KICAgIGcuc2V0U3VtKCk7CiAgICBmb3IoY1RFMV9yM0E9KDApO2NURTFfcjNBPCh5KTtjVEUxX3IzQSsrKXsKICAgICAgdG1wLnB1c2hfYmFjaygwKTsKICAgIH0KICAgIGZvcih4cjIwc2h4WT0oMCk7eHIyMHNoeFk8KHgpO3hyMjBzaHhZKyspewogICAgICByZXMucHVzaF9iYWNrKHRtcCk7CiAgICB9CiAgICBmb3IoaT0oMCk7aTwoeCk7aSsrKXsKICAgICAgaW50IGo7CiAgICAgIGZvcihqPSgwKTtqPCh5KTtqKyspewogICAgICAgIHJlc1tpXVtqXSA9IGcuZ2V0U3VtKG1heF9MKDAsIGktSyksbWF4X0woMCwgai1LKSxtaW5fTCh4LTEsIGkrSyksbWluX0woeS0xLCBqK0spKTsKICAgICAgfQogICAgfQogICAgZy5mcmVlKCk7CiAgICByZXR1cm4gcmVzOwogIH0KfQo7Ci8vIGNMYXkgdmFyc2lvbiAyMDIwMDExMi0xCgovLyAtLS0gb3JpZ2luYWwgY29kZSAtLS0KLy8gI2RlZmluZSBtYWluIGR1bW15X21haW4KLy8ge30KLy8gI3VuZGVmIG1haW4KLy8gCi8vIGludCB4LCB5OwovLyBHcmlkMmQ8aW50PiBnOwovLyAKLy8gY2xhc3MgU29sdXRpb24gewovLyBwdWJsaWM6Ci8vICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiBtYXRyaXhCbG9ja1N1bSh2ZWN0b3I8dmVjdG9yPGludD4+JiBtYXQsIGludCBLKSB7Ci8vICAgICB2ZWN0b3I8dmVjdG9yPGludD4+IHJlczsKLy8gICAgIHZlY3RvcjxpbnQ+IHRtcDsKLy8gICAgIGR1bW15X21haW4oKTsKLy8gICAgIHggPSBtYXQuc2l6ZSgpOwovLyAgICAgeSA9IG1hdFswXS5zaXplKCk7Ci8vICAgICBnLm1hbGxvYyh4LHkpOwovLyAgICAgcmVwKGkseCkgcmVwKGoseSkgZ1tpXVtqXSA9IG1hdFtpXVtqXTsKLy8gICAgIGcuc2V0U3VtKCk7Ci8vIAovLyAgICAgcmVwKHkpIHRtcC5wdXNoX2JhY2soMCk7Ci8vICAgICByZXAoeCkgcmVzLnB1c2hfYmFjayh0bXApOwovLyAKLy8gICAgIHJlcChpLHgpIHJlcChqLHkpIHJlc1tpXVtqXSA9IGcuZ2V0U3VtKG1heCgwLGktSyksIG1heCgwLGotSyksIG1pbih4LTEsaStLKSwgbWluKHktMSxqK0spKTsKLy8gCi8vICAgICBnLmZyZWUoKTsKLy8gICAgIHJldHVybiByZXM7Ci8vICAgfQovLyB9Owo=