#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
#include <iomanip>
#include <fstream>
using namespace std;
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1<<29;
typedef long long ll;
typedef pair<int,int> pii;

int w, h;
inline bool get(ll S, int y, int x) {
  return S>>(y*w+x)&1;
}
inline ll bit(int y, int x) {
  return 1LL<<(y*w+x);
}
inline bool ok(ll S, int y, int x) {
  if (y<0||y>=h||x<0||x>=w) return 0;
  if (get(S,y,x)) return 0;
  return 1;
}
const int dy[] = {-1,0,1,0};
const int dx[] = {0,1,0,-1};

bool visited[7][7];
int sy,sx;
map<ll, int> mp[7][7];
bool dfs(ll S, int y, int x, int num) {
//  if (num < 30) {
  // if (y) { 
    if (mp[y][x].count(S)) return 0;
    mp[y][x][S] = 1;
  // }
//  }
  // cout << y << "," << x << "," << num << endl;
  // REP(i,h) {
  //   REP(j,w) cout << get(S,i,j);
  //   cout << endl;
  // }
  if (num == 0) {
    return abs(y-sy)+abs(x-sx) == 1;
  }
  // {
  //   // 最初の場所の近傍が全部埋まってたらだめ
  //   int c = 0;
  //   REP(k,4) {
  //     int yy=sy+dy[k];
  //     int xx=sx+dx[k];
  //     if (ok(S,yy,xx)) c++;
  //   }
  //   if (c==0) return 0;
  // }
  // BFSして領域が2つあったらだめ
  {
    REP(i,h)REP(j,w)visited[i][j]=0;
    REP(i,h)REP(j,w) {
      if (get(S,i,j)) continue;
      queue<pii>Q;
      Q.push(pii(i,j));
      visited[i][j] = 1;
      int cnt = 0;
      bool f = 0;
      while(!Q.empty()) {
        pii p = Q.front(); Q.pop();
        ++cnt;
        REP(k,4) {
          int ii=p.first+dy[k];
          int jj=p.second+dx[k];
          if (ii==sy&&jj==sx) f = 1;
          if (!ok(S,ii,jj)) continue;
          if (visited[ii][jj]) continue;
          visited[ii][jj] = 1;
          Q.push(pii(ii,jj));
        }
      }
      if (cnt != num || !f) return 0;
      goto next;
    }
  next:;
  }
  {
    // 今の場所と最初の場所以外で凸の部分があったらだめ
    int cnt = 0;
    REP(i,h)REP(j,w) {
      if (get(S,i,j)) continue;
      int c = 0;
      REP(k,4) {
        int ii=i+dy[k];
        int jj=j+dx[k];
        if (!ok(S,ii,jj)) {
          if (ii!=y||jj!=x) {
            if (ii!=sy||jj!=sx) {
              ++c;
            }
          }
        }
      }
      if (c >= 3) {
        ++cnt;
      }
    }
    if (cnt >= 1) return 0;
  }
  REP(k,4) {
    int yy=y+dy[k];
    int xx=x+dx[k];
    if (!ok(S,yy,xx)) continue;
    if (dfs(S|bit(yy,xx),yy,xx,num-1)) return 1;
  }
  return 0;
}

int main() {
  while(cin>>w>>h,w||h) {
    ll S = 0;
    int num = 0;
    REP(i,h) REP(j,w) {
      int a; cin >> a;
      if (a) S |= bit(i,j);
      else {
        sy=i,sx=j;
        ++num;
      }
    }
    if (num <= 3) {               // 空きマスが3以下
      puts("No");
      continue;
    }
    S |= bit(sy,sx); --num;
    REP(i,h)REP(j,w) mp[i][j].clear();
    cout << (dfs(S,sy,sx,num)?"Yes":"No") << endl;
  }
}

Measured memory_bytes: 20140