#include #include #include #include #include #include #include #include #include #include int nn, mm; int MAXN = 1e6 * 2; int IndexToNumber(int ii, int jj) { return ii * mm + jj; } int BitByIndex(int table, int ii, int jj) { return (table >> IndexToNumber(ii, jj)) % 2; } bool Check(int table) { for (int ii = 0; ii < nn; ++ii) { for (int jj = 0; jj < mm; ++jj) { if (ii > 0) { if (BitByIndex(table, ii, jj) == BitByIndex(table, ii - 1, jj)) { return false; } } if (jj > 0) { if (BitByIndex(table, ii, jj) == BitByIndex(table, ii, jj - 1)) { return false; } } } } return true; } int XorByIndex(int table, int ii, int jj) { return table xor (1 << IndexToNumber(ii, jj)); } void PushNew(std::vector &used, std::queue> &qu, int table, int num) { for (int ii = 0; ii < nn; ++ii) { for (int jj = 0; jj < mm; ++jj) { if (ii + 1 != nn) { int new_table = XorByIndex(table, ii, jj); new_table = XorByIndex(new_table, ii + 1, jj); if (!used[new_table]) { used[new_table] = true; qu.push({new_table, num + 1}); } } if (jj + 1 != mm) { int new_table = XorByIndex(table, ii, jj); new_table = XorByIndex(new_table, ii, jj + 1); if (!used[new_table]) { used[new_table] = true; qu.push({new_table, num + 1}); } } } } } int Bfs(int table) { std::vector used(MAXN); std::queue> qu; qu.push({table, 0}); used[table] = true; while (!qu.empty()) { auto item = qu.front(); if (Check(item.first)) { return item.second; } qu.pop(); PushNew(used, qu, item.first, item.second); } return -1; } int main() { std::cin >> nn >> mm; int table = 0; for (int i = 0; i < nn; ++i) { for (int j = 0; j < mm; ++j) { char sim; std::cin >> sim; if (sim == '1') { table = table | (1 << (i * mm + j)); } } } std::cout << Bfs(table); }