// Arup Guha
// Java Solution to Match Making - Converted from C solution
// Original conversion by TA on 7/20/2011
// Edited on 3/18/2015 to use recursive permutations.

import java.util.*;

public class matching {

    public static int best_score;
    public static int best_diff;
	public static int[] best_perm;
	public static int[][] men_ratings;
	public static int[][] women_ratings;

	public static void main(String[] args) {

		Scanner input = new Scanner(System.in);
		int numcases = input.nextInt();

		// Loop through each case
		for (int loop = 1; loop <= numcases; loop++) {

			// Get the number of couples
			int size = input.nextInt();

			// Read in everyone's names.
			String[] men = new String[size];
			String[] women = new String[size];

			for (int i = 0; i < size; i++)
				men[i] = input.next();
			for (int i = 0; i < size; i++)
				women[i] = input.next();

			// Read in everyone's ratings.
			men_ratings = new int[size][size];
			women_ratings = new int[size][size];

			for (int i = 0; i < size; i++)
				for (int j = 0; j < size; j++)
					men_ratings[i][j] = input.nextInt();
			for (int i = 0; i < size; i++)
				for (int j = 0; j < size; j++)
					women_ratings[i][j] = input.nextInt();

            // Set up recursion and solve.
            best_score = 0;
		    best_diff = 0;
			int[] fem_perm = new int[size];
			boolean[] used = new boolean[size];
			solve(fem_perm, used, 0);

			// Output the answers.
			System.out.println("Matching #" + loop + ": Maximum Score = " + best_score + ".");
			System.out.println();

			for (int i = 0; i < size; i++)
				System.out.println(men[i] + " " + women[best_perm[i]]);

			System.out.println();
			System.out.println();
		}
	}

	public static void solve(int[] fem_perm, boolean[] used, int k) {

        // Finished perm - evaluate.
        if (k == fem_perm.length) {

            // Calculate the score and difference of the current permutation of females against their male matches
            int this_score = getMatchScore(fem_perm);
            int this_diff = getMatchDiff(fem_perm);

            // See if we have a new best matching
            if (this_score > best_score || (this_score == best_score && this_diff < best_diff)) {
                best_perm = Arrays.copyOf(fem_perm, fem_perm.length);
                best_score = this_score;
                best_diff = this_diff;
            }
        }

        // Recursive case.
        else {

            // Typical recursive permutation algorithm.
            for (int i=0; i<fem_perm.length; i++) {
                if (!used[i]) {
                    used[i] = true;
                    fem_perm[k] = i;
                    solve(fem_perm, used, k+1);
                    used[i] = false;
                }
            }
        }
	}

	// Method: getMatchScore
	// Returns the match score of all the women matched with the men in their current order
	public static int getMatchScore(int[] perm) {
		int score = 0;
		for (int i = 0; i < perm.length; i++) {
			// Guy was more stingy here.
			if (men_ratings[i][perm[i]] < women_ratings[perm[i]][i])
				score += men_ratings[i][perm[i]];
			// Gal was more stingy here.
			else
				score += women_ratings[perm[i]][i];
		}

		return score;
	}

	// Method: getMatchDiff
	// Returns the match difference between all of the women matched with the men in their current order
	public static int getMatchDiff(int[] perm)
	{
		// Go through each couple and just add in the difference of scores.
	    int score = 0;
	    for (int i = 0; i < perm.length; i++)
	        score += Math.abs(men_ratings[i][perm[i]]-women_ratings[perm[i]][i]);

	    return score;
	}
}
