#include <bits/stdc++.h>
using namespace std;
int maps[1005][1005], degree[1005][1005];
bool vis[1005][1005];
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int n, m;
int uprow[1005];
void init() {
  memset(maps, 0, sizeof(maps));
  memset(degree, 0, sizeof(degree));
  memset(vis, false, sizeof(vis));
}
bool inedges(int x, int y) {
  if (1 <= x && x <= n && 1 <= y && y <= m) return true;
  return false;
}
void dfs(int x, int y) {
  vis[x][y] = true;
  for (int i = 0; i < 4; i++) {
    int nx = x + dir[i][0];
    int ny = y + dir[i][1];
    if (!inedges(nx, ny)) continue;
    if (!maps[nx][ny]) continue;
    degree[nx][ny]++;
    if (vis[nx][ny]) continue;
    dfs(nx, ny);
  }
}
bool isConnected() {
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (maps[i][j] && !vis[i][j]) {
        if (cnt) return false;
        dfs(i, j);
        cnt++;
      }
    }
  }
  return true;
}
bool haveEuler() {
  int OddNodecnt = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      if (maps[i][j]) {
        if (degree[i][j] & 1) {
          OddNodecnt++;
        }
      }
    }
  }
  if (OddNodecnt == 0 || OddNodecnt == 2) return true;
  return false;
}
int gcd(int a, int b) {
  if (a == 0) return b;
  while (b) {
    int t = a % b;
    a = b;
    b = t;
  }
  return a;
}
void readmap() {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      cin >> maps[i][j];
    }
  }
}
bool isInsec(int x, int y) {
  int tmp[5];
  if (degree[x][y] == 1) return true;
  memset(tmp, 0, sizeof(tmp));
  for (int i = 0; i < 4; i++) {
    int nx = x + dir[i][0];
    int ny = y + dir[i][1];
    if (!inedges(nx, ny)) continue;
    if (maps[nx][ny]) tmp[i] = true;
  }
  if (tmp[1] || tmp[0]) {
    if (tmp[2] || tmp[3])
      return true;
    else
      return false;
  } else if (tmp[2] || tmp[3]) {
    if (tmp[1] || tmp[0])
      return true;
    else
      return false;
  }
}
int main() {
  readmap();
  if (!isConnected()) {
    cout << "-1" << endl;
    return 0;
  }
  if (!haveEuler()) {
    cout << "-1" << endl;
    return 0;
  }
  int leftcol = 0;
  memset(uprow, 0, sizeof(uprow));
  int maxlen = 0;
  for (int i = 1; i <= n; i++) {
    leftcol = 0;
    for (int j = 1; j <= n; j++) {
      if (!maps[i][j]) continue;
      if (!isInsec(i, j)) continue;
      ;
      if (leftcol && maps[i][j - 1]) maxlen = gcd(maxlen, j - leftcol);
      if (maps[i][j - 1] == 0) leftcol = j;
      if (uprow[j] && maps[i - 1][j]) maxlen = gcd(maxlen, i - uprow[j]);
      if (maps[i - 1][j] == 0) uprow[j] = i;
    }
  }
  if (maxlen < 2) {
    cout << "-1" << endl;
    return 0;
  }
  for (int i = 2; i < maxlen; i++) {
    if (maxlen % i == 0) cout << i << " ";
  }
  cout << maxlen << endl;
  return 0;
}
