// Arup Guha
// 9/14/2015
// Solution to 2015 Fall COP 3502 Program #3: Mastermind

#include <stdio.h>
#include <stdlib.h>

int numPerfectMatches(int* board, int* answer);
int solve(int* combo, int k);
int eval(int* combo);
int numWrongMatches(int* board, int* answer);
int totalMatches(int* board, int* answer);
int* getColorChart(int* board);
int sumMatches(int* colors1, int* colors2);
int min(int a, int b);

// Making these global so our recursive function isn't over-burdened with variables.
int numSlots, numColors, numMoves;
int** guesses;
int* correct;
int* incorrect;

int main() {

    int loop, numCases;
    scanf("%d", &numCases);

    // Process each case.
    for (loop=0; loop<numCases; loop++) {

        int i, j;
        scanf("%d%d%d", &numSlots, &numColors, &numMoves);

        // Make space for guess table and results of guesses.
        guesses = calloc(numMoves, sizeof(int*));
        correct = calloc(numMoves, sizeof(int));
        incorrect = calloc(numMoves, sizeof(int));

        for (i=0; i<numMoves; i++)
            guesses[i] = calloc(numSlots, sizeof(int));

        // Read in all guess data here.
        for (i=0; i<numMoves; i++) {
            for (j=0; j<numSlots; j++)
                scanf("%d", &guesses[i][j]);
            scanf("%d%d", &correct[i], &incorrect[i]);
        }

        // Store combo we're filling in here.
        int* combo = calloc(numSlots, sizeof(int));

        // Make initial recursive call and print solution.
        printf("%d\n", solve(combo, 0));

        // Memory clean up.
        for (i=0; i<numMoves; i++)
            free(guesses[i]);
        free(guesses);
        free(correct);
        free(incorrect);
        free(combo);
    }

    return 0;
}

// Returns the number of possible solutions given that the first k slots of combo are
// fixed to their current value.
int solve(int* combo, int k) {

    // Base case - all slots filled in.
    if (k == numSlots) return eval(combo);

    int i, sum = 0;

    // Try each color in slot k.
    for (i=0; i<numColors; i++) {
        combo[k] = i;
        sum += solve(combo, k+1);
    }

    // Here is our total number of solutions.
    return sum;
}

// Returns 1 iff combo is consistent with given information, 0 otherwise.
int eval(int* combo) {

    int i;

    // Look at each guess.
    for (i=0; i<numMoves; i++) {

        // Get the matches between the guess and this combo.
        int correctMatches = numPerfectMatches(guesses[i], combo);
        int incorrectMatches = numWrongMatches(guesses[i], combo);

        // If the results aren't identical to what was given, it couldn't have been this combo!
        if (correctMatches != correct[i] || incorrectMatches != incorrect[i])
            return 0;
    }

    // If we get here, we're good!
    return 1;
}

// Returns the number of perfect matches between board and answer.
int numPerfectMatches(int* board, int* answer) {

    int i;
    int numMatches = 0;

    // Go through each slot once, seeing if corresponding slots match.
    for (i=0; i<numSlots; i++)
        if (board[i] == answer[i])
            numMatches++;

    // Return the correct number of matches.
    return numMatches;
}

// A wrapper function to make the code easier to read.
int numWrongMatches(int* board, int* answer) {
    return totalMatches(board, answer) - numPerfectMatches(board, answer);
}

// Returns the number of total matches, correct and incorrect between board and answer.
int totalMatches(int* board, int* answer) {

    // Get frequencies of both boards.
    int* boardColors = getColorChart(board);
    int* answerColors = getColorChart(answer);

    // Solve, free memory and return answer.
    int res = sumMatches(boardColors, answerColors);
    free(boardColors);
    free(answerColors);
    return res;
}

// Returns a frequency chart of each color on board.
int* getColorChart(int* board) {

    int i;
    int* colors = calloc(numColors, sizeof(int));
    for (i=0; i<numSlots; i++)
        colors[board[i]]++;
    return colors;
}

// Return the total number of matches between color frequencies colors1 and colors2.
int sumMatches(int* colors1, int* colors2) {

    int sum = 0, i;

    // For each color, the minimum between the two combos is what we want to count.
    for (i=0; i<numColors; i++)
        sum += min(colors1[i], colors2[i]);
    return sum;
}

// Returns the minimum of a and b.
int min(int a, int b) {
    return a < b ? a : b;
}
