/*
卫风·芄兰
芄兰之支,童子佩觿.
虽则佩觿,能不我知?
容兮遂兮,垂带悸兮.
芄兰之叶,童子佩韘.
虽则佩韘,能不我甲?
容兮遂兮,垂带悸兮.
*/
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
#define int long long
#define tul tuple<int,int,int>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define rep_(i,a,b) for(int i=a;i>=b;--i)
#define all(x) x.begin(),x.end()
#define bp(x) __builtin_popcountll(x)
#define cy cout<<"YES"<<endl
#define cn cout<<"NO"<<endl
#define lc (rt<<1)
#define rc (rt<<1|1)
mt19937_64 rnd(time(0));
const int N=3e3+5,yyx=1e9+7;
vector<PII> to[N];
int n,m,k;
char a[N][N],b[N][N];
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
int sx,sy,ans;
int st[N][N],d[N][N],dp[N][N];
set<PII> s,ss;
int check(char ch){
if(ch=='.') return 1;
return 0;
}
void dfs(int x,int y){
rep(i,0,3){
int px=x+dx[i],py=y+dy[i];
if(px>n||py>m||px<1||py<1||a[px][py]=='#') continue;
if(st[px][py]) continue;
st[px][py]=1;
dfs(px,py);
}
if(x==n||y==m||x==1||y==1){
if(a[x][y]!='#') s.insert({x,y});
return;
}
}
void bfs(int x,int y){
queue<PII> q;
rep(i,1,n) rep(j,1,m) st[i][j]=0,d[i][j]=2e14;
d[x][y]=0;
q.push({x,y});
while(q.size()){
auto [xx,yy]=q.front();q.pop();
if(st[xx][yy]) continue;
st[xx][yy]=1;
rep(i,0,3){
int px=xx+dx[i],py=yy+dy[i];
if(px>n||py>m||px<1||py<1||a[px][py]=='#') continue;
d[px][py]=min(d[px][py],d[xx][yy]+check(a[px][py]));
q.push({px,py});
}
}
}
void bbfs(int x,int y){
queue<PII> q;
rep(i,1,n) rep(j,1,m) st[i][j]=0,dp[i][j]=2e14;
dp[x][y]=0;
q.push({x,y});
while(q.size()){
auto [xx,yy]=q.front();q.pop();
if(st[xx][yy]) continue;
st[xx][yy]=1;
rep(i,0,3){
int px=xx+dx[i],py=yy+dy[i];
if(px>n||py>m||px<1||py<1||a[px][py]=='#') continue;
dp[px][py]=min(dp[px][py],dp[xx][yy]+check(a[px][py]));
q.push({px,py});
}
}
}
void rbfs(int x,int y,int ssx,int ssy){
queue<PII> q;
rep(i,1,n) rep(j,1,m) st[i][j]=0;
q.push({x,y});
ss.insert({x,y});
while(q.size()){
auto [xx,yy]=q.front();q.pop();
if(xx==ssx&&yy==ssy) return;
if(st[xx][yy]) continue;
st[xx][yy]=1;
rep(i,0,3){
int px=xx+dx[i],py=yy+dy[i];
if(px>n||py>m||px<1||py<1||a[px][py]=='#') continue;
if(dp[xx][yy]==dp[px][py]+1) q.push({px,py}),ss.insert({px,py});
}
}
}
inline void solve(){
cin>>n>>m;
s.clear();ss.clear();
map<char,int> mp;
rep(i,1,n) rep(j,1,m) cin>>a[i][j],st[i][j]=0,b[i][j]=a[i][j];
rep(i,1,n) rep(j,1,m){
if(a[i][j]=='V') sx=i,sy=j;
mp[a[i][j]]++;
}
dfs(sx,sy);
ans=s.size();
bfs(sx,sy);
if(!ans){
int x=mp['#'];
cout<<max(n*m-1-x,0ll)<<endl;
return;
}
set<tul> st;
for(auto [x,y]:s){
st.insert({d[x][y],x,y});
}
if(ans==1){
auto [dis,x,y]=*st.begin();
int p=mp['#'];
cout<<max(n*m-dis-p-1,0ll)<<endl;
return;
}
int ma=0;
st.clear();
for(auto [x,y]:s){
int an=0;
rep(i,1,n) rep(j,1,m) dp[i][j]=d[i][j];
rbfs(x,y,sx,sy);
st.clear();
for(auto [xx,yy]:ss) a[xx][yy]='R';
int cnt=ss.size();
an+=max(cnt-dp[x][y]-1,0ll);
bbfs(x,y);
for(auto [px,py]:s){
if(px==x&&py==y) continue;
st.insert({dp[px][py],px,py});
}
auto [td,tx,ty]=*st.begin();
rbfs(tx,ty,x,y);
for(auto [xx,yy]:ss) a[xx][yy]='R';
mp.clear();
rep(i,1,n) rep(j,1,m){
mp[a[i][j]]++;
}
an+=mp['.'];
ma=max(ma,an);
ss.clear();
rep(i,1,n){
rep(j,1,m) a[i][j]=b[i][j];
}
}
cout<<ma<<endl;
}
signed main(){
cin.tie(0)->sync_with_stdio(0);
//freopen("D://321//in.txt","r",stdin);
//freopen("D://321//out.txt","w",stdout);
int _=1;
cin>>_;
while(_--)
solve();
return 0;
}