/*
 * Find two paths of length W+H-2 from top-left to
 * bottom right corner. Use dynamic programming to compute
 * best[d][r1][r2] = opt value after d steps if paths are now
 * in rows r1 and r2 where r1 <= r2.
 *
 * Answer is in best[W+H-2][H][H]
 *
 * Somewhat slow. Maybe due to large inputs?
 */

import java.io.*;
import java.util.*;

class tourist_mg {
    static BufferedReader stdin;
    static PrintWriter stdout;
    static final int infty = 1<<30;

    public static void main(String[] ss)  throws Exception
    {
	Reader r = new InputStreamReader(System.in);
	stdin = new BufferedReader(r);
	Writer w = new OutputStreamWriter(System.out);
	w = new BufferedWriter(w);
	stdout = new PrintWriter(w);
	(new tourist_mg()).run();
	stdout.close();
    }

    void run()  throws Exception
    {
	int n = Integer.parseInt(stdin.readLine());
	for (int i = 1;	i <= n; ++i) {
	    try {
		
		solve();
	    }
	    catch(Exception e) {
		System.err.println("Case " + i);
		
	    }
	}
	
    }
    

    void solve() throws Exception
    {
	StringTokenizer st = new StringTokenizer(stdin.readLine());
	int W = Integer.parseInt(st.nextToken());
	int H = Integer.parseInt(st.nextToken());
	int D = H+W-2;
	int[][] val = new int[H+1][W+1];
	int[][][] best = new int[D+1][H+1][H+1];

	// 0:th row and column are unreachable (probably unneccessary)
	for(int r = 0; r <= H; ++r)  val[r][0] = -infty;	
	for(int c = 1; c <= W; ++c)  val[0][c] = -infty;

	// assume all positions are unreachable for the two paths
	// Can be speeded up. Only need to fill it in where rows = 0,
	// where corresponding columns are 0, and where r2 = r1-1
	for (int d = 0; d <= D; ++d)
	    for(int r1 = 0; r1 <= H; ++r1)
		for(int r2 = 0; r2 <= H; ++r2) 
		    best[d][r1][r2] = -infty;
	
	
	// Read input and record in val
	// I wonder if skipping val and saving strings is much slower?
	for (int r = 1; r <= H; ++r) {
	    String s = stdin.readLine();
	    int n = s.length();
	    if (n != W) System.err.println("Line length wrong");
	    for (int i = 0; i < W; ++i)
		switch (s.charAt(i)) {
		case '.' : val[r][i+1] = 0; break; 	
		case '*' : val[r][i+1] = 1; break; 	
		case '#' : val[r][i+1] = -infty; break; 
		default  : System.err.println("Illegal char"); 
		}
	}
	

	// Can clearly reach first square
	best[0][1][1] = val[1][1];
	// Now fill table using dyn. prog.
	for (int d = 1; d <= D; ++d) {
	    for (int r1 = 1; r1 <= H; ++r1) {
		int c1 = d-r1+2;
		if (c1 <= 0) break;
		if (c1 > W) continue;		
		if (val[r1][c1] != -infty) {
		    best[d][r1][r1] = 
			Math.max(
				 Math.max(best[d-1][r1][r1],
					  best[d-1][r1-1][r1]),
				 best[d-1][r1-1][r1-1]
				 ) + val[r1][c1];
		    for (int r2 = r1+1; r2 <= H; ++r2) {
			int c2 = d-r2+2;
			if (c2 <= 0) break;
			if (c2 > W) continue;			
			if (val[r2][c2] != -infty) {
			    best[d][r1][r2] = 
				Math.max(
					 Math.max(best[d-1][r1][r2],
						  best[d-1][r1-1][r2]),
					 Math.max(best[d-1][r1][r2-1],
						  best[d-1][r1-1][r2-1])
					 );
			    if (best[d][r1][r2] != -infty) {
				best[d][r1][r2] += val[r1][c1]+val[r2][c2];
				
			    }
			}
		    }
		}
	    }
	    
	}
	stdout.println(best[D][H][H]);
    }
}
