// Arup Guha
// 4/25/2013
// Solution to 2013 UCF High School Contest Problem: Puzzle

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

	public final static int NUM_PIECES = 9;
	public final static int NUM_PIECES_SIDE = 3;

	public static void main(String[] args) throws Exception {

		Scanner fin = new Scanner(new File("puzzle.in"));
		int numCases = fin.nextInt();
		
		// Go through each case.
		for (int loop=1; loop<=numCases; loop++) {

			int n = fin.nextInt();
			char[][] pieces = new char[NUM_PIECES_SIDE*n][NUM_PIECES_SIDE*n];

			// Read in each of the 9 pieces where they go.
			for (int i=0; i<NUM_PIECES; i++) {

				// Our offset.
				int dx = (i/NUM_PIECES_SIDE)*n;
				int dy = (i%NUM_PIECES_SIDE)*n;

				// Read in this piece.
				String[] next = new String[n];
				for (int j=0; j<n; j++)
					next[j] = fin.next();

				// Fill this piece in.
				for (int x=dx; x<dx+n; x++)
					for (int y=dy; y<dy+n; y++)
						pieces[x][y] = next[x-dx].charAt(y-dy);
			}

			// Solve!
			int mySols = numSols(pieces);

			// Output corresponding result.
			if (mySols == 0)
				System.out.println("Puzzle #"+loop+": NO");
			else if (mySols == 1)
				System.out.println("Puzzle #"+loop+": YES");
			else
				System.out.println("Puzzle #"+loop+": MULTIPLE");

		}

		fin.close();
	}

	// Wrapper function that solves the original query.
	public static int numSols(char[][] pieces) {
		return numSolsRec(pieces, 0);
	}

	// Returns the number of solutions with the first k pieces (out of 9) fixed.
	public static int numSolsRec(char[][] pieces, int k) {

		// Our puzzle is fixed, our answer is either 1 arrangement or none.
		if (k == NUM_PIECES) {
			if  (isValid(pieces)) return 1;
			return 0;
		}

		// Try swapping each future piece into slot k.
		int cnt = 0;
		for (int i=k; i<NUM_PIECES; i++) {
			swap(pieces, i, k);
			cnt += numSolsRec(pieces, k+1);
			swap(pieces, i, k);
		}

		// Here are the number of valid puzzles.
		return cnt;

	}

	public static boolean isValid(char[][] pieces) {

		// Get original piece size.
		int n = pieces.length/NUM_PIECES_SIDE;

		// These for seams have to match.
		return checkRow(pieces, n) && checkRow(pieces, 2*n) && checkCol(pieces, n) && checkCol(pieces, 2*n);
	}

	// Returns true iff row and row-1 are identical.
	public static boolean checkRow(char[][] pieces, int row) {
		for (int i=0; i<pieces.length; i++)
			if (pieces[row][i] != pieces[row-1][i])
				return false;
		return true;
	}

	// Returns true iff col and col-1 are identical.
	public static boolean checkCol(char[][] pieces, int col) {
		for (int i=0; i<pieces[0].length; i++)
			if (pieces[i][col] != pieces[i][col-1])
				return false;
		return true;
	}

	// Swaps pieces p1 and p2 (both have to be in between 0 and numpieces - 1)
	public static void swap(char[][] pieces, int p1, int p2) {

		int n = pieces.length/NUM_PIECES_SIDE;

		// Starting indexes of the two pieces to swap.
		int startx1 = (p1/NUM_PIECES_SIDE)*n;
		int starty1 = (p1%NUM_PIECES_SIDE)*n;
		int startx2 = (p2/NUM_PIECES_SIDE)*n;
		int starty2 = (p2%NUM_PIECES_SIDE)*n;

		// Swap each character between these two pieces 1 by 1.
		for (int i=0; i<n; i++) {
			for (int j=0; j<n; j++) {
				char tmp = pieces[startx1+i][starty1+j];
				pieces[startx1+i][starty1+j] = pieces[startx2+i][starty2+j];
				pieces[startx2+i][starty2+j] = tmp;
			}
		}
	}
}
