#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<ll, ll>;
using pll = pair<ll, ll>;
using ld = double;
using pld = pair<ld, ld>;
template <class T>
istream &operator>>(istream &in, vector<T> &a) {
  for (auto &i : a) in >> i;
  return in;
}
template <class T>
ostream &operator<<(ostream &out, vector<T> a) {
  for (auto &i : a) out << i << ' ';
  return out;
}
template <class T, class U>
istream &operator>>(istream &in, pair<T, U> &p) {
  in >> p.first >> p.second;
  return in;
}
template <class T, class U>
ostream &operator<<(ostream &out, pair<T, U> p) {
  out << p.first << " " << p.second << " ";
  return out;
}
inline void Start() {
  ios_base::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
}
vector<vector<ll>> rot(vector<vector<ll>> a) {
  ll n = a.size(), m = a[0].size();
  vector<vector<ll>> b(m, vector<ll>(n));
  for (ll i = 0; i < m; ++i) {
    for (ll j = 0; j < n; ++j) {
      b[m - i - 1][j] = a[j][i];
    }
  }
  return b;
}
bool check(vector<vector<ll>> a, vector<vector<ll>> b) {
  if (a == b) return false;
  b = rot(b);
  if (a == b) return false;
  b = rot(b);
  if (a == b) return false;
  b = rot(b);
  if (a == b) return false;
  return true;
}
signed main() {
  Start();
  ll n, m;
  cin >> n >> m;
  vector<vector<char>> c(n, vector<char>(m));
  cin >> c;
  vector<vector<ll>> a(n, vector<ll>(m));
  for (ll i = 0; i < n; ++i)
    for (ll j = 0; j < m; ++j) a[i][j] = c[i][j] - 'A';
  pii ans = {1e9, 1e9};
  ll lol = 0;
  for (ll x = 1; x <= n; ++x) {
    for (ll y = 1; y <= m; ++y) {
      if (n % x != 0 || m % y != 0) continue;
      vector<vector<vector<ll>>> kek;
      vector<vector<ll>> cur(x, vector<ll>(y));
      for (ll i = 0; i < n; i += x) {
        for (ll j = 0; j < m; j += y) {
          for (ll e = i; e < i + x; ++e)
            for (ll f = j; f < j + y; ++f) cur[e - i][f - j] = a[e][f];
          kek.emplace_back(cur);
        }
      }
      bool can = true;
      for (ll i = 0; i < kek.size(); ++i) {
        for (ll j = i + 1; j < kek.size(); ++j) {
          can = can && check(kek[i], kek[j]);
        }
      }
      if (can) {
        ++lol;
        if (ans.first * ans.second > x * y ||
            ans.first * ans.second == x * y && ans.first > x)
          ans = {x, y};
      }
    }
  }
  cout << lol << endl << ans;
  return 0;
}
