#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int mxN = 1001;
int n, m;
int board[mxN][mxN];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
pair<int, int> st = {-1, -1};
bool flag[mxN][mxN];
int ones = 0;
bool inside(int a, int b) { return a >= 0 && a < n && b >= 0 && b < m; }
bool check(int k) {
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      flag[i][j] = false;
    }
  }
  queue<pair<int, int>> Q;
  Q.push({st.first, st.second});
  flag[st.first][st.second] = 1;
  int odd = 0;
  while (!Q.empty()) {
    auto p = Q.front();
    Q.pop();
    int curr = 0;
    for (int d = 0; d < 4; ++d) {
      if (!inside(p.first + dx[d] * k, p.second + dy[d] * k)) continue;
      for (int b = 1; b <= k; ++b) {
        if (board[p.first + dx[d] * b][p.second + dy[d] * b] == 0) {
          goto next;
        }
      }
      curr++;
      for (int b = 1; b < k; ++b) {
        flag[p.first + dx[d] * b][p.second + dy[d] * b] = 1;
      }
      if (!flag[p.first + dx[d] * k][p.second + dy[d] * k]) {
        Q.push({p.first + dx[d] * k, p.second + dy[d] * k});
        flag[p.first + dx[d] * k][p.second + dy[d] * k] = true;
      }
    next:;
    }
    if (curr % 2) odd++;
  }
  int cnt = 0;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      cnt += flag[i][j];
    }
  }
  return cnt == ones && (odd == 0 || odd == 2);
}
int main() {
  cin.tie(0)->sync_with_stdio(0);
  cin >> n >> m;
  int mxL = 0;
  for (int i = 0; i < n; ++i) {
    int len = 0;
    for (int j = 0; j < m; ++j) {
      cin >> board[i][j];
      ones += board[i][j];
      if (board[i][j]) {
        if (st.first == -1) {
          st = {i, j};
        }
        len++;
      } else {
        len = 0;
      }
      mxL = max(mxL, len);
    }
  }
  for (int i = 0; i < m; ++i) {
    int len = 0;
    for (int j = 0; j < n; ++j) {
      if (board[j][i]) {
        len++;
      } else {
        len = 0;
      }
      mxL = max(mxL, len);
    }
  }
  mxL--;
  vector<int> divi;
  for (int i = 1; i * i <= mxL; ++i) {
    if (mxL % i == 0) {
      divi.push_back(i);
      if (i * i != mxL) {
        divi.push_back(mxL / i);
      }
    }
  }
  vector<int> ans;
  for (int k : divi) {
    if (k == 1) continue;
    if (check(k)) {
      ans.push_back(k);
    }
  }
  sort(ans.begin(), ans.end());
  if (ans.size() == 0) {
    cout << "-1\n";
  } else {
    for (int j : ans) {
      cout << j << " ";
    }
  }
  return 0;
}
