#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int MAXN = 2e6 + 5;
int query(int a, int b, int c, int d, vector<vector<int>> &v) {
return v[c][d] - v[c][b - 1] - v[a - 1][d] + v[a - 1][b - 1];
}
int n, m;
int lg[MAXN];
int calc(int a, int b, int c, int d) {
int tx = c - a + 1;
int qtdx = 1 + (n - c) / tx + !!((n - c) % tx) + (a - 1) / tx + !!((a - 1) % tx);
int ty = d - b + 1;
int qtdy = 1 + (m - d) / ty + !!((m - d) % ty) + (b - 1) / ty + !!((b - 1) % ty);
return lg[qtdx] + lg[qtdy];
}
// int calc(int a, int b, int c, int d) {
// int w = 0, x = 0, y = 0, z = 0;
// int tam = c - a + 1;
// while (tam < c) {
// tam *= 2;
// w++;
// }
// tam = c;
// while (tam < n) {
// tam *= 2;
// w++;
// }
// tam = c - a + 1;
// while (tam < n - a + 1) {
// tam *= 2;
// x++;
// }
// tam = n - a + 1;
// while (tam < n) {
// tam *= 2;
// x++;
// }
// tam = d - b + 1;
// while (tam < d) {
// tam *= 2;
// y++;
// }
// tam = d;
// while (tam < m) {
// tam *= 2;
// y++;
// }
// tam = d - b + 1;
// while (tam < m - b + 1) {
// tam *= 2;
// z++;
// }
// tam = m - b + 1;
// while (tam < m) {
// tam *= 2;
// z++;
// }
// return min(w, x) + min(y, z);
// }
int main() {
int a = 1, cnt = 0;
while (a < MAXN) {
for (int i = a; i >= 2; i--) {
if (lg[i]) break;
lg[i] = cnt;
}
a *= 2;
cnt++;
}
cin >> n >> m;
vector<vector<int>> v(n + 1, vector<int> (m + 1));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
char c;
cin >> c;
v[i][j] = c - '0';
v[i][j] += v[i][j - 1];
}
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
v[j][i] += v[j - 1][i];
}
}
int ans = 200;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
// cout << i << ' ' << j << '\n';
int lin = n - i + 1;
int col = m - j + 1;
vector<int> ver, hor;
while (lin > 1) {
ver.push_back(lin);
lin = (lin / 2) + lin % 2;
}
while (col > 1) {
hor.push_back(col);
col = (col / 2) + col % 2;
}
ver.push_back(1);
hor.push_back(1);
reverse(ver.begin(), ver.end());
reverse(hor.begin(), hor.end());
// for (int x : ver) cout << x << ' ';
// cout << '\n';
// for (int x : hor) cout << x << ' ';
// cout << '\n';
for (int k = 0; k < (int)ver.size(); k++) {
if (query(i, j, i + ver[k] - 1, j, v) != ver[k]) break;
for (int l = 0; l < (int)hor.size(); l++) {
if (query(i, j, i + ver[k] - 1, j + hor[l] - 1, v) != ver[k] * hor[l]) break;
ans = min(ans, calc(i, j, i + ver[k] - 1, j + hor[l] - 1));
}
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = m; j >= 1; j--) {
// cout << i << ' ' << j << '\n';
int lin = n - i + 1;
int col = j;
vector<int> ver, hor;
while (lin > 1) {
ver.push_back(lin);
lin = (lin / 2) + lin % 2;
}
while (col > 1) {
hor.push_back(col);
col = (col / 2) + col % 2;
}
ver.push_back(1);
hor.push_back(1);
reverse(ver.begin(), ver.end());
reverse(hor.begin(), hor.end());
// for (int x : ver) cout << x << ' ';
// cout << '\n';
// for (int x : hor) cout << x << ' ';
// cout << '\n';
for (int k = 0; k < (int)ver.size(); k++) {
if (query(i, j, i + ver[k] - 1, j, v) != ver[k]) break;
for (int l = 0; l < (int)hor.size(); l++) {
if (query(i, j - hor[l] + 1, i + ver[k] - 1, j, v) != ver[k] * hor[l]) break;
ans = min(ans, calc(i, j - hor[l] + 1, i + ver[k] - 1, j));
}
}
}
}
for (int i = n; i >= 1; i--) {
for (int j = 1; j <= m; j++) {
// cout << i << ' ' << j << '\n';
int lin = i;
int col = m - j + 1;
vector<int> ver, hor;
while (lin > 1) {
ver.push_back(lin);
lin = (lin / 2) + lin % 2;
}
while (col > 1) {
hor.push_back(col);
col = (col / 2) + col % 2;
}
ver.push_back(1);
hor.push_back(1);
reverse(ver.begin(), ver.end());
reverse(hor.begin(), hor.end());
// for (int x : ver) cout << x << ' ';
// cout << '\n';
// for (int x : hor) cout << x << ' ';
// cout << '\n';
for (int k = 0; k < (int)ver.size(); k++) {
if (query(i - ver[k] + 1, j, i, j, v) != ver[k]) break;
for (int l = 0; l < (int)hor.size(); l++) {
if (query(i - ver[k] + 1, j, i, j + hor[l] - 1, v) != ver[k] * hor[l]) break;
ans = min(ans, calc(i - ver[k] + 1, j, i, j + hor[l] - 1));
}
}
}
}
for (int i = n; i >= 1; i--) {
for (int j = m; j >= 1; j--) {
// cout << i << ' ' << j << '\n';
int lin = i;
int col = j;
vector<int> ver, hor;
while (lin > 1) {
ver.push_back(lin);
lin = (lin / 2) + lin % 2;
}
while (col > 1) {
hor.push_back(col);
col = (col / 2) + col % 2;
}
ver.push_back(1);
hor.push_back(1);
reverse(ver.begin(), ver.end());
reverse(hor.begin(), hor.end());
// for (int x : ver) cout << x << ' ';
// cout << '\n';
// for (int x : hor) cout << x << ' ';
// cout << '\n';
for (int k = 0; k < (int)ver.size(); k++) {
if (query(i - ver[k] + 1, j, i, j, v) != ver[k]) break;
for (int l = 0; l < (int)hor.size(); l++) {
if (query(i - ver[k] + 1, j - hor[l] + 1, i, j, v) != ver[k] * hor[l]) break;
ans = min(ans, calc(i - ver[k] + 1, j - hor[l] + 1, i, j));
}
}
}
}
cout << ans << '\n';
}