# Arup Guha
# 6/26/2017
# Example for SI@UCF - Determines # of possible solutions to a mastermind game
# given a game transcript.

import random

# Global variables for ease of parameter passing.
numslots = 0
numcolors = 0
nummoves = 0

# Global lists for ease of parameter passing.
guesses = []
black = []
white = []

def main():

    global numslots
    global numcolors
    global nummoves
    global guesses
    global black
    global white

    # Open the input file.
    myfile = open('mastermind.in', 'r')
    numCases = int(myfile.readline().strip())

    # Process each input case.
    for loop in range(numCases):

        # Get key input items for this case.
        toks = myfile.readline().split()
        numslots = int(toks[0])
        numcolors = int(toks[1])
        nummoves = int(toks[2])

        # Initialize these.
        guesses = []
        black = []
        white = []
        
        # Go through each move - store into guesses, white and black.
        for i in range(nummoves):

            # Parse out guess and white and black.
            toks = myfile.readline().split()
            combo = []
            for j in range(numslots):
                combo.append(int(toks[j]))
            guesses.append(combo)
            black.append(int(toks[numslots]))
            white.append(int(toks[numslots+1]))
        
        # Store our potential solution here (our odometer!)
        potential = []
        for i in range(numslots):
            potential.append(-1)

        # We modify our odometer function to return the number of viable solutions.                     
        res = solve(potential, 0)                
        print(res)
                             
    # Good style to close it.
    myfile.close()

# Edit of the odometer - returns the number of solutions where the first
# k items of curlist (potential solution) are fixed and there are numD
# potential colors.
def solve(curlist, k):

    global guesses
    global black
    global white
    global numslots
    global numcolors
    global nummoves
    
    # We've filled out a setting.
    if k == len(curlist):
        return evaluate(curlist)

    # Try each possible digits (0 to numD-1) in slot k and add up solutions
    # from each branch.
    res = 0
    for i in range(numcolors):
        curlist[k] = i
        res += solve(curlist, k+1)

    return res

# Returns 1 iff curlist is consistent with the game transcript.
def evaluate(curlist):

    global guesses
    global black
    global white
    global numslots
    global numcolors
    global nummoves
    
    # Go through each move.
    for i in range(nummoves):

        # Calculate how many white and black pegs this guess would get
        # if curlist was the actual answer.
        bCnt = getperfectmatch(curlist, guesses[i])
        allmatch = getallmatches(curlist, guesses[i])
        wCnt = allmatch - bCnt

        # This clue isn't possible so curlist CAN'T be the actual solution.
        if wCnt != white[i] or bCnt != black[i]:
            return 0

    # If we get here, this is a single consistent solution.
    return 1                             
                             
# Counts the number of 'perfect' matches (correct colors correct squares)
def getperfectmatch(sol, guess):

    global numslots
    
    # For each slot, see if there's a match.
    cnt = 0
    for i in range(numslots):
        if sol[i] == guess[i]:
            cnt = cnt + 1

    return cnt

# Counts all of the matches.
def getallmatches(sol, guess):

    global numslots
    global numcolors
    
    total = 0

    #Loop through each color
    for col in range(numcolors):

        # Count the frequency of col in the solution.
        cntsol = 0
        for i in range(numslots):
            if sol[i] == col:
                cntsol = cntsol + 1

        # Count the frequency of col in the guess.
        cntguess = 0
        for i in range(numslots):
            if guess[i] == col:
                cntguess = cntguess + 1

        # The number of matches is the minimum of these two.
        if cntsol < cntguess:
            total = total + cntsol
        else:
            total = total + cntguess

    # This is all of the matches
    return total

# Get it all started.
main()
