
import java.lang.*;
import java.util.*;
import java.io.*;


public class city
{
	private char[][] map;
	
	public city(int width, int height)
	{
		// Sets grid to 1x1 if invalid dimensions are given.
		if (width < 1 || height < 1)
		{
			width = 1;
			height = 1;
		}
		
		// Initializes map to have all spaces.
		map = new char[height][width];
		for (int x = 0; x < width; x++)
		{
			for (int y = 0; y < height; y++)
			{
				map[y][x] = ' ';
			}
		}
		
	}
	
	public boolean plotBuilding(String buildingName, int x, int y)
	{
		if (buildingName.equals("post_office"))
		{
			// 1x1, 'P'
			if (isAvailable(x, y, 1, 1))
			{
				plotSpace('P', x, y, 1, 1);
				return true;
			}
			else
			{
				return false;
			}
		}
		else if (buildingName.equals("house"))
		{
			// 1x1, 'H'
			if (isAvailable(x, y, 1, 1))
			{
				
				plotSpace('H', x, y, 1, 1);
				return true;
			}
			else
			{
				return false;
			}
		}
		else if (buildingName.equals("grocery_store"))
		{
			// 4x4, 'G'
			if (isAvailable(x, y, 4, 4))
			{
				plotSpace('G', x, y, 4, 4);
				return true;
			}
			else
			{
				return false;
			}
		}
		else if (buildingName.equals("department_store"))
		{
			// 5x5, 'S'
			if (isAvailable(x, y, 5, 5))
			{
				plotSpace('S', x, y, 5, 5);
				return true;
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
	}
	
	private boolean isAvailable(int sx, int sy, int w, int h)
	{
		// Returns false if any dimensions are out of bounds.
		if (sx < 0 || sy < 0 || sx+w > map[0].length || sy+h > map.length)
			return false;
			
		// Returns false if any square in the area for building was previously built on.
		for (int y = 0; y < h; y++)
		{
			for (int x = 0; x < w; x++)
			{
				if (map[sy + y][sx + x] != ' ')
				{
					return false;
				}
			}
		}
		
		return true;
	}
	
	private void plotSpace(char marker, int sx, int sy, int w, int h)
	{
		for (int y = 0; y < h; y++)
		{
			for (int x = 0; x < w; x++)
			{
				
				map[sy + y][sx + x] = marker;
			}
		}
	}
	
	public boolean plotField(String fieldType, int x, int y, int width, int height)
	{
		if (isAvailable(x, y, width, height))
		{
			if (fieldType.equals("grass"))
			{
				plotSpace('"', x, y, width, height);
			}
			else if (fieldType.equals("trees"))
			{
				plotSpace('^', x, y, width, height);
			}
			else if (fieldType.equals("water"))
			{
				plotSpace('~', x, y, width, height);
			}
			else
			{
				return false;
			}
			return true;
		}
		return false;
	}
	
	public boolean plotRoad(int startX, int startY, int endX, int endY)
	{
		int incr_x = 0;
		int incr_y = 0;
		
		if (startX == endX)
		{
			// vertical line
			if (startY < endY) incr_y = 1;
			else incr_y = -1;
		}
		else if (startY == endY)
		{
			// horizontal line
			if (startX < endX) incr_x = 1;
			else incr_x = -1;
		}
		else if (startY != endY || startX != endX)
		{
			// diagonal
			if (startX < endX) incr_x = 1;
			else incr_x = -1;
			if (startY < endY) incr_y = 1;
			else incr_y = -1;
		}
		else
		{
			return false;
		}

		int x = startX;
		int y = startY;
		
		while (x != endX || y != endY)
		{
			if (map[y][x] != ' ' && map[y][x] != '*')
				return false;

			y += incr_y;
			x += incr_x;			
		}

		x = startX;
		y = startY;
		
		while (x != endX || y != endY)
		{
			map[y][x] = '*';
			y += incr_y;
			x += incr_x;
		}
		map[endY][endX] = '*';
		
		return true;
	}
	
    public void printMap()
    {
	   	for (int y = 0; y < map.length; y++)
    	{
    		for (int x = 0; x < map[y].length; x++)
    		{
    			System.out.print(map[y][x]);
    		}
    		System.out.println("");
    	}
    	System.out.println();
    }	
	
    public static void main(String[] args)
    {
	 	
    	try
    	{
	    	Scanner inFile = new Scanner(new File("city.in"));
	    	int numMaps = inFile.nextInt();
	    	
	    	for (int i=1; i<=numMaps; i++)
	    	{
	    		int w = inFile.nextInt();
	    		int h = inFile.nextInt();
	    		city cb = new city(w, h);
	    		String cmd;
	    		
	    		// Carry out the rest of this case.
	    		do {
	    		
	    			// Get next command
	    			cmd = inFile.next();
	    			
	    			if (cmd.equals("plotBuilding"))
	    			{
	    				String building = inFile.next();
	    				int x = inFile.nextInt();
	    				int y = inFile.nextInt();
	    				cb.plotBuilding(building, x, y);
	    			}
	    			else if (cmd.equals("plotField"))
	    			{
			
	    				String fieldType = inFile.next();
						    			
	    				int x = inFile.nextInt();
	    				int y = inFile.nextInt();
	    			
	    				int wField = inFile.nextInt();
	    				int hField = inFile.nextInt();
	    				cb.plotField(fieldType, x, y, wField, hField);
	    			}    		
	    			else if (cmd.equals("plotRoad"))
	    			{
	    				int sx = inFile.nextInt();
	    				int sy = inFile.nextInt();
	    			
	    				int ex = inFile.nextInt();
	    				int ey = inFile.nextInt();
	    			
	    				cb.plotRoad(sx, sy, ex, ey);
	    			}
	    			else if (cmd.equals("printMap"))
	    			{
	    				System.out.println("Map #"+i);
	    				cb.printMap();
	    			}
	    			
	    		} while (!cmd.equals("printMap"));	    		
	    	}
    	}
    	catch (Exception e)
    	{
    		System.out.println("The program could not read from file city.in, reason: " + e.getMessage());
    	}
    }
}
