#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 15

struct Info{
	Info(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	int row,col;
};

int N,num_maze;
int boss[3*SIZE],height[3*SIZE];
ll POW[3*SIZE],CODE[3*SIZE];
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
char input[SIZE][SIZE],used[3*SIZE];
bool visited[SIZE][SIZE];
vector<ll> data[4][1005];
map<vector<ll>,bool> MAP;

bool rangeCheck(int row,int col){

	return row >= 0 && row <= N-1 && col >= 0 && col <= N-1;
}

int get_boss(int id){
	if(boss[id] == id)return id;
	else{
		return boss[id] = get_boss(boss[id]);
	}
}

int isSame(int x,int y){
	return get_boss(x) == get_boss(y);
}

void unite(int x,int y){
	int boss_x = get_boss(x);
	int boss_y = get_boss(y);

	//既に同じグループなら何もしない
	if(boss_x == boss_y)return;

	//高さが高い方に吸収する
	if(height[x] > height[y]){

		boss[boss_y] = boss_x;

	}else if(height[x] < height[y]){

		boss[boss_x] = boss_y;

	}else{ //height[x] == height[y]

		boss[boss_y] = boss_x;
		height[x]++;
	}
}

void init(){

	for(int i = 0; i < 2*N; i++){

		boss[i] = i;
		height[i] = 0;
	}
}


void roll_90(char table[SIZE][SIZE]){

	char tmp[SIZE][SIZE];

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			tmp[col][N-1-row] = table[row][col];
		}
	}

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			table[row][col] = tmp[row][col];
		}
	}
}

void func(){

	for(int i = 0; i < 4; i++){
		for(int k = 0; k < 1005; k++){

			data[i][k].clear();
		}
	}

	queue<Info> Q;

	for(int i = 0; i < num_maze; i++){

		for(int row = 0; row < N; row++){
			scanf("%s",input[row]);
		}

		for(int loop = 0; loop < 4; loop++){ //表を回転させ、右端と左端の連結性を調べておく

			roll_90(input);

			vector<ll> tmp_data;

			for(int start_row = 0; start_row < N; start_row++){

				if(input[start_row][0] == '#')continue;

				init();

				for(int row = 0; row < N; row++){
					for(int col = 0; col < N; col++){
						visited[row][col] = false;
					}
				}

				for(int k = 0; k < 2*N; k++){

					CODE[k] = 0;
				}

				visited[start_row][0] = true;
				Q.push(Info(start_row,0));

				while(!Q.empty()){

					for(int a = 0; a < 4; a++){

						int adj_row = Q.front().row+diff_row[a];
						int adj_col = Q.front().col+diff_col[a];

						if(rangeCheck(adj_row,adj_col) == false || input[adj_row][adj_col] == '#' ||
								visited[adj_row][adj_col] == true)continue;

						visited[adj_row][adj_col] = true;
						Q.push(Info(adj_row,adj_col));
					}

					Q.pop();
				}

				//★他のstart_rowとのグループ化★
				for(int other_start_row = 0; other_start_row < N; other_start_row++){
					if(other_start_row == start_row)continue;

					if(visited[other_start_row][0]){
						unite(start_row,other_start_row);
					}
				}

				for(int goal_row = 0; goal_row < N; goal_row++){

					if(visited[goal_row][N-1]){

						unite(start_row,N+goal_row);
					}
				}

				for(int k = 0; k < 2*N; k++){
					if((k < N && visited[k][0] == false) || (k >= N && visited[k-N][N-1] == false))continue;

					CODE[get_boss(k)] += POW[k];
				}

				for(int k = 0; k < 2*N; k++){

					if(CODE[k] == 0)continue;
					tmp_data.push_back(CODE[k]);
				}
			}

			for(int goal_row = 0; goal_row < N; goal_row++){ //★★折り返し対策★★

				if(input[goal_row][N-1] == '#')continue;

				init();

				for(int row = 0; row < N; row++){
					for(int col = 0; col < N; col++){
						visited[row][col] = false;
					}
				}

				for(int k = 0; k < 2*N; k++){

					CODE[k] = 0;
				}

				visited[goal_row][N-1] = true;
				Q.push(Info(goal_row,N-1));

				while(!Q.empty()){

					for(int a = 0; a < 4; a++){

						int adj_row = Q.front().row+diff_row[a];
						int adj_col = Q.front().col+diff_col[a];

						if(rangeCheck(adj_row,adj_col) == false || input[adj_row][adj_col] == '#' ||
								visited[adj_row][adj_col] == true)continue;

						visited[adj_row][adj_col] = true;
						Q.push(Info(adj_row,adj_col));
					}

					Q.pop();
				}

				bool left_FLG = false;

				for(int row = 0; row < N; row++){
					if(visited[row][0]){

						left_FLG = true;
						break;
					}
				}

				if(left_FLG)continue; //計上済なのでSKIP

				//★他のgoal_rowとのグループ化
				for(int other_goal_row = 0; other_goal_row < N; other_goal_row++){
					if(other_goal_row == goal_row)continue;

					if(visited[other_goal_row][N-1]){

						unite(N+goal_row,N+other_goal_row);
					}
				}

				for(int k = N; k < 2*N; k++){
					if(!visited[k-N][N-1])continue;

					CODE[get_boss(k)] += POW[k];
				}

				for(int k = N; k < 2*N; k++){

					if(CODE[k] == 0)continue;
					tmp_data.push_back(CODE[k]);
				}
			}
			sort(tmp_data.begin(),tmp_data.end());
			tmp_data.erase(unique(tmp_data.begin(),tmp_data.end()),tmp_data.end());

			//少なくとも1つ、左端&右端にビットが立っているグループを持っているか調べる
			bool FLG = false;

			for(int a = 0; a < tmp_data.size(); a++){ //グループのループ

				for(int b = 0; b < N; b++){

					if(tmp_data[a] & POW[b]){
						for(int c = N; c < 2*N; c++){
							if(tmp_data[a] & POW[c]){
								FLG = true;
								break;
							}
						}
						if(FLG)break;
					}
				}
				if(FLG)break;
			}

			if(!FLG)continue;

			data[loop][i] = tmp_data;
		}
	}

	vector<vector<ll>> PRE,NEXT;

	for(int loop = 0; loop < 4; loop++){ //スタートのマップ

		if(data[loop][0].size() == 0)continue;

		PRE.emplace_back(data[loop][0]);
	}

	for(int right = 1; right < num_maze; right++){ //マップのループ(右側となる)

		MAP.clear();

		for(int left = 0; left < PRE.size(); left++){ //左側のループ
			for(int roll = 0; roll < 4; roll++){ //右側に連結する、マップrightの回転のループ

				vector<ll> work;

				for(int a = 0; a < data[roll][right].size(); a++){

					work.push_back(data[roll][right][a]*POW[N]); //★【左のマップの右端コード==右のマップの左端コード】にする★
				}

				vector<ll> tmp_data;

				for(int a = 0; a < 3*N; a++){
					boss[a] = a;
					height[a] = 0;
					used[a] = false;
					CODE[a] = 0;
				}

				int parent;

				//左側の連結成分情報を反映
				for(int a = 0; a < PRE[left].size(); a++){
					//代表をどれか1つ選ぶ
					for(int b = 0; b < 2*N; b++){
						if(PRE[left][a] & POW[b]){
							used[b] = true;
							parent = b;
							break;
						}
					}
					for(int b = 0; b < 2*N; b++){
						if(b == parent)continue;
						if(PRE[left][a] & POW[b]){
							used[b] = true;
							unite(parent,b);
						}
					}
				}

				//右側の連結成分情報を反映
				for(int a = 0; a < work.size(); a++){
					//代表をどれか1つ選ぶ
					for(int b = N; b < 3*N; b++){ //★インデックスに注意★
						if(work[a] & POW[b]){
							used[b] = true;
							parent = b;
							break;
						}
					}
					for(int b = N; b < 3*N; b++){
						if(b == parent)continue;
						if(work[a] & POW[b]){
							used[b] = true;
							unite(parent,b);
						}
					}
				}

				//左端
				for(int a = 0; a < N; a++){
					if(!used[a])continue;

					CODE[get_boss(a)] += POW[a];
				}

				//★中間は抜く★

				//右端
				for(int a = 2*N; a < 3*N; a++){
					if(!used[a])continue;

					CODE[get_boss(a)] += POW[a-N]; //加算分を減じる
				}

				for(int a = 0; a < 3*N; a++){

					if(CODE[a] == 0)continue;
					tmp_data.push_back(CODE[a]);
				}

				sort(tmp_data.begin(),tmp_data.end());

				auto at = MAP.find(tmp_data);
				if(at != MAP.end())continue;

				//少なくとも1つ、左端&右端にビットが立っているグループを持っているか調べる
				bool FLG = false;

				for(int a = 0; a < tmp_data.size(); a++){
					for(int p = N; p < 2*N; p++){
						if(tmp_data[a] & POW[p]){
							for(int q = 0; q < N; q++){
								if(tmp_data[a] & POW[q]){

									FLG = true;
									break;
								}
							}
							if(FLG)break;
						}
					}
					if(FLG)break;
				}

				if(!FLG)continue; //ゴールできない、または右のマップに渡れないので不可

				MAP[tmp_data] = true;

				NEXT.emplace_back(tmp_data);
			}
		}
		PRE.clear();
		PRE = NEXT;
		NEXT.clear();
	}

	//左端と右端が連結しているコードがあるか調べる
	for(int i = 0; i < PRE.size(); i++){
		for(int k = 0; k < PRE[i].size(); k++){
			for(int p = N; p < 2*N; p++){
				if(PRE[i][k] & POW[p]){ //少なくとも右端にビットが立っている
					for(int q = 0; q < N; q++){
						if(PRE[i][k] & POW[q]){

							printf("Yes\n");
							return;
						}
					}
				}
			}
		}
	}

	printf("No\n");
}

int main(){

	POW[0] = 1;
	for(int i = 1; i < 3*SIZE; i++){

		POW[i] = POW[i-1]*2;
	}

	while(true){
		scanf("%d %d",&N,&num_maze);
		if(N == 0 && num_maze == 0)break;

		func();
	}

	return 0;
}





Measured memory_bytes: 3500