#include<bits/stdc++.h>
using namespace std;
int dx[] = {0, 0, 1, -1}, mod = 1000000007;
int dy[] = {1, -1, 0, 0}, n, cg = 0, tot = 0, cb = 0, cp = 0, q = 0, vis[57][57];
vector<string> v;
int issafe(int x, int y)
{
if(x < 0 || x == n || y < 0 || y == n || v[x][y] == '.' || vis[x][y] == 1)
return 0;
else return 1;
}
int dfs(int x, int y)
{
tot++;
vis[x][y] = 1;
if(v[x][y] == 'B') cb++;
else if(v[x][y] == 'P') cp++;
else if(v[x][y] == 'G') cg++;
else if(v[x][y] == '?') q++;
for(int i = 0; i < 4; i++)
{
if(issafe(x+dx[i],y+dy[i]))
dfs(x+dx[i], y+dy[i]);
}
return 0;
}
int main()
{
int t;
cin>>t;
while(t--)
{
memset(vis, 0, sizeof(vis));
v.clear();
cin>>n;
int ans = 1;
string s;
for(int i = 0; i < n; i++)
{
cin>>s;
v.push_back(s);
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
if(v[i][j] != '.' && vis[i][j] != 1)
{
int temp = 0;
cg = 0, tot = 0, cb = 0, cp = 0, q = 0;
dfs(i,j);
if(tot == 1)
{
if(q == 1) temp += 3;
else temp += 1;
}
else
{
if(cg > 0 || (cb > 0 && cp > 0)) temp = 0;
else if(q > 0)
{
if(cb > 0 || cp > 0) temp += 1;
else temp += 2;
}
else temp += 1;
}
ans = (ans * temp)%mod;
}
}
}
cout<<ans<<"\n";
}
return 0;
}
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmludCBkeFtdID0gezAsIDAsIDEsIC0xfSwgbW9kID0gMTAwMDAwMDAwNzsKaW50IGR5W10gPSB7MSwgLTEsIDAsIDB9LCBuLCBjZyA9IDAsIHRvdCA9IDAsIGNiID0gMCwgY3AgPSAwLCBxID0gMCwgdmlzWzU3XVs1N107CnZlY3RvcjxzdHJpbmc+IHY7CgppbnQgaXNzYWZlKGludCB4LCBpbnQgeSkKewoJaWYoeCA8IDAgfHwgeCA9PSBuIHx8IHkgPCAwIHx8IHkgPT0gbiB8fCB2W3hdW3ldID09ICcuJyB8fCB2aXNbeF1beV0gPT0gMSkKCQlyZXR1cm4gMDsKCWVsc2UgcmV0dXJuIDE7Cn0KCmludCBkZnMoaW50IHgsIGludCB5KQp7Cgl0b3QrKzsKCXZpc1t4XVt5XSA9IDE7CgoJaWYodlt4XVt5XSA9PSAnQicpIGNiKys7CgllbHNlIGlmKHZbeF1beV0gPT0gJ1AnKSBjcCsrOwoJZWxzZSBpZih2W3hdW3ldID09ICdHJykgY2crKzsKCWVsc2UgaWYodlt4XVt5XSA9PSAnPycpIHErKzsKCglmb3IoaW50IGkgPSAwOyBpIDwgNDsgaSsrKQoJewoJCWlmKGlzc2FmZSh4K2R4W2ldLHkrZHlbaV0pKQoJCQlkZnMoeCtkeFtpXSwgeStkeVtpXSk7Cgl9CglyZXR1cm4gMDsKfQoKaW50IG1haW4oKQp7CglpbnQgdDsKCgljaW4+PnQ7CgoJd2hpbGUodC0tKQoJewoJCW1lbXNldCh2aXMsIDAsIHNpemVvZih2aXMpKTsKCQkKCQl2LmNsZWFyKCk7CgkJCgkJY2luPj5uOwoKCQlpbnQgYW5zID0gMTsKCgkJc3RyaW5nIHM7CgoJCWZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspCgkJewoJCQljaW4+PnM7CgkJCXYucHVzaF9iYWNrKHMpOwoJCX0KCQkKCQlmb3IoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQoJCXsKCQkJZm9yKGludCBqID0gMDsgaiA8IG47IGorKykKCQkJewoJCQkJaWYodltpXVtqXSAhPSAnLicgJiYgdmlzW2ldW2pdICE9IDEpCgkJCQl7CgkJCQkJaW50IHRlbXAgPSAwOwoJCQkJCWNnID0gMCwgdG90ID0gMCwgY2IgPSAwLCBjcCA9IDAsIHEgPSAwOwoJCQkJCWRmcyhpLGopOwoJCQkJCWlmKHRvdCA9PSAxKQoJCQkJCXsKCQkJCQkJaWYocSA9PSAxKSB0ZW1wICs9IDM7CgkJCQkJCWVsc2UgdGVtcCArPSAxOwoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewoJCQkJCQlpZihjZyA+IDAgfHwgKGNiID4gMCAmJiBjcCA+IDApKSB0ZW1wID0gMDsKCQkJCQkgICAgZWxzZSBpZihxID4gMCkKCQkJCQkgICAgewoJCQkJCSAgICAJaWYoY2IgPiAwIHx8IGNwID4gMCkgdGVtcCArPSAxOwoJCQkJCSAgICAJZWxzZSB0ZW1wICs9IDI7CgkJCQkJICAgIH0KCQkJCQkgICAgZWxzZSB0ZW1wICs9IDE7CgkJCQkJfQoJCQkJICAgIGFucyA9IChhbnMgKiB0ZW1wKSVtb2Q7CgkJCQl9CgkJCX0KCQl9CgkJY291dDw8YW5zPDwiXG4iOwoJfQoJcmV0dXJuIDA7Cn0K