// Arup Guha
// Solution to 2011 MCPC Problem D: Su-domino-ku
// 10/8/2013

import java.util.*;

public class d {

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);
		int n = stdin.nextInt();
		int loop = 1;

		while (n != 0) {

			// Just get initial tiles.
			board sudoku = new board();
			for (int i=0; i<n; i++) {
				int t1 = stdin.nextInt();
				String p1 = stdin.next();
				int t2 = stdin.nextInt();
				String p2 = stdin.next();
				sudoku.addSquare(p1, t1-1);
				sudoku.addSquare(p2, t2-1);
				sudoku.markUsed(t1-1, t2-1);
			}

			// Put in fixed 0 to 8, this is what I am storing, consistently!
			for (int i=0; i<9; i++) {
				String p = stdin.next();
				sudoku.addSquare(p, i);
			}

			// Solve & print.
			boolean ans = sudoku.solve();
			System.out.println("Puzzle "+loop);
			sudoku.print();

			// Get next case.
			n = stdin.nextInt();
			loop++;
		}
	}
}

class board {

	public final static int UNFILLED = -1;

	public int[] grid;
	public boolean[][] used;
	public boolean[] immutable;

	public board() {
		grid = new int[81];
		Arrays.fill(grid, UNFILLED);
		used = new boolean[9][9];
		immutable = new boolean[81];
	}

	public void addSquare(String loc, int value) {
		grid[9*(loc.charAt(0)-'A') + (loc.charAt(1)-'1')] = value;
		immutable[9*(loc.charAt(0)-'A') + (loc.charAt(1)-'1')] = true;
	}

	public void markUsed(int r, int c) {
		if (r > c) {
			int temp = r;
			r = c;
			c = temp;
		}
		used[r][c] = true;
	}

	public boolean solve() {
		return solve(0);
	}

	public boolean solve(int slot) {

		// Woo hoo, we solved it!
		if (slot == 81) return true;

		// This spot's already taken.
		if (immutable[slot])
			return solve(slot+1);

		// Skip over this slot for now.
		if (grid[slot] != UNFILLED) {
			boolean answer = solve(slot+1);
			if (answer) return true;
		}

		// Go through each unused tile and try it here.
		/*** Using 0-based indexes here. ***/
		for (int i=0; i<9; i++) {
			for (int j=i+1; j<9; j++) {
				if (!used[i][j]) {

					// Place horizontal in numerical order.
					if (canPlaceHoriz(slot, i, j)) {
						used[i][j] = true;
						placeHoriz(slot, i, j);
						boolean answer = solve(slot+1);
						if (answer) return true;
						unDoHoriz(slot);
						used[i][j] = false;
					}

					// Place horizontal in reverse numerical order.
					if (canPlaceHoriz(slot, j, i)) {
						used[i][j] = true;
						placeHoriz(slot, j, i);
						boolean answer = solve(slot+1);
						if (answer) return true;
						unDoHoriz(slot);
						used[i][j] = false;
					}

					// Place vertical in numerical order.
					if (canPlaceVert(slot, i, j)) {
						used[i][j] = true;
						placeVert(slot, i, j);
						boolean answer = solve(slot+1);
						if (answer) return true;
						unDoVert(slot);
						used[i][j] = false;
					}

					// Place vertical in reverse numerical order.
					if (canPlaceVert(slot, j, i)) {
						used[i][j] = true;
						placeVert(slot, j, i);
						boolean answer = solve(slot+1);
						if (answer) return true;
						unDoVert(slot);
						used[i][j] = false;
					}
				}
			}
		}

		return false;
	}

	public void unDoHoriz(int slot) {
		grid[slot] = -1;
		grid[slot+1] = -1;
	}

	public void unDoVert(int slot) {
		grid[slot] = -1;
		grid[slot+9] = -1;
	}

	public void placeHoriz(int slot, int i, int j) {
		grid[slot] = i;
		grid[slot+1] = j;
	}

	public void placeVert(int slot, int i, int j) {
		grid[slot] = i;
		grid[slot+9] = j;
	}

	// i, j are 0 based, but in grid they are 1-based.
	public boolean canPlaceHoriz(int slot, int i, int j) {

		// Out of bounds.
		if (slot%9 == 8) return false;
		if (grid[slot] != UNFILLED) return false;
		if (grid[slot+1] != UNFILLED) return false;

		// Violate one of our three principles.
		if (rowContains(slot, i) || colContains(slot, i) || boxContains(slot, i)) return false;
		if (rowContains(slot+1, j) || colContains(slot+1, j) || boxContains(slot+1, j)) return false;

		// Okay if we get here.
		return true;
	}

	public boolean canPlaceVert(int slot, int i, int j) {

		// Out of bounds.
		if (slot/9 == 8) return false;
		if (grid[slot] != UNFILLED) return false;
		if (grid[slot+9] != UNFILLED) return false;

		// Violate one of our three principles.
		if (rowContains(slot, i) || colContains(slot, i) || boxContains(slot, i)) return false;
		if (rowContains(slot+9, j) || colContains(slot+9, j) || boxContains(slot+9, j)) return false;

		// Okay if we get here.
		return true;
	}

	// Returns true iff the row of slot contains item.
	public boolean rowContains(int slot, int item) {
		int start = 9*(slot/9);
		for (int i=start; i<start+9; i++)
			if (grid[i] == item)
				return true;
		return false;
	}

	// Returns true iff the column of slot contains item.
	public boolean colContains(int slot, int item) {
		int start = slot%9;
		for (int i=start; i<81; i+=9)
			if (grid[i] == item)
				return true;
		return false;
	}

	// Returns true iff the box of slot contains item.
	public boolean boxContains(int slot, int item) {

		// Parse out box.
		int row = slot/9;
		int col = slot%9;
		int boxR = row/3;
		int boxC = col/3;

		// Here is how to index it.
		for (int i=3*boxR; i<3*boxR+3; i++)
			for (int j=3*boxC; j<3*boxC+3; j++)
				if (grid[9*i+j] == item)
					return true;
		return false;
	}

	// Prints current state of the game board.
	public void print() {
		for (int i=0; i<9; i++) {
			for (int j=0; j<9; j++)
				System.out.print(grid[9*i+j]+1);
			System.out.println();
		}
	}
}