#include <bits/stdc++.h>
using namespace std;
const int inf = 2000000000;
static inline int Rint() {
  struct X {
    int dig[256];
    X() {
      for (int i = '0'; i <= '9'; ++i) dig[i] = 1;
      dig['-'] = 1;
    }
  };
  static X fuck;
  int s = 1, v = 0, c;
  for (; !fuck.dig[c = getchar()];)
    ;
  if (c == '-')
    s = 0;
  else if (fuck.dig[c])
    v = c ^ 48;
  for (; fuck.dig[c = getchar()]; v = v * 10 + (c ^ 48))
    ;
  return s ? v : -v;
}
template <typename T>
static inline void cmax(T& a, const T& b) {
  if (b > a) a = b;
}
template <typename T>
static inline void cmin(T& a, const T& b) {
  if (b < a) a = b;
}
const int maxn = 100005;
int data[1005][1005];
int cnt[1005][1005];
int rows[1005];
int cols[1005];
int ps_row[1005][1005];
int ps_col[1005][1005];
int deg[1005][1005];
int visited[1005][1005];
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int check(int n, int m) {
  int x0 = -1, y0 = -1;
  for (int i = (0); i < (n); ++i)
    for (int j = (0); j < (m); ++j)
      if (data[i][j] == 1) {
        x0 = i, y0 = j;
      }
  queue<int> q;
  q.push(x0), q.push(y0);
  visited[x0][y0] = 1;
  int s = 0;
  while (!q.empty()) {
    const int x = q.front();
    q.pop();
    const int y = q.front();
    q.pop();
    s += 1;
    for (int i = 0; i < 4; ++i) {
      const int nx = x + dir[i][0];
      const int ny = y + dir[i][1];
      if (nx < 0 || ny < 0) continue;
      if (nx >= n || ny >= m) continue;
      if (!data[nx][ny] || visited[nx][ny]) continue;
      visited[nx][ny] = 1;
      q.push(nx), q.push(ny);
    }
  }
  return s;
}
int check_edge_row(int i, int j, int k, int l) {
  int a = ps_row[i][j];
  int b = ps_row[i][k - 1];
  int total = b - a;
  if (total == l - 1) {
    return data[i][k] == 1 && data[i][j] == 1 ? 1 : -1;
  }
  if (total == 0) {
    return 0;
  }
  return -1;
}
int check_edge_col(int i, int j, int k, int l) {
  int a = ps_col[j][i];
  int b = ps_col[k - 1][i];
  int total = b - a;
  if (total == l - 1) {
    return data[j][i] == 1 && data[k][i] == 1 ? 1 : -1;
  }
  if (total == 0) {
    return 0;
  }
  return -1;
}
int tested[1005];
int main() {
  const int n = Rint(), m = Rint();
  int s = 0;
  int x0 = -1, y0 = -1;
  for (int i = (0); i < (n); ++i)
    for (int j = (0); j < (m); ++j) {
      data[i][j] = Rint(), s += data[i][j];
      if (x0 == -1 && data[i][j]) {
        x0 = i, y0 = j;
      }
    }
  if (check(n, m) != s) {
    puts("-1");
    return 0;
  }
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) {
      ps_row[i][j] = j == 0 ? data[i][j] : ps_row[i][j - 1] + data[i][j];
    }
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) {
      ps_col[i][j] = i == 0 ? data[i][j] : ps_col[i - 1][j] + data[i][j];
    }
  const int mink = 2, maxk = min(n - 1, m - 1);
  vector<int> ans;
  for (int k = mink; k <= maxk; ++k) {
    if (s < k + 1) continue;
    if (tested[k]) {
      ans.push_back(k);
      continue;
    }
    for (int i = 0; i < k; ++i)
      fill(cnt[i], cnt[i] + k, 0), fill(deg[i], deg[i] + k, 0);
    fill(rows, rows + k, 0);
    fill(cols, cols + k, 0);
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < m; ++j)
        if (data[i][j] == 1) {
          const int u = i % k;
          const int v = j % k;
          ++cnt[u][v];
          ++rows[u];
          ++cols[v];
        }
    int ok = 0;
    int sx = x0 % k;
    int sy = y0 % k;
    for (int x = sx; x <= sx; ++x)
      for (int y = sy; y <= sy; ++y)
        if (rows[x] + cols[y] - cnt[x][y] == s) {
          for (int u = x; u < n; u += k)
            for (int v = y; v < m; v += k) {
              if (v + k < m) {
                int t = check_edge_row(u, v, v + k, k);
                if (t == -1) goto finished;
                if (t == 1) ++deg[u][v], ++deg[u][v + k];
              } else {
                if (ps_row[u][m - 1] - ps_row[u][v] > 0) {
                  goto finished;
                }
              }
              if (u + k < n) {
                int t = check_edge_col(v, u, u + k, k);
                if (t == -1) goto finished;
                if (t == 1) ++deg[u][v], ++deg[u + k][v];
              } else {
                if (ps_col[n - 1][v] - ps_col[u][v] > 0) {
                  goto finished;
                }
              }
            }
          {
            int odd = 0;
            for (int u = x; u < n; u += k)
              for (int v = y; v < m; v += k) odd += deg[u][v] % 2 == 1;
            ok = odd == 0 || odd == 2;
          }
        finished:;
          if (ok) break;
        }
    if (ok) {
      ans.push_back(k);
    }
  }
  if (ans.empty())
    puts("-1");
  else {
    for (__typeof((ans).begin()) it = (ans).begin(); it != (ans).end(); ++it)
      printf("%d ", it);
    puts("");
  }
  return 0;
}
