#include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS (1e-7)
#define equals(a,b) (fabs((a)-(b))<EPS)
using namespace std;

typedef unsigned long long ull;
const int IINF = INT_MAX;


class Point{
public:
  double x,y;

  Point(double x = -IINF,double y = -IINF): x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  Point operator * (Point a){ return Point(x * a.x - y * a.y, x * a.y + y * a.x); }

  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:y<p.y; }

  bool operator == (const Point& p)const{ return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS; }

};
ostream& operator << (ostream& os,const Point& a){ os << "(" << a.x << "," << a.y << ")"; }


Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

double toRad(double agl){ return agl*M_PI/180.0; }

Point ps[40];
int h,w,Index[11][11],dex,transfer[40];
bool r[11][11];
set<ull> invalid;
ull adj[40];
int dx[] = {1,0,-1,0};
int dy[] = {0,1,0,-1};
/*
  transfer[i] := i番目のノードを達也に与えた場合、それに対応した拓也のノード
 */

bool isValid(int x,int y){ return 0 <= x && x < w && 0 <= y && y < h; }

bool dfs(ull p1,ull p2){
  if( invalid.count(p1|p2) ) return false;
  if( (p1|p2) == ((1ULL<<dex)-1ULL) ) return true;
  rep(i,dex){
    int index1 = i, index2 = transfer[i];
    if( index2 == -1 ) continue;
    if( ((p1>>index1)&1ULL) || ((p2>>index2)&1ULL) || ((p1>>index2)&1ULL) || ((p2>>index1)&1ULL) ) continue;
    if( !(p1&adj[index1]) || !(p2&adj[index2]) ) continue;
    if( dfs(p1|(1ULL<<index1),p2|(1ULL<<index2)) ) return true;
  }
  invalid.insert(p1|p2);
  return false;
}

int main(){

  while( cin >> w >> h, w|h ){
    dex = 0;
    rep(i,h) rep(j,w) {
      cin >> r[i][j];
      if( r[i][j] ) { Index[i][j] = dex; ps[dex++] = Point(j,i); }
      else            Index[i][j] = -1;
    }

    if( dex & 1 ) {
      puts("NO");
      continue;
    }

    rep(i,dex) adj[i] = 0ULL;

    rep(i,h) rep(j,w)if( Index[i][j] != -1 )rep(k,4){
      int nx = j + dx[k], ny = i + dy[k];
      if( !isValid(nx,ny) ) continue;
      if( Index[ny][nx] == -1 ) continue;
      adj[Index[i][j]] |= (1ULL<<Index[ny][nx]);
    }

    Point sp1 = ps[0];
    REP(i,1,dex){
      Point sp2 = ps[i];
      Point dir = Point(1,0); 
      rep(_,4){
        rep(rev,2){
          rep(j,dex) transfer[j] = -1;
          bool failed = false;
          int rt[50];
          rep(k,50) rt[k] = -1;
          rep(j,dex){
            Point p = ps[j];
            p = p - sp1;
            if( rev ) p.x = -p.x;
            p = ( p * dir ) + sp2;

            if( !isValid((int)p.x,(int)p.y) ) continue;
            transfer[j] = Index[(int)p.y][(int)p.x];
            if( transfer[j] == j ) {
              failed = true;
              break;
            }
            if( transfer[j] != -1 ) rt[transfer[j]] = j;
          }

          rep(j,dex){
            if( ( transfer[j] == -1 && rt[j] == -1) ) {
              failed = true;
              break;
            }
          }


          if( !failed ){
            invalid.clear();
            if( dfs(1ULL,(1ULL<<i)) ){
              puts("YES");
              goto Fin;
            }
          }

        }
        dir = rotate(dir,toRad(90));
        if( equals(dir.x,0) ) dir.x = 0;
        if( equals(dir.y,0) ) dir.y = 0;
      }
    }
    puts("NO");
  Fin:;
    
    
  }
  return 0;
}

Measured memory_bytes: 1456