#include <bits/stdc++.h>
using namespace std;
static int XMOV[4] = {-1, 1, 0, 0};
static int YMOV[4] = {0, 0, -1, 1};
int n, m, t, len, first;
int tbl[1001][1001];
inline void parse_pos(int p, int &x, int &y) {
  x = p / m;
  y = p % m;
}
inline int to_pos(int x, int y) { return x * m + y; }
inline bool valid(int x, int y) { return x >= 0 && x < n && y >= 0 && y < m; }
inline void get_len() {
  len = 0;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      if (tbl[i][j]) {
        int k = i - 1;
        while (k >= 0 && tbl[k][j]) {
          --k;
        }
        if (len < i - k - 1) {
          len = i - k - 1;
        }
        k = j - 1;
        while (k >= 0 && tbl[i][k]) {
          --k;
        }
        if (len < j - k - 1) {
          len = j - k - 1;
        }
      }
    }
  }
}
inline bool is_adj(int p, int l, int d) {
  int x, y;
  parse_pos(p, x, y);
  for (int i = 1; i < l; ++i) {
    x += XMOV[d];
    y += YMOV[d];
    if (!tbl[x][y]) {
      return false;
    }
  }
  return true;
}
inline bool is_good(int l) {
  int cnt = 0;
  vector<int> nod;
  vector<int> adj[n * m];
  int graph[n * m];
  int deg[n * m];
  memset(graph, 0, sizeof graph);
  memset(deg, 0, sizeof deg);
  graph[first] = 1;
  nod.push_back(first);
  queue<int> que;
  que.push(first);
  while (!que.empty()) {
    int p = que.front();
    que.pop();
    int a, b;
    parse_pos(p, a, b);
    for (int i = 0; i < 4; ++i) {
      int x = a + XMOV[i] * l;
      int y = b + YMOV[i] * l;
      if (valid(x, y) && tbl[x][y] && is_adj(p, l, i)) {
        int np = to_pos(x, y);
        adj[p].push_back(np);
        ++deg[p];
        ++cnt;
        if (!graph[np]) {
          nod.push_back(np);
          graph[np] = 1;
          que.push(np);
        }
      }
    }
  }
  int t1 = (cnt / 2) * (l - 1) + nod.size();
  if (t1 != t) {
    return false;
  }
  int odd = 0;
  for (int i = 0; i < (int)nod.size(); ++i) {
    if (deg[nod[i]] % 2) {
      ++odd;
    }
  }
  return odd < 3;
}
int main() {
  bool b = 1;
  cin >> n >> m;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      cin >> tbl[i][j];
      if (tbl[i][j]) {
        ++t;
        if (b) {
          first = to_pos(i, j);
          b = 0;
        }
      }
    }
  }
  get_len();
  vector<int> all;
  if (len > 1) {
    for (int i = 2; i <= len; ++i) {
      if (!(len % i) && is_good(i)) {
        all.push_back(i);
      }
    }
  }
  if (all.empty()) {
    cout << -1 << endl;
  } else {
    for (int i = 0; i < (int)all.size(); ++i) {
      if (i) cout << ' ';
      cout << all[i];
    }
    cout << endl;
  }
  return 0;
}
