#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cstdlib>

using namespace std;

const int dy[]={-1,0,0,1};
const int dx[]={0,-1,1,0};

bool ok;
int w,h;
int field[10][10];

class edge{
public:
	int x,y,num;
};

vector<edge> G[8][8];
int en;
bool isPassedEdge[500];
bool isPassedNode[10][10];
int emp;

int sx,sy;

bool passed[10][10];

vector<int> sEdge;

void searchArrivable(int x,int y){
	passed[y][x]=true;
	for(int i = 0; i < 4; i++){
		int ny=y+dy[i];
		int nx=x+dx[i];
		if(ny>=0&&nx>=0&&ny<h&&nx<w){
			if(!passed[ny][nx]&&field[ny][nx]==0&&!isPassedNode[ny][nx]){
				searchArrivable(nx,ny);
			}
		}
	}
}

void dfs(int x,int y){
	if(ok)
		return;
	// ¡Ìm[h©ç¼ÌÜ¾½Çè¢ÄÈ¢m[h·×ÄÉBÂ\©Ç¤©ðTõ
	memset(passed,0,sizeof(passed));
	searchArrivable(x,y);
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			if(passed[i][j]||isPassedNode[i][j]||field[i][j]==1)
				continue;
			// àµêÂÅàBsÂ\Èm[hª êÎ
			else
				return;
		}
	}
	// startm[hÌ¢gpGbWªSÌm[hÉB·éÜ¦É0ÉÈÁÄµÜÁ½êÍAreturn
	int cnt=0;
	for(int i = 0; i < G[sy][sx].size(); i++){
		if(!isPassedNode[G[sy][sx][i].y][G[sy][sx][i].x])
			cnt++;
	}
	if(cnt==0&&emp!=0)
		return;

	// Ü¾½Çè¢Ä¢È¢ ém[h©ç½Çè¯ém[hªPÂµ©È¢ê
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			if(!isPassedNode[i][j]&&field[i][j]==0&&!(i==y&&j==x)){
				int cc=0;
				for(int k = 0; k < G[i][j].size(); k++){
					if(!isPassedNode[G[i][j][k].y][G[i][j][k].x]||(G[i][j][k].y==y&&G[i][j][k].x==x)
						||(sy==G[i][j][k].y&&sx==G[i][j][k].x)){
						cc++;
					}
				}
				if(cc==1){
					return;
				}
			}
		}
	}

	for(int i = 0; i < G[y][x].size(); i++){
		edge &e=G[y][x][i];
		if(!isPassedEdge[e.num]){
			if(emp==0&&e.x==sx&&e.y==sy){
				ok=true;
				return;
			}
			else if(!isPassedNode[e.y][e.x]){
				isPassedNode[e.y][e.x]=true;
				isPassedEdge[e.num]=true;
				emp--;
				dfs(e.x,e.y);
				if(ok)
					return;
				emp++;
				isPassedNode[e.y][e.x]=false;
				isPassedEdge[e.num]=false;
			}
		}
	}
}



int main(){

	while(cin>>w>>h&&!(w==0&&h==0)){
		sEdge.clear();
		for(int i = 0; i < 8; i++)
			for(int j = 0; j < 8; j++)
				G[i][j].clear();
		ok=false;
		emp=0;
		memset(isPassedEdge,0,sizeof(isPassedEdge));
		memset(isPassedNode,0,sizeof(isPassedNode));
		for(int i = 0; i < h; i++){
			for(int j = 0; j < w; j++){
				cin>>field[i][j];
				if(field[i][j]==0)
					emp++;
			}
		}
		en=0;
		bool fir=true;
		for(int i = 0; i < h; i++){
			for(int j = 0; j < w; j++){
				if(field[i][j]==1)
					continue;
				if(fir){
					sx=j;
					sy=i;
					fir=false;
				}
				// right
				int ny=i;
				int nx=j+1;
				if(ny>=0&&nx>=0&&ny<h&&nx<w&&field[ny][nx]==0){
					edge e;
					e.y=ny;
					e.x=nx;
					e.num=en;
					G[i][j].push_back(e);
					e.y=i;
					e.x=j;
					G[ny][nx].push_back(e);
					en++;
				}
				// down
				ny=i+1;
				nx=j;
				if(ny>=0&&nx>=0&&ny<h&&nx<w&&field[ny][nx]==0){
					edge e;
					e.y=ny;
					e.x=nx;
					e.num=en;
					G[i][j].push_back(e);
					e.y=i;
					e.x=j;
					G[ny][nx].push_back(e);
					en++;
				}
			}
		}

		bool isFail=false;
		for(int i = 0; i < h; i++){
			for(int j = 0; j < w; j++){
				if(G[i][j].size()==1){
					isFail=true;
					break;
				}
			}
			if(isFail)
				break;
		}

		if(emp==0||isFail)
			cout<<"No"<<endl;
		else{
			emp--;
			isPassedNode[sy][sx]=true;
			for(int i = 0; i < G[sy][sx].size(); i++)
				sEdge.push_back(G[sy][sx][i].num);
			dfs(sx,sy);
			if(ok)
				cout<<"Yes"<<endl;
			else
				cout<<"No"<<endl;
		}
	}

	return 0;
}

Measured memory_bytes: 900