// Arup Guha
// Started on 4/23/2013, finised on 6/26/2013
// Solution to 2013 UCF High School Contest Problem: Craft

import java.util.*;
import java.io.*;
public class craft {

	public static void main(String[] args) throws Exception {
		
		Scanner fin = new Scanner(new File("craft.in"));
		int numCases = fin.nextInt();
		
		// Go through each case.
		for (int loop=1; loop<=numCases; loop++) {
			
			// Read in the grid.
			int L = fin.nextInt();
			int W = fin.nextInt();
			int H = fin.nextInt();
			char[][][] grid = new char[H][L][W];
			for (int i=0; i<H; i++) {
				for (int j=0; j<L; j++) {
					String s = fin.next();
					for (int k=0; k<W; k++)
						grid[i][j][k] = s.charAt(k);
				}
			}
			
			// Solve an output.
			System.out.println("Map #"+loop+": "+bfs(grid, H, L, W));
		}
	}
	
	// Use a breadth first search to solve the problem.
	public static int bfs(char[][][] grid, int H, int L, int W) {
		
		// Set up the search here.
		int[] star = findStar(grid);
		LinkedList<Integer> q = new LinkedList<Integer>();
		q.offer(code(star));
		grid[star[0]][star[1]][star[2]] = '&';
		int cnt = 0;
		
		while (q.size() > 0) {
			
			int item = q.poll();
			int[] next = getcode(item);
			cnt++;
				
			// Go below in this situation. It's a really, really bizarre rule. You do try to go down if there's lava
			// below you, but lava doesn't flow in that case, you stop. So, I check if there's NOT solid ground. But,
			// I only enqueue the new block if it's not lava.
			if (next[0]+1 < H && (grid[next[0]+1][next[1]][next[2]] == '.' || grid[next[0]+1][next[1]][next[2]] == '&')) {
				int val = 10000*(next[0]+1)+100*next[1]+next[2];
				if (grid[next[0]+1][next[1]][next[2]] == '.')
					q.offer(val);
				grid[next[0]+1][next[1]][next[2]] = '&';
			}
			
			// There is a block below you so go in all four cardinal directions.
			else {
				
				// The code for all four parts is similar, going in each respective direction.
				if (next[1]+1 < L) {
					int val = 10000*next[0]+100*(next[1]+1)+next[2];
					if (grid[next[0]][next[1]+1][next[2]] == '.') {
						q.offer(val);
						grid[next[0]][next[1]+1][next[2]] = '&';
					}
				}
				if (next[1] > 0) {
					int val = 10000*next[0] + 100*(next[1]-1) + next[2];
					if (grid[next[0]][next[1]-1][next[2]] == '.') {
						q.offer(val);
						grid[next[0]][next[1]-1][next[2]] = '&';
					}
				}
				if (next[2]+1 < W) {
					int val = 10000*next[0]+100*next[1]+next[2]+1;
					if (grid[next[0]][next[1]][next[2]+1] == '.') {
						q.offer(val);
						grid[next[0]][next[1]][next[2]+1] = '&';
					}
				}
				if (next[2] > 0) {
					int val = 10000*next[0]+100*next[1]+next[2]-1;
					if (grid[next[0]][next[1]][next[2]-1] == '.') {
						q.offer(val);
						grid[next[0]][next[1]][next[2]-1] = '&';
					}
				}
			}
			
		}
		
		return cnt;
	}
	
	// Converts array to one integer for the queue.
	public static int code(int[] a) {
		return 10000*a[0]+100*a[1]+a[2];
	}
	
	// Converts integer back to the array form.
	public static int[] getcode(int a) {
		int[] ans = new int[3];
		ans[2] = a%100;
		ans[1] = (a/100)%100;
		ans[0] = a/10000;
		return ans;
	}
	
	// Returns the x,y,z location of the star.
	public static int[] findStar(char[][][] grid) {
		
		for (int i=0; i<grid.length; i++)
			for (int j=0; j<grid[0].length; j++)
				for (int k=0; k<grid[0][0].length; k++)
					if (grid[i][j][k] == '*') {
						int[] ans = {i,j,k};
						return ans;
					}
		
		return null;
	}
}
