#include <bits/stdc++.h>
using namespace std;
const int mn = 22;
int m, n;
string grid[mn];
vector<string> rot(vector<string> v) {
  int m = v.size(), n = v[0].size();
  vector<string> ret(n);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) ret[i].push_back(' ');
  for (int i = 0; i < m; i++)
    for (int j = 0; j < n; j++) ret[n - j - 1][i] = v[i][j];
  return ret;
}
int main() {
  cin >> m >> n;
  for (int i = 0; i < m; i++) cin >> grid[i];
  int ans = 0, ansx = m, ansy = n;
  for (int x = 1; x < m + 1; x++)
    for (int y = 1; y < n + 1; y++) {
      if (m % x || n % y) continue;
      vector<vector<string> > pieces;
      int mbx = m / x, nby = n / y;
      set<vector<string> > sv;
      bool ok = 1;
      for (int i = 0; i < mbx; i++)
        for (int j = 0; j < nby; j++) {
          vector<string> v;
          for (int i1 = i * x; i1 < i * x + x; i1++)
            v.push_back(grid[i1].substr(j * y, y));
          pieces.push_back(v);
          if (sv.find(v) != sv.end()) ok = 0;
          sv.insert(v);
        }
      for (int i = 0; i < pieces.size(); i++) {
        vector<string> v = pieces[i];
        for (int times = 0; times < 3; times++) {
          v = rot(v);
          if (v != pieces[i] && sv.find(v) != sv.end()) ok = 0;
        }
      }
      if (ok) {
        ans++;
        if (x * y < ansx * ansy || x * y == ansx * ansy && x < ansx)
          ansx = x, ansy = y;
      }
    }
  cout << ans << endl << ansx << " " << ansy << endl;
  return 0;
}
