#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <unordered_set>
 
using namespace std;
 
#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
 
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }
 
typedef unsigned long long ull;
 
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int W, H, C;
int grid[10][10];
vector<int> G[100];
unordered_set<ull> used[100];
bool dfs(int u, ull s){
    if(s == (1ULL << C) - 1){
        for(auto v : G[0]) if(v == u) return true;
        return false;
    }
    if(used[u].count(s)) return false;
 
    // u = 0 にいけない
    {
        bool any = true;
        for(auto v : G[0]) if(!(s & (1ULL << v))) any = false;
        if(any) return false;
    }
 
    // のこりの頂点の次数が1以下の個数を数える
    int low_degrees = 0;
    REP(i, C) if(!(s & (1ULL << i))){
        int deg = 0;
        for(auto v : G[i]) if(!(s & (1ULL << v))) deg++;
        if(deg <= 1) low_degrees += 1;
        if(low_degrees >= 3) return false;
    }
 
    used[u].insert(s);
 
    // のこりの頂点が連結かどうか
    queue<int> que;
    ull used_s = s;
    que.push(u);
    while(!que.empty()){
        int u = que.front(); que.pop();
        REP(i, G[u].size()) {
            int v = G[u][i];
            if(used_s & (1ULL << v)) continue;
            used_s |= 1ULL << v;
            que.push(v);
        }
    }
    if(used_s != (1ULL << C) - 1){
        return false;
    }
 
    for(auto v : G[u]){
        if(s & (1ULL << v)) continue;
        if(dfs(v, s | (1ULL << v))) return true;
    }
    return false;
}
bool dfs_naive(int u, ull s){
    if(s == (1ULL << C) - 1){
        for(auto v : G[0]) if(v == u) return true;
        return false;
    }
    for(auto v : G[u]){
        if(s & (1ULL << v)) continue;
        if(dfs_naive(v, s | (1ULL << v))){
            //printf("%d->%d\n", u, v);
            return true;
        }
    }
    return false;
}
 
bool solve(int W, int H){
    C = 0;
 
    int id[10][10];
    REP(y, H) REP(x, W){
        if(grid[y][x] == 0) {
            id[y][x] = C++;
        }
    }
 
    REP(i, C) G[i].clear();
    REP(y, H) REP(x, W) if(grid[y][x] == 0){
        REP(r, 4) {
            int nx = x + dx[r];
            int ny = y + dy[r];
            if(valid(nx, ny, W, H) && grid[ny][nx] == 0) G[id[y][x]].push_back(id[ny][nx]);
        }
    }
 
 
    /*
    REP(i, 100) used[i].clear();
    if(dfs(0, 1) != dfs_naive(0, 1)){
        REP(y, H) {
            REP(x, W) cout << grid[y][x] << " ";
            cout << endl;
        }
        REP(i, 100) used[i].clear();
        cout << dfs(0, 1) << endl;
        cout << dfs_naive(0, 1) << endl;
        assert(false);
    }
    */
 
    REP(i, C) used[i].clear();
    if(C > 3 && (C == 1 || dfs(0, 1))){
        return true;
    }else{
        return false;
    }
}
 
int main(){
    /*
    REP(_, 100000){
        int W = rand() % 5 + 1;
        int H = rand() % 5 + 1;
        REP(y, H) REP(x, W) grid[y][x] = rand() % 2;
        solve(W, H);
    }
    */
    while(cin >> W >> H && W){
        REP(y, H) REP(x, W) cin >> grid[y][x];
        if(solve(W, H)) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    return 0;
}

Measured memory_bytes: 56968