//SUST_ZadeedBoss_Fanclub
//code_korlei_life_ase
//na_korle_lifeNai
#include<bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T> using o_set = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define int long long
#define double long double
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
const int N = 2010;
int dpr[N][N];
int dpl[N][N];
int dpu[N][N];
int dpd[N][N];
char inp[N][N];
void solve ()
{
int n, m; cin >>n >>m; n++; m++;
for (int i=1; i<n; i++)
{
for (int j=1; j<m; j++)
{
cin >>inp[i][j];
// cout <<inp[i][j] <<" ";
}
// cout <<"\n";
}
dpl[n][m] = 0;
dpr[n][m] = 0;
dpu[n][m] = 0;
dpd[n][m] = 0;
for (int i=1; i<n; i++)
{
for (int j=1; j<m; j++)
{
dpr[i][j] = (inp[i][j] == '+' ? dpr[i][j-1] + 1 : 0);
}
}
for (int i=1; i<n; i++)
{
for (int j=m-1; j; j--)
{
dpl[i][j] = (inp[i][j] == '+' ? dpl[i][j+1] + 1 : 0);
}
}
for (int i=1; i<m; i++)
{
for (int j=1; j<n; j++)
{
dpd[j][i] = (inp[j][i] == '+' ? dpd[j-1][i] + 1 : 0);
}
}
for (int i=1; i<m; i++)
{
for (int j=n-1; j; j--)
{
dpu[j][i] = (inp[j][i] == '+' ? dpu[j+1][i] + 1 : 0);
}
}
int ans = 0;
for (int i=1; i<n; i++)
{
for (int j=1; j<m; j++)
{
if (inp[i][j] != '+') continue;
int up = dpd[i][j] - 1;
int down = dpu[i][j] - 1;
int left = dpr[i][j] - 1;
int right = dpl[i][j] - 1;
// if (i==3 && j==2) cout <<up <<" " <<down <<" " <<left <<" " <<right <<"\n";
ans = max(ans, (min({left, right, up, down})) * 4 + 1);
}
}
cout <<ans <<"\n";
}
signed main()
{
ios_base::sync_with_stdio(0);
cin.tie(NULL);
int TCASE = 1;
cin >> TCASE;
for (int tcase = 1; tcase <= TCASE; tcase++)
{
solve();
}
}