Problem:
宇宙人のメッセージ
宇宙人 Mr.X は地球への来星記念として、地球人に向けてのメッセージを残しました。 Mr.X がメッセージを残す場所に選んだのは古代遺跡として有名な"トロンコ遺跡"でした。  ここはいろいろな大きさの碁盤のマス目に、奇抜な石像が無造作に配置されている不思議な場所でした。
Mr.X は、メッセージとして、石像が置かれていない全てのマス目を一度だけ通る、単一の閉曲線を描きました。Mr.X はとても賢く、このような閉曲線を描くことが可能な碁盤であれば必ず閉曲線を描き、メッセージを残しました。しかし、石像の配置によっては、閉曲線を描くことが不可能な碁盤もあり、その場合はメッセージを残しませんでした。 図1の碁盤に描かれている閉曲線は、全ての空いているマス目を一度だけ通っています。Mr.X はこのような閉曲線をメッセージとして残しました。
図1
Mr.X は、図2の碁盤に描かれているような閉曲線は描きませんでした。
図2
後に Mr.X のメッセージは、古代遺跡と見事に調和した宇宙人の美として、地球人に夢とロマンを与える伝説となりました。しかし、長年に渡る風化によってメッセージは消えてしまい、伝説だけが残りました。
碁盤の情報を入力とし、Mr.X がその碁盤上にメッセージを残した場合は Yes と、残さなかった場合は No と出力するプログラムを作成してください。ただし、全てのマスに石像が配置されている場合は、No と出力することとします。
Input
複数のデータセットの並びが入力として与えられます。入力の終わりはゼロふたつの行で示されます。各データセットは以下の形式で与えられます。
W
H
c
1,1
c
1,2
...
c
1,W
c
2,1
c
2,2
...
c
2,W
:
c
H,1
c
H,2
...
c
H,W
1 行目に碁盤の横方向に並ぶマス目の数
W
, 縦方向に並ぶマス目の数
H
(1 ≤
W, H
≤ 7) が与えられる。
続く
H
行に碁盤の状態が与えられる。
c
i,j
は碁盤の
i
行目の左から
j
番目のマス目を表す整数であり、0 のとき何も置かれていないマス目、1 のとき石像が置かれているマス目を表す。
データセットの数は 1000 を超えない。
Output
データセットごとに、Yes または No を１行に出力する。
Sample Input
5 4
0 0 0 0 0
0 1 1 0 0
0 0 1 0 1
1 0 0 0 1
5 4
0 0 0 0 0
0 1 1 0 0
0 0 0 0 1
1 0 0 0 1
0 0
Output for the Sample Input
Yes
No

Submitted solutions:

code_snippet: #include <algorithm>
#include <bitset>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
set<unsigned long long> memo;
void make_graph() {
  enum { Y, X };
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex = vector<vector<int>>(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge = vector<vector<int>>(size);
  edge.reserve(size);
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[Y];
        int nx = x + d[X];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(const int &from, bitset<N> &visited) {
  visited.set(from);
  for (const auto &to : edge[from])
    if (!visited[to])
      reachability(to, visited);
}
bool cut_vertex(const int &from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    return dup.count() != size;
  }
  return dup.count() != size;
}
bool dfs(const int &start, int from) {
  unsigned long long m = visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  if (cut_vertex(from))
    return false;
  int visitedCount = visited.count();
  for (int u = 0; u < size; ++u) {
    if (u == from || visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited = bitset<N>(0);
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  while (cin >> w >> h, w | h) {
    field = vector<vector<int>>(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 530
memory_kb: 28860
final_rank: 11

code_snippet: #include <algorithm>
#include <bitset>
#include <iostream>
#include <set>
#include <stack>
#include <vector>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
set<unsigned long long> memo;
void make_graph() {
  enum { Y, X };
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex = vector<vector<int>>(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge = vector<vector<int>>(h * w, vector<int>());
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[Y];
        int nx = x + d[X];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(const int &from, bitset<N> &visited) {
  stack<int> st;
  st.push(from);
  visited.set(from);
  while (!st.empty()) {
    int curr = st.top();
    st.pop();
    for (const auto &to : edge[curr]) {
      if (!visited[to]) {
        visited.set(to);
        st.push(to);
      }
    }
  }
}
bool cut_vertex(const int &from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    return dup.count() != size;
  }
  return dup.count() != size;
}
bool dfs(const int &start, int from) {
  unsigned long long m = visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  if (cut_vertex(from))
    return false;
  for (int u = 0; u < size; ++u) {
    if (u == from)
      continue;
    if (visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited = bitset<N>(0);
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  while (cin >> w >> h, w | h) {
    field = vector<vector<int>>(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 570
memory_kb: 29068
final_rank: 20

code_snippet: #include <iostream>
#include <vector>
#include <bitset>
#include <unordered_set>
using namespace std;

constexpr int N = 49;
constexpr int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
constexpr int NIL = -1;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
unordered_set<unsigned long long> memo;

inline void make_graph() {
    size = 0;
    vertex.assign(h, vector<int>(w, NIL));
    for (int y = 0; y < h; ++y)
        for (int x = 0; x < w; ++x)
            if (!field[y][x])
                vertex[y][x] = size++;
    edge.assign(h * w, vector<int>());
    for (int y = 0; y < h; ++y)
        for (int x = 0; x < w; ++x) {
            if (vertex[y][x] == NIL)
                continue;
            for (const auto &d : NEXT) {
                int ny = y + d[0];
                int nx = x + d[1];
                if (ny < 0 || h <= ny || nx < 0 || w <= nx)
                    continue;
                if (vertex[ny][nx] == NIL)
                    continue;
                edge[vertex[y][x]].push_back(vertex[ny][nx]);
            }
        }
}

inline void reachability(const int &from, bitset<N> &visited) {
    visited.set(from);
    for (const auto &to : edge[from])
        if (!visited.test(to))
            reachability(to, visited);
}

inline bool cut_vertex(const int &from) {
    auto dup = visited;
    dup.set(from);
    for (const auto &to : edge[from]) {
        if (dup[to])
            continue;
        reachability(to, dup);
        if (dup.count() != size)
            return true;
    }
    return false;
}

inline bool dfs(const int &start, int from) {
    unsigned long long m = visited.to_ullong() * N + from;
    if (memo.count(m))
        return false;
    memo.insert(m);
    if (cut_vertex(from))
        return false;
    for (int u = 0; u < size; ++u) {
        if (u == from || visited.test(u))
            continue;
        int degree = 0;
        for (const auto &v : edge[u])
            if (v == start || !visited.test(v))
                ++degree;
        if (degree < 2)
            return false;
    }
    visited.set(from);
    for (const auto &to : edge[from]) {
        if (to == start && visited.count() == size)
            return true;
        if (visited[to])
            continue;
        if (dfs(start, to))
            return true;
    }
    visited.reset(from);
    return false;
}

bool solve() {
    visited.reset();
    make_graph();
    memo.clear();
    for (int y = 0; y < h; ++y)
        for (int x = 0; x < w; ++x)
            if (!field[y][x])
                return dfs(vertex[y][x], vertex[y][x]);
    return false;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    while (cin >> w >> h, w | h) {
        field.assign(h, vector<int>(w));
        for (auto &line : field)
            for (auto &v : line)
                cin >> v;
        cout << (solve() ? "Yes\n" : "No\n");
    }
    return 0;
}
accuracy: 1
time_ms: 550
memory_kb: 27392
final_rank: 9

code_snippet: #include <algorithm>
#include <bitset>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
set<unsigned long long> memo;
void make_graph() {
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex.assign(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge.assign(h * w, vector<int>());
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[0];
        int nx = x + d[1];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(int from, bitset<N> &visited) {
  visited.set(from);
  for (const auto &to : edge[from])
    if (!visited[to])
      reachability(to, visited);
}
bool cut_vertex(int from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    if (dup.count() != size)
      return true;
  }
  return false;
}
bool dfs(int start, int from) {
  unsigned long long m = (unsigned long long)visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  if (cut_vertex(from))
    return false;
  for (int u = 0; u < size; ++u) {
    if (u == from || visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited.reset();
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  while (cin >> w >> h, w | h) {
    field.assign(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes\n" : "No\n");
  }
}
accuracy: 1
time_ms: 530
memory_kb: 29168
final_rank: 13

code_snippet: #include <algorithm>
#include <bitset>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
set<unsigned long long> memo;
void make_graph() {
  enum { Y, X };
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex = vector<vector<int>>(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge = vector<vector<int>>(h * w, vector<int>());
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[Y];
        int nx = x + d[X];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(int from, bitset<N> &visited) {
  visited.set(from);
  for (const auto &to : edge[from])
    if (!visited[to])
      reachability(to, visited);
}
bool cut_vertex(int from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    return dup.count() != size;
  }
  return dup.count() != size;
}
bool dfs(int start, int from) {
  unsigned long long m = visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  bool deadend = true;
  for (const auto &v : edge[start])
    deadend &= visited[v];
  if (deadend)
    return false;
  if (cut_vertex(from))
    return false;
  for (int u = 0; u < size; ++u) {
    if (u == from)
      continue;
    if (visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited = bitset<N>(0);
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  while (cin >> w >> h, w | h) {
    field = vector<vector<int>>(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 290
memory_kb: 17528
final_rank: 7

code_snippet: #include <algorithm>
#include <bitset>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
set<unsigned long long> memo;
void make_graph() {
  enum { Y, X };
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex = vector<vector<int>>(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge = vector<vector<int>>(h * w, vector<int>());
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[Y];
        int nx = x + d[X];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(const int &from, bitset<N> &visited) {
  visited.set(from);
  for (const auto &to : edge[from])
    if (!visited[to])
      reachability(to, visited);
}
bool cut_vertex(const int &from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    return dup.count() != size;
  }
  return dup.count() != size;
}
bool dfs(const int &start, int from) {
  unsigned long long m = visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  if (cut_vertex(from))
    return false;
  for (int u = 0; u < size; ++u) {
    if (u == from)
      continue;
    if (visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited = bitset<N>(0);
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  while (cin >> w >> h, w | h) {
    field = vector<vector<int>>(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 550
memory_kb: 29056
final_rank: 14

code_snippet: #include <algorithm>
#include <bitset>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
set<unsigned long long> memo;
void make_graph() {
  enum { Y, X };
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex = vector<vector<int>>(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge = vector<vector<int>>(h * w, vector<int>());
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[Y];
        int nx = x + d[X];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(const int &from, bitset<N> &visited) {
  visited.set(from);
  for (const auto &to : edge[from])
    if (!visited[to])
      reachability(to, visited);
}
bool cut_vertex(const int &from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    if (dup.count() != size)
      return true;
  }
  return false;
}
bool dfs(const int &start, int from) {
  unsigned long long m = visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  if (cut_vertex(from))
    return false;
  for (int u = 0; u < size; ++u) {
    if (u == from || visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited = bitset<N>(0);
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  while (cin >> w >> h, w | h) {
    field.assign(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 530
memory_kb: 29052
final_rank: 12

code_snippet: #include <algorithm>
#include <bitset>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
set<unsigned long long> memo;
void make_graph() {
  enum { Y, X };
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex = vector<vector<int>>(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge = vector<vector<int>>(size, vector<int>());
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[Y];
        int nx = x + d[X];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(const int &from, bitset<N> &visited) {
  visited.set(from);
  for (const auto &to : edge[from])
    if (!visited[to])
      reachability(to, visited);
}
bool cut_vertex(const int &from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    return dup.count() != size;
  }
  return dup.count() != size;
}
bool dfs(const int &start, int from) {
  unsigned long long m = visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  if (cut_vertex(from))
    return false;
  for (int u = 0; u < size; ++u) {
    if (u == from)
      continue;
    if (visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited = bitset<N>(0);
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  while (cin >> w >> h, w | h) {
    field = vector<vector<int>>(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes" : "No") << '\n';
  }
  return 0;
}
accuracy: 1
time_ms: 560
memory_kb: 29012
final_rank: 16

code_snippet: #include <algorithm>
#include <bitset>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
set<unsigned long long> memo;
void make_graph() {
  enum { Y, X };
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex = vector<vector<int>>(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge = vector<vector<int>>(size, vector<int>());
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[Y];
        int nx = x + d[X];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(const int &from, bitset<N> &visited) {
  visited.set(from);
  for (const auto &to : edge[from])
    if (!visited[to])
      reachability(to, visited);
}
bool cut_vertex(const int &from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    return dup.count() != size;
  }
  return dup.count() != size;
}
bool dfs(const int &start, int from) {
  unsigned long long m = visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  if (cut_vertex(from))
    return false;
  for (int u = 0; u < size; ++u) {
    if (u == from)
      continue;
    if (visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited = bitset<N>(0);
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  while (cin >> w >> h, w | h) {
    field = vector<vector<int>>(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 540
memory_kb: 29176
final_rank: 17

code_snippet: #pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <algorithm>
#include <bitset>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
set<unsigned long long> memo;
void make_graph() {
  enum { Y, X };
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex = vector<vector<int>>(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge = vector<vector<int>>(h * w, vector<int>());
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[Y];
        int nx = x + d[X];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(const int &from, bitset<N> &visited) {
  visited.set(from);
  for (const auto &to : edge[from])
    if (!visited[to])
      reachability(to, visited);
}
bool cut_vertex(const int &from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    return dup.count() != size;
  }
  return dup.count() != size;
}
bool dfs(const int &start, int from) {
  unsigned long long m = visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  if (cut_vertex(from))
    return false;
  for (int u = 0; u < size; ++u) {
    if (u == from)
      continue;
    if (visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited = bitset<N>(0);
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  while (cin >> w >> h, w | h) {
    field = vector<vector<int>>(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 550
memory_kb: 29152
final_rank: 19

code_snippet: #include <algorithm>
#include <bitset>
#include <iostream>
#include <unordered_set>
#include <vector>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
unordered_set<unsigned long long> memo;
void make_graph() {
  enum { Y, X };
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex = vector<vector<int>>(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge = vector<vector<int>>(h * w, vector<int>());
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[Y];
        int nx = x + d[X];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(const int &from, bitset<N> &visited) {
  visited.set(from);
  for (const auto &to : edge[from])
    if (!visited[to])
      reachability(to, visited);
}
bool cut_vertex(const int &from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    return dup.count() != size;
  }
  return dup.count() != size;
}
bool dfs(const int &start, int from) {
  unsigned long long m = visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  if (cut_vertex(from))
    return false;
  for (int u = 0; u < size; ++u) {
    if (u == from)
      continue;
    if (visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited = bitset<N>(0);
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  while (cin >> w >> h, w | h) {
    field = vector<vector<int>>(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 540
memory_kb: 27632
final_rank: 10

code_snippet: #pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#include <algorithm>
#include <bitset>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
set<unsigned long long> memo;
void make_graph() {
  enum { Y, X };
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex = vector<vector<int>>(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge = vector<vector<int>>(h * w, vector<int>());
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[Y];
        int nx = x + d[X];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(const int &from, bitset<N> &visited) {
  visited.set(from);
  for (const auto &to : edge[from])
    if (!visited[to])
      reachability(to, visited);
}
bool cut_vertex(const int &from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    return dup.count() != size;
  }
  return dup.count() != size;
}
bool dfs(const int &start, int from) {
  unsigned long long m = visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  if (cut_vertex(from))
    return false;
  for (int u = 0; u < size; ++u) {
    if (u == from)
      continue;
    if (visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited = bitset<N>(0);
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  while (cin >> w >> h, w | h) {
    field = vector<vector<int>>(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 560
memory_kb: 29088
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int N = 49;
int w, h;
vector<vector<int>> field;
int size;
vector<vector<int>> vertex;
vector<vector<int>> edge;
bitset<N> visited;
set<unsigned long long> memo;
void make_graph() {
  enum { Y, X };
  const int NEXT[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
  const int NIL = -1;
  size = 0;
  vertex = vector<vector<int>>(h, vector<int>(w, NIL));
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        vertex[y][x] = size++;
  edge = vector<vector<int>>(h * w, vector<int>());
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x) {
      if (vertex[y][x] == NIL)
        continue;
      for (const auto &d : NEXT) {
        int ny = y + d[Y];
        int nx = x + d[X];
        if (ny < 0 || h <= ny || nx < 0 || w <= nx)
          continue;
        if (vertex[ny][nx] == NIL)
          continue;
        edge[vertex[y][x]].push_back(vertex[ny][nx]);
      }
    }
};
void reachability(const int &from, bitset<N> &visited) {
  visited.set(from);
  for (const auto &to : edge[from])
    if (!visited[to])
      reachability(to, visited);
}
bool cut_vertex(const int &from) {
  auto dup = visited;
  dup.set(from);
  for (const auto &to : edge[from]) {
    if (dup[to])
      continue;
    reachability(to, dup);
    return dup.count() != size;
  }
  return dup.count() != size;
}
bool dfs(const int &start, int from) {
  unsigned long long m = visited.to_ullong() * N + from;
  if (memo.count(m))
    return false;
  memo.insert(m);
  if (cut_vertex(from))
    return false;
  for (int u = 0; u < size; ++u) {
    if (u == from)
      continue;
    if (visited[u])
      continue;
    int degree = 0;
    for (const auto &v : edge[u])
      if (v == start || !visited[v])
        ++degree;
    if (degree < 2)
      return false;
  }
  visited.set(from);
  for (const auto &to : edge[from]) {
    if (to == start && visited.count() == size)
      return true;
    if (visited[to])
      continue;
    if (dfs(start, to))
      return true;
  }
  visited.reset(from);
  return false;
}
bool solve() {
  visited = bitset<N>(0);
  make_graph();
  memo.clear();
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (!field[y][x])
        return dfs(vertex[y][x], vertex[y][x]);
  return false;
}
int main() {
  while (cin >> w >> h, w | h) {
    field = vector<vector<int>>(h, vector<int>(w));
    for (auto &line : field)
      for (auto &v : line)
        cin >> v;
    cout << (solve() ? "Yes" : "No") << endl;
  }
}
accuracy: 1
time_ms: 550
memory_kb: 29072
final_rank: 15

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>
#include <set>
using namespace std;

typedef pair<int, int> Pii;


Pii dx_dy_array[] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };

bool is_degree_ok(int w, int h, const vector<vector<int>>& grid, vector<vector<int>>& degree_grid, set<Pii>& exception_set) {
	for (int y = 0; y < h; y++) {
		fill(degree_grid[y].begin(), degree_grid[y].end(), 0);
	}

	for (int y = 0; y < h; y++) {
		for (int x = 0; x < w; x++) {
			if (exception_set.count({ x, y }) > 0) {
				continue;
			}

			if (grid[y][x] == 0) {
				for (Pii dx_dy : dx_dy_array) {
					int nx = x + dx_dy.first;
					int ny = y + dx_dy.second;

					if (nx < 0 || nx >= w || ny < 0 || ny >= h) {
						continue;
					}

					if (grid[ny][nx] == 0) {
						degree_grid[y][x]++;
					}
				}
			}
		}
	}

	for (int y = 0; y < h; y++) {
		for (int x = 0; x < w; x++) {
			if (degree_grid[y][x] == 1) {
				return false;
			}
		}
	}
	return true;
}

bool backtrack(int w, int h, int sx, int sy, int cx, int cy, vector<vector<int>>& is_visited_grid, vector<vector<int>>& degree_grid) {
	bool is_end = true;

	for (Pii dx_dy : dx_dy_array) {
		int nx = cx + dx_dy.first;
		int ny = cy + dx_dy.second;

		if (nx < 0 || nx >= w || ny < 0 || ny >= h) {
			continue;
		}

		if (is_visited_grid[ny][nx] == 0) {
			is_end = false;

			set<Pii> exception_set;
			
			exception_set.insert({ sx, sy });
			exception_set.insert({ nx, ny });

			for (Pii ddx_ddy : dx_dy_array) {
				int nsx = sx + ddx_ddy.first;
				int nsy = sy + ddx_ddy.second;

				if (0 <= nsx && nsx < w && 0 <= nsy && nsy < h) {
					exception_set.insert({ nsx, nsy });
				}
			}

			if (!is_degree_ok(w, h, is_visited_grid, degree_grid, exception_set)) {
				continue;
			}

			is_visited_grid[ny][nx] = 1;
			if (backtrack(w, h, sx, sy, nx, ny, is_visited_grid, degree_grid)) {
				return true;
			}
			else {
				is_visited_grid[ny][nx] = 0;
			}
		}
	}
	
	if (!is_end) {
		return false;
	}

	for (Pii dx_dy : dx_dy_array) {
		int nx = cx + dx_dy.first;
		int ny = cy + dx_dy.second;

		if (nx == sx && ny == sy) {
			for (int y = 0; y < h; y++) {
				for (int x = 0; x < w; x++) {
					if (is_visited_grid[y][x] == 0) {
						return false;
					}
				}
			}
			return true;
		}
	}

	return false;
}


bool is_ok(int w, int h, const vector<vector<int>>& grid) {
	int sx = -1;
	int sy = -1;
	int num_space_cells = 0;
	
	for (int y = 0; y < h; y++) {
		for (int x = 0; x < w; x++) {
			if (grid[y][x] == 0) {
				num_space_cells++;
				if (sx < 0) {
					sx = x;
					sy = y;
				}
			}
		}
	}

	if (sx < 0 || num_space_cells % 2 != 0) {
		return false;
	}

	vector<vector<int>> degree_grid(h, vector<int>(w));
	set<Pii> exception_set;

	if (!is_degree_ok(w, h, grid, degree_grid, exception_set)) {
		return false;
	}

	vector<vector<int>> is_visited_grid = grid;
	
	is_visited_grid[sy][sx] = 1;
	return backtrack(w, h, sx, sy, sx, sy, is_visited_grid, degree_grid);
}

int main() {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		int w = 0;
		int h = 0;

		cin >> w >> h;
		if (w == 0 && h == 0) {
			break;
		}

		vector<vector<int>> grid(h, vector<int>(w));

		for (int y = 0; y < h; y++) {
			for (int x = 0; x < w; x++) {
				cin >> grid[y][x];
			}
		}

		cout << (is_ok(w, h, grid) ? "Yes" : "No") << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 880
memory_kb: 3388
final_rank: 6

code_snippet: #define READ_FROM_FILE 0

#if READ_FROM_FILE
#include <fstream>
#endif

#include <iostream>
#include <vector>
#include <set>
using namespace std;

typedef pair<int, int> Pii;


Pii dx_dy_array[] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };

bool is_degree_ok(int w, int h, const vector<vector<int>>& grid, vector<vector<int>>& degree_grid, set<Pii>& exception) {
	for (int y = 0; y < h; y++) {
		fill(degree_grid[y].begin(), degree_grid[y].end(), 0);
	}

	for (int y = 0; y < h; y++) {
		for (int x = 0; x < w; x++) {
			if (exception.count({ x, y }) > 0) {
				continue;
			}

			if (grid[y][x] == 0) {
				for (Pii dx_dy : dx_dy_array) {
					int nx = x + dx_dy.first;
					int ny = y + dx_dy.second;

					if (nx < 0 || nx >= w || ny < 0 || ny >= h) {
						continue;
					}

					if (grid[ny][nx] == 0) {
						degree_grid[y][x]++;
					}
				}
			}
		}
	}

	for (int y = 0; y < h; y++) {
		for (int x = 0; x < w; x++) {
			if (degree_grid[y][x] == 1) {
				return false;
			}
		}
	}
	return true;
}

bool backtrack(int w, int h, int sx, int sy, int cx, int cy, vector<vector<int>>& is_visited_grid, vector<vector<int>>& degree_grid) {
	bool is_end = true;

	for (Pii dx_dy : dx_dy_array) {
		int nx = cx + dx_dy.first;
		int ny = cy + dx_dy.second;

		if (nx < 0 || nx >= w || ny < 0 || ny >= h) {
			continue;
		}

		if (is_visited_grid[ny][nx] == 0) {
			is_end = false;

			set<Pii> exception;
			
			exception.insert({ sx, sy });
			exception.insert({ nx, ny });

			for (Pii ddx_ddy : dx_dy_array) {
				int nsx = sx + ddx_ddy.first;
				int nsy = sy + ddx_ddy.second;

				if (0 <= nsx && nsx < w && 0 <= nsy && nsy < h) {
					exception.insert({ nsx, nsy });
				}
			}

			if (!is_degree_ok(w, h, is_visited_grid, degree_grid, exception)) {
				continue;
			}

			is_visited_grid[ny][nx] = 1;
			if (backtrack(w, h, sx, sy, nx, ny, is_visited_grid, degree_grid)) {
				return true;
			}
			else {
				is_visited_grid[ny][nx] = 0;
			}
		}
	}
	
	if (!is_end) {
		return false;
	}

	for (Pii dx_dy : dx_dy_array) {
		int nx = cx + dx_dy.first;
		int ny = cy + dx_dy.second;

		if (nx == sx && ny == sy) {
			for (int y = 0; y < h; y++) {
				for (int x = 0; x < w; x++) {
					if (is_visited_grid[y][x] == 0) {
						return false;
					}
				}
			}
			return true;
		}
	}

	return false;
}


bool is_ok(int w, int h, const vector<vector<int>>& grid) {
	int sx = -1;
	int sy = -1;
	int num_space_cells = 0;
	
	for (int y = 0; y < h; y++) {
		for (int x = 0; x < w; x++) {
			if (grid[y][x] == 0) {
				num_space_cells++;
				if (sx < 0) {
					sx = x;
					sy = y;
				}
			}
		}
	}

	if (sx < 0 || num_space_cells % 2 != 0) {
		return false;
	}

	vector<vector<int>> degree_grid(h, vector<int>(w));
	set<Pii> exception;

	if (!is_degree_ok(w, h, grid, degree_grid, exception)) {
		return false;
	}

	vector<vector<int>> is_visited_grid = grid;
	
	is_visited_grid[sy][sx] = 1;
	return backtrack(w, h, sx, sy, sx, sy, is_visited_grid, degree_grid);
}

int main() {
#if READ_FROM_FILE
	ifstream ifs("test0.txt");
	cin.rdbuf(ifs.rdbuf());
#endif

	while (true) {
		int w = 0;
		int h = 0;

		cin >> w >> h;
		if (w == 0 && h == 0) {
			break;
		}

		vector<vector<int>> grid(h, vector<int>(w));

		for (int y = 0; y < h; y++) {
			for (int x = 0; x < w; x++) {
				cin >> grid[y][x];
			}
		}

		cout << (is_ok(w, h, grid) ? "Yes" : "No") << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 870
memory_kb: 3076
final_rank: 5

code_snippet: #include<iostream>
#include<algorithm>
using namespace std;
int H,W;
int d[5]={0,1,0,-1};
int sx,sy;
int c[10][10];
int deg[10][10];
bool dfs(int x,int y,int rest)
{
	for(int i=0;i<H;i++)for(int j=0;j<W;j++)if(!c[i][j])
	{
		if(abs(sx-i)+abs(sy-j)<=1)continue;
		if(abs(x-i)+abs(y-j)<=1)continue;
		if(deg[i][j]<=1)return false;
	}
	for(int r=0;r<4;r++)
	{
		int tx=x+d[r],ty=y+d[r+1];
		if(tx<0||ty<0||tx>=H||ty>=W)continue;
		if(sx==tx&&sy==ty)
		{
			if(rest==0)return true;
		}
		else if(!c[tx][ty])
		{
			for(int nr=0;nr<4;nr++)
			{
				int ttx=tx+d[nr],tty=ty+d[nr+1];
				if(ttx>=0&&tty>=0&&ttx<H&&tty<W)deg[ttx][tty]--;
			}
			c[tx][ty]=1;
			if(dfs(tx,ty,rest-1))return true;
			c[tx][ty]=0;
			for(int nr=0;nr<4;nr++)
			{
				int ttx=tx+d[nr],tty=ty+d[nr+1];
				if(ttx>=0&&tty>=0&&ttx<H&&tty<W)deg[ttx][tty]++;
			}
		}
	}
	return false;
}
main()
{
	while(cin>>W>>H,H)
	{
		sx=sy=-1;
		int cnt=0;
		for(int i=0;i<H;i++)for(int j=0;j<W;j++)
		{
			cin>>c[i][j];
			if(!c[i][j])
			{
				sx=i;
				sy=j;
				cnt++;
			}
		}
		if(sx<0||cnt%2==1)
		{
			cout<<"No"<<endl;
			continue;
		}
		c[sx][sy]=1;
		for(int i=0;i<H;i++)for(int j=0;j<W;j++)
		{
			deg[i][j]=0;
			if(!c[i][j])
			{
				for(int r=0;r<4;r++)
				{
					int x=i+d[r],y=j+d[r+1];
					if(x>=0&&y>=0&&x<H&&y<W&&!c[x][y])deg[i][j]++;
				}
			}
		}
		cout<<(dfs(sx,sy,cnt-1)?"Yes":"No")<<endl;
	}
}
accuracy: 1
time_ms: 220
memory_kb: 3096
final_rank: 1

code_snippet: #include<iostream>
#include<algorithm>
using namespace std;
int H,W;
int d[5]={0,1,0,-1};
int sx,sy;
int c[10][10];
int deg[10][10];
bool dfs(int x,int y,int rest)
{
	for(int i=0;i<H;i++)for(int j=0;j<W;j++)if(!c[i][j])
	{
		if(abs(sx-i)+abs(sy-j)<=1)continue;
		if(abs(x-i)+abs(y-j)<=2)continue;
		if(deg[i][j]<=1)return false;
	}
	for(int r=0;r<4;r++)
	{
		int tx=x+d[r],ty=y+d[r+1];
		if(tx<0||ty<0||tx>=H||ty>=W)continue;
		if(sx==tx&&sy==ty)
		{
			if(rest==0)return true;
		}
		else if(!c[tx][ty])
		{
			for(int nr=0;nr<4;nr++)
			{
				int ttx=tx+d[nr],tty=ty+d[nr+1];
				if(ttx>=0&&tty>=0&&ttx<H&&tty<W)deg[ttx][tty]--;
			}
			c[tx][ty]=1;
			if(dfs(tx,ty,rest-1))return true;
			c[tx][ty]=0;
			for(int nr=0;nr<4;nr++)
			{
				int ttx=tx+d[nr],tty=ty+d[nr+1];
				if(ttx>=0&&tty>=0&&ttx<H&&tty<W)deg[ttx][tty]++;
			}
		}
	}
	return false;
}
main()
{
	while(cin>>W>>H,H)
	{
		sx=sy=-1;
		int cnt=0;
		for(int i=0;i<H;i++)for(int j=0;j<W;j++)
		{
			cin>>c[i][j];
			if(!c[i][j])
			{
				sx=i;
				sy=j;
				cnt++;
			}
		}
		if(sx<0||cnt%2==1)
		{
			cout<<"No"<<endl;
			continue;
		}
		c[sx][sy]=1;
		for(int i=0;i<H;i++)for(int j=0;j<W;j++)
		{
			deg[i][j]=0;
			if(!c[i][j])
			{
				for(int r=0;r<4;r++)
				{
					int x=i+d[r],y=j+d[r+1];
					if(x>=0&&y>=0&&x<H&&y<W&&!c[x][y])deg[i][j]++;
				}
			}
		}
		cout<<(dfs(sx,sy,cnt-1)?"Yes":"No")<<endl;
	}
}
accuracy: 1
time_ms: 630
memory_kb: 3060
final_rank: 3

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


#define SIZE 10

enum DIR{
	N,
	W,
	E,
	S
};

enum Type{
	N_S,
	W_E,
	W_S,
	W_N,
	N_E,
	S_E,
	UNDEFINED,
};

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


bool FLG;
int h,w;
int first_row,first_col;
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
int base_map[SIZE][SIZE],rest[SIZE][SIZE];
int sum_rest; //未確定出次の個数
Type table[SIZE][SIZE];
bool check[6][4] = {{true,false,false,true},//N_S
					 {false,true,true,false}, //W_E
					 {false,true,false,true},//W_S
					 {true,true,false,false},//W_N
					 {true,false,true,false},//N_E
					 {false,false,true,true} //S_E
					 };
Type type_array[7] = {N_S,W_E,W_S,W_N,N_E,S_E,UNDEFINED};
vector<LOC> V;


bool rangeCheck(int row,int col){

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

void recursive(int row,int col){

	if(FLG)return;

	if(row == h){

		if(sum_rest == 0){

			FLG = true;
		}

		return;
	}

	int next_row,next_col;
	if(col == w-1){

		next_row = row+1;
		next_col = 0;
	}else{

		next_row = row;
		next_col = col+1;
	}

	if(base_map[row][col] == 1){ //石マス

		recursive(next_row,next_col);
		return;
	}

	//空白マス

	if((row != first_row || col != first_col) && sum_rest == 0){
		return; //非初セル&&未確定出次が残っていないなら閉路が発生しているはず
	}

	for(int i = 0; i < 6; i++){ //配置パネルを走査
		int adj_row[2],adj_col[2];

		switch(type_array[i]){
		case N_S:

			adj_row[0] = row-1;
			adj_col[0] = col;

			adj_row[1] = row+1;
			adj_col[1] = col;

			break;
		case W_E:

			adj_row[0] = row;
			adj_col[0] = col-1;

			adj_row[1] = row;
			adj_col[1] = col+1;

			break;
		case W_S:

			adj_row[0] = row;
			adj_col[0] = col-1;

			adj_row[1] = row+1;
			adj_col[1] = col;

			break;
		case W_N:

			adj_row[0] = row;
			adj_col[0] = col-1;

			adj_row[1] = row-1;
			adj_col[1] = col;

			break;
		case N_E:

			adj_row[0] = row-1;
			adj_col[0] = col;

			adj_row[1] = row;
			adj_col[1] = col+1;

			break;
		case S_E:

			adj_row[0] = row+1;
			adj_col[0] = col;

			adj_row[1] = row;
			adj_col[1] = col+1;

			break;
		}

		//出次先が範囲外または石マスならSKIP
		if(!rangeCheck(adj_row[0],adj_col[0])||!rangeCheck(adj_row[1],adj_col[1])||
				(base_map[adj_row[0]][adj_col[0]] == 1)||(base_map[adj_row[1]][adj_col[1]] == 1))continue;


		if(rangeCheck(row-1,col) && check[table[row-1][col]][S] && !check[i][N])continue; //上のS出次を満たせないなら刈る
		if(rangeCheck(row,col-1) && check[table[row][col-1]][E] && !check[i][W])continue; //左のE出次を満たせないなら刈る


		int rest_add = 0;  //sum_restに足した分
		int rest_minus = 0; //sum_restから引いた分
		bool is_OK = true;

		//パネルの整合性チェック
		switch(i){
		case N_S: //N_S

			//上のパネルのS
			if(!check[table[adj_row[0]][adj_col[0]]][S]){

				is_OK = false;
			}else{

				//sum_restは変動なし
			}

			break;
		case W_E:

			//左のパネルのE
			if(!check[table[adj_row[0]][adj_col[0]]][E]){

				is_OK = false;
			}else{

				//sum_restは変動なし
			}

			break;
		case W_S:

			//左のパネルのE
			if(!check[table[adj_row[0]][adj_col[0]]][E]){

				is_OK = false;
			}else{

				//sum_restは変動なし
			}

			break;
		case W_N:

			//左のパネルのEと上のパネルのS
			if(!check[table[adj_row[0]][adj_col[0]]][E]||!check[table[adj_row[1]][adj_col[1]]][S]){

				is_OK = false;
			}else{

				sum_rest -= 2;
				rest_minus = 2;
			}

			break;
		case N_E:

			//上のパネルのS
			if(!check[table[adj_row[0]][adj_col[0]]][S]){

				is_OK = false;
			}else{

				//sum_restは変動なし
			}

			break;
		case S_E: //S_E

			sum_rest += 2;
			rest_add = 2;

			break;
		}


		if(!is_OK){

			continue;
		}

		table[row][col] = type_array[i];

		recursive(next_row,next_col);

		sum_rest -= rest_add;
		sum_rest += rest_minus;
	}
}

void func(){

	V.clear();
	first_row = -1;

	for(int row = 0; row < h; row++){
		for(int col = 0; col < w; col++){

			scanf("%d",&base_map[row][col]);
			if(base_map[row][col] == 0){

				V.push_back(LOC(row,col));
				if(first_row == -1){
					first_row = row;
					first_col = col;
				}
			}
		}
	}
	if(V.size() == 0){

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

	sum_rest = 0;
	FLG = false;

	for(int row = 0; row < h; row++){
		for(int col = 0; col < w; col++){

			table[row][col] = UNDEFINED;
		}
	}

	recursive(0,0);

	if(FLG){

		printf("Yes\n");

	}else{

		printf("No\n");
	}
}

int main(){

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

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 630
memory_kb: 3068
final_rank: 4

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

array<int, 4> dy{-1, 1, 0, 0}, dx{0, 0, -1, 1};
array<int, 6> A{3, 5, 6, 9, 10, 12};
struct Solution {
    int h, w, cnt;
    vector<vector<int>> G, used;
    Solution(int h, int w) : h(h), w(w), G(h, vector<int>(w, 0)), used(h, vector<int>(w, 0)), cnt(0) {};

    void dfs(int y, int x, int &cnt2){
        used[y][x] = 1;
        cnt2++;
        for (int k = 0; k < 4; ++k) {
            if(G[y][x] & (1 << k) && !used[y+dy[k]][x+dx[k]]){
                dfs(y+dy[k], x+dx[k], cnt2);
            }
        }
    }
    bool rec(int y, int x){
        if(y == h){
            for (int i = 0; i < h; ++i) {
                for (int j = 0; j < w; ++j) {
                    used[i][j] = 0;
                }
            }
            for (int i = 0; i < h; ++i) {
                for (int j = 0; j < w; ++j) {
                    if(G[i][j]){
                        int c = 0;
                        dfs(i, j, c);
                        return c == cnt;
                    }
                }
            }
            return false;
        }
        if(!G[y][x]){
            if(y && G[y-1][x] & 2) return false;
            if(x && G[y][x-1] & 8) return false;
            if(rec(y+(x == w-1), (x+1)%w)) return true;
        }else {
            for (int k = 0; k < 6; ++k) {
                if(y && ((G[y-1][x] >> 1)^A[k])&1) continue;
                if(x && ((G[y][x-1] >> 3)^(A[k] >> 2))&1) continue;
                if(!y && A[k]&1) continue;
                if(y == h-1 && A[k]&2) continue;
                if(!x && A[k]&4) continue;
                if(x == w-1 && A[k]&8) continue;
                G[y][x] = A[k];
                if(rec(y+(x == w-1), (x+1)%w)) return true;
            }
            G[y][x] = 1;
        }
        return false;
    }
};

void solve(int w, int h){
    Solution S(h, w);
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            cin >> S.G[i][j];
            S.G[i][j] ^= 1;
            S.cnt += S.G[i][j];
        }
    }
    puts((S.rec(0, 0)) ? "Yes" : "No");
}

int main() {
    int w, h;
    while(cin >> w >> h, w){
        solve(w, h);
    }
    return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 2948
final_rank: 2

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

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

int H, W, sum;

bool dfs(int x, int y, int sx, int sy, int cnt, vector< vector<int> > &degs, vector< vector<int> > &board) {
    if(false) {
        fprintf(stderr, "x = %d, y = %d, cnt = %d\n", x, y, cnt);
        for(int i=0; i<H; i++) {
            for(int j=0; j<W; j++) {
                if(i == x and j == y) fprintf(stderr, "* ");
                else fprintf(stderr, "%d ", board[i][j]);
            }
            fprintf(stderr, "\n");
        }
    }
    
    if(x == sx and y == sy) {
        if(cnt != sum) return cnt == 0;
    }
    else if(cnt == 0) return false;
    
    for(int k=0; k<4; k++) {
        int nx = x + dx[k], ny = y + dy[k];
        if(nx < 0 or nx >= H or ny < 0 or ny >= W) continue;
        if(board[nx][ny] == 1) continue;
        for(int i=0; i<4; i++) {
            int gx = nx + dx[i], gy = ny + dy[i];
            if(gx < 0 or gx >= H or gy < 0 or gy >= W) continue;
            if(board[gx][gy] == 1) continue;
            degs[gx][gy]--;
        }

        bool ok = true;
        for(int i=0; i<H; i++) {
            for(int j=0; j<W; j++) {
                if(board[i][j] == 1) continue;
                {
                    int d = abs(sx - i) + abs(sy - j);
                    if(d <= 1) continue;
                }

                {
                    int d = abs(nx - i) + abs(ny - j);
                    if(d <= 1) continue;
                }

                if(degs[i][j] <= 1) {
                    // fprintf(stderr, "[x = %d, y = %d, nx = %d, ny = %d] false: i = %d, j = %d\n", x, y, nx, ny, i, j);
                    ok = false;
                    i = H, j = W;
                }
            }
        }

        if(ok) {
            board[nx][ny] = 1;
            bool b = dfs(nx, ny, sx, sy, cnt - 1, degs, board);
            board[nx][ny] = 0;
            if(b) return true;
        }

        for(int i=0; i<4; i++) {
            int gx = nx + dx[i], gy = ny + dy[i];
            if(gx < 0 or gx >= H or gy < 0 or gy >= W) continue;
            if(board[gx][gy] == 1) continue;
            degs[gx][gy]++;
        }
    }
    return false;
}

int solve_testcase() {
    cin >> W >> H;
    if(W == 0 and H == 0) return 1;
    
    vector< vector<int> > board(H, vector<int>(W));
    vector< vector<int> > degs(H, vector<int>(W));
    
    int cnt = 0, deg0 = 0, deg1 = 0, sx = -1, sy = -1;
    for(int i=0; i<H; i++) {
        for(int j=0; j<W; j++) {
            cin >> board[i][j];
            if(board[i][j] == 0) {
                cnt++;
                sx = i, sy = j;
            }
        }
    }
    for(int i=0; i<H; i++) {
        for(int j=0; j<W; j++) {
            if(board[i][j] == 1) continue;
            int deg = 0;
            for(int k=0; k<4; k++) {
                int x = i + dx[k], y = j + dy[k];
                if(x < 0 or x >= H or y < 0 or y >= W) continue;
                if(board[x][y] == 1) continue;
                deg++;
            }
            degs[i][j] = deg;

            if(deg == 0) deg0++;
            if(deg == 1) deg1++;
        }
    }

    sum = cnt;
    bool ok = true;
    // ok &= (deg0 == 0 and deg1 == 0);
    // ok &= (cnt > 0 and cnt % 2 == 0);
    cout << (ok && dfs(sx, sy, sx, sy, cnt, degs, board) ? "Yes" : "No") << endl;
    return 0;
}

int main() {
    while(!solve_testcase());
    return 0;
}
accuracy: 1
time_ms: 4400
memory_kb: 3052
final_rank: 8