#include <bits/stdc++.h>
using namespace std;
struct piece {
  int x, y;
  char p[20][20];
  piece(int _x, int _y) : x(_x), y(_y) {}
  bool operator<(const piece& rhs) const {
    if ((x * y) != (rhs.x * rhs.y))
      return (x * y) < (rhs.x * rhs.y);
    else
      return x < rhs.x;
  }
};
struct Piece {
  int x, y;
  char p[20][20];
  Piece() {}
  bool operator==(const Piece& rhs) const {
    bool eq = true;
    for (int i = 0; i < x; i++)
      for (int j = 0; j < y; j++)
        if (p[i][j] != rhs.p[i][j]) {
          eq = false;
          goto n1;
        }
  n1:
    if (eq) return true;
    char tmp[20][20];
    if (x == y) {
      for (int i = 0; i < x; i++)
        for (int j = 0; j < y; j++) tmp[i][j] = rhs.p[y - (j + 1)][i];
      eq = true;
      for (int i = 0; i < x; i++)
        for (int j = 0; j < y; j++)
          if (p[i][j] != tmp[i][j]) {
            eq = false;
            goto n2;
          }
    n2:
      if (eq) return true;
    }
    for (int i = 0; i < x; i++)
      for (int j = 0; j < y; j++) tmp[i][j] = rhs.p[x - (i + 1)][y - (j + 1)];
    eq = true;
    for (int i = 0; i < x; i++)
      for (int j = 0; j < y; j++)
        if (p[i][j] != tmp[i][j]) {
          eq = false;
          goto n3;
        }
  n3:
    if (eq) return true;
    if (x == y) {
      for (int i = 0; i < x; i++)
        for (int j = 0; j < y; j++) tmp[i][j] = rhs.p[j][x - (i + 1)];
      eq = true;
      for (int i = 0; i < x; i++)
        for (int j = 0; j < y; j++)
          if (p[i][j] != tmp[i][j]) {
            eq = false;
            goto n4;
          }
    n4:
      if (eq) return true;
    }
    return false;
  }
};
char p[20][20];
set<int> fa, fb;
set<piece> P;
int a, b;
int good(int x, int y) {
  vector<Piece> ps;
  int ih = a / x, jh = b / y;
  for (int i = 1; i <= ih; i++)
    for (int j = 1; j <= jh; j++) {
      Piece tmp;
      tmp.x = x;
      tmp.y = y;
      int kh = (i - 1) * x + x - 1, lh = (j - 1) * y + y - 1;
      for (int k = (i - 1) * x, m = 0; k <= kh; k++, m++)
        for (int l = (j - 1) * y, n = 0; l <= lh; l++, n++)
          tmp.p[m][n] = p[k][l];
      for (unsigned int k = 0; k < ps.size(); k++)
        if (ps[k] == tmp) return false;
      ps.push_back(tmp);
    }
  return true;
}
int main() {
  cin >> a >> b;
  for (int i = 0; i < a; i++)
    for (int j = 0; j < b; j++) cin >> p[i][j];
  for (int i = 1; i <= a; i++)
    if (!(a % i)) fa.insert(i);
  for (int i = 1; i <= b; i++)
    if (!(b % i)) fb.insert(i);
  for (set<int>::iterator ita = fa.begin(); ita != fa.end(); ita++)
    for (set<int>::iterator itb = fb.begin(); itb != fb.end(); itb++) {
      int x = *ita, y = *itb;
      if (good(x, y)) P.insert(piece(x, y));
    }
  cout << P.size() << endl;
  cout << (*(P.begin())).x << " " << (*(P.begin())).y << endl;
  return 0;
}
