#include <iostream>
#include <iomanip>
using namespace std;

const int SIZE = 15;
const int NUMCOLORS = 20;
const int MAX = 32768;		// NUMCOLORS^SIZE must be <= this value
const int MAXGUESS = 10;

char *check = "DFEA";  // debugging purposes

struct code {
	char vals[SIZE];
} codes[MAX], guesses[MAXGUESS];
int nCodes;				// number of possible codes

struct ans {
	int b, w;
} answer[MAXGUESS];

int possible[MAX];		// index to possible answer codes
int nPoss;

void genCodes(int i, int size, int numColor, int code[])
//
// generate and store all possible code for a given size and given number
// of colors
//
{
	if (i == size) {
		for(int j=0; j<size; j++)
			codes[nCodes].vals[j] = code[j];
		nCodes++;
	}
	else {
		for(int j=0; j<numColor; j++) {
			code[i] = 'A' + j;
			genCodes(i+1, size, numColor, code);
		}
	}
}

void printCode(int c, int size)
{
	for(int i=0; i<size; i++)
		cout << codes[c].vals[i];
}

void calc(code guess, code code, int size, int &b, int &w)
//
// determine number of black and white answer pegs for a given guess vs.
// a given code
//
{
	w = b = 0;
	for(int i=0; i<size; i++) {
		if (guess.vals[i] == code.vals[i]) {
			b++;
			guess.vals[i] = -1;
			code.vals[i] = -2;
		}
	}
	for(int i=0; i<size; i++) {
		for(int j=0; j<size; j++) {
			if (guess.vals[i] == code.vals[j]) {
				w++;
				guess.vals[i] = -1;
				code.vals[j] = -2;
			}
		}
	}
}

void determinePoss(code guesses[], ans answer[], int numGuess, int size)
//
// determine all possible codes that comply with a given set of guesses
//
{
	nPoss = 0;
	for(int i=0; i<nCodes; i++) {
		int b, w;
		int j;
		for(j=0; j<numGuess; j++) {
			calc(guesses[j], codes[i], size, b, w);
			if (b != answer[j].b || w != answer[j].w) {
				break;
			}
		}
		if (j == numGuess) {
			possible[nPoss++] = i;
		}
	}
}


int partition(code guess, int icodes[], int n, int size)
//
// determine how a given guess partitions remaining possible codes
//
// guess - the players guess
// icodes - list of remaining possible codes
// n - size of icodes
// size - length of codewords
//
// return value - size of maximum set in partition
//
{
	int ans[SIZE+1][SIZE+1];
	int black, white;
	for(black=0; black<=size; black++)
		for(white=0; white<=size; white++)
			ans[black][white] = 0;
	for(int i=0; i<n; i++) {
		calc(guess, codes[icodes[i]], size, black, white);
		ans[black][white]++;
	}
	int max = ans[size-1][0];				// only possible one for size-1 blacks
	for(int j=0; j<size-1; j++) {			// no need to check for size blacks
		for(int k=0; k<=size-j; k++)
			if (ans[j][k] > max) {
				max = ans[j][k];
			}
	}
	return max;
}

int main()
{
	int i, j;
	int size, numColor, numGuess;
	int numCase;
	cin >> numCase;
	for(int iCase = 1; iCase <= numCase; iCase++) {
		cin >> size >> numColor >> numGuess;
		nCodes = 0;
		int *temp = new int[size];
		genCodes(0, size, numColor, temp);
		for(i=0; i<numGuess; i++) {
			for(j=0; j<size; j++)
				cin >> guesses[i].vals[j];
			cin >> answer[i].b >> answer[i].w;
		}
		determinePoss(guesses, answer, numGuess, size);
		int best = partition(codes[0], possible, nPoss, size);
		int c = 0;
		for(i=1; i<nCodes; i++) {
			int max = partition(codes[i], possible, nPoss, size);
			if (max < best) {
				best = max;
				c = i;
			}
		}
		printCode(c, size);
		cout << ' ' << best << endl;
	}
return 0;
}
