#pragma GCC optimize("Ofast") #include #define ud unsigned int #define ll long long #define ull unsigned long long #define MAX_INF 0x3f #define MAX_INF_VAL 0x3f3f3f3f #define MAX_INF_VAL_LL 0x3f3f3f3f3f3f3f3f //#define pi 3.141592653589 #define eps 1e-9 #define F(x) ((x)/3+((x)%3==1?0:tb)) #define G(x) ((x) void read( T &x ) { x = 0; char ch = getchar(); ll f = 1; while( !isdigit( ch ) ) { if( ch == '-' ) f *= -1; ch = getchar(); } while( isdigit( ch ) ) { x = x * 10 + ch - 48; ch = getchar(); } x *= f; } struct custom_hash { static uint64_t splitmix64( uint64_t x ) { x += 0x9e3779b97f4a7c15; x = ( x ^ ( x >> 30 ) ) * 0xbf58476d1ce4e5b9; x = ( x ^ ( x >> 27 ) ) * 0x94d049bb133111eb; return x ^ ( x >> 31 ); } size_t operator() ( uint64_t x ) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64( x + FIXED_RANDOM ); } }; struct p { int x1, y1, x2, y2; }; int movx[] = { 0, 1 }; int movy[] = { 1, 0 }; char s[ 11 ][ 11 ]; bool vis2[ 11 ][ 11 ][ 11 ][ 11 ]; bool vis1[ 11 ][ 11 ]; bool ok2( int ); bool ok1( int ); int main() { ios::sync_with_stdio( false ); cin.tie( 0 ), cout.tie( 0 ); int t; cin >> t; while( t-- ) { int n; cin >> n; for( int i = 1; i <= n; ++i ) cin >> s[ i ] + 1; if( ok2( n ) ) cout << 2 << '\n'; else if( ok1( n ) ) cout << 1 << '\n'; else cout << 0 << '\n'; } return 0; } bool ok2( int n ) { if( s[ 1 ][ 1 ] == '#' || s[ n ][ n ] == '#' ) return false; if( s[ 1 ][ 2 ] == '#' || s[ 2 ][ 1 ] == '#' ) return false; queue< p > q; q.push( { 1, 2, 2, 1 } ); memset( vis2, false, sizeof( vis2 ) ); while( !q.empty() ) { auto fk = q.front(); auto x1 = fk.x1; auto y1 = fk.y1; auto x2 = fk.x2; auto y2 = fk.y2; q.pop(); for( int i = 0; i < 2; ++i ) { int nx1 = x1 + movx[ i ]; int ny1 = y1 + movy[ i ]; if( nx1 < 1 || nx1 > n || ny1 < 1 || ny1 > n ) continue; if( s[ nx1 ][ ny1 ] == '#' ) continue; for( int j = 0; j < 2; ++j ) { int nx2 = x2 + movx[ j ]; int ny2 = y2 + movy[ j ]; if( nx2 < 1 || nx2 > n || ny2 < 1 || ny2 > n ) continue; if( s[ nx2 ][ ny2 ] == '#' ) continue; if( nx1 == n && ny1 == n && nx2 == n && ny2 == n ) return true; if( nx1 == nx2 && ny1 == ny2 ) continue; if( vis2[ nx1 ][ ny1 ][ nx2 ][ ny2 ] ) continue; vis2[ nx1 ][ ny1 ][ nx2 ][ ny2 ] = true; q.push( { nx1, ny1, nx2, ny2 } ); } } } return false; } bool ok1( int n ) { if( s[ 1 ][ 1 ] == '#' || s[ n ][ n ] == '#' ) return false; memset( vis1, false, sizeof( vis1 ) ); queue< pair< int, int > > q; q.push( { 1, 1 } ); while( !q.empty() ) { auto fk = q.front(); auto x = fk.first; auto y = fk.second; q.pop(); for( int i = 0; i < 2; ++i ) { int nx = x + movx[ i ]; int ny = y + movy[ i ]; if( nx < 1 || nx > n || ny < 1 || ny > n ) continue; if( s[ nx ][ ny ] == '#' ) continue; if( nx == n && ny == n ) return true; if( vis1[ nx ][ ny ] ) continue; vis1[ nx ][ ny ] = true; q.push( { nx, ny } ); } } return false; }