#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
void * wmem;
char memarr[ 96000000 ] ;
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) ;
}
struct unionFind{
int * d;
int N;
int M;
inline void malloc ( const int n) {
d = ( int * ) std:: malloc ( n* sizeof ( int ) ) ;
M = n;
}
inline void malloc ( const int n, const int fg) {
d = ( int * ) std:: malloc ( n* sizeof ( int ) ) ;
M = n;
if ( fg) {
init( n) ;
}
}
inline void free ( void ) {
std:: free ( d) ;
}
inline void walloc( const int n, void ** mem= & wmem) {
walloc1d( & d, n, mem) ;
M = n;
}
inline void walloc( const int n, const int fg, void ** mem= & wmem) {
walloc1d( & d, n, mem) ;
M = n;
if ( fg) {
init( n) ;
}
}
inline void init( const int n) {
int i;
N = n;
for ( i= ( 0 ) ; i< ( n) ; i++ ) {
d[ i] = - 1 ;
}
}
inline void init( void ) {
init( M) ;
}
inline int get( int a) {
int t = a;
int k;
while ( d[ t] >= 0 ) {
t= d[ t] ;
}
while ( d[ a] >= 0 ) {
k= d[ a] ;
d[ a] = t;
a= k;
}
return a;
}
inline int connect( int a, int b) {
if ( d[ a] >= 0 ) {
a= get( a) ;
}
if ( d[ b] >= 0 ) {
b= get( b) ;
}
if ( a== b) {
return 0 ;
}
if ( d[ a] < d[ b] ) {
d[ a] + = d[ b] ;
d[ b] = a;
}
else {
d[ b] + = d[ a] ;
d[ a] = b;
}
return 1 ;
}
inline int operator( ) ( int a) {
return get( a) ;
}
inline int operator( ) ( int a, int b) {
return connect( a,b) ;
}
inline int & operator[ ] ( const int a) {
return d[ a] ;
}
inline int size( int a) {
a = get( a) ;
return - d[ a] ;
}
inline int sizeList( int res[ ] ) {
int i;
int sz= 0 ;
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
if ( d[ i] < 0 ) {
res[ sz++ ] = - d[ i] ;
}
}
return sz;
}
}
;
#define main dummy_main
int main( ) {
wmem = memarr;
return 0 ;
}
#undef main
int con[ 6 ] [ 4 ] = { // U, L, D, R
0 ,1 ,0 ,1 ,
1 ,0 ,1 ,0 ,
0 ,1 ,1 ,0 ,
0 ,0 ,1 ,1 ,
1 ,1 ,0 ,0 ,
1 ,0 ,0 ,1
} ;
class Solution{
public :
bool hasValidPath( vector< vector< int >> & A) {
int i;
dummy_main( ) ;
int X = A.size ( ) ;
int Y = A[ 0 ] .size ( ) ;
unionFind uf;
uf.walloc ( X* Y, 1 ) ;
for ( i= ( 0 ) ; i< ( X) ; i++ ) {
int j;
for ( j= ( 0 ) ; j< ( Y) ; j++ ) {
A[ i] [ j] -- ;
}
}
for ( i= ( 0 ) ; i< ( X) ; i++ ) {
int j;
for ( j= ( 0 ) ; j< ( Y- 1 ) ; j++ ) {
if ( con[ A[ i] [ j] ] [ 3 ] && con[ A[ i] [ j+ 1 ] ] [ 1 ] ) {
uf( i* Y+ j, i* Y+ j+ 1 ) ;
}
}
}
for ( i= ( 0 ) ; i< ( X- 1 ) ; i++ ) {
int j;
for ( j= ( 0 ) ; j< ( Y) ; j++ ) {
if ( con[ A[ i] [ j] ] [ 2 ] && con[ A[ i+ 1 ] [ j] ] [ 0 ] ) {
uf( i* Y+ j, ( i+ 1 ) * Y+ j) ;
}
}
}
return uf( 0 ) == uf( X* Y- 1 ) ;
}
}
;
// cLay varsion 20200325-1
// --- original code ---
// #define main dummy_main
// {}
// #undef main
//
// int con[6][4] = { // U, L, D, R
// 0,1,0,1,
// 1,0,1,0,
// 0,1,1,0,
// 0,0,1,1,
// 1,1,0,0,
// 1,0,0,1
// };
//
// class Solution {
// public:
// bool hasValidPath(vector<vector<int>>& A) {
// dummy_main();
// int X = A.size(), Y = A[0].size();
// unionFind uf;
// uf.walloc(X*Y, 1);
// rep(i,X) rep(j,Y) A[i][j]--;
// rep(i,X) rep(j,Y-1) if(con[A[i][j]][3] && con[A[i][j+1]][1]) uf(i*Y+j, i*Y+j+1);
// rep(i,X-1) rep(j,Y) if(con[A[i][j]][2] && con[A[i+1][j]][0]) uf(i*Y+j, (i+1)*Y+j);
// return uf(0) == uf(X*Y-1);
// }
// };
I3ByYWdtYSBHQ0Mgb3B0aW1pemUgKCJPZmFzdCIpCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnZvaWQgKndtZW07CmNoYXIgbWVtYXJyWzk2MDAwMDAwXTsKdGVtcGxhdGU8Y2xhc3MgVD4gaW5saW5lIHZvaWQgd2FsbG9jMWQoVCAqKmFyciwgaW50IHgsIHZvaWQgKiptZW0gPSAmd21lbSl7CiAgc3RhdGljIGludCBza2lwWzE2XSA9IHswLCAxNSwgMTQsIDEzLCAxMiwgMTEsIDEwLCA5LCA4LCA3LCA2LCA1LCA0LCAzLCAyLCAxfTsKICAoKm1lbSkgPSAodm9pZCopKCAoKGNoYXIqKSgqbWVtKSkgKyBza2lwWygodW5zaWduZWQgbG9uZyBsb25nKSgqbWVtKSkgJiAxNV0gKTsKICAoKmFycik9KFQqKSgqbWVtKTsKICAoKm1lbSk9KCgqYXJyKSt4KTsKfQpzdHJ1Y3QgdW5pb25GaW5kewogIGludCAqZDsKICBpbnQgTjsKICBpbnQgTTsKICBpbmxpbmUgdm9pZCBtYWxsb2MoY29uc3QgaW50IG4pewogICAgZCA9IChpbnQqKXN0ZDo6bWFsbG9jKG4qc2l6ZW9mKGludCkpOwogICAgTSA9IG47CiAgfQogIGlubGluZSB2b2lkIG1hbGxvYyhjb25zdCBpbnQgbiwgY29uc3QgaW50IGZnKXsKICAgIGQgPSAoaW50KilzdGQ6Om1hbGxvYyhuKnNpemVvZihpbnQpKTsKICAgIE0gPSBuOwogICAgaWYoZmcpewogICAgICBpbml0KG4pOwogICAgfQogIH0KICBpbmxpbmUgdm9pZCBmcmVlKHZvaWQpewogICAgc3RkOjpmcmVlKGQpOwogIH0KICBpbmxpbmUgdm9pZCB3YWxsb2MoY29uc3QgaW50IG4sIHZvaWQgKiptZW09JndtZW0pewogICAgd2FsbG9jMWQoJmQsIG4sIG1lbSk7CiAgICBNID0gbjsKICB9CiAgaW5saW5lIHZvaWQgd2FsbG9jKGNvbnN0IGludCBuLCBjb25zdCBpbnQgZmcsIHZvaWQgKiptZW09JndtZW0pewogICAgd2FsbG9jMWQoJmQsIG4sIG1lbSk7CiAgICBNID0gbjsKICAgIGlmKGZnKXsKICAgICAgaW5pdChuKTsKICAgIH0KICB9CiAgaW5saW5lIHZvaWQgaW5pdChjb25zdCBpbnQgbil7CiAgICBpbnQgaTsKICAgIE4gPSBuOwogICAgZm9yKGk9KDApO2k8KG4pO2krKyl7CiAgICAgIGRbaV0gPSAtMTsKICAgIH0KICB9CiAgaW5saW5lIHZvaWQgaW5pdCh2b2lkKXsKICAgIGluaXQoTSk7CiAgfQogIGlubGluZSBpbnQgZ2V0KGludCBhKXsKICAgIGludCB0ID0gYTsKICAgIGludCBrOwogICAgd2hpbGUoZFt0XT49MCl7CiAgICAgIHQ9ZFt0XTsKICAgIH0KICAgIHdoaWxlKGRbYV0+PTApewogICAgICBrPWRbYV07CiAgICAgIGRbYV09dDsKICAgICAgYT1rOwogICAgfQogICAgcmV0dXJuIGE7CiAgfQogIGlubGluZSBpbnQgY29ubmVjdChpbnQgYSwgaW50IGIpewogICAgaWYoZFthXT49MCl7CiAgICAgIGE9Z2V0KGEpOwogICAgfQogICAgaWYoZFtiXT49MCl7CiAgICAgIGI9Z2V0KGIpOwogICAgfQogICAgaWYoYT09Yil7CiAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYoZFthXSA8IGRbYl0pewogICAgICBkW2FdICs9IGRbYl07CiAgICAgIGRbYl0gPSBhOwogICAgfQogICAgZWxzZXsKICAgICAgZFtiXSArPSBkW2FdOwogICAgICBkW2FdID0gYjsKICAgIH0KICAgIHJldHVybiAxOwogIH0KICBpbmxpbmUgaW50IG9wZXJhdG9yKCkoaW50IGEpewogICAgcmV0dXJuIGdldChhKTsKICB9CiAgaW5saW5lIGludCBvcGVyYXRvcigpKGludCBhLCBpbnQgYil7CiAgICByZXR1cm4gY29ubmVjdChhLGIpOwogIH0KICBpbmxpbmUgaW50JiBvcGVyYXRvcltdKGNvbnN0IGludCBhKXsKICAgIHJldHVybiBkW2FdOwogIH0KICBpbmxpbmUgaW50IHNpemUoaW50IGEpewogICAgYSA9IGdldChhKTsKICAgIHJldHVybiAtZFthXTsKICB9CiAgaW5saW5lIGludCBzaXplTGlzdChpbnQgcmVzW10pewogICAgaW50IGk7CiAgICBpbnQgc3o9MDsKICAgIGZvcihpPSgwKTtpPChOKTtpKyspewogICAgICBpZihkW2ldPDApewogICAgICAgIHJlc1tzeisrXSA9IC1kW2ldOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gc3o7CiAgfQp9CjsKI2RlZmluZSBtYWluIGR1bW15X21haW4KaW50IG1haW4oKXsKICB3bWVtID0gbWVtYXJyOwogIHJldHVybiAwOwp9CiN1bmRlZiBtYWluCmludCBjb25bNl1bNF0gPSB7IC8vIFUsIEwsIEQsIFIKICAwLDEsMCwxLAogIDEsMCwxLDAsCiAgMCwxLDEsMCwKICAwLDAsMSwxLAogIDEsMSwwLDAsCiAgMSwwLDAsMQp9OwpjbGFzcyBTb2x1dGlvbnsKICBwdWJsaWM6CiAgYm9vbCBoYXNWYWxpZFBhdGgodmVjdG9yPHZlY3RvcjxpbnQ+PiYgQSl7CiAgICBpbnQgaTsKICAgIGR1bW15X21haW4oKTsKICAgIGludCBYID0gQS5zaXplKCk7CiAgICBpbnQgWSA9IEFbMF0uc2l6ZSgpOwogICAgdW5pb25GaW5kIHVmOwogICAgdWYud2FsbG9jKFgqWSwgMSk7CiAgICBmb3IoaT0oMCk7aTwoWCk7aSsrKXsKICAgICAgaW50IGo7CiAgICAgIGZvcihqPSgwKTtqPChZKTtqKyspewogICAgICAgIEFbaV1bal0tLTsKICAgICAgfQogICAgfQogICAgZm9yKGk9KDApO2k8KFgpO2krKyl7CiAgICAgIGludCBqOwogICAgICBmb3Ioaj0oMCk7ajwoWS0xKTtqKyspewogICAgICAgIGlmKGNvbltBW2ldW2pdXVszXSAmJiBjb25bQVtpXVtqKzFdXVsxXSl7CiAgICAgICAgICB1ZihpKlkraiwgaSpZK2orMSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBmb3IoaT0oMCk7aTwoWC0xKTtpKyspewogICAgICBpbnQgajsKICAgICAgZm9yKGo9KDApO2o8KFkpO2orKyl7CiAgICAgICAgaWYoY29uW0FbaV1bal1dWzJdICYmIGNvbltBW2krMV1bal1dWzBdKXsKICAgICAgICAgIHVmKGkqWStqLCAoaSsxKSpZK2opOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHVmKDApID09IHVmKFgqWS0xKTsKICB9Cn0KOwovLyBjTGF5IHZhcnNpb24gMjAyMDAzMjUtMQoKLy8gLS0tIG9yaWdpbmFsIGNvZGUgLS0tCi8vICNkZWZpbmUgbWFpbiBkdW1teV9tYWluCi8vIHt9Ci8vICN1bmRlZiBtYWluCi8vIAovLyBpbnQgY29uWzZdWzRdID0geyAvLyBVLCBMLCBELCBSCi8vICAgMCwxLDAsMSwKLy8gICAxLDAsMSwwLAovLyAgIDAsMSwxLDAsCi8vICAgMCwwLDEsMSwKLy8gICAxLDEsMCwwLAovLyAgIDEsMCwwLDEKLy8gfTsKLy8gCi8vIGNsYXNzIFNvbHV0aW9uIHsKLy8gcHVibGljOgovLyAgIGJvb2wgaGFzVmFsaWRQYXRoKHZlY3Rvcjx2ZWN0b3I8aW50Pj4mIEEpIHsKLy8gICAgIGR1bW15X21haW4oKTsKLy8gICAgIGludCBYID0gQS5zaXplKCksIFkgPSBBWzBdLnNpemUoKTsKLy8gICAgIHVuaW9uRmluZCB1ZjsKLy8gICAgIHVmLndhbGxvYyhYKlksIDEpOwovLyAgICAgcmVwKGksWCkgcmVwKGosWSkgQVtpXVtqXS0tOwovLyAgICAgcmVwKGksWCkgcmVwKGosWS0xKSBpZihjb25bQVtpXVtqXV1bM10gJiYgY29uW0FbaV1baisxXV1bMV0pIHVmKGkqWStqLCBpKlkraisxKTsKLy8gICAgIHJlcChpLFgtMSkgcmVwKGosWSkgaWYoY29uW0FbaV1bal1dWzJdICYmIGNvbltBW2krMV1bal1dWzBdKSB1ZihpKlkraiwgKGkrMSkqWStqKTsKLy8gICAgIHJldHVybiB1ZigwKSA9PSB1ZihYKlktMSk7Ci8vICAgfQovLyB9Owo=