// Arup Guha
// 3/17/2017
// Solution to 2017 UCF HS Contest Problem: Chutes and Ladders

import java.util.*;

public class ladders {

	// Movement on a level.
	final public static int[] DX = {-1,0,0,1};
	final public static int[] DY = {0,-1,1,0};

	public static int r;
	public static int c;
	public static int h;
	public static char[][][] grid;

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);
		int numCases = stdin.nextInt();

		// Process each case.
		for (int loop=1; loop<=numCases; loop++) {

			// Read in the data.
			r = stdin.nextInt();
			c = stdin.nextInt();
			h = stdin.nextInt();
			grid = new char[h][r][];
			for (int i=0; i<h; i++)
				for (int j=0; j<r; j++)
					grid[i][j] = stdin.next().toCharArray();

			// Get our search locations.
			int start = find('S');
			int end = find('E');

			// Output result.
			System.out.println("Map #"+loop+": "+bfs(start, end));
		}
	}

	// Returns the location of ch in the grid. Returns -1 if not found.
	public static int find(char ch) {
		for (int i=0; i<h*r*c; i++)
			if (grid[i/(r*c)][(i%(r*c))/c][i%c] == ch)
				return i;
		return -1;
	}

	public static String bfs(int start, int end) {

		// Usual beginning BFS stuff.
		boolean[] used = new boolean[h*r*c];
		used[start] = true;
		LinkedList<Integer> q = new LinkedList<Integer>();
		q.offer(start);

		// Run to completion.
		while (q.size() > 0) {

			// Get next item.
			int cur = q.poll();
			if (cur == end) return "Yes";

			// Extract out the point.
			int level = cur/(r*c);
			int x = (cur%(r*c))/c;
			int y = cur%c;

			// Just move in usual directions for anything but a chute.
			if (grid[level][x][y] != '*') {
				enqueue(level, x, y, used, q);
			}

			// Chutes can only go down, but you stop if what's below isn't one.
			if (grid[level][x][y] == '*') {

				// Don't go down any more - go in usual directions.
				if (level == h-1 || grid[level+1][x][y] != '*') enqueue(level,x,y,used,q);

				// Just go down.
				else {
					int newVal = (level+1)*r*c + x*c + y;
					if (!used[newVal]) {
						q.offer(newVal);
						used[newVal] = true;
					}
				}
			}

			// Process moving up and down here.
			if (grid[level][x][y] == '#') {

				// Move up.
				if (level > 0 && grid[level-1][x][y] == '#') {
					int newVal = (level-1)*r*c + x*c + y;
					if (!used[newVal]) {
						q.offer(newVal);
						used[newVal] = true;
					}
				}

				// Move down.
				if (level < h-1 && grid[level+1][x][y] == '#') {
					int newVal = (level+1)*r*c + x*c + y;
					if (!used[newVal]) {
						q.offer(newVal);
						used[newVal] = true;
					}
				}
			}
		}

		// If we get out here we never made it to end.
		return "No";
	}

	// Returns true iff (x,y) is inbounds on a level or not.
	public static boolean inbounds(int x, int y) {
		return x >= 0 && x < r && y >= 0 && y < c;
	}

	// Enqueues neighbors on same level of (x,y).
	public static void enqueue(int level, int x, int y, boolean[] used, LinkedList<Integer> q) {

		// Try each direction on this level.
		for (int i=0; i<DX.length; i++) {
			int newx = x + DX[i];
			int newy = y + DY[i];
			int newVal = level*r*c + newx*c + newy;
			if (inbounds(newx,newy) && !used[newVal]) {
				q.offer(newVal);
				used[newVal] = true;
			}
		}

	}
}