const int N = 1e6 + 7;
int n, m, l, r, mid, flg, ans;
string s[N], ss[N];
inline bool check(int x) {
int bg = x <= mid ? l : x + 1, ed = x <= mid ? x : r;
for (int i = 1; i <= n; ++i) for (int j = bg; j <= ed; ++j)
if (s[i][j] ^ s[i][x + x - j + 1]) return false;
return true;
}
inline void dfs(int x, int y) {
if (x < 1 || x > n || y < l || y > r || s[x][y] == '1') return ;
s[x][y] = '1';
dfs(x + 1, y);
dfs(x - 1, y);
dfs(x, y + 1);
dfs(x, y - 1);
}
signed main() {
// freopen("", "r", stdin);
// freopen("", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
for (int T = read<int>(); T--; ) {
read(n, m), ans = 0;
for (int i = 1; i <= n; ++i) read(s[i]), s[i] = ' ' + s[i];
l = 1, r = m, flg = 1;
solve: {
mid = l + r - 1 >> 1;
for (int i = l + r >> 1; l <= i && i < r; i = l + r - i - (i > mid))
if (check(i)) {
if (i <= mid) l = i + 1;
else r = i;
goto solve;
}
}
if (flg) { // 旋转
int k = r - l + 1;
for (int i = 1; i <= n; ++i) ss[i] = s[i].substr(l, k);
for (int i = 1, j; i <= k; ++i) for (s[i] = " ", j = 1; j <= n; ++j)
s[i] += ss[j][i - 1];
l = 1, r = n, n = k, flg = 0;
goto solve;
}
for (int i = 1; i <= n; ++i) for (int j = l; j <= r; ++j)
if (s[i][j] == '0') dfs(i, j), ++ans;
print(ans, '\n');
}
return Flush;
}
数据感人