#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
int t, h, w;
vector<string> grid;
vector<pair<int,int>> boxPos, targetPos;
int distBFS[50][50];
int dh[4] = {1, -1, 0, 0};
int dw[4] = {0, 0, 1, -1};
int main() {
cin >> t;
while (t--) {
cin >> h >> w;
grid.resize(h);
for (int i = 0; i < h; i++) cin >> grid[i];
boxPos.clear();
targetPos.clear();
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
if (grid[i][j] == 'B') boxPos.push_back({i,j});
if (grid[i][j] == 'X') targetPos.push_back({i,j});
}
}
int n = boxPos.size();
int m = targetPos.size();
vector<vector<int>> A(n+1, vector<int>(m+1, INF));
for (int b = 0; b < n; b++) {
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
distBFS[i][j] = INF;
queue<pair<int,int>> q;
auto [sx, sy] = boxPos[b];
distBFS[sx][sy] = 0;
q.push({sx, sy});
while (!q.empty()) {
auto [x, y] = q.front(); q.pop();
for (int k = 0; k < 4; k++) {
int nx = x + dh[k], ny = y + dw[k];
if (nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
if (grid[nx][ny] == '#') continue;
if (distBFS[nx][ny] > distBFS[x][y] + 1) {
distBFS[nx][ny] = distBFS[x][y] + 1;
q.push({nx, ny});
}
}
}
for (int t = 0; t < m; t++) {
auto [tx, ty] = targetPos[t];
A[b+1][t+1] = distBFS[tx][ty];
}
}
vector<int> u(n+1), v(m+1), p(m+1), way(m+1);
for (int i = 1; i <= n; ++i) {
p[0] = i;
int j0 = 0;
vector<int> minv(m+1, INF);
vector<bool> used(m+1, false);
do {
used[j0] = true;
int i0 = p[j0], delta = INF, j1 = 0;
for (int j = 1; j <= m; ++j)
if (!used[j]) {
int cur = A[i0][j] - u[i0] - v[j];
if (cur < minv[j])
minv[j] = cur, way[j] = j0;
if (minv[j] < delta)
delta = minv[j], j1 = j;
}
for (int j = 0; j <= m; ++j)
if (used[j])
u[p[j]] += delta, v[j] -= delta;
else
minv[j] -= delta;
j0 = j1;
} while (p[j0] != 0);
do {
int j1 = way[j0];
p[j0] = p[j1];
j0 = j1;
} while (j0);
}
int answer = -v[0];
cout << answer << endl;
}
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgpjb25zdCBpbnQgSU5GID0gMWU5OwoKaW50IHQsIGgsIHc7CnZlY3RvcjxzdHJpbmc+IGdyaWQ7CnZlY3RvcjxwYWlyPGludCxpbnQ+PiBib3hQb3MsIHRhcmdldFBvczsKaW50IGRpc3RCRlNbNTBdWzUwXTsKCmludCBkaFs0XSA9IHsxLCAtMSwgMCwgMH07CmludCBkd1s0XSA9IHswLCAwLCAxLCAtMX07CgoKaW50IG1haW4oKSB7CiAgICBjaW4gPj4gdDsKICAgIHdoaWxlICh0LS0pIHsKICAgICAgICBjaW4gPj4gaCA+PiB3OwogICAgICAgIGdyaWQucmVzaXplKGgpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaDsgaSsrKSBjaW4gPj4gZ3JpZFtpXTsKCiAgICAgICAgYm94UG9zLmNsZWFyKCk7CiAgICAgICAgdGFyZ2V0UG9zLmNsZWFyKCk7CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaDsgaSsrKSB7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgdzsgaisrKSB7CiAgICAgICAgICAgICAgICBpZiAoZ3JpZFtpXVtqXSA9PSAnQicpIGJveFBvcy5wdXNoX2JhY2soe2ksan0pOwogICAgICAgICAgICAgICAgaWYgKGdyaWRbaV1bal0gPT0gJ1gnKSB0YXJnZXRQb3MucHVzaF9iYWNrKHtpLGp9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50IG4gPSBib3hQb3Muc2l6ZSgpOwogICAgICAgIGludCBtID0gdGFyZ2V0UG9zLnNpemUoKTsKCiAgICAgICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiBBKG4rMSwgdmVjdG9yPGludD4obSsxLCBJTkYpKTsKCiAgICAgICAgZm9yIChpbnQgYiA9IDA7IGIgPCBuOyBiKyspIHsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBoOyBpKyspCiAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHc7IGorKykKICAgICAgICAgICAgICAgICAgICBkaXN0QkZTW2ldW2pdID0gSU5GOwoKICAgICAgICAgICAgcXVldWU8cGFpcjxpbnQsaW50Pj4gcTsKICAgICAgICAgICAgYXV0byBbc3gsIHN5XSA9IGJveFBvc1tiXTsKICAgICAgICAgICAgZGlzdEJGU1tzeF1bc3ldID0gMDsKICAgICAgICAgICAgcS5wdXNoKHtzeCwgc3l9KTsKCiAgICAgICAgICAgIHdoaWxlICghcS5lbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBhdXRvIFt4LCB5XSA9IHEuZnJvbnQoKTsgcS5wb3AoKTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgNDsgaysrKSB7CiAgICAgICAgICAgICAgICAgICAgaW50IG54ID0geCArIGRoW2tdLCBueSA9IHkgKyBkd1trXTsKICAgICAgICAgICAgICAgICAgICBpZiAobnggPCAwIHx8IG55IDwgMCB8fCBueCA+PSBoIHx8IG55ID49IHcpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIGlmIChncmlkW254XVtueV0gPT0gJyMnKSBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICBpZiAoZGlzdEJGU1tueF1bbnldID4gZGlzdEJGU1t4XVt5XSArIDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZGlzdEJGU1tueF1bbnldID0gZGlzdEJGU1t4XVt5XSArIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIHEucHVzaCh7bngsIG55fSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGludCB0ID0gMDsgdCA8IG07IHQrKykgewogICAgICAgICAgICAgICAgYXV0byBbdHgsIHR5XSA9IHRhcmdldFBvc1t0XTsKICAgICAgICAgICAgICAgIEFbYisxXVt0KzFdID0gZGlzdEJGU1t0eF1bdHldOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB2ZWN0b3I8aW50PiB1KG4rMSksIHYobSsxKSwgcChtKzEpLCB3YXkobSsxKTsKCiAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gbjsgKytpKSB7CiAgICAgICAgICAgIHBbMF0gPSBpOwogICAgICAgICAgICBpbnQgajAgPSAwOwogICAgICAgICAgICB2ZWN0b3I8aW50PiBtaW52KG0rMSwgSU5GKTsKICAgICAgICAgICAgdmVjdG9yPGJvb2w+IHVzZWQobSsxLCBmYWxzZSk7CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIHVzZWRbajBdID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGludCBpMCA9IHBbajBdLCBkZWx0YSA9IElORiwgajEgPSAwOwogICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPD0gbTsgKytqKQogICAgICAgICAgICAgICAgICAgIGlmICghdXNlZFtqXSkgewogICAgICAgICAgICAgICAgICAgICAgICBpbnQgY3VyID0gQVtpMF1bal0gLSB1W2kwXSAtIHZbal07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXIgPCBtaW52W2pdKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWludltqXSA9IGN1ciwgd2F5W2pdID0gajA7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtaW52W2pdIDwgZGVsdGEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWx0YSA9IG1pbnZbal0sIGoxID0gajsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8PSBtOyArK2opCiAgICAgICAgICAgICAgICAgICAgaWYgKHVzZWRbal0pCiAgICAgICAgICAgICAgICAgICAgICAgIHVbcFtqXV0gKz0gZGVsdGEsIHZbal0gLT0gZGVsdGE7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBtaW52W2pdIC09IGRlbHRhOwogICAgICAgICAgICAgICAgajAgPSBqMTsKICAgICAgICAgICAgfSB3aGlsZSAocFtqMF0gIT0gMCk7CgogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICBpbnQgajEgPSB3YXlbajBdOwogICAgICAgICAgICAgICAgcFtqMF0gPSBwW2oxXTsKICAgICAgICAgICAgICAgIGowID0gajE7CiAgICAgICAgICAgIH0gd2hpbGUgKGowKTsKICAgICAgICB9CgogICAgICAgIGludCBhbnN3ZXIgPSAtdlswXTsKICAgICAgICBjb3V0IDw8IGFuc3dlciA8PCBlbmRsOwogICAgfQoKICAgIHJldHVybiAwOwp9Cg==