#include <bits/stdc++.h>
using namespace std;
struct fig {
  int sx, sy;
  char buf[22][22];
  bool operator<(const fig &sec) const {
    for (int i = 0; i < 22; i++) {
      if (strcmp(buf[i], sec.buf[i]) != 0) {
        return strcmp(buf[i], sec.buf[i]) < 0;
      }
    }
    return false;
  }
};
struct puzzle {
  int x, y;
  bool operator<(const puzzle &sec) const {
    return x * y != sec.x * sec.y ? x * y < sec.x * sec.y : x < sec.x;
  }
} arr[404];
char buf[40][40];
set<fig> cmp;
fig rotate(fig str) {
  fig ret = {};
  for (int i = 0; i < str.sx; i++) {
    for (int j = 0; j < str.sy; j++) {
      ret.buf[i][j] = str.buf[str.sy - j - 1][i];
    }
  }
  ret.sx = str.sy;
  ret.sy = str.sx;
  return ret;
}
int main() {
  int a, b, kol = 0;
  cin >> a >> b;
  for (int i = 0; i < a; i++) {
    cin >> buf[i];
  }
  for (int i = 1; i <= a; i++) {
    if (a % i) {
      continue;
    }
    for (int j = 1; j <= b; j++) {
      if (b % j) {
        continue;
      }
      cmp.clear();
      bool bad = false;
      for (int x = 0; x < a / i && !bad; x++) {
        for (int y = 0; y < b / j && !bad; y++) {
          fig tmp = {};
          for (int l = 0; l < i; l++) {
            for (int p = 0; p < j; p++) {
              tmp.buf[l][p] = buf[x * i + l][y * j + p];
            }
          }
          tmp.sx = j;
          tmp.sy = i;
          for (int k = 0; k < 4; k++) {
            if (cmp.find(tmp) != cmp.end()) {
              bad = true;
              break;
            }
            tmp = rotate(tmp);
          }
          cmp.insert(tmp);
        }
      }
      if (bad) {
        continue;
      }
      arr[kol].x = i;
      arr[kol].y = j;
      kol++;
    }
  }
  sort(arr, arr + kol);
  cout << kol << endl;
  cout << arr[0].x << " " << arr[0].y << endl;
  return 0;
}
