Chess is a very popular game played by hundreds of millions of people. Nowadays, we have chess engines such as Stockfish and Komodo to help us analyze games. These engines are very powerful pieces of well-developed software that use intelligent ideas and algorithms to analyze positions and sequences of moves, as well as find tactical ideas. Consider the following simplified version of chess:

Board: It's played on a $4\times4$ board between two players named Black and White. 
Pieces and Movement: 

White initially has $\boldsymbol{w}$ pieces and Black initially has $\boldsymbol{b}$ pieces. 
There are no Kings and no Pawns on the board. Each player has exactly one Queen, at most two Rooks, and at most two minor pieces (i.e., a Bishop and/or Knight). 
Each piece's possible moves are the same as in classical chess, and each move made by any player counts as a single move.
There is no draw when positions are repeated as there is in classical chess.
Objective: The goal of the game is to capture the opponent’s Queen without losing your own. 

Given $m$ and the layout of pieces for $\mathrm{~g~}$ games of simplified chess, implement a very basic (in comparison to the real ones) engine for our simplified version of chess with the ability to determine whether or not White can win in $\leq m$ moves (regardless of how Black plays) if White always moves first. For each game, print YES on a new line if White can win under the specified conditions; otherwise, print NO.

Input Format

The first line contains a single integer, $\mathrm{~g~}$, denoting the number of simplified chess games. The subsequent lines define each game in the following format:

The first line contains three space-separated integers denoting the respective values of $\boldsymbol{w}$ (the number of White pieces), $\boldsymbol{b}$ (the number of Black pieces), and $m$ (the maximum number of moves we want to know if White can win in).   
The $w+b$ subsequent lines describe each chesspiece in the format t c r, where $\boldsymbol{\boldsymbol{t}}$ is a character $\in\{Q,N,B,R\}$ denoting the type of piece (where $\mbox{Q}$ is Queen, $N$ is Knight, $\mbox{B}$ is Bishop, and $\mbox{R}$ is Rook), and $c$ and $r$ denote the respective column and row on the board where the figure is placed (where $c\in\{A,B,C,D\}$ and $r\in\{1,2,3,4\}$). These inputs are given as follows:
Each of the $\boldsymbol{w}$ subsequent lines denotes the type and location of a White piece on the board. 
Each of the $\boldsymbol{b}$ subsequent lines denotes the type and location of a Black piece on the board.

Constraints

It is guaranteed that the locations of all pieces given as input are distinct.
$1\leq g\leq200$    
$1\leq w,b\leq5$  
$1\leq m\leq6$  
Each player initially has exactly one Queen, at most two Rooks and at most two minor pieces.

Output Format

For each of the $\mathrm{~g~}$ games of simplified chess, print whether or not White can win in $\leq m$ moves on a new line. If it's possible, print YES; otherwise, print NO.

Sample Input 0
1
2 1 1
N B 2
Q B 1
Q A 4

Sample Output 0
YES

Explanation 0

We play $g=1$ games of simplified chess, where the initial piece layout is as follows:

White is the next to move, and they can win the game in $1$ move by taking their Knight to $A4$ and capturing Black's Queen. Because it took $1$ move to win and $1\leq m$, we print YES on a new line.

Source: hackerrank | Difficulty: MEDIUM
Tags: Complete search


Solutions:
N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


knight_directions = {(0, 1): ((2, 0), (2, 2), (1, 3)), (1, 2): ((3, 1), (3, 3), (0, 0), (2, 0)), (3, 2): ((1, 1), (1, 3), (2, 0)), (0, 0): ((2, 1), (1, 2)), (3, 3): ((1, 2), (2, 1)), (3, 0): ((1, 1), (2, 2)), (3, 1): ((1, 0), (1, 2), (2, 3)), (2, 1): ((0, 0), (0, 2), (1, 3), (3, 3)), (0, 2): ((2, 1), (2, 3), (1, 0)), (2, 0): ((0, 1), (1, 2), (3, 2)), (1, 3): ((3, 2), (0, 1), (2, 1)), (2, 3): ((0, 2), (1, 1), (3, 1)), (2, 2): ((0, 1), (0, 3), (1, 0), (3, 0)), (1, 0): ((3, 1), (0, 2), (2, 2)), (0, 3): ((2, 2), (1, 1)), (1, 1): ((3, 0), (3, 2), (0, 3), (2, 3))}

def KnightMoves(board, side, pos):
	other = 1 - side
	for step in knight_directions[pos]:
		if step in board[other]:
			res = tuple((item.copy() for item in board))
			del res[side][pos]
			del res[other][step]
			res[side][step] = 'N'
			yield res
		elif step not in board[side]:
			res = tuple((item.copy() for item in board))
			del res[side][pos]
			res[side][step] = 'N'
			yield res
	raise StopIteration
bishop_directions = {(0, 1): (((1, 2), (2, 3)), ((1, 0),)), (1, 2): (((2, 3),), ((2, 1), (3, 0)), ((0, 3),), ((0, 1),)), (3, 2): (((2, 3),), ((2, 1), (1, 0))), (0, 0): (((1, 1), (2, 2), (3, 3)),), (3, 3): (((2, 2), (1, 1), (0, 0)),), (3, 0): (((2, 1), (1, 2), (0, 3)),), (3, 1): (((2, 2), (1, 3)), ((2, 0),)), (2, 1): (((3, 2),), ((3, 0),), ((1, 2), (0, 3)), ((1, 0),)), (0, 2): (((1, 3),), ((1, 1), (2, 0))), (2, 0): (((3, 1),), ((1, 1), (0, 2))), (1, 3): (((2, 2), (3, 1)), ((0, 2),)), (2, 3): (((3, 2),), ((1, 2), (0, 1))), (2, 2): (((3, 3),), ((3, 1),), ((1, 3),), ((1, 1), (0, 0))), (1, 0): (((2, 1), (3, 2)), ((0, 1),)), (0, 3): (((1, 2), (2, 1), (3, 0)),), (1, 1): (((2, 2), (3, 3)), ((2, 0),), ((0, 2),), ((0, 0),))}

def BishopMoves(board, side, pos):
	other = 1 - side
	for direction in bishop_directions[pos]:
		for step in direction:
			if step in board[other]:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				del res[other][step]
				res[side][step] = 'B'
				yield res
				break
			elif step in board[side]:
				break
			else:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				res[side][step] = 'B'
				yield res
	raise StopIteration
rook_directions = {(0, 1): (((1, 1), (2, 1), (3, 1)), ((0, 0),), ((0, 2), (0, 3))), (1, 2): (((2, 2), (3, 2)), ((1, 1), (1, 0)), ((1, 3),), ((0, 2),)), (3, 2): (((3, 1), (3, 0)), ((3, 3),), ((2, 2), (1, 2), (0, 2))), (0, 0): (((1, 0), (2, 0), (3, 0)), ((0, 1), (0, 2), (0, 3))), (3, 3): (((3, 2), (3, 1), (3, 0)), ((2, 3), (1, 3), (0, 3))), (3, 0): (((3, 1), (3, 2), (3, 3)), ((2, 0), (1, 0), (0, 0))), (3, 1): (((3, 0),), ((3, 2), (3, 3)), ((2, 1), (1, 1), (0, 1))), (2, 1): (((3, 1),), ((2, 0),), ((2, 2), (2, 3)), ((1, 1), (0, 1))), (0, 2): (((1, 2), (2, 2), (3, 2)), ((0, 1), (0, 0)), ((0, 3),)), (2, 0): (((3, 0),), ((2, 1), (2, 2), (2, 3)), ((1, 0), (0, 0))), (1, 3): (((2, 3), (3, 3)), ((1, 2), (1, 1), (1, 0)), ((0, 3),)), (2, 3): (((3, 3),), ((2, 2), (2, 1), (2, 0)), ((1, 3), (0, 3))), (2, 2): (((3, 2),), ((2, 1), (2, 0)), ((2, 3),), ((1, 2), (0, 2))), (1, 0): (((2, 0), (3, 0)), ((1, 1), (1, 2), (1, 3)), ((0, 0),)), (0, 3): (((1, 3), (2, 3), (3, 3)), ((0, 2), (0, 1), (0, 0))), (1, 1): (((2, 1), (3, 1)), ((1, 0),), ((1, 2), (1, 3)), ((0, 1),))}

def RookMoves(board, side, pos):
	other = 1 - side
	for direction in rook_directions[pos]:
		for step in direction:
			if step in board[other]:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				del res[other][step]
				res[side][step] = 'R'
				yield res
				break
			elif step in board[side]:
				break
			else:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				res[side][step] = 'R'
				yield res
	raise StopIteration
queen_directions = {pos: rook_directions[pos] + bishop_directions[pos] for pos in rook_directions}

def QueenMoves(board, side, pos):
	other = 1 - side
	for direction in queen_directions[pos]:
		for step in direction:
			if step in board[other]:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				del res[other][step]
				res[side][step] = 'Q'
				yield res
				break
			elif step in board[side]:
				break
			else:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				res[side][step] = 'Q'
				yield res
	raise StopIteration
func_dict = {'Q': QueenMoves, 'N': KnightMoves, 'B': BishopMoves, 'R': RookMoves}

def checkcont(board):
	return 'Q' in board[0].values()

def checkwin(board):
	return 'Q' not in board[1].values()

def GetResult(board, layer=0):
	if any(map(checkwin, NextMove(board, 0))):
		return True
	if not layer:
		return False
	for newboard in NextMove(board, 0):
		temp = tuple(NextMove(newboard, 1))
		if all(map(checkcont, temp)) and all((GetResult(newround, layer - 1) for newround in temp)):
			return True
	return False

def NextMove(board, side):
	curr = board[side]
	for pos in curr:
		for newboard in func_dict[curr[pos]](board, side, pos):
			yield newboard
posdict = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
for _ in range(int(input())):
	(w, b, m) = map(int, input().split())
	board = ({}, {})
	for _ in range(w):
		(t, c, r) = input().split()
		board[0][posdict[c], int(r) - 1] = t
	for _ in range(b):
		(t, c, r) = input().split()
		board[1][posdict[c], int(r) - 1] = t
	print('YES' if GetResult(board, (m - 1) // 2) else 'NO')


from copy import deepcopy
INDEX_1 = '1234'
INDEX_2 = 'ABCD'

def parse_piece(player, board):
	(type, column, row) = input().split()
	board[INDEX_1.index(row)][INDEX_2.index(column)] = player + type

def player_won(board, player):
	search_tile = invert_player(player) + 'Q'
	return not any((tile == search_tile for sub_board in board for tile in sub_board))

def invert_player(player):
	if player == 'W':
		return 'B'
	elif player == 'B':
		return 'W'
	else:
		raise ValueError("player can only be 'W' or 'B', not '%s'" % player)

def is_tile_obstructed(board, row, column, player):
	return row not in range(len(board)) or column not in range(len(board[row])) or player == board[row][column][0]

def generate_possible_moves(board, row, column):
	tile = board[row][column]
	player = tile[0]
	type = tile[1]
	if type == 'N':
		moves = [(1, 2), (-1, 2), (1, -2), (-1, -2), (2, 1), (-2, 1), (2, -1), (-2, -1)]
		for move in moves:
			dest_row = row + move[0]
			dest_col = column + move[1]
			if not is_tile_obstructed(board, dest_row, dest_col, player):
				yield (dest_row, dest_col)
	else:
		directions = []
		if type == 'Q' or type == 'R':
			directions += [(0, 1), (0, -1), (1, 0), (-1, 0)]
		if type == 'Q' or type == 'B':
			directions += [(1, 1), (-1, 1), (1, -1), (-1, -1)]
		for dir in directions:
			(dir_row, dir_col) = dir
			(cur_row, cur_col) = (row + dir_row, column + dir_col)
			while not is_tile_obstructed(board, cur_row, cur_col, player):
				yield (cur_row, cur_col)
				if board[cur_row][cur_col][0] == invert_player(player):
					break
				cur_row += dir_row
				cur_col += dir_col

def can_win(board, current_player, moves_left):
	if player_won(board, 'W'):
		return True
	if player_won(board, 'B'):
		return False
	if moves_left == 0:
		return False
	ret = current_player != 'W'
	for row in range(len(board)):
		for column in range(len(board[row])):
			tile = board[row][column]
			if current_player == tile[0]:
				for move in generate_possible_moves(board, row, column):
					(dest_row, dest_col) = move
					dest_tile = board[dest_row][dest_col]
					board[row][column] = '__'
					board[dest_row][dest_col] = tile
					stop = False
					if current_player == 'W':
						if ret == False:
							ret = can_win(board, invert_player(current_player), moves_left - 1)
							if ret == True:
								stop = True
					elif ret == True:
						ret = can_win(board, invert_player(current_player), moves_left - 1)
						if ret == False:
							stop = True
					board[row][column] = tile
					board[dest_row][dest_col] = dest_tile
					if stop:
						return ret
	return ret
for _ in range(int(input())):
	(num_white, num_black, max_moves) = map(int, input().split())
	board = [['__' for _ in range(4)] for _ in range(4)]
	for _ in range(num_white):
		parse_piece('W', board)
	for _ in range(num_black):
		parse_piece('B', board)
	if can_win(board, 'W', max_moves):
		print('YES')
	else:
		print('NO')


SIZE = 4

def queen(row, col, p1, p2):
	return rook(row, col, p1, p2) + bishop(row, col, p1, p2)

def rook(row, col, p1, p2):
	moves = []
	for r in range(row - 1, -1, -1):
		if (r, col) in p1:
			break
		if (r, col) in p2:
			moves.append((r, col))
			break
		moves.append((r, col))
	for r in range(row + 1, SIZE):
		if (r, col) in p1:
			break
		if (r, col) in p2:
			moves.append((r, col))
			break
		moves.append((r, col))
	for c in range(col - 1, -1, -1):
		if (row, c) in p1:
			break
		if (row, c) in p2:
			moves.append((row, c))
			break
		moves.append((row, c))
	for c in range(col + 1, SIZE):
		if (row, c) in p1:
			break
		if (row, c) in p2:
			moves.append((row, c))
			break
		moves.append((row, c))
	return moves

def bishop(row, col, p1, p2):
	moves = []
	r = row - 1
	c = col - 1
	while r > -1 and c > -1:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r -= 1
		c -= 1
	r = row + 1
	c = col - 1
	while r < SIZE and c > -1:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r += 1
		c -= 1
	r = row - 1
	c = col + 1
	while r > -1 and c < SIZE:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r -= 1
		c += 1
	r = row + 1
	c = col + 1
	while r < SIZE and c < SIZE:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r += 1
		c += 1
	return moves

def knight(row, col, player):
	moves = []
	if row - 1 > 0:
		if col > 0 and (not (row - 2, col - 1) in player):
			moves.append((row - 2, col - 1))
		if col + 1 < SIZE and (not (row - 2, col + 1) in player):
			moves.append((row - 2, col + 1))
	if row + 2 < SIZE:
		if col > 0 and (not (row + 2, col - 1) in player):
			moves.append((row + 2, col - 1))
		if col + 1 < SIZE and (not (row + 2, col + 1) in player):
			moves.append((row + 2, col + 1))
	if col - 1 > 0:
		if row > 0 and (not (row - 1, col - 2) in player):
			moves.append((row - 1, col - 2))
		if row + 1 < SIZE and (not (row + 1, col - 2) in player):
			moves.append((row + 1, col - 2))
	if col + 2 < SIZE:
		if row > 0 and (not (row - 1, col + 2) in player):
			moves.append((row - 1, col + 2))
		if row + 1 < SIZE and (not (row + 1, col + 2) in player):
			moves.append((row + 1, col + 2))
	return moves

def canPlayer(W, B, m, rw, cw, rb, cb, isWhite):
	(movesQ, movesN, movesB, movesR, movesNX, movesBX, movesRX) = ([], [], [], [], [], [], [])
	white = [(r, c) for (r, c, _) in W]
	black = [(r, c) for (r, c, _) in B]
	for (row, col, pc) in W:
		if pc == 'Q':
			movesQ = queen(row, col, white, black)
			if (rb, cb) in movesQ:
				return True
		elif pc == 'N':
			movesN = knight(row, col, white)
			if (rb, cb) in movesN:
				return True
		elif pc == 'B':
			movesB = bishop(row, col, white, black)
			if (rb, cb) in movesB:
				return True
		elif pc == 'R':
			movesR = rook(row, col, white, black)
			if (rb, cb) in movesR:
				return True
		elif pc == 'NX':
			movesNX = knight(row, col, white)
			if (rb, cb) in movesNX:
				return True
		elif pc == 'BX':
			movesBX = bishop(row, col, white, black)
			if (rb, cb) in movesBX:
				return True
		elif pc == 'RX':
			movesRX = rook(row, col, white, black)
			if (rb, cb) in movesRX:
				return True
	if isWhite and m <= 2:
		return False
	for i in range(len(W)):
		for (r, c) in eval('moves' + W[i][2]):
			Wcopy = W[:]
			del Wcopy[i]
			Wcopy.append((r, c, W[i][2]))
			Bcopy = B[:]
			if (r, c) in black:
				for j in range(len(B)):
					if B[j][0] == r and B[j][1] == c:
						del Bcopy[j]
						break
			if W[i][2] == 'Q':
				blackWin = canPlayer(Bcopy, Wcopy, m - 1, rb, cb, r, c, isWhite ^ True)
			else:
				blackWin = canPlayer(Bcopy, Wcopy, m - 1, rb, cb, rw, cw, isWhite ^ True)
			if not blackWin:
				return True
	return False
for _ in range(int(input())):
	(w, b, moves) = map(int, input().strip().split())
	(W, B) = ([], [])
	typelist = []
	for playerw in range(w):
		(pc, col, row) = input().strip().split()
		if pc in typelist:
			pc = pc + 'X'
		W.append((int(row) - 1, ord(col) - 65, pc))
		typelist.append(pc)
		if pc == 'Q':
			qwr = int(row) - 1
			qwc = ord(col) - 65
	typelist = []
	for playerb in range(b):
		(pc, col, row) = input().strip().split()
		if pc in typelist:
			pc = pc + 'X'
		B.append((int(row) - 1, ord(col) - 65, pc))
		typelist.append(pc)
		if pc == 'Q':
			qbr = int(row) - 1
			qbc = ord(col) - 65
	if canPlayer(W, B, moves, qwr, qwc, qbr, qbc, True):
		print('YES')
	else:
		print('NO')


def cloneboard(board):
	tmp = []
	for elt in board:
		tmp.append(list(elt))
	return tmp

def dispboard(board):
	for c in board:
		print(c)
	print()

def getmoves(board, c, r):
	if board[c][r][0] == 'N':
		return _getknightmoves(board, c, r)
	elif board[c][r][0] == 'B':
		return _getbishopmoves(board, c, r)
	elif board[c][r][0] == 'R':
		return _getrookmoves(board, c, r)
	else:
		tmp1 = _getbishopmoves(board, c, r)
		tmp2 = _getrookmoves(board, c, r)
		return (tmp1[0] + tmp2[0], tmp1[1] or tmp2[1])

def _getknightmoves(board, c, r):
	moves = []
	eatqueen = False
	for i in [2, 1]:
		j = 3 - i
		for k in [1, -1]:
			for l in [1, -1]:
				newc = c + k * i
				newr = r + l * j
				if newc in range(4) and newr in range(4):
					if board[newc][newr] == None or board[newc][newr][1] != board[c][r][1]:
						if board[newc][newr] != None and board[newc][newr][0] == 'Q':
							eatqueen = True
						newboard = cloneboard(board)
						newboard[newc][newr] = board[c][r]
						newboard[c][r] = None
						moves.append(newboard)
	return (moves, eatqueen)

def _getbishopmoves(board, c, r):
	moves = []
	eatqueen = False
	for k in [1, -1]:
		for l in [1, -1]:
			newc = c + k
			newr = r + l
			while newc in range(4) and newr in range(4):
				if board[newc][newr] != None and board[newc][newr][1] == board[c][r][1]:
					break
				if board[newc][newr] != None and board[newc][newr][0] == 'Q':
					eatqueen = True
				newboard = cloneboard(board)
				eat = board[newc][newr] != None
				newboard[newc][newr] = board[c][r]
				newboard[c][r] = None
				moves.append(newboard)
				if eat:
					break
				newc += k
				newr += l
	return (moves, eatqueen)

def _getrookmoves(board, c, r):
	moves = []
	eatqueen = False
	for k in [1, -1]:
		newc = c + k
		while newc in range(4):
			if board[newc][r] != None and board[newc][r][1] == board[c][r][1]:
				break
			if board[newc][r] != None and board[newc][r][0] == 'Q':
				eatqueen = True
			eat = board[newc][r] != None
			newboard = cloneboard(board)
			newboard[newc][r] = board[c][r]
			newboard[c][r] = None
			moves.append(newboard)
			if eat:
				break
			newc += k
	for l in [1, -1]:
		newr = r + l
		while newr in range(4):
			if board[c][newr] != None and board[c][newr][1] == board[c][r][1]:
				break
			if board[c][newr] != None and board[c][newr][0] == 'Q':
				eatqueen = True
			eat = board[c][newr] != None
			newboard = cloneboard(board)
			newboard[c][newr] = board[c][r]
			newboard[c][r] = None
			moves.append(newboard)
			if eat:
				break
			newr += l
	return (moves, eatqueen)

def echecmat(board, m):
	if m < 1:
		return False
	whiteturn = m % 2 == 1
	possibilities = []
	for i in range(4):
		for j in range(4):
			if board[i][j] != None and board[i][j][1] == whiteturn:
				(moves, eatqueen) = getmoves(board, i, j)
				if eatqueen:
					return whiteturn
				possibilities += moves
	for possibility in possibilities:
		if echecmat(possibility, m - 1) == whiteturn:
			return whiteturn
	else:
		return not whiteturn
T = int(input())
for t in range(T):
	(w, b, m) = map(int, input().split(' '))
	board = [[None for j in range(4)] for i in range(4)]
	for i in range(w):
		(t, c, r) = input().split(' ')
		c = ord(c) - ord('A')
		r = int(r) - 1
		board[c][r] = [t, True]
	for i in range(b):
		(t, c, r) = input().split(' ')
		c = ord(c) - ord('A')
		r = int(r) - 1
		board[c][r] = [t, False]
	if m % 2 == 0:
		m -= 1
	result = echecmat(board, m)
	if result:
		print('YES')
	else:
		print('NO')


from copy import deepcopy

class Player:
	d = {'A': 1, 'B': 2, 'C': 3, 'D': 4}

	def __init__(self, p):
		if isinstance(p, str):
			self.name = p
			self.pieces = {}
		else:
			self.name = p.name
			self.pieces = deepcopy(p.pieces)

	def addPieces(self, n):
		idt = {'Q': 0, 'N': 0, 'R': 0, 'B': 0}
		for i in range(n):
			t = input().strip().split()
			self.pieces.update({t[0] + str(idt[t[0]]): (Player.d[t[1]], int(t[2]))})
			idt[t[0]] += 1

	def allMoves(self, P):
		self.pm = {}
		(t, s) = (self.pieces.values(), P.pieces.values())
		for p in self.pieces.items():
			p = (p[0], p[1][0], p[1][1])
			if 'N' in p[0]:
				if p[1] + 2 <= 4:
					if p[2] - 1 > 0 and (p[1] + 2, p[2] - 1) not in t:
						self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] + 2, p[2] - 1),)})
					if p[2] + 1 <= 4 and (p[1] + 2, p[2] + 1) not in t:
						self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] + 2, p[2] + 1),)})
				if p[1] - 2 > 0:
					if p[2] - 1 > 0 and (p[1] - 2, p[2] - 1) not in t:
						self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] - 2, p[2] - 1),)})
					if p[2] + 1 <= 4 and (p[1] - 2, p[2] + 1) not in t:
						self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] - 2, p[2] + 1),)})
				if p[2] + 2 <= 4:
					if p[1] + 1 <= 4 and (p[1] + 1, p[2] + 2) not in t:
						self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] + 1, p[2] + 2),)})
					if p[1] - 1 > 0 and (p[1] - 1, p[2] + 2) not in t:
						self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] - 1, p[2] + 2),)})
				if p[2] - 2 > 0:
					if p[1] + 1 <= 4 and (p[1] + 1, p[2] - 2) not in t:
						self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] + 1, p[2] - 2),)})
					if p[1] - 1 > 0 and (p[1] - 1, p[2] - 2) not in t:
						self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] - 1, p[2] - 2),)})
			else:
				i = 1
				(leap_horiz, leap_up_diag, leap_down_diag) = (False, False, False)
				while p[1] + i <= 4:
					if 'B' not in p[0] and (not leap_horiz):
						if (p[1] + i, p[2]) not in t:
							self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] + i, p[2]),)})
							if (p[1] + i, p[2]) in s:
								leap_horiz = True
						else:
							leap_horiz = True
					if 'R' not in p[0]:
						if p[2] + i <= 4 and (not leap_up_diag):
							if (p[1] + i, p[2] + i) not in t:
								self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] + i, p[2] + i),)})
								if (p[1] + i, p[2] + i) in s:
									leap_up_diag = True
							else:
								leap_up_diag = True
						if p[2] - i > 0 and (not leap_down_diag):
							if (p[1] + i, p[2] - i) not in t:
								self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] + i, p[2] - i),)})
								if (p[1] + i, p[2] - i) in s:
									leap_down_diag = True
							else:
								leap_down_diag = True
					i += 1
				i = 1
				(leap_horiz, leap_up_diag, leap_down_diag) = (False, False, False)
				while p[1] - i > 0:
					if 'B' not in p[0] and (not leap_horiz):
						if (p[1] - i, p[2]) not in t:
							self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] - i, p[2]),)})
							if (p[1] - i, p[2]) in s:
								leap_horiz = True
						else:
							leap_horiz = True
					if 'R' not in p[0]:
						if p[2] + i <= 4 and (not leap_up_diag):
							if (p[1] - i, p[2] + i) not in t:
								self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] - i, p[2] + i),)})
								if (p[1] - i, p[2] + i) in s:
									leap_up_diag = True
							else:
								leap_up_diag = True
						if p[2] - i > 0 and (not leap_down_diag):
							if (p[1] - i, p[2] - i) not in t:
								self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1] - i, p[2] - i),)})
								if (p[1] - i, p[2] - i) in s:
									leap_down_diag = True
							else:
								leap_down_diag = True
					i += 1
				if 'B' not in p[0]:
					i = 1
					leap = False
					while p[2] + i <= 4 and (not leap):
						if (p[1], p[2] + i) not in t:
							self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1], p[2] + i),)})
							if (p[1], p[2] + i) in s:
								leap = True
						else:
							leap = True
						i += 1
					i = 1
					leap = False
					while p[2] - i > 0 and (not leap):
						if (p[1], p[2] - i) not in t:
							self.pm.update({p[0]: self.pm.get(p[0], ()) + ((p[1], p[2] - i),)})
							if (p[1], p[2] - i) in s:
								leap = True
						else:
							leap = True
						i += 1

def play(player, otherPlayer, m):
	if not m:
		return 'B'
	player.allMoves(otherPlayer)
	for values in player.pm.values():
		for value in values:
			if value == otherPlayer.pieces['Q0']:
				return player.name
	for piece in player.pm.items():
		for move in piece[1]:
			(P, O) = (Player(player), Player(otherPlayer))
			P.pieces.update({piece[0]: move})
			for (pc, cord) in O.pieces.items():
				if cord == move:
					O.pieces.pop(pc)
					break
			if play(O, P, m - 1) == P.name:
				return P.name
	return otherPlayer.name
g = int(input().strip())
for i in range(g):
	(w, b, m) = map(int, input().strip().split())
	(W, B) = (Player('W'), Player('B'))
	W.addPieces(w)
	B.addPieces(b)
	print('YES' if play(W, B, m) == 'W' else 'NO')


import sys

def possible_moves(x, y, board):
	(player, piece) = (board[x][y][0], board[x][y][1])
	oposite = 'w' if player == 'b' else 'b'
	moves = []
	if piece == 'N':
		for (i, j) in [(-2, 1), (-2, -1), (2, 1), (2, -1), (-1, 2), (-1, -2), (1, -2), (1, 2)]:
			if 0 <= x + i < 4 and 0 <= y + j < 4:
				if board[x + i][y + j][1] != player:
					moves.append((x + i, y + j))
	dmoves = [(1, 1), (-1, 1), (-1, -1), (1, -1)]
	vmoves = [(0, 1), (-1, 0), (0, -1), (1, 0)]
	vectors = []
	if piece == 'B':
		vectors = dmoves
	elif piece == 'R':
		vectors = vmoves
	elif piece == 'Q':
		vectors = dmoves + vmoves
	for (c, d) in vectors:
		(i, j) = (x + c, y + d)
		while 0 <= i < 4 and 0 <= j < 4:
			if board[i][j][0] == player:
				break
			if board[i][j][0] == oposite:
				moves.append((i, j))
				break
			moves.append((i, j))
			(i, j) = (i + c, j + d)
	return moves

def whitewon(board):
	for i in range(4):
		for j in range(4):
			if board[i][j] == 'bQ':
				return False
	return True

def blackwon(board):
	for i in range(4):
		for j in range(4):
			if board[i][j] == 'wQ':
				return False
	return True

def g(player, turns, board):
	if player == 'b' and turns == 1:
		return whitewon(board)
	if turns == 0:
		return whitewon(board)
	if whitewon(board):
		return True
	if blackwon(board):
		return False
	for x in range(4):
		for y in range(4):
			if board[x][y][0] == player:
				for (mx, my) in possible_moves(x, y, board):
					cpy = [['' for _ in range(4)] for _ in range(4)]
					for a in range(4):
						for b in range(4):
							cpy[a][b] = board[a][b]
					cpy[mx][my] = cpy[x][y]
					cpy[x][y] = 'xx'
					nxt = g('w' if player == 'b' else 'b', turns - 1, cpy)
					if player == 'w':
						if nxt:
							return True
					elif not nxt:
						return False
	return True if player == 'b' else False
for _ in range(int(input())):
	(w, b, m) = map(int, input().split())
	board = [['xx' for _ in range(4)] for _ in range(4)]
	for _ in range(w):
		(f, y, x) = input().split()
		board[ord(x) - ord('1')][ord(y) - ord('A')] = 'w' + f
	for _ in range(b):
		(f, y, x) = input().split()
		board[ord(x) - ord('1')][ord(y) - ord('A')] = 'b' + f
	print('YES' if g('w', m, board) else 'NO')


class Piece:

	def __init__(self, piece, color, x, y):
		self.piece = piece
		self.color = color
		self.x = x
		self.y = y
		self.alive = True

	def __str__(self):
		output = 'White' if self.color == 'w' else 'Black'
		return '{} piece of type {} at ({}, {}) ({})'.format('White' if self.color == 'w' else 'Black', {'Q': 'Queen', 'N': 'Knight', 'B': 'Bishop', 'R': 'Rook'}[self.piece], self.x, self.y, 'alive' if self.alive else 'dead')

def parse_piece(string, color):
	(piece, x, y) = string.split(' ')
	x = ord(x) - ord('A')
	y = int(y) - 1
	return Piece(piece, color, x, y)
G = int(input())

def rook_locations(x, y):
	locations = []
	locations.append([(i, y) for i in range(x + 1, 4)])
	locations.append([(i, y) for i in range(x - 1, -1, -1)])
	locations.append([(x, i) for i in range(y + 1, 4)])
	locations.append([(x, i) for i in range(y - 1, -1, -1)])
	return list(filter(lambda x: len(x) > 0, locations))

def knight_locations(x, y):
	locations = []
	offsets = [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (2, -1), (2, 1), (1, -2), (1, 2)]
	for d in offsets:
		if x + d[0] < 0 or x + d[0] > 3:
			continue
		if y + d[1] < 0 or y + d[1] > 3:
			continue
		locations.append([(x + d[0], y + d[1])])
	return locations

def bishop_locations(x, y):
	locations = []
	for d in [(1, 1), (1, -1), (-1, 1), (-1, -1)]:
		(s_x, s_y) = (x, y)
		direction = []
		while True:
			s_x += d[0]
			s_y += d[1]
			if s_x < 0 or s_x > 3:
				break
			if s_y < 0 or s_y > 3:
				break
			direction.append((s_x, s_y))
		if len(direction) > 0:
			locations.append(direction)
	return locations

def queen_locations(x, y):
	return bishop_locations(x, y) + rook_locations(x, y)
locations_by_pos = {}
locations_by_pos['Q'] = [[queen_locations(x, y) for x in range(4)] for y in range(4)]
locations_by_pos['N'] = [[knight_locations(x, y) for x in range(4)] for y in range(4)]
locations_by_pos['B'] = [[bishop_locations(x, y) for x in range(4)] for y in range(4)]
locations_by_pos['R'] = [[rook_locations(x, y) for x in range(4)] for y in range(4)]

def black_move(board, max_depth, depth):
	if depth > max_depth:
		return True
	for piece in black_pieces:
		if not piece.alive:
			continue
		cur_x = piece.x
		cur_y = piece.y
		for direction in locations_by_pos[piece.piece][piece.y][piece.x]:
			for (x, y) in direction:
				existing_piece = board[y][x]
				if existing_piece != None:
					if existing_piece.color == 'w':
						if existing_piece.piece == 'Q':
							return True
						board[cur_y][cur_x] = None
						piece.x = x
						piece.y = y
						board[y][x] = piece
						existing_piece.alive = False
						escaped = not white_move(board, max_depth, depth + 1)
						existing_piece.alive = True
						board[y][x] = existing_piece
						piece.x = cur_x
						piece.y = cur_y
						board[cur_y][cur_x] = piece
						if escaped:
							return True
					break
				else:
					board[cur_y][cur_x] = None
					piece.x = x
					piece.y = y
					board[y][x] = piece
					escaped = not white_move(board, max_depth, depth + 1)
					board[y][x] = None
					piece.x = cur_x
					piece.y = cur_y
					board[cur_y][cur_x] = piece
					if escaped:
						return True
	return False

def white_move(board, max_depth, depth):
	if depth > max_depth:
		return False
	for piece in white_pieces:
		if not piece.alive:
			continue
		cur_x = piece.x
		cur_y = piece.y
		for direction in locations_by_pos[piece.piece][piece.y][piece.x]:
			for (x, y) in direction:
				existing_piece = board[y][x]
				if existing_piece != None:
					if existing_piece.color == 'b':
						if existing_piece.piece == 'Q':
							return True
						board[cur_y][cur_x] = None
						piece.x = x
						piece.y = y
						board[y][x] = piece
						existing_piece.alive = False
						won = not black_move(board, max_depth, depth + 1)
						existing_piece.alive = True
						board[y][x] = existing_piece
						piece.x = cur_x
						piece.y = cur_y
						board[cur_y][cur_x] = piece
						if won:
							return True
					break
				else:
					board[cur_y][cur_x] = None
					piece.x = x
					piece.y = y
					board[y][x] = piece
					won = not black_move(board, max_depth, depth + 1)
					board[y][x] = None
					piece.x = cur_x
					piece.y = cur_y
					board[cur_y][cur_x] = piece
					if won:
						return True
	return False
if locations_by_pos['B'][0][0] != [[(1, 1), (2, 2), (3, 3)]]:
	raise ValueError('test failure #1')
if locations_by_pos['B'][3][3] != [[(2, 2), (1, 1), (0, 0)]]:
	raise ValueError('test failure #2')
if locations_by_pos['B'][3][0] != [[(1, 2), (2, 1), (3, 0)]]:
	raise ValueError('test failure #3')
if locations_by_pos['B'][0][3] != [[(2, 1), (1, 2), (0, 3)]]:
	raise ValueError('test failure #4')
if locations_by_pos['R'][0][0] != [[(1, 0), (2, 0), (3, 0)], [(0, 1), (0, 2), (0, 3)]]:
	raise ValueError('test failure #5')
if locations_by_pos['R'][3][3] != [[(2, 3), (1, 3), (0, 3)], [(3, 2), (3, 1), (3, 0)]]:
	raise ValueError('test failure #6')
if locations_by_pos['Q'][0][0] != [[(1, 1), (2, 2), (3, 3)], [(1, 0), (2, 0), (3, 0)], [(0, 1), (0, 2), (0, 3)]]:
	raise ValueError('test failure #7')
for g in range(G):
	(W, B, M) = [int(x) for x in input().split(' ')]
	white_pieces = []
	black_pieces = []
	board = [[None] * 4 for i in range(4)]
	for w in range(W):
		white_pieces.append(parse_piece(input(), 'w'))
	for b in range(B):
		black_pieces.append(parse_piece(input(), 'b'))
	for piece in white_pieces:
		board[piece.y][piece.x] = piece
	for piece in black_pieces:
		board[piece.y][piece.x] = piece
	print('YES' if white_move(board, M, 1) else 'NO')


from collections import namedtuple
Piece = namedtuple('Piece', ['kind', 'x', 'y', 'color'])

def cell_content(x, y, active_pieces, passive_pieces):
	for piece in active_pieces + passive_pieces:
		if piece.x == x and piece.y == y:
			return piece
	return None

def move_piece(piece, target_x, target_y, actives, passives):
	(a, p) = (len(actives), len(passives))
	assert piece.color == actives[0].color and piece.color != passives[0].color
	copy_active_pieces = actives[:]
	copy_active_pieces.remove(piece)
	copy_active_pieces.append(Piece(piece.kind, target_x, target_y, piece.color))
	copy_passive_pieces = []
	status = None
	for passive_piece in passives:
		if passive_piece.x == target_x and passive_piece.y == target_y:
			if passive_piece.kind == 'Q':
				status = passive_piece.color
			continue
		else:
			copy_passive_pieces.append(passive_piece)
	assert a + p - (len(copy_active_pieces) + len(copy_passive_pieces)) <= 1
	return (copy_active_pieces, copy_passive_pieces, status)

def possible_cell(x, y):
	return 1 <= x <= 4 and 1 <= y <= 4

def possible_moves_for_piece(piece, active_pieces, passive_pieces):
	possible_moves_for_piece_list = []
	if piece.kind == 'R' or piece.kind == 'Q':
		for sign in [1, -1]:
			for x_d in range(1, 4):
				target_x = piece.x + sign * x_d
				target_y = piece.y
				if not possible_cell(target_x, target_y):
					break
				target = cell_content(target_x, target_y, active_pieces, passive_pieces)
				if target is None:
					possible_moves_for_piece_list.append(move_piece(piece, target_x, target_y, active_pieces, passive_pieces))
					continue
				if target.color != piece.color:
					possible_moves_for_piece_list.append(move_piece(piece, target_x, target_y, active_pieces, passive_pieces))
				break
		for sign in [1, -1]:
			for y_d in range(1, 4):
				target_x = piece.x
				target_y = piece.y + sign * y_d
				if not possible_cell(target_x, target_y):
					break
				target = cell_content(target_x, target_y, active_pieces, passive_pieces)
				if target is None:
					possible_moves_for_piece_list.append(move_piece(piece, target_x, target_y, active_pieces, passive_pieces))
					continue
				if target.color != piece.color:
					possible_moves_for_piece_list.append(move_piece(piece, target_x, target_y, active_pieces, passive_pieces))
				break
	if piece.kind == 'B' or piece.kind == 'Q':
		for sign in [1, -1]:
			for x_d in range(1, 4):
				target_x = piece.x + sign * x_d
				target_y = piece.y + sign * x_d
				if not possible_cell(target_x, target_y):
					break
				target = cell_content(target_x, target_y, active_pieces, passive_pieces)
				if target is None:
					possible_moves_for_piece_list.append(move_piece(piece, target_x, target_y, active_pieces, passive_pieces))
					continue
				if target.color != piece.color:
					possible_moves_for_piece_list.append(move_piece(piece, target_x, target_y, active_pieces, passive_pieces))
				break
		for sign in [1, -1]:
			for y_d in range(1, 4):
				target_x = piece.x + sign * y_d
				target_y = piece.y - sign * y_d
				if not possible_cell(target_x, target_y):
					break
				target = cell_content(target_x, target_y, active_pieces, passive_pieces)
				if target is None:
					possible_moves_for_piece_list.append(move_piece(piece, target_x, target_y, active_pieces, passive_pieces))
					continue
				if target.color != piece.color:
					possible_moves_for_piece_list.append(move_piece(piece, target_x, target_y, active_pieces, passive_pieces))
				break
	if piece.kind == 'N':
		for d_x in [1, 2, -1, -2]:
			for d_y in [1, 2, -1, -2]:
				if (d_x + d_y) % 2 == 0:
					continue
				target_x = piece.x + d_x
				target_y = piece.y + d_y
				if not possible_cell(target_x, target_y):
					continue
				target = cell_content(target_x, target_y, active_pieces, passive_pieces)
				if target is None or target.color != piece.color:
					possible_moves_for_piece_list.append(move_piece(piece, target_x, target_y, active_pieces, passive_pieces))
	return possible_moves_for_piece_list

def possible_moves(configuration, move):
	if move % 2 == 1:
		(active_pieces, passive_pieces, status) = configuration
	else:
		(passive_pieces, active_pieces, status) = configuration
	possible_move_list = []
	if status is not None:
		return []
	for active_piece in active_pieces:
		possible_move_list += possible_moves_for_piece(active_piece, active_pieces, passive_pieces)
	if move % 2 == 0:
		possible_move_list = [(b, a, c) for (a, b, c) in possible_move_list]
	assert len(possible_move_list) == 0 or len(possible_move_list[0][0]) == 0 or possible_move_list[0][0][0].color == 'white'
	return possible_move_list

def whites_win_in_one(configuration_0):
	(whites, blacks, _) = configuration_0
	for configuration_1 in possible_moves(configuration_0, 1):
		if configuration_1[2] == 'black':
			return True
	return False

def whites_win_in_three(configuration_0):
	(whites, blacks, _) = configuration_0
	for configuration_1 in possible_moves(configuration_0, 1):
		if configuration_1[2] == 'black':
			return True
		pm2 = possible_moves(configuration_1, 2)
		if not pm2:
			continue
		for configuration_2 in pm2:
			if configuration_2[2] == 'white':
				break
			if not whites_win_in_one(configuration_2):
				break
		else:
			return True
	return False

def whites_win_in_five(configuration_0):
	(whites, blacks, _) = configuration_0
	for configuration_1 in possible_moves(configuration_0, 1):
		if configuration_1[2] == 'black':
			return True
		pm2 = possible_moves(configuration_1, 2)
		if not pm2:
			continue
		for configuration_2 in pm2:
			if configuration_2[2] == 'white':
				break
			if not whites_win_in_three(configuration_2):
				break
		else:
			return True
	return False

def solve():
	(m, white, black) = read_test_case()
	if m % 2 == 0:
		m -= 1
	current_configuration = (white, black, None)
	if whites_win_in_one(current_configuration):
		return True
	if m >= 3:
		if whites_win_in_three(current_configuration):
			return True
	if m >= 5:
		if whites_win_in_five(current_configuration):
			return True
	return False

def read_piece(input_string, color):
	(kind, x_input, y_input) = input_string.split()
	x = 'ABCD'.index(x_input) + 1
	y = int(y_input)
	return Piece(kind, x, y, color)

def read_test_case():
	(w, b, m) = [int(x) for x in input().split()]
	white = []
	black = []
	for w_ in range(w):
		white.append(read_piece(input(), color='white'))
	for b_ in range(b):
		black.append(read_piece(input(), color='black'))
	return (m, white, black)

def print_possible_moves_for_piece(piece, active_pieces, passive_pieces, number):
	print('Moving', piece)
	print('Active', active_pieces)
	print('Passive', passive_pieces)
	moves = possible_moves_for_piece(piece, active_pieces, passive_pieces)
	print('Moves:', len(moves))
	assert number == len(moves)
	for possible_move in moves:
		print(possible_move)
	print()
number_of_test_cases = int(input())
for _ in range(number_of_test_cases):
	if solve():
		print('YES')
	else:
		print('NO')


def allowed_moves(board, I, J, delta_i, delta_j):
	moves = []
	(i, j) = (I, J)
	while True:
		i += delta_i
		j += delta_j
		if i < 0 or 3 < i or j < 0 or (3 < j):
			break
		moves.append((i, j))
		if board[i][j] != '.':
			break
	return moves

def bishop_moves(board, I, J):
	moves = []
	moves += allowed_moves(board, I, J, +1, +1)
	moves += allowed_moves(board, I, J, +1, -1)
	moves += allowed_moves(board, I, J, -1, -1)
	moves += allowed_moves(board, I, J, -1, +1)
	return moves

def night_moves(board, I, J):
	moves = []
	if I < 2:
		if J < 3:
			moves.append((I + 2, J + 1))
		if J > 0:
			moves.append((I + 2, J - 1))
	if I > 1:
		if J < 3:
			moves.append((I - 2, J + 1))
		if J > 0:
			moves.append((I - 2, J - 1))
	if I > 0:
		if J < 2:
			moves.append((I - 1, J + 2))
		if J > 1:
			moves.append((I - 1, J - 2))
	if I < 3:
		if J < 2:
			moves.append((I + 1, J + 2))
		if J > 1:
			moves.append((I + 1, J - 2))
	return moves

def rook_moves(board, I, J):
	moves = []
	moves += allowed_moves(board, I, J, +1, 0)
	moves += allowed_moves(board, I, J, -1, 0)
	moves += allowed_moves(board, I, J, 0, +1)
	moves += allowed_moves(board, I, J, 0, -1)
	return moves

def queen_moves(board, I, J):
	return bishop_moves(board, I, J) + rook_moves(board, I, J)

def gather_moves(board, I, J, piece):
	if piece == 'b' or piece == 'B':
		return bishop_moves(board, I, J)
	elif piece == 'n' or piece == 'N':
		return night_moves(board, I, J)
	elif piece == 'r' or piece == 'R':
		return rook_moves(board, I, J)
	elif piece == 'q' or piece == 'Q':
		return queen_moves(board, I, J)

class ChessMove(object):

	def __init__(self, piece, row, col):
		self.piece = piece
		self.old_row = row
		self.old_col = col

	def move_to(self, row, col):
		self.new_row = row
		self.new_col = col

class ChessBoard(object):
	max_moves = 0

	def __init__(self):
		self.black = False
		self.white = True
		self.num_moves = 0
		self.board = [['.'] * 4, ['.'] * 4, ['.'] * 4, ['.'] * 4]

	def copy(self, other):
		self.black = not other.black
		self.white = not other.white
		self.num_moves = other.num_moves + 1
		for i in range(4):
			for j in range(4):
				self.board[i][j] = other.board[i][j]

	def queens(self):
		count = 0
		for i in range(4):
			for j in range(4):
				if 'q' == self.board[i][j] or 'Q' == self.board[i][j]:
					count += 1
		return count

	def __str__(self):
		return '\n'.join([''.join(self.board[3 - i]) for i in range(4)])

	def update(self, move):
		self.board[move.old_row][move.old_col] = '.'
		self.board[move.new_row][move.new_col] = move.piece
		return

	def setup(self, pieces):
		for piece in pieces:
			self.board[piece[1]][piece[2]] = piece[0]

	def get_moves(self):
		moves = []
		for i in range(4):
			for j in range(4):
				if self.black and self.board[i][j].islower():
					moves.append(ChessMove(self.board[i][j], i, j))
				if self.white and self.board[i][j].isupper():
					moves.append(ChessMove(self.board[i][j], i, j))
		for move in moves:
			for (i, j) in gather_moves(self.board, move.old_row, move.old_col, move.piece):
				if self.black and self.board[i][j].islower() or (self.white and self.board[i][j].isupper()):
					continue
				new_move = ChessMove(move.piece, move.old_row, move.old_col)
				new_move.move_to(i, j)
				yield new_move

def next_move(old_board):
	if old_board.queens() < 2:
		return old_board.black
	if old_board.num_moves == ChessBoard.max_moves:
		return False
	results = []
	for new_move in old_board.get_moves():
		new_board = ChessBoard()
		new_board.copy(old_board)
		new_board.update(new_move)
		result = next_move(new_board)
		results.append(result)
		if old_board.black and (not result):
			return False
		if old_board.white and result:
			return True
	return old_board.black

def solution(w, b, m, white, black):
	ChessBoard.max_moves = m - 1 if m % 2 == 0 else m
	board = ChessBoard()
	board.setup(black + white)
	return next_move(board)

def main():
	g = int(input())
	col = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
	row = {'1': 0, '2': 1, '3': 2, '4': 3}
	for games in range(g):
		(w, b, m) = [int(s) for s in input().split()]
		white = []
		for whites in range(w):
			(t, c, r) = input().split()
			white.append((t.upper(), row[r], col[c]))
		black = []
		for blacks in range(b):
			(t, c, r) = input().split()
			white.append((t.lower(), row[r], col[c]))
		print('YES' if solution(w, b, m, white, black) else 'NO')
main()


def display(b):
	X = ['_', 'N', 'B', 'R', 'Q']
	Y = ['_', 'n', 'b', 'r', 'q']
	for i in range(16):
		if b[i] >= 0:
			print(X[b[i]], end=' ')
		else:
			print(Y[-b[i]], end=' ')
		if i % 4 == 3:
			print()
	print()

def get_init_board(n_white, n_black):
	b = [0] * 16
	for i in range(n_white + n_black):
		(p, r, c) = input().split()
		if p == 'Q':
			v = 4
		if p == 'R':
			v = 3
		if p == 'B':
			v = 2
		if p == 'N':
			v = 1
		if i >= n_white:
			v *= -1
		idx = 0
		if r == 'A':
			idx = 0
		if r == 'B':
			idx = 4
		if r == 'C':
			idx = 8
		if r == 'D':
			idx = 12
		if c == '1':
			idx += 0
		if c == '2':
			idx += 1
		if c == '3':
			idx += 2
		if c == '4':
			idx += 3
		b[idx] = v
	return b
moves = [[-1 for i in range(16)] for j in range(8)]

def precompute_moves():
	for i in range(16):
		if i % 4 != 3:
			moves[0][i] = i + 1
		if i <= 11:
			moves[1][i] = i + 4
		if i % 4 != 0:
			moves[2][i] = i - 1
		if i >= 4:
			moves[3][i] = i - 4
		if i % 4 != 3 and i <= 11:
			moves[4][i] = i + 5
		if i % 4 != 0 and i <= 11:
			moves[5][i] = i + 3
		if i % 4 != 3 and i >= 4:
			moves[6][i] = i - 3
		if i % 4 != 0 and i >= 4:
			moves[7][i] = i - 5

def n_moves(b, i, rv):
	for s in range(4):
		j = moves[s][i]
		if j == -1:
			continue
		j = moves[s][j]
		if j == -1:
			continue
		for t in range(2):
			tt = (s + 2 * t + 1) % 4
			k = moves[tt][j]
			if k == -1:
				continue
			if b[k] <= 0:
				x = b[:]
				x[i] = 0
				x[k] = 1
				rv.append(x)

def dir_moves(b, i, d, rv):
	pos = i
	while True:
		pos = moves[d][pos]
		if pos == -1:
			return
		if b[pos] > 0:
			return
		x = b[:]
		x[pos] = x[i]
		x[i] = 0
		rv.append(x)
		if b[pos] < 0:
			return

def b_moves(b, i, rv):
	for d in range(4, 8):
		dir_moves(b, i, d, rv)

def r_moves(b, i, rv):
	for d in range(0, 4):
		dir_moves(b, i, d, rv)

def q_moves(b, i, rv):
	for d in range(0, 8):
		dir_moves(b, i, d, rv)

def new_boards(b):
	rv = []
	for i in range(16):
		if b[i] == 1:
			n_moves(b, i, rv)
		if b[i] == 2:
			b_moves(b, i, rv)
		if b[i] == 3:
			r_moves(b, i, rv)
		if b[i] == 4:
			q_moves(b, i, rv)
	return rv

def is_win(b):
	for p in b:
		if p == -4:
			return False
	return True
hist = {}

def board_value(b, depth):
	ggg = tuple(b + [depth])
	if ggg in hist:
		return hist[ggg]
	if depth == 0:
		return 0
	bb = new_boards(b)
	if len(bb) == 0:
		return 0
	for x in bb:
		if is_win(x):
			hist[ggg] = 1
			return 1
	best = -1
	for x in bb:
		y = [-p for p in x]
		v = -board_value(y, depth - 1)
		if v > best:
			best = v
		if best == 1:
			break
	hist[ggg] = best
	return best
num_prob = int(input())
for prob in range(num_prob):
	(n_white, n_black, depth) = (int(x) for x in input().split())
	b = get_init_board(n_white, n_black)
	precompute_moves()
	v = board_value(b, depth)
	if v == 1:
		print('YES')
	else:
		print('NO')


SIZE = 4

def queen(row, col, p1, p2):
	return rook(row, col, p1, p2) + bishop(row, col, p1, p2)

def rook(row, col, p1, p2):
	moves = []
	for r in range(row - 1, -1, -1):
		if (r, col) in p1:
			break
		if (r, col) in p2:
			moves.append((r, col))
			break
		moves.append((r, col))
	for r in range(row + 1, SIZE):
		if (r, col) in p1:
			break
		if (r, col) in p2:
			moves.append((r, col))
			break
		moves.append((r, col))
	for c in range(col - 1, -1, -1):
		if (row, c) in p1:
			break
		if (row, c) in p2:
			moves.append((row, c))
			break
		moves.append((row, c))
	for c in range(col + 1, SIZE):
		if (row, c) in p1:
			break
		if (row, c) in p2:
			moves.append((row, c))
			break
		moves.append((row, c))
	return moves

def bishop(row, col, p1, p2):
	moves = []
	r = row - 1
	c = col - 1
	while r > -1 and c > -1:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r -= 1
		c -= 1
	r = row + 1
	c = col - 1
	while r < SIZE and c > -1:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r += 1
		c -= 1
	r = row - 1
	c = col + 1
	while r > -1 and c < SIZE:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r -= 1
		c += 1
	r = row + 1
	c = col + 1
	while r < SIZE and c < SIZE:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r += 1
		c += 1
	return moves

def knight(row, col, player):
	moves = []
	if row - 1 > 0:
		if col > 0 and (not (row - 2, col - 1) in player):
			moves.append((row - 2, col - 1))
		if col + 1 < SIZE and (not (row - 2, col + 1) in player):
			moves.append((row - 2, col + 1))
	if row + 2 < SIZE:
		if col > 0 and (not (row + 2, col - 1) in player):
			moves.append((row + 2, col - 1))
		if col + 1 < SIZE and (not (row + 2, col + 1) in player):
			moves.append((row + 2, col + 1))
	if col - 1 > 0:
		if row > 0 and (not (row - 1, col - 2) in player):
			moves.append((row - 1, col - 2))
		if row + 1 < SIZE and (not (row + 1, col - 2) in player):
			moves.append((row + 1, col - 2))
	if col + 2 < SIZE:
		if row > 0 and (not (row - 1, col + 2) in player):
			moves.append((row - 1, col + 2))
		if row + 1 < SIZE and (not (row + 1, col + 2) in player):
			moves.append((row + 1, col + 2))
	return moves

def canPlayer(W, B, m, rw, cw, rb, cb, isWhite):
	(movesQ, movesN, movesB, movesR, movesNX, movesBX, movesRX) = ([], [], [], [], [], [], [])
	white = [(r, c) for (r, c, _) in W]
	black = [(r, c) for (r, c, _) in B]
	for (row, col, pc) in W:
		if pc == 'Q':
			movesQ = queen(row, col, white, black)
			if (rb, cb) in movesQ:
				return True
		elif pc == 'N':
			movesN = knight(row, col, white)
			if (rb, cb) in movesN:
				return True
		elif pc == 'B':
			movesB = bishop(row, col, white, black)
			if (rb, cb) in movesB:
				return True
		elif pc == 'R':
			movesR = rook(row, col, white, black)
			if (rb, cb) in movesR:
				return True
		elif pc == 'NX':
			movesNX = knight(row, col, white)
			if (rb, cb) in movesNX:
				return True
		elif pc == 'BX':
			movesBX = bishop(row, col, white, black)
			if (rb, cb) in movesBX:
				return True
		elif pc == 'RX':
			movesRX = rook(row, col, white, black)
			if (rb, cb) in movesRX:
				return True
	if isWhite and m <= 2:
		return False
	for i in range(len(W)):
		for (r, c) in eval('moves' + W[i][2]):
			Wcopy = W[:]
			del Wcopy[i]
			Wcopy.append((r, c, W[i][2]))
			Bcopy = B[:]
			if (r, c) in black:
				for j in range(len(B)):
					if B[j][0] == r and B[j][1] == c:
						del Bcopy[j]
						break
			if W[i][2] == 'Q':
				blackWin = canPlayer(Bcopy, Wcopy, m - 1, rb, cb, r, c, isWhite ^ True)
			else:
				blackWin = canPlayer(Bcopy, Wcopy, m - 1, rb, cb, rw, cw, isWhite ^ True)
			if not blackWin:
				return True
	return False
for _ in range(int(input())):
	(w, b, moves) = map(int, input().strip().split())
	(W, B) = ([], [])
	typelist = []
	for playerw in range(w):
		(pc, col, row) = input().strip().split()
		if pc in typelist:
			pc = pc + 'X'
		W.append((int(row) - 1, ord(col) - 65, pc))
		typelist.append(pc)
		if pc == 'Q':
			qwr = int(row) - 1
			qwc = ord(col) - 65
	typelist = []
	for playerb in range(b):
		(pc, col, row) = input().strip().split()
		if pc in typelist:
			pc = pc + 'X'
		B.append((int(row) - 1, ord(col) - 65, pc))
		typelist.append(pc)
		if pc == 'Q':
			qbr = int(row) - 1
			qbc = ord(col) - 65
	if canPlayer(W, B, moves, qwr, qwc, qbr, qbc, True):
		print('YES')
	else:
		print('NO')


constant = {}
constant['b'] = ['bR', 'bQ', 'bN', 'bB', 'out']
constant['w'] = ['wR', 'wQ', 'wN', 'wB', 'out']

def possibleMoves(p, pos, board):

	def bd(x, y):
		if 0 <= x < 4 and 0 <= y < 4:
			return board[x][y]
		else:
			return 'out'

	def movesN(pos):
		moves = []
		(y, x) = pos
		if bd(x + 1, y + 2) not in constant['w']:
			moves.append([x + 1, y + 2])
		if bd(x + 1, y - 2) not in constant['w']:
			moves.append([x + 1, y - 2])
		if bd(x - 1, y + 2) not in constant['w']:
			moves.append([x - 1, y + 2])
		if bd(x - 1, y - 2) not in constant['w']:
			moves.append([x - 1, y - 2])
		if bd(x + 2, y + 1) not in constant['w']:
			moves.append([x + 2, y + 1])
		if bd(x + 2, y - 1) not in constant['w']:
			moves.append([x + 2, y - 1])
		if bd(x - 2, y + 1) not in constant['w']:
			moves.append([x - 2, y + 1])
		if bd(x - 2, y - 1) not in constant['w']:
			moves.append([x - 2, y - 1])
		return moves

	def movesNb(pos):
		moves = []
		(y, x) = pos
		if bd(x + 1, y + 2) not in constant['b']:
			moves.append([x + 1, y + 2])
		if bd(x + 1, y - 2) not in constant['b']:
			moves.append([x + 1, y - 2])
		if bd(x - 1, y + 2) not in constant['b']:
			moves.append([x - 1, y + 2])
		if bd(x - 1, y - 2) not in constant['b']:
			moves.append([x - 1, y - 2])
		if bd(x + 2, y + 1) not in constant['b']:
			moves.append([x + 2, y + 1])
		if bd(x + 2, y - 1) not in constant['b']:
			moves.append([x + 2, y - 1])
		if bd(x - 2, y + 1) not in constant['b']:
			moves.append([x - 2, y + 1])
		if bd(x - 2, y - 1) not in constant['b']:
			moves.append([x - 2, y - 1])
		return moves

	def movesR(pos):
		(y, x) = pos
		moves = []
		i = 1
		while bd(x, y + i) == '':
			moves.append([x, y + i])
			i += 1
		else:
			if bd(x, y + i)[0] == 'b':
				moves.append([x, y + i])
		i = 1
		while bd(x, y - i) == '':
			moves.append([x, y - i])
			i += 1
		else:
			if bd(x, y - i)[0] == 'b':
				moves.append([x, y - i])
		i = 1
		while bd(x + i, y) == '':
			moves.append([x + i, y])
			i += 1
		else:
			if bd(x + i, y)[0] == 'b':
				moves.append([x + i, y])
		i = 1
		while bd(x - i, y) == '':
			moves.append([x - i, y])
			i += 1
		else:
			if bd(x - i, y)[0] == 'b':
				moves.append([x - i, y])
		return moves

	def movesRb(pos):
		(y, x) = pos
		moves = []
		i = 1
		while bd(x, y + i) == '':
			moves.append([x, y + i])
			i += 1
		else:
			if bd(x, y + i)[0] == 'w':
				moves.append([x, y + i])
		i = 1
		while bd(x, y - i) == '':
			moves.append([x, y - i])
			i += 1
		else:
			if bd(x, y - i)[0] == 'w':
				moves.append([x, y - i])
		i = 1
		while bd(x + i, y) == '':
			moves.append([x + i, y])
			i += 1
		else:
			if bd(x + i, y)[0] == 'w':
				moves.append([x + i, y])
		i = 1
		while bd(x - i, y) == '':
			moves.append([x - i, y])
			i += 1
		else:
			if bd(x - i, y)[0] == 'w':
				moves.append([x - i, y])
		return moves

	def movesQ(pos):
		(y, x) = pos
		moves = []
		i = 1
		while bd(x, y + i) == '':
			moves.append([x, y + i])
			i += 1
		else:
			if bd(x, y + i)[0] == 'b':
				moves.append([x, y + i])
		i = 1
		while bd(x, y - i) == '':
			moves.append([x, y - i])
			i += 1
		else:
			if bd(x, y - i)[0] == 'b':
				moves.append([x, y - i])
		i = 1
		while bd(x + i, y) == '':
			moves.append([x + i, y])
			i += 1
		else:
			if bd(x + i, y)[0] == 'b':
				moves.append([x + i, y])
		i = 1
		while bd(x - i, y) == '':
			moves.append([x - i, y])
			i += 1
		else:
			if bd(x - i, y)[0] == 'b':
				moves.append([x - i, y])
		i = 1
		while bd(x - i, y - i) == '':
			moves.append([x - i, y - i])
			i += 1
		else:
			if bd(x - i, y - i)[0] == 'b':
				moves.append([x - i, y - i])
		i = 1
		while bd(x - i, y + i) == '':
			moves.append([x - i, y + i])
			i += 1
		else:
			if bd(x - i, y + i)[0] == 'b':
				moves.append([x - i, y + i])
		i = 1
		while bd(x + i, y + i) == '':
			moves.append([x + i, y + i])
			i += 1
		else:
			if bd(x + i, y + i)[0] == 'b':
				moves.append([x + i, y + i])
		i = 1
		while bd(x + i, y - i) == '':
			moves.append([x + i, y - i])
			i += 1
		else:
			if bd(x + i, y - i)[0] == 'b':
				moves.append([x + i, y - i])
		return moves

	def movesQb(pos):
		(y, x) = pos
		moves = []
		i = 1
		while bd(x, y + i) == '':
			moves.append([x, y + i])
			i += 1
		else:
			if bd(x, y + i)[0] == 'w':
				moves.append([x, y + i])
		i = 1
		while bd(x, y - i) == '':
			moves.append([x, y - i])
			i += 1
		else:
			if bd(x, y - i)[0] == 'w':
				moves.append([x, y - i])
		i = 1
		while bd(x + i, y) == '':
			moves.append([x + i, y])
			i += 1
		else:
			if bd(x + i, y)[0] == 'w':
				moves.append([x + i, y])
		i = 1
		while bd(x - i, y) == '':
			moves.append([x - i, y])
			i += 1
		else:
			if bd(x - i, y)[0] == 'w':
				moves.append([x - i, y])
		i = 1
		while bd(x - i, y - i) == '':
			moves.append([x - i, y - i])
			i += 1
		else:
			if bd(x - i, y - i)[0] == 'w':
				moves.append([x - i, y - i])
		i = 1
		while bd(x - i, y + i) == '':
			moves.append([x - i, y + i])
			i += 1
		else:
			if bd(x - i, y + i)[0] == 'w':
				moves.append([x - i, y + i])
		i = 1
		while bd(x + i, y + i) == '':
			moves.append([x + i, y + i])
			i += 1
		else:
			if bd(x + i, y + i)[0] == 'w':
				moves.append([x + i, y + i])
		i = 1
		while bd(x + i, y - i) == '':
			moves.append([x + i, y - i])
			i += 1
		else:
			if bd(x + i, y - i)[0] == 'w':
				moves.append([x + i, y - i])
		return moves

	def movesB(pos):
		(y, x) = pos
		moves = []
		i = 1
		while bd(x - i, y - i) == '':
			moves.append([x - i, y - i])
			i += 1
		else:
			if bd(x - i, y - i)[0] == 'b':
				moves.append([x - i, y - i])
		i = 1
		while bd(x - i, y + i) == '':
			moves.append([x - i, y + i])
			i += 1
		else:
			if bd(x - i, y + i)[0] == 'b':
				moves.append([x - i, y + i])
		i = 1
		while bd(x + i, y + i) == '':
			moves.append([x + i, y + i])
			i += 1
		else:
			if bd(x + i, y + i)[0] == 'b':
				moves.append([x + i, y + i])
		i = 1
		while bd(x + i, y - i) == '':
			moves.append([x + i, y - i])
			i += 1
		else:
			if bd(x + i, y - i)[0] == 'b':
				moves.append([x + i, y - i])
		return moves

	def movesBb(pos):
		(y, x) = pos
		moves = []
		i = 1
		while bd(x - i, y - i) == '':
			moves.append([x - i, y - i])
			i += 1
		else:
			if bd(x - i, y - i)[0] == 'w':
				moves.append([x - i, y - i])
		i = 1
		while bd(x - i, y + i) == '':
			moves.append([x - i, y + i])
			i += 1
		else:
			if bd(x - i, y + i)[0] == 'w':
				moves.append([x - i, y + i])
		i = 1
		while bd(x + i, y + i) == '':
			moves.append([x + i, y + i])
			i += 1
		else:
			if bd(x + i, y + i)[0] == 'w':
				moves.append([x + i, y + i])
		i = 1
		while bd(x + i, y - i) == '':
			moves.append([x + i, y - i])
			i += 1
		else:
			if bd(x + i, y - i)[0] == 'w':
				moves.append([x + i, y - i])
		return moves
	(y, x) = pos
	moves = []
	if p == 'wN':
		moves = movesN(pos)
	if p == 'bN':
		moves = movesNb(pos)
	if p == 'wR':
		moves = movesR(pos)
	if p == 'bR':
		moves = movesRb(pos)
	if p == 'wQ':
		moves = movesQ(pos)
	if p == 'bQ':
		moves = movesQb(pos)
	if p == 'wB':
		moves = movesB(pos)
	if p == 'bB':
		moves = movesBb(pos)
	return moves

def hasbQ(board):
	return 'bQ' in board[0] + board[1] + board[2] + board[3]

def haswQ(board):
	return 'wQ' in board[0] + board[1] + board[2] + board[3]

def makeMove(board, node, move):
	b = [item.copy() for item in board]
	b[node.j][node.i] = ''
	b[move[0]][move[1]] = node.val
	return b

def makewb(bd):
	(w, b) = ([], [])
	for i in range(4):
		for j in range(4):
			if bd[i][j] in constant['w']:
				w.append([j, i])
			elif bd[i][j] in constant['b']:
				b.append([j, i])
	return (w, b)

class Node:

	def __init__(self, ai, board, side, pos, val, moves):
		self.side = side
		self.val = val
		self.moves = moves
		self.ai = ai
		self.i = pos[0]
		self.j = pos[1]
		self.pos = pos
		self.board = board
		self.parent = None
		self.hasSolution = False
		self.makesSolution = False

	def children(self, depth):
		for i in range(len(self.moves)):
			w = self.ai.whites.copy()
			b = self.ai.blacks.copy()
			bd = self.board
			bd = makeMove(bd, self, self.moves[i])
			if self.side:
				w[w.index(self.pos)] = self.moves[i][::-1]
				if self.moves[i][::-1] in b:
					del b[b.index(self.moves[i][::-1])]
			else:
				b[b.index(self.pos)] = self.moves[i][::-1]
				if self.moves[i][::-1] in w:
					del w[w.index(self.moves[i][::-1])]
			if not haswQ(bd):
				self.hasSolution = False
				self.parent.makesSolution = False
				return
			if not hasbQ(bd):
				if depth != 1:
					self.parent.hasSolution = True
				self.makesSolution = True
				return
			if depth + 1 == m and m % 2 == 0 or depth == m:
				continue
			if self.side:
				for pos in b:
					val = bd[pos[1]][pos[0]]
					n = Node(AI(board, w, b, depth), bd, not self.side, pos, val, possibleMoves(val, pos, bd))
					n.parent = self
					n.children(depth + 1)
					if not n.hasSolution:
						break
				else:
					self.makesSolution = True
					if depth != 1:
						self.parent.hasSolution = True
					return
			else:
				self.hasSolution = False
				for pos in w:
					val = bd[pos[1]][pos[0]]
					n = Node(AI(board, w, b, depth), bd, not self.side, pos, val, possibleMoves(val, pos, bd))
					n.parent = self
					n.children(depth + 1)
					if self.hasSolution:
						break
				else:
					break

class AI:

	def __init__(self, board, whites, blacks, depth):
		self.board = board
		self.whites = whites
		self.blacks = blacks
		self.depth = depth

def execute(board, whites, blacks, depth):
	for pos in whites:
		val = board[pos[1]][pos[0]]
		node = Node(AI(board, whites, blacks, depth), board, True, pos, val, possibleMoves(val, pos, board))
		Tree = node.children(1)
		if node.makesSolution:
			return True
	return False
g = int(input())
import random
for test in range(g):
	(w, b, m) = [int(item) for item in input().split()]
	board = [['' for i in range(4)] for j in range(4)]
	whites = []
	blacks = []
	for i in range(w):
		line = input().split()
		whites.append([ord(line[1]) - 65, 4 - int(line[2])])
		board[4 - int(line[2])][ord(line[1]) - 65] = 'w' + line[0]
	for i in range(b):
		line = input().split()
		blacks.append([ord(line[1]) - 65, 4 - int(line[2])])
		board[4 - int(line[2])][ord(line[1]) - 65] = 'b' + line[0]
	random.shuffle(whites)
	random.shuffle(blacks)
	result = execute(board, whites, blacks, m)
	if result:
		print('YES')
	else:
		print('NO')


from collections import namedtuple
trans = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
trans_r = {0: 'A', 1: 'B', 2: 'C', 3: 'D'}

def translate(c, r):
	return (int(trans[c]), int(r) - 1)
Piece = namedtuple('Piece', ['side', 'type', 'pos'])

def move_paths(c, r):
	orthogonals = (tuple(((c, r_) for r_ in range(r + 1, 4))), tuple(((c, r_) for r_ in reversed(range(r)))), tuple(((c_, r) for c_ in range(c + 1, 4))), tuple(((c_, r) for c_ in reversed(range(c)))))
	diagonals = (tuple(zip(range(c + 1, 4), range(r + 1, 4))), tuple(zip(range(c + 1, 4), reversed(range(r)))), tuple(zip(reversed(range(c)), range(r + 1, 4))), tuple(zip(reversed(range(c)), reversed(range(r)))))
	knights = [(c + 2, r + 1), (c + 2, r - 1), (c - 2, r + 1), (c - 2, r - 1), (c + 1, r + 2), (c - 1, r + 2), (c + 1, r - 2), (c - 1, r - 2)]
	knights = [((c, r),) for (c, r) in knights if 0 <= c < 4 and 0 <= r < 4]
	return {'R': orthogonals, 'B': diagonals, 'Q': orthogonals + diagonals, 'N': knights}
all_move_paths = {(c, r): move_paths(c, r) for c in range(4) for r in range(4)}

def forced_win_white(grid, turn, m):
	for piece in (p for p in grid.values() if p.side == turn):
		for path in all_move_paths[piece.pos][piece.type]:
			for pos in path:
				other_p = grid.get(pos, None)
				if other_p and other_p.side == turn:
					break
				elif other_p and other_p.side != turn and (other_p.type == 'Q'):
					return turn == 'W'
				elif m > 1:
					grid_ = grid.copy()
					grid_[pos] = Piece(piece.side, piece.type, pos)
					del grid_[piece.pos]
					if (turn == 'B') ^ forced_win_white(grid_, 'B' if turn == 'W' else 'W', m - 1):
						return turn == 'W'
				if other_p:
					break
	return turn == 'B'
for _ in range(int(input().strip())):
	(w, b, m) = [int(x) for x in input().strip().split(' ')]
	white = [Piece('W', t, translate(c, r)) for (t, c, r) in (input().strip().split(' ') for _ in range(w))]
	black = [Piece('B', t, translate(c, r)) for (t, c, r) in (input().strip().split(' ') for _ in range(b))]
	grid = {p.pos: p for p in white + black}
	if m % 2 == 0:
		m -= 1
	print('YES' if forced_win_white(grid, 'W', m) else 'NO')


def display(b):
	X = ['_', 'N', 'B', 'R', 'Q']
	Y = ['_', 'n', 'b', 'r', 'q']
	for i in range(16):
		if b[i] >= 0:
			print(X[b[i]], end=' ')
		else:
			print(Y[-b[i]], end=' ')
		if i % 4 == 3:
			print()
	print()

def get_init_board(n_white, n_black):
	b = [0] * 16
	for i in range(n_white + n_black):
		(p, r, c) = input().split()
		if p == 'Q':
			v = 4
		if p == 'R':
			v = 3
		if p == 'B':
			v = 2
		if p == 'N':
			v = 1
		if i >= n_white:
			v *= -1
		idx = 0
		if r == 'A':
			idx = 0
		if r == 'B':
			idx = 4
		if r == 'C':
			idx = 8
		if r == 'D':
			idx = 12
		if c == '1':
			idx += 0
		if c == '2':
			idx += 1
		if c == '3':
			idx += 2
		if c == '4':
			idx += 3
		b[idx] = v
	return b
moves = [[-1 for i in range(16)] for j in range(8)]

def precompute_moves():
	for i in range(16):
		if i % 4 != 3:
			moves[0][i] = i + 1
		if i <= 11:
			moves[1][i] = i + 4
		if i % 4 != 0:
			moves[2][i] = i - 1
		if i >= 4:
			moves[3][i] = i - 4
		if i % 4 != 3 and i <= 11:
			moves[4][i] = i + 5
		if i % 4 != 0 and i <= 11:
			moves[5][i] = i + 3
		if i % 4 != 3 and i >= 4:
			moves[6][i] = i - 3
		if i % 4 != 0 and i >= 4:
			moves[7][i] = i - 5

def n_moves(b, i, rv):
	for s in range(4):
		j = moves[s][i]
		if j == -1:
			continue
		j = moves[s][j]
		if j == -1:
			continue
		for t in range(2):
			tt = (s + 2 * t + 1) % 4
			k = moves[tt][j]
			if k == -1:
				continue
			if b[k] <= 0:
				x = b[:]
				x[i] = 0
				x[k] = 1
				rv.append(x)

def dir_moves(b, i, d, rv):
	pos = i
	while True:
		pos = moves[d][pos]
		if pos == -1:
			return
		if b[pos] > 0:
			return
		x = b[:]
		x[pos] = x[i]
		x[i] = 0
		rv.append(x)
		if b[pos] < 0:
			return

def b_moves(b, i, rv):
	for d in range(4, 8):
		dir_moves(b, i, d, rv)

def r_moves(b, i, rv):
	for d in range(0, 4):
		dir_moves(b, i, d, rv)

def q_moves(b, i, rv):
	for d in range(0, 8):
		dir_moves(b, i, d, rv)

def new_boards(b):
	rv = []
	for i in range(16):
		if b[i] == 1:
			n_moves(b, i, rv)
		if b[i] == 2:
			b_moves(b, i, rv)
		if b[i] == 3:
			r_moves(b, i, rv)
		if b[i] == 4:
			q_moves(b, i, rv)
	return rv

def is_win(b):
	for p in b:
		if p == -4:
			return False
	return True
hist = {}

def board_value(b, depth):
	ggg = tuple(b + [depth])
	if ggg in hist:
		return hist[ggg]
	if depth == 0:
		return 0
	bb = new_boards(b)
	if len(bb) == 0:
		return 0
	for x in bb:
		if is_win(x):
			hist[ggg] = 1
			return 1
	best = -1
	for x in bb:
		y = [-p for p in x]
		v = -board_value(y, depth - 1)
		if v > best:
			best = v
		if best == 1:
			break
	hist[ggg] = best
	return best
num_prob = int(input())
for prob in range(num_prob):
	(n_white, n_black, depth) = (int(x) for x in input().split())
	b = get_init_board(n_white, n_black)
	precompute_moves()
	v = board_value(b, depth)
	if v == 1:
		print('YES')
	else:
		print('NO')


knight_directions = {(0, 1): ((2, 0), (2, 2), (1, 3)), (1, 2): ((3, 1), (3, 3), (0, 0), (2, 0)), (3, 2): ((1, 1), (1, 3), (2, 0)), (0, 0): ((2, 1), (1, 2)), (3, 3): ((1, 2), (2, 1)), (3, 0): ((1, 1), (2, 2)), (3, 1): ((1, 0), (1, 2), (2, 3)), (2, 1): ((0, 0), (0, 2), (1, 3), (3, 3)), (0, 2): ((2, 1), (2, 3), (1, 0)), (2, 0): ((0, 1), (1, 2), (3, 2)), (1, 3): ((3, 2), (0, 1), (2, 1)), (2, 3): ((0, 2), (1, 1), (3, 1)), (2, 2): ((0, 1), (0, 3), (1, 0), (3, 0)), (1, 0): ((3, 1), (0, 2), (2, 2)), (0, 3): ((2, 2), (1, 1)), (1, 1): ((3, 0), (3, 2), (0, 3), (2, 3))}

def KnightMoves(board, side, pos):
	other = 1 - side
	for step in knight_directions[pos]:
		if step in board[other]:
			res = tuple((item.copy() for item in board))
			del res[side][pos]
			del res[other][step]
			res[side][step] = 'N'
			yield res
		elif step not in board[side]:
			res = tuple((item.copy() for item in board))
			del res[side][pos]
			res[side][step] = 'N'
			yield res
	raise StopIteration
bishop_directions = {(0, 1): (((1, 2), (2, 3)), ((1, 0),)), (1, 2): (((2, 3),), ((2, 1), (3, 0)), ((0, 3),), ((0, 1),)), (3, 2): (((2, 3),), ((2, 1), (1, 0))), (0, 0): (((1, 1), (2, 2), (3, 3)),), (3, 3): (((2, 2), (1, 1), (0, 0)),), (3, 0): (((2, 1), (1, 2), (0, 3)),), (3, 1): (((2, 2), (1, 3)), ((2, 0),)), (2, 1): (((3, 2),), ((3, 0),), ((1, 2), (0, 3)), ((1, 0),)), (0, 2): (((1, 3),), ((1, 1), (2, 0))), (2, 0): (((3, 1),), ((1, 1), (0, 2))), (1, 3): (((2, 2), (3, 1)), ((0, 2),)), (2, 3): (((3, 2),), ((1, 2), (0, 1))), (2, 2): (((3, 3),), ((3, 1),), ((1, 3),), ((1, 1), (0, 0))), (1, 0): (((2, 1), (3, 2)), ((0, 1),)), (0, 3): (((1, 2), (2, 1), (3, 0)),), (1, 1): (((2, 2), (3, 3)), ((2, 0),), ((0, 2),), ((0, 0),))}

def BishopMoves(board, side, pos):
	other = 1 - side
	for direction in bishop_directions[pos]:
		for step in direction:
			if step in board[other]:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				del res[other][step]
				res[side][step] = 'B'
				yield res
				break
			elif step in board[side]:
				break
			else:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				res[side][step] = 'B'
				yield res
	raise StopIteration
rook_directions = {(0, 1): (((1, 1), (2, 1), (3, 1)), ((0, 0),), ((0, 2), (0, 3))), (1, 2): (((2, 2), (3, 2)), ((1, 1), (1, 0)), ((1, 3),), ((0, 2),)), (3, 2): (((3, 1), (3, 0)), ((3, 3),), ((2, 2), (1, 2), (0, 2))), (0, 0): (((1, 0), (2, 0), (3, 0)), ((0, 1), (0, 2), (0, 3))), (3, 3): (((3, 2), (3, 1), (3, 0)), ((2, 3), (1, 3), (0, 3))), (3, 0): (((3, 1), (3, 2), (3, 3)), ((2, 0), (1, 0), (0, 0))), (3, 1): (((3, 0),), ((3, 2), (3, 3)), ((2, 1), (1, 1), (0, 1))), (2, 1): (((3, 1),), ((2, 0),), ((2, 2), (2, 3)), ((1, 1), (0, 1))), (0, 2): (((1, 2), (2, 2), (3, 2)), ((0, 1), (0, 0)), ((0, 3),)), (2, 0): (((3, 0),), ((2, 1), (2, 2), (2, 3)), ((1, 0), (0, 0))), (1, 3): (((2, 3), (3, 3)), ((1, 2), (1, 1), (1, 0)), ((0, 3),)), (2, 3): (((3, 3),), ((2, 2), (2, 1), (2, 0)), ((1, 3), (0, 3))), (2, 2): (((3, 2),), ((2, 1), (2, 0)), ((2, 3),), ((1, 2), (0, 2))), (1, 0): (((2, 0), (3, 0)), ((1, 1), (1, 2), (1, 3)), ((0, 0),)), (0, 3): (((1, 3), (2, 3), (3, 3)), ((0, 2), (0, 1), (0, 0))), (1, 1): (((2, 1), (3, 1)), ((1, 0),), ((1, 2), (1, 3)), ((0, 1),))}

def RookMoves(board, side, pos):
	other = 1 - side
	for direction in rook_directions[pos]:
		for step in direction:
			if step in board[other]:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				del res[other][step]
				res[side][step] = 'R'
				yield res
				break
			elif step in board[side]:
				break
			else:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				res[side][step] = 'R'
				yield res
	raise StopIteration
queen_directions = {pos: rook_directions[pos] + bishop_directions[pos] for pos in rook_directions}

def QueenMoves(board, side, pos):
	other = 1 - side
	for direction in queen_directions[pos]:
		for step in direction:
			if step in board[other]:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				del res[other][step]
				res[side][step] = 'Q'
				yield res
				break
			elif step in board[side]:
				break
			else:
				res = tuple((item.copy() for item in board))
				del res[side][pos]
				res[side][step] = 'Q'
				yield res
	raise StopIteration
func_dict = {'Q': QueenMoves, 'N': KnightMoves, 'B': BishopMoves, 'R': RookMoves}

def checkcont(board):
	return 'Q' in board[0].values()

def checkwin(board):
	return 'Q' not in board[1].values()

def GetResult(board, layer=0):
	if any(map(checkwin, NextMove(board, 0))):
		return True
	if not layer:
		return False
	for newboard in NextMove(board, 0):
		temp = tuple(NextMove(newboard, 1))
		if all(map(checkcont, temp)) and all((GetResult(newboard, layer - 1) for newboard in temp)):
			return True
	return False

def NextMove(board, side):
	curr = board[side]
	for pos in curr:
		for newboard in func_dict[curr[pos]](board, side, pos):
			yield newboard
posdict = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
for _ in range(int(input())):
	(w, b, m) = map(int, input().split())
	board = ({}, {})
	for _ in range(w):
		(t, c, r) = input().split()
		board[0][posdict[c], int(r) - 1] = t
	for _ in range(b):
		(t, c, r) = input().split()
		board[1][posdict[c], int(r) - 1] = t
	print('YES' if GetResult(board, (m - 1) // 2) else 'NO')


class ChessBoard:
	QUEEN = 1
	BISHOP = 2
	ROCK = 3
	KNIGHT = 4

	def SetBoard(self, board):
		self.board = board
		self.player_capture = [False, False]

	def Move(self, move):
		(from_row, from_col, to_row, to_col) = move
		src = self.board[from_row][from_col]
		dest = self.board[to_row][to_col]
		self.board[to_row][to_col] = src
		self.board[from_row][from_col] = False
		if dest != False and dest[1] == self.QUEEN:
			self.player_capture[dest[0]] = not self.player_capture[dest[0]]
		return [(src, from_row, from_col), (dest, to_row, to_col)]

	def Undo(self, move):
		(src, dest) = move
		self.board[src[1]][src[2]] = src[0]
		self.board[dest[1]][dest[2]] = dest[0]
		if dest[0] != False and dest[0][1] == self.QUEEN:
			self.player_capture[dest[0][0]] = not self.player_capture[dest[0][0]]

	def GenerateMove(self, player):
		for row in range(4):
			for col in range(4):
				piece = self.board[row][col]
				if piece == False:
					continue
				if piece[0] == player:
					if piece[1] == self.QUEEN:
						for x in self.GenerateRockMove(row, col):
							yield x
						for x in self.GenerateBishopMove(row, col):
							yield x
					elif piece[1] == self.KNIGHT:
						for x in self.GenerateKnightMove(row, col):
							yield x
					elif piece[1] == self.BISHOP:
						for x in self.GenerateBishopMove(row, col):
							yield x
					elif piece[1] == self.ROCK:
						for x in self.GenerateRockMove(row, col):
							yield x
		yield from []

	def GenerateKnightMove(self, row, col):
		player = self.board[row][col][0]
		moves = [(1, 2), (1, -2), (-1, 2), (-1, -2), (2, -1), (2, 1), (-2, -1), (-2, 1)]
		for m in moves:
			x = col + m[1]
			y = row + m[0]
			if (x >= 0 and x < 4 and (y >= 0) and (y < 4)) and (self.board[y][x] == False or self.board[y][x][0] != player):
				yield (row, col, y, x)
		yield from []

	def GenerateBishopMove(self, row, col):
		player = self.board[row][col][0]
		x = col - 1
		y = row - 1
		while x >= 0 and y >= 0 and (self.board[y][x] == False or self.board[y][x][0] != player):
			yield (row, col, y, x)
			if self.board[y][x] != False:
				break
			x -= 1
			y -= 1
		x = col - 1
		y = row + 1
		while x >= 0 and y < 4 and (self.board[y][x] == False or self.board[y][x][0] != player):
			yield (row, col, y, x)
			if self.board[y][x] != False:
				break
			x -= 1
			y += 1
		x = col + 1
		y = row - 1
		while x < 4 and y >= 0 and (self.board[y][x] == False or self.board[y][x][0] != player):
			yield (row, col, y, x)
			if self.board[y][x] != False:
				break
			x += 1
			y -= 1
		x = col + 1
		y = row + 1
		while x < 4 and y < 4 and (self.board[y][x] == False or self.board[y][x][0] != player):
			yield (row, col, y, x)
			if self.board[y][x] != False:
				break
			x += 1
			y += 1
		yield from []

	def GenerateRockMove(self, row, col):
		player = self.board[row][col][0]
		x = col - 1
		while x >= 0 and (self.board[row][x] == False or self.board[row][x][0] != player):
			yield (row, col, row, x)
			if self.board[row][x] != False:
				break
			x -= 1
		x = col + 1
		while x < 4 and (self.board[row][x] == False or self.board[row][x][0] != player):
			yield (row, col, row, x)
			if self.board[row][x] != False:
				break
			x += 1
		y = row - 1
		while y >= 0 and (self.board[y][col] == False or self.board[y][col][0] != player):
			yield (row, col, y, col)
			if self.board[y][col] != False:
				break
			y -= 1
		y = row + 1
		while y < 4 and (self.board[y][col] == False or self.board[y][col][0] != player):
			yield (row, col, y, col)
			if self.board[y][col] != False:
				break
			y += 1
		yield from []

	def Eval(self, m, step):
		player = step % 2
		if m == step:
			return self.player_capture[1]
		if player == 0:
			for move in self.GenerateMove(player):
				detail = self.Move(move)
				if self.player_capture[1]:
					self.Undo(detail)
					return True
				if self.Eval(m, step + 1):
					self.Undo(detail)
					return True
				self.Undo(detail)
			return False
		else:
			for move in self.GenerateMove(player):
				detail = self.Move(move)
				if self.player_capture[0]:
					self.Undo(detail)
					return False
				if not self.Eval(m, step + 1):
					self.Undo(detail)
					return False
				self.Undo(detail)
			return True
chess = ChessBoard()
d = {'N': ChessBoard.KNIGHT, 'B': ChessBoard.BISHOP, 'Q': ChessBoard.QUEEN, 'R': ChessBoard.ROCK}
g = int(input())
for g0 in range(g):
	board = [[False, False, False, False], [False, False, False, False], [False, False, False, False], [False, False, False, False]]
	(w, b, m) = list(map(int, input().split(' ')))
	for w0 in range(w):
		(t, c, r) = list(input().split(' '))
		board[int(r) - 1][int(ord(c) - ord('A'))] = (0, d[t])
	for b0 in range(b):
		(t, c, r) = list(input().split(' '))
		board[int(r) - 1][int(ord(c) - ord('A'))] = (1, d[t])
	chess.SetBoard(board)
	result = chess.Eval(m, 0)
	if result:
		print('YES')
	else:
		print('NO')


from copy import deepcopy
num_games = int(input().strip())

def print_board(board):
	print('\n'.join([''.join(i) for i in reversed(board)]))

def move(board, moves, row, col, cpref, pawn=False):
	ret = []
	for moveset in moves:
		for move in moveset:
			(r, c) = (row + move[0], col + move[1])
			if not (3 >= r >= 0 and 3 >= c >= 0):
				break
			if board[r][c] in cpref['pieces']:
				break
			if board[r][c] == 'Q':
				return False
			if board[r][c] == 'q':
				return True
			if pawn and move[1] != 0 and (board[r][c] == '_'):
				continue
			if pawn and move[1] == 0 and (board[r][c] != '_'):
				continue
			if pawn and r == cpref['last_row']:
				for i in cpref['pieces'][1:4]:
					new_board = deepcopy(board)
					new_board[r][c] = i
					new_board[row][col] = '_'
					ret.append(new_board)
				continue
			new_board = deepcopy(board)
			new_board[r][c] = board[row][col]
			new_board[row][col] = '_'
			ret.append(new_board)
			if board[r][c] != '_':
				break
	return ret

def play(board, color, max_moves):
	if max_moves <= 0:
		return False
	cpref = {'W': {'pieces': 'QNBRP', 'pawn_move': 1, 'last_row': 3, 'next_color': 'B'}, 'B': {'pieces': 'qnbrp', 'pawn_move': -1, 'last_row': 0, 'next_color': 'W'}}[color]
	rook_moves = [[[-1, 0], [-2, 0], [-3, 0]], [[1, 0], [2, 0], [3, 0]], [[0, -1], [0, -2], [0, -3]], [[0, 1], [0, 2], [0, 3]]]
	bishop_moves = [[[1, 1], [2, 2], [3, 3]], [[-1, -1], [-2, -2], [-3, -3]], [[1, -1], [2, -2], [3, -3]], [[-1, 1], [-2, 2], [-3, 3]]]
	knight_moves = [[[-2, -1]], [[-2, 1]], [[2, -1]], [[2, 1]], [[-1, -2]], [[-1, 2]], [[1, -2]], [[1, 2]]]
	next_states = []
	for (row_num, row) in enumerate(board):
		for (col_num, piece) in enumerate(row):
			if piece not in cpref['pieces']:
				continue
			piece = piece.upper()
			if piece == 'Q':
				moves = rook_moves + bishop_moves
				states = move(board, moves, row_num, col_num, cpref)
			elif piece == 'R':
				states = move(board, rook_moves, row_num, col_num, cpref)
			elif piece == 'N':
				states = move(board, knight_moves, row_num, col_num, cpref)
			elif piece == 'B':
				states = move(board, bishop_moves, row_num, col_num, cpref)
			elif piece == 'P':
				moves = [[[cpref['pawn_move'], -1]], [[cpref['pawn_move'], 0]], [[cpref['pawn_move'], 1]]]
				states = move(board, moves, row_num, col_num, cpref, True)
			if states is True:
				return True
			if states is False:
				return False
			next_states.extend(states)
	plays = (play(state, cpref['next_color'], max_moves - 1) for state in next_states)
	if color == 'B':
		return all(plays)
	else:
		return any(plays)
for game in range(num_games):
	(num_white, num_black, max_moves) = map(int, input().split())
	board = [list('____') for i in range(4)]
	for i in range(num_white):
		(piece, col, row) = input().split()
		col = 'ABCD'.index(col)
		row = int(row) - 1
		board[row][col] = piece
	for i in range(num_black):
		(piece, col, row) = input().split()
		col = 'ABCD'.index(col)
		row = int(row) - 1
		board[row][col] = piece.lower()
	if play(board, 'W', max_moves):
		print('YES')
	else:
		print('NO')


g = int(input().strip())
Map1 = {'A': 0, 'B': 1, 'C': 2, 'D': 3}

def Reverse(S):
	SNew = [[m2 for m2 in m1] for m1 in S]
	(SNew[0], SNew[1]) = (SNew[1], SNew[0])
	for (I, i) in enumerate(SNew):
		for (J, j) in enumerate(i):
			SNew[I][J] = (j[0], (j[1][0], 3 - j[1][1]))
	return SNew

def GetLegal(S, MaxDepth, Depth=0):
	if type(S) != list:
		return S
	if Depth % 2 == 1:
		S = Reverse(S)
	Pos = []
	for i in S:
		Pos.append([])
		for j in i:
			Pos[-1].append(j[1])
	AllPos = Pos[0] + Pos[1]
	NewS = []
	for (I, i) in enumerate(S[0]):
		Type = i[0]
		Coord = i[1]
		if Type == 'P':
			if Coord[1] == 2:
				NewType = ['R', 'N', 'B']
			else:
				NewType = ['P']
			if (Coord[0], Coord[1] + 1) not in AllPos:
				for T in NewType:
					TempS = [[m2 for m2 in m1] for m1 in S]
					TempS[0][I] = (T, (Coord[0], Coord[1] + 1))
					NewS.append(TempS)
			for Shift in [-1, 1]:
				if (Coord[0] + Shift, Coord[1] + 1) in Pos[1]:
					for (J, j) in enumerate(Pos[1]):
						if j == (Coord[0] + Shift, Coord[1] + 1):
							CaptureInd = J
							break
					for T in NewType:
						TempS = [[m2 for m2 in m1] for m1 in S]
						del TempS[1][CaptureInd]
						TempS[0][I] = (T, (Coord[0] + Shift, Coord[1] + 1))
						NewS.append(TempS)
		if Type == 'Q' or Type == 'R':
			LR = lambda j, Coord: (j, Coord[1])
			UD = lambda j, Coord: (Coord[0], j)
			for (TravInd, TravRng) in enumerate([range(Coord[0] - 1, -1, -1), range(Coord[0] + 1, 4), range(Coord[1] - 1, -1, -1), range(Coord[1] + 1, 4)]):
				if TravInd == 0 or TravInd == 1:
					CFun = LR
				else:
					CFun = UD
				for j in TravRng:
					if CFun(j, Coord) in Pos[0]:
						break
					elif CFun(j, Coord) in Pos[1]:
						for (K, k) in enumerate(Pos[1]):
							if k == CFun(j, Coord):
								CaptureInd = K
								break
						TempS = [[m2 for m2 in m1] for m1 in S]
						del TempS[1][CaptureInd]
						TempS[0][I] = (Type, CFun(j, Coord))
						NewS.append(TempS)
						break
					else:
						TempS = [[m2 for m2 in m1] for m1 in S]
						TempS[0][I] = (Type, CFun(j, Coord))
						NewS.append(TempS)
		if Type == 'Q' or Type == 'B':
			for TravDir in [[1, 1], [-1, 1], [1, -1], [-1, -1]]:
				for ShiftMag in range(1, 4):
					NewCoord = (Coord[0] + ShiftMag * TravDir[0], Coord[1] + ShiftMag * TravDir[1])
					if NewCoord[0] < 0 or NewCoord[0] > 3:
						break
					if NewCoord[1] < 0 or NewCoord[1] > 3:
						break
					if NewCoord in Pos[0]:
						break
					elif NewCoord in Pos[1]:
						for (K, k) in enumerate(Pos[1]):
							if k == NewCoord:
								CaptureInd = K
								break
						TempS = [[m2 for m2 in m1] for m1 in S]
						del TempS[1][CaptureInd]
						TempS[0][I] = (Type, NewCoord)
						NewS.append(TempS)
						break
					else:
						TempS = [[m2 for m2 in m1] for m1 in S]
						TempS[0][I] = (Type, NewCoord)
						NewS.append(TempS)
		NMove = [(1, 2), (-1, 2), (1, -2), (-1, -2), (2, 1), (-2, 1), (2, -1), (-2, -1)]
		if Type == 'N':
			for (J, j) in enumerate(NMove):
				NewCoord = (Coord[0] + j[0], Coord[1] + j[1])
				if NewCoord[0] > -1 and NewCoord[0] < 4 and (NewCoord[1] > -1) and (NewCoord[1] < 4) and (NewCoord not in Pos[0]):
					TempS = [[m2 for m2 in m1] for m1 in S]
					for (K, k) in enumerate(Pos[1]):
						if k == NewCoord:
							del TempS[1][K]
							break
					TempS[0][I] = (Type, NewCoord)
					NewS.append(TempS)
	for i in NewS:
		if type(i) == list:
			QueenFound = False
			for j in i[1]:
				if j[0] == 'Q':
					QueenFound = True
					break
			if not QueenFound:
				return Depth % 2
	if Depth % 2 == 1:
		NewS = [Reverse(m) for m in NewS]
	if Depth < MaxDepth:
		NewS = [GetLegal(m, MaxDepth, Depth + 1) for m in NewS]
	else:
		NewS = [1 if type(m) == list else m for m in NewS]
	if sum([1 if type(m) == list else 0 for m in NewS]) == 0:
		if Depth % 2 in NewS:
			return Depth % 2
		else:
			return NewS[0]
	return NewS
for a0 in range(g):
	(w, b, m) = input().strip().split(' ')
	(w, b, m) = [int(w), int(b), int(m)]
	white = []
	for white_i in range(w):
		white_t = [str(white_temp) for white_temp in input().strip().split(' ')]
		white_t = (white_t[0], (Map1[white_t[1]], int(white_t[2]) - 1))
		white.append(white_t)
	black = []
	for black_i in range(b):
		black_t = [str(black_temp) for black_temp in input().strip().split(' ')]
		black_t = (black_t[0], (Map1[black_t[1]], int(black_t[2]) - 1))
		black.append(black_t)
	if m % 2 == 0:
		m -= 1
	State = [white, black]
	if GetLegal(State, m - 1) == 0:
		print('YES')
	else:
		print('NO')


from pprint import pprint as pp
L2N = {'A': 1, 'B': 2, 'C': 3, 'D': 4}
pmoves = {}
pmoves['R'] = m = {}
for i in range(1, 5):
	for j in range(1, 5):
		m[i, j] = mij = []
		mij.append([(x, j) for x in range(i + 1, 5)])
		mij.append([(x, j) for x in range(i - 1, 0, -1)])
		mij.append([(i, y) for y in range(j + 1, 5)])
		mij.append([(i, y) for y in range(j - 1, 0, -1)])
pmoves['B'] = m = {}
for i in range(1, 5):
	for j in range(1, 5):
		m[i, j] = mij = []
		mij.append([(i + d, j + d) for d in range(1, 4) if 1 <= i + d <= 4 and 1 <= j + d <= 4])
		mij.append([(i + d, j - d) for d in range(1, 4) if 1 <= i + d <= 4 and 1 <= j - d <= 4])
		mij.append([(i - d, j + d) for d in range(1, 4) if 1 <= i - d <= 4 and 1 <= j + d <= 4])
		mij.append([(i - d, j - d) for d in range(1, 4) if 1 <= i - d <= 4 and 1 <= j - d <= 4])
pmoves['Q'] = m = {}
for i in range(1, 5):
	for j in range(1, 5):
		m[i, j] = mij = []
		mij += pmoves['B'][i, j]
		mij += pmoves['R'][i, j]
pmoves['N'] = m = {}
ndiff = ((-1, 2), (1, 2), (2, 1), (2, -1), (1, -2), (-1, -2), (-2, -1), (-2, 1))
for i in range(1, 5):
	for j in range(1, 5):
		m[i, j] = mij = []
		mij += [(i + dx, j + dy) for (dx, dy) in ndiff if 1 <= i + dx <= 4 and 1 <= j + dy <= 4]
pmoves['P'] = m = {}
for i in range(1, 5):
	for j in range(1, 5):
		m[i, j] = mij = [(i, j + 1)]
		if i > 1:
			mij.append((i - 1, j + 1))
		if i < 1:
			mij.append((i + 1, j + 1))

def move_queen(board, player, pos, piece):
	for row in pmoves[piece][pos]:
		for new_pos in row:
			if new_pos in board[player]:
				break
			if new_pos in board[player ^ 1]:
				new_board = tuple((i.copy() for i in board))
				del new_board[player][pos]
				del new_board[player ^ 1][new_pos]
				new_board[player][new_pos] = piece
				yield new_board
				break
			else:
				new_board = tuple((i.copy() for i in board))
				del new_board[player][pos]
				new_board[player][new_pos] = piece
				yield new_board
move_rook = move_bishop = move_queen

def move_knight(board, player, pos, piece):
	for new_pos in pmoves[piece][pos]:
		if new_pos in board[player]:
			continue
		elif new_pos in board[player ^ 1]:
			new_board = tuple((i.copy() for i in board))
			del new_board[player][pos]
			del new_board[player ^ 1][new_pos]
			new_board[player][new_pos] = piece
			yield new_board
		else:
			new_board = tuple((i.copy() for i in board))
			del new_board[player][pos]
			new_board[player][new_pos] = piece
			yield new_board
edge = (4, 1)

def move_pawn(board, player, pos, piece):
	new_pos = pmoves[piece][pos][0]
	if new_pos[1] == edge[player]:
		for new_piece in ('B', 'K', 'R'):
			new_board = tuple((i.copy() for i in board))
			del new_board[player][pos]
			new_board[player][new_pos] = new_piece
			yield new_board
	else:
		new_board = tuple((i.copy() for i in board))
		del new_board[player][pos]
		new_board[player][new_pos] = piece
		yield new_board
	for new_pos in pmoves[piece][pos][1:]:
		if new_pos in board[player ^ 1]:
			if new_pos[1] == edge[player]:
				for new_piece in ('B', 'K', 'R'):
					new_board = tuple((i.copy() for i in board))
					del new_board[player][pos]
					del new_board[player ^ 1][new_pos]
					new_board[player][new_pos] = new_piece
					yield new_board
			else:
				new_board = tuple((i.copy() for i in board))
				del new_board[player][pos]
				del new_board[player ^ 1][new_pos]
				new_board[player][new_pos] = piece
				yield new_board
move = {'Q': move_queen, 'R': move_rook, 'B': move_bishop, 'N': move_knight, 'P': move_pawn}

def moves(board, player):
	for (pos, piece) in board[player].items():
		yield from move[piece](board, player, pos, piece)

def white_won(board):
	return 'Q' not in board[1].values()

def white_lost(board):
	return 'Q' not in board[0].values()

def solve(board, turns_left):
	if not turns_left:
		return False
	boards_for_1 = tuple(moves(board, 0))
	if any(map(white_won, boards_for_1)):
		return True
	for board_for_1 in boards_for_1:
		boards_for_0 = tuple(moves(board_for_1, 1))
		if any(map(white_lost, boards_for_0)):
			continue
		if all((solve(b, turns_left - 1) for b in boards_for_0)):
			return True
	return False
for _ in range(int(input())):
	(w, b, m) = map(int, input().split())
	board = ({}, {})
	for _ in range(w):
		(piece, i, j) = input().split()
		board[0][L2N[i], int(j)] = piece
	for _ in range(b):
		(piece, i, j) = input().split()
		board[1][L2N[i], int(j)] = piece
	print('YES' if solve(board, (m + 1) // 2) else 'NO')


class Board:

	def __init__(self, board):
		self.board = [['o' for x in range(4)] for y in range(4)]
		for y in range(len(board)):
			for x in range(len(board[0])):
				self.board[y][x] = board[y][x]

	def print_board(self):
		for y in range(3, -1, -1):
			print(self.board[y])

def get_queens(B):
	b = B.board
	(wQueen, bQueen) = (False, False)
	for row in b:
		for t in row:
			if t == 'bQ':
				bQueen = True
			if t == 'wQ':
				wQueen = True
	return (wQueen, bQueen)

def get_boards2(B, player):
	board = B.board
	n = len(board)
	for row in range(n):
		for col in range(n):
			(c, t) = board[row][col]
			if c == player:
				for nBoard in get_boards(B, player, t, row, col):
					yield nBoard

def get_boards(B, player, t, row, col):
	if t == 'Q':
		for deltaRow in [-1, 0, 1]:
			for deltaCol in [-1, 0, 1]:
				if deltaRow == 0 and deltaCol == 0:
					continue
				for nb in get_boards_moving_strait_line(B, player, t, row, col, deltaRow, deltaCol):
					yield nb
	elif t == 'R':
		for deltaRow in [-1, 0, 1]:
			for deltaCol in [-1, 0, 1]:
				if deltaRow == 0 and deltaCol == 0 or (deltaRow != 0 and deltaCol != 0):
					continue
				for nb in get_boards_moving_strait_line(B, player, t, row, col, deltaRow, deltaCol):
					yield nb
	elif t == 'B':
		for deltaRow in [-1, 0, 1]:
			for deltaCol in [-1, 0, 1]:
				if deltaRow == 0 or deltaCol == 0:
					continue
				for nb in get_boards_moving_strait_line(B, player, t, row, col, deltaRow, deltaCol):
					yield nb
	elif t == 'N':
		for nb in get_boards_moving_in_L_shape(B, player, t, row, col):
			yield nb

def get_boards_moving_strait_line(B, player, t, row, col, deltaRow, deltaCol):
	step = 1
	while row + step * deltaRow >= 0 and row + step * deltaRow < 4 and (col + step * deltaCol >= 0) and (col + step * deltaCol < 4):
		(c, _) = list(B.board[row + step * deltaRow][col + step * deltaCol])
		if c == player:
			break
		nb = Board(B.board)
		nb.board[row + step * deltaRow][col + step * deltaCol] = player + t
		nb.board[row][col] = 'oo'
		yield nb
		if not c == player and c != 'o':
			break
		step += 1

def get_boards_moving_in_L_shape(B, player, t, row, col):
	deltas = [(-2, 1), (-1, 2), (1, 2), (2, 1), (2, -1), (1, -2), (-1, -2), (-2, -1)]
	for (drow, dcol) in deltas:
		if row + drow >= 0 and row + drow < 4 and (col + dcol >= 0) and (col + dcol < 4):
			(c, _) = list(B.board[row + drow][col + dcol])
			if c == player:
				continue
			nb = Board(B.board)
			nb.board[row + drow][col + dcol] = player + t
			nb.board[row][col] = 'oo'
			yield nb

def wwins(m, B, p, np):
	(whiteQueen, blackQueen) = get_queens(B)
	if not blackQueen and (not whiteQueen):
		raise Exception('no queens')
	if not blackQueen:
		return True
	if not whiteQueen:
		return False
	if m == 0 or (m == 1 and p == 'b'):
		return False
	if p == 'w':
		for nb in get_boards2(B, p):
			if wwins(m - 1, nb, np, p):
				return True
		return False
	for nb in get_boards2(B, p):
		if not wwins(m - 1, nb, np, p):
			return False
	return True
g = int(input())
for j in range(g):
	(w, b, m) = list(map(int, input().split(' ')))
	board = [['oo' for x in range(4)] for y in range(4)]
	cols = ['A', 'B', 'C', 'D']
	for i in range(w):
		(t, c, r) = input().split(' ')
		board[int(r) - 1][cols.index(c)] = 'w' + t
	for i in range(b):
		(t, c, r) = input().split(' ')
		board[int(r) - 1][cols.index(c)] = 'b' + t
	print('YES' if wwins(m, Board(board), 'w', 'b') else 'NO')


FIGS = {'R': 1, 'B': 2, 'N': 3, 'Q': 4}
MOVES = [(), (((-1, 0), (-2, 0), (-3, 0)), ((1, 0), (2, 0), (3, 0)), ((0, -1), (0, -2), (0, -3)), ((0, 1), (0, 2), (0, 3))), (((-1, -1), (-2, -2), (-3, -3)), ((1, 1), (2, 2), (3, 3)), ((-1, 1), (-2, 2), (-3, 3)), ((1, -1), (2, -2), (3, -3))), (((1, 2),), ((2, 1),), ((1, -2),), ((2, -1),), ((-1, 2),), ((-2, 1),), ((-1, -2),), ((-2, -1),))]
MOVES.append(MOVES[1] + MOVES[2])

def nextMoves(F, M):
	if M == 0:
		return False
	if M & 1:
		for i in range(16):
			(r, c) = (i >> 2, i & 3)
			if F[r][c] > 0:
				for md in MOVES[F[r][c]]:
					for m in md:
						(nr, nc) = (r + m[0], c + m[1])
						if nr >= 0 and nr < 4 and (nc >= 0) and (nc < 4):
							f = F[nr][nc]
							if f == -4:
								return True
							if f > 0:
								break
							(fsrc, fdst) = (F[r][c], F[nr][nc])
							F[r][c] = 0
							F[nr][nc] = fsrc
							res = M > 1 and nextMoves(F, M - 1)
							(F[r][c], F[nr][nc]) = (fsrc, fdst)
							if res:
								return True
							if f < 0:
								break
		return False
	else:
		for i in range(16):
			(r, c) = (i >> 2, i & 3)
			fsrc = F[r][c]
			if fsrc < 0:
				for md in MOVES[-F[r][c]]:
					for m in md:
						(nr, nc) = (r + m[0], c + m[1])
						if nr >= 0 and nr < 4 and (nc >= 0) and (nc < 4):
							f = F[nr][nc]
							if f == 4:
								return False
							if f < 0:
								break
							(fsrc, fdst) = (F[r][c], F[nr][nc])
							F[r][c] = 0
							F[nr][nc] = fsrc
							res = M > 1 and (not nextMoves(F, M - 1))
							(F[r][c], F[nr][nc]) = (fsrc, fdst)
							if res:
								return False
							if f > 0:
								break
		return True
G = int(input().strip())
for g in range(G):
	(W, B, M) = map(int, input().strip().split())
	if M & 1 == 0:
		M -= 1
	F = [[0] * 4 for _ in range(4)]
	for _ in range(W):
		(fs, cs, rs) = input().strip().split()
		(f, c, r) = (FIGS[fs], ord(cs) - ord('A'), ord(rs) - ord('1'))
		F[r][c] = f
	for _ in range(B):
		(fs, cs, rs) = input().strip().split()
		(f, c, r) = (FIGS[fs], ord(cs) - ord('A'), ord(rs) - ord('1'))
		F[r][c] = -f
	print(('NO', 'YES')[nextMoves(F, M)])


EMPTY = 0
WALL = None
(Q_, R_, B_, N_) = (1, 2, 3, 4)
(q_, r_, b_, n_) = (-1, -2, -3, -4)
VALID = [i * 8 + j for i in range(2, 6) for j in range(2, 6)]
rays = {Q_: [1, -1, 8, -8, 7, -7, 9, -9], R_: [1, -1, 8, -8], B_: [7, -7, 9, -9], N_: [6, -6, 10, -10, 15, -15, 17, -17], q_: [1, -1, 8, -8, 7, -7, 9, -9], r_: [1, -1, 8, -8], b_: [7, -7, 9, -9], n_: [6, -6, 10, -10, 15, -15, 17, -17]}

def find_pieces(board, color):
	for i in VALID:
		p = board[i]
		if p * color > 0:
			yield (i, p)

def follow_ray(board, stm, i, ray):
	while True:
		i += ray
		q = board[i]
		if q is WALL or q * stm > 0:
			break
		yield i
		if q != EMPTY:
			break

def moves(board, stm):
	for (i, p) in find_pieces(board, stm):
		for r in rays[p]:
			for j in follow_ray(board, stm, i, r):
				yield (i, j)

def read_board(w, b):
	board = [WALL] * 64
	for i in VALID:
		board[i] = EMPTY
	idx = dict(zip('QRBN', range(1, 5)))
	for i in range(w + b):
		(P, file, rank) = input().split()
		pos = 2 + ord(file) - ord('A') + 8 * (int(rank) + 1)
		board[pos] = idx[P] if i < w else -idx[P]
	return board

class Chess:

	def __init__(self, board):
		self.board = board
		self.stack = []

	def make_move(self, fr, to):
		self.stack.append(board[to])
		self.board[to] = board[fr]
		self.board[fr] = EMPTY

	def undo_move(self, fr, to):
		self.board[fr] = self.board[to]
		self.board[to] = self.stack.pop()

def kill_queen(chess, stm, m):
	if m == 0:
		return 0
	ret = -stm
	for (fr, to) in moves(chess.board, stm):
		if abs(board[to]) == 1:
			return stm
		chess.make_move(fr, to)
		res = kill_queen(chess, -stm, m - 1)
		chess.undo_move(fr, to)
		if res == stm:
			return stm
		elif res == 0:
			ret = 0
	return ret
g = int(input())
for i in range(g):
	(w, b, m) = map(int, input().split())
	board = read_board(w, b)
	if m > 0 and m % 2 == 0:
		m -= 1
	print('YES' if kill_queen(Chess(board), 1, m) == 1 else 'NO')


from collections import deque
import sys
mappX = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
mappY = {'1': 0, '2': 1, '3': 2, '4': 3}
mappP = {'Q': 1, 'N': 2, 'B': 3, 'R': 4}
Nm = [(2, 1), (2, -1), (-2, 1), (-2, -1), (1, 2), (1, -2), (-1, 2), (-1, -2)]
Rm = [(1, 0), (2, 0), (3, 0), (4, 0), (-1, 0), (-2, 0), (-3, 0), (-4, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, -1), (0, -2), (0, -3), (0, -4)]
Rd = [(1, 0), (-1, 0), (0, 1), (0, -1)]
Bm = [(1, 1), (2, 2), (3, 3), (4, 4), (-1, -1), (-2, -2), (-3, -3), (-4, -4), (-1, 1), (-2, 2), (-3, 3), (-4, 4), (1, -1), (2, -2), (3, -3), (4, -4)]
Bd = [(1, 1), (-1, -1), (-1, 1), (1, -1)]
Qm = Rm[:]
Qm.extend(Bm)
Qd = Rd[:]
Qd.extend(Bd)

def pos(x, y):
	if x < 0 or x >= 4 or y < 0 or (y >= 4):
		return 16
	return x + 4 * y
q = int(input())
for _ in range(q):
	(a, b, m) = [int(x) for x in input().split()]
	brade = [0] * 17
	brade[16] = 1
	for _ in range(a):
		I = input().split()
		c = mappP[I[0]]
		x = mappX[I[1]]
		y = mappY[I[2]]
		brade[pos(x, y)] = c
	for _ in range(b):
		I = input().split()
		c = mappP[I[0]]
		x = mappX[I[1]]
		y = mappY[I[2]]
		brade[pos(x, y)] = -c

	def canWin(B):
		movs = abs(B[16]) - 1
		if movs >= m:
			return False
		if B[16] > 0:
			for x in range(4):
				for y in range(4):
					cpos = pos(x, y)
					P = B[cpos]
					if P <= 0:
						continue
					if P == 2:
						for mv in Nm:
							tpos = pos(x + mv[0], y + mv[1])
							if B[tpos] <= 0:
								if B[tpos] == -1:
									return True
								n_B = B[:]
								n_B[16] = -(n_B[16] + 1)
								n_B[tpos] = n_B[cpos]
								n_B[cpos] = 0
								if canWin(n_B):
									return True
					if P == 4:
						for d in Rd:
							dx = d[0]
							dy = d[1]
							tpos = pos(x + dx, y + dy)
							while B[tpos] <= 0:
								if B[tpos] == -1:
									return True
								n_B = B[:]
								n_B[16] = -(n_B[16] + 1)
								n_B[tpos] = n_B[cpos]
								n_B[cpos] = 0
								if canWin(n_B):
									return True
								if B[tpos] < 0:
									break
								dx += d[0]
								dy += d[1]
								tpos = pos(x + dx, y + dy)
					if P == 3:
						for d in Bd:
							dx = d[0]
							dy = d[1]
							tpos = pos(x + dx, y + dy)
							while B[tpos] <= 0:
								if B[tpos] == -1:
									return True
								n_B = B[:]
								n_B[16] = -(n_B[16] + 1)
								n_B[tpos] = n_B[cpos]
								n_B[cpos] = 0
								if canWin(n_B):
									return True
								if B[tpos] < 0:
									break
								dx += d[0]
								dy += d[1]
								tpos = pos(x + dx, y + dy)
					if P == 1:
						for d in Qd:
							dx = d[0]
							dy = d[1]
							tpos = pos(x + dx, y + dy)
							while B[tpos] <= 0:
								if B[tpos] == -1:
									return True
								n_B = B[:]
								n_B[16] = -(n_B[16] + 1)
								n_B[tpos] = n_B[cpos]
								n_B[cpos] = 0
								if canWin(n_B):
									return True
								if B[tpos] < 0:
									break
								dx += d[0]
								dy += d[1]
								tpos = pos(x + dx, y + dy)
			return False
		else:
			canalwayswin = True
			for x in range(4):
				for y in range(4):
					cpos = pos(x, y)
					P = B[cpos]
					if P >= 0:
						continue
					if P == -2:
						for mv in Nm:
							tpos = pos(x + mv[0], y + mv[1])
							if B[tpos] >= 0:
								if B[tpos] == 1:
									return False
								n_B = B[:]
								n_B[16] = -(n_B[16] - 1)
								n_B[tpos] = n_B[cpos]
								n_B[cpos] = 0
								if not canWin(n_B):
									return False
					if P == -4:
						for d in Rd:
							dx = d[0]
							dy = d[1]
							tpos = pos(x + dx, y + dy)
							while B[tpos] >= 0:
								if B[tpos] == 1:
									return False
								n_B = B[:]
								n_B[16] = -(n_B[16] - 1)
								n_B[tpos] = n_B[cpos]
								n_B[cpos] = 0
								if not canWin(n_B):
									return False
								if B[tpos] > 0:
									break
								dx += d[0]
								dy += d[1]
								tpos = pos(x + dx, y + dy)
					if P == -3:
						for d in Bd:
							dx = d[0]
							dy = d[1]
							tpos = pos(x + dx, y + dy)
							while B[tpos] >= 0:
								if B[tpos] == 1:
									return False
								n_B = B[:]
								n_B[16] = -(n_B[16] - 1)
								n_B[tpos] = n_B[cpos]
								n_B[cpos] = 0
								if not canWin(n_B):
									return False
								if B[tpos] > 0:
									break
								dx += d[0]
								dy += d[1]
								tpos = pos(x + dx, y + dy)
					if P == -1:
						for d in Qd:
							dx = d[0]
							dy = d[1]
							tpos = pos(x + dx, y + dy)
							while B[tpos] >= 0:
								if B[tpos] == 1:
									return False
								n_B = B[:]
								n_B[16] = -(n_B[16] - 1)
								n_B[tpos] = n_B[cpos]
								n_B[cpos] = 0
								if not canWin(n_B):
									return False
								if B[tpos] > 0:
									break
								dx += d[0]
								dy += d[1]
								tpos = pos(x + dx, y + dy)
			return True
	if canWin(brade):
		print('YES')
	else:
		print('NO')


ROW_TRANS = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
COL_TRANS = {'1': 0, '2': 1, '3': 2, '4': 3}
games = []
for _ in range(int(input().strip())):
	game = [None] * 2
	(white_ps, black_ps, game[0]) = (int(x) for x in input().strip().split(' '))
	start_pieces = []
	for _ in range(white_ps):
		temp_p = ['w']
		temp_p.extend(input().strip().split(' '))
		start_pieces.append(temp_p)
	for _ in range(black_ps):
		temp_p = ['b']
		temp_p.extend(input().strip().split(' '))
		start_pieces.append(temp_p)
	for p in start_pieces:
		p[2] = ROW_TRANS[p[2]]
		p[3] = COL_TRANS[p[3]]
	game[1] = start_pieces
	games.append(game)
SQUARE_MOVES = [(-1, 0), (1, 0), (0, -1), (0, 1)]
DIAG_MOVES = [(-1, -1), (1, -1), (-1, 1), (1, 1)]
KNIGHT_MOVES = [(2, 1), (1, 2), (2, -1), (1, -2), (-2, 1), (-1, 2), (-2, -1), (-1, -2)]

def other_player(player):
	if player == 'w':
		return 'b'
	else:
		return 'w'

def get_moves(pieces, index):
	him = pieces[index]
	him_type = him[1]
	can = []
	pimo = []
	priority_move = None
	if him_type == 'R' or him_type == 'Q':
		pimo += SQUARE_MOVES
	if him_type == 'B' or him_type == 'Q':
		pimo += DIAG_MOVES
	if him_type == 'N':
		pimo += KNIGHT_MOVES
	for mo in pimo:
		squares_move = 1
		keepmoving = True
		while keepmoving:
			(newx, newy) = (him[2] + mo[0] * squares_move, him[3] + mo[1] * squares_move)
			if newx not in ROW_TRANS.values() or newy not in COL_TRANS.values():
				keepmoving = False
				break
			this_sq_ok = True
			for p in pieces:
				if p[2] == newx and p[3] == newy:
					if p[0] == him[0]:
						keepmoving = False
						this_sq_ok = False
					else:
						keepmoving = False
						if p[0] == 'b' and p[1] == 'Q':
							priority_move = (newx, newy)
			if this_sq_ok:
				can.append((newx, newy))
			squares_move += 1
	if priority_move:
		index = can.index(priority_move)
		can.insert(0, can.pop(index))
	return can

def do_move(pieces, player, t_elapsed, t_limit):
	(b_queen, w_queen) = (False, False)
	for p in pieces:
		if p[1] == 'Q':
			if p[0] == 'w':
				w_queen = True
			if p[0] == 'b':
				b_queen = True
	if not w_queen:
		return False
	if not b_queen:
		return True
	if t_elapsed >= t_limit:
		return False
	if player == 'b' and t_elapsed + 1 >= t_limit:
		return False
	for (i, p) in enumerate(pieces):
		if player == p[0]:
			moves = get_moves(pieces, i)
			for m in moves:
				moved_piece = pieces[i]
				new_pieces = [[np0, np1, np2, np3] for (np0, np1, np2, np3) in pieces if np2 != m[0] or np3 != m[1]]
				for np in new_pieces:
					if np == moved_piece:
						np[2] = m[0]
						np[3] = m[1]
				res = do_move(new_pieces, other_player(player), t_elapsed + 1, t_limit)
				if res and player == 'w':
					return True
				if not res and player == 'b':
					return False
	if player == 'w':
		return False
	if player == 'b':
		return True
	assert False

def calc_games(list_of_games):
	for g in list_of_games:
		res = do_move(g[1], 'w', 0, g[0])
		if res:
			print('YES')
		else:
			print('NO')
	return
calc_games(games)


def inside_boundaries(pos):
	(x, y) = pos
	return 1 <= x <= 4 and 1 <= y <= 4

def possible_moves(kind, row, col, my_pos, enemy_pos):

	def test_pos(pos_agg, pos_cand):
		if pos_cand in my_pos or not inside_boundaries(pos_cand):
			return True
		elif pos_cand in enemy_pos:
			pos_agg.append(pos_cand)
			return True
		else:
			pos_agg.append(pos_cand)
			return False
	if kind == 'R':
		rv = []
		for i in [1, 2, 3, 4]:
			x = (row, col + i)
			if test_pos(rv, x):
				break
		for i in [1, 2, 3, 4]:
			x = (row, col - i)
			if test_pos(rv, x):
				break
		for i in [1, 2, 3, 4]:
			x = (row + i, col)
			if test_pos(rv, x):
				break
		for i in [1, 2, 3, 4]:
			x = (row - i, col)
			if test_pos(rv, x):
				break
		return rv
	elif kind == 'B':
		rv = []
		for i in [1, 2, 3, 4]:
			x = (row + i, col + i)
			if test_pos(rv, x):
				break
		for i in [1, 2, 3, 4]:
			x = (row + i, col - i)
			if test_pos(rv, x):
				break
		for i in [1, 2, 3, 4]:
			x = (row - i, col + i)
			if test_pos(rv, x):
				break
		for i in [1, 2, 3, 4]:
			x = (row - i, col - i)
			if test_pos(rv, x):
				break
		return rv
	elif kind == 'Q':
		return possible_moves('R', row, col, my_pos, enemy_pos) + possible_moves('B', row, col, my_pos, enemy_pos)
	elif kind == 'N':
		moves = [(row + 2, col + 1), (row + 2, col - 1), (row - 2, col + 1), (row - 2, col - 1), (row + 1, col + 2), (row - 1, col + 2), (row + 1, col - 2), (row - 1, col - 2)]
		return [p for p in moves if inside_boundaries(p) and p not in my_pos]
	else:
		raise ValueError('Piece type ' + kind + ' not recognized.')

class Piece:

	def __init__(self, t, r, c):
		self.kind = t
		self.row = r
		self.col = c

	def __eq__(self, other):
		if isinstance(other, self.__class__):
			return self.kind == other.kind and self.row == other.row and (self.col == other.col)
		else:
			return False

	def __neq__(self, other):
		return not self.__eq__(other)

	def __hash__(self):
		return hash((self.kind, self.row, self.col))

	def __str__(self):
		return self.kind + '@' + {1: 'A', 2: 'B', 3: 'C', 4: 'D'}[self.col] + str(self.row)

def get_winner(player, player_pieces, enemy_pieces, moves_left):
	if moves_left > 0:
		player_occupied = [(p.row, p.col) for p in player_pieces]
		enemy_occupied = [(p.row, p.col) for p in enemy_pieces]
		enemy_queen = [(p.row, p.col) for p in enemy_pieces if p.kind == 'Q'][0]
		enum_player_pieces = enumerate(player_pieces)
		next_configs = []
		for (k, piece) in enum_player_pieces:
			piece_moves = [m for m in possible_moves(piece.kind, piece.row, piece.col, player_occupied, enemy_occupied)]
			if enemy_queen in piece_moves:
				return player
			next_configs += [(player_pieces[:k] + [Piece(piece.kind, x, y)] + player_pieces[k + 1:], [e for e in enemy_pieces if (e.row, e.col) != (x, y)]) for (x, y) in piece_moves]
		if player == 'W':
			enemy = 'B'
		else:
			enemy = 'W'
		next_winners = [get_winner(enemy, e, p, moves_left - 1) for (p, e) in next_configs]
		if any([nw == player for nw in next_winners]):
			return player
		elif all([nw == enemy for nw in next_winners]):
			return enemy
		else:
			return '?'
	else:
		return '?'
G = int(input())
for _ in range(G):
	(W, B, M) = [int(x) for x in input().split(' ')]
	if M > 0 and M % 2 == 0:
		M = M - 1
	whites = []
	for i in range(W):
		(t, c, r) = [x for x in input().split(' ')]
		whites.append(Piece(t, int(r), {'A': 1, 'B': 2, 'C': 3, 'D': 4}[c]))
	blacks = []
	for i in range(B):
		(t, c, r) = [x for x in input().split(' ')]
		blacks.append(Piece(t, int(r), {'A': 1, 'B': 2, 'C': 3, 'D': 4}[c]))
	winner = get_winner('W', whites, blacks, M)
	if winner == 'W':
		print('YES')
	else:
		print('NO')


from itertools import product
SIZE = 4
WHITE = 0
BLACK = 1
EMPTY = (-1, None)
CACHE_LIMIT = 3
DIRECTIONS = {'Q': [[(y * i, x * i) for i in range(1, SIZE)] for (y, x) in product(range(-1, 2), repeat=2) if y or x], 'N': [[(y, x)] for (y, x) in product([-2, -1, 1, 2], repeat=2) if (y + x) % 2], 'B': [[(y * i, x * i) for i in range(1, SIZE)] for (y, x) in [(-1, 1), (1, 1), (1, -1), (-1, -1)]], 'R': [[(y * i, x * i) for i in range(1, SIZE)] for (y, x) in [(-1, 0), (0, 1), (1, 0), (0, -1)]]}

def play(board, white, black, turn, moves_left, memo):
	if not has_queen(black):
		return (0, True)
	if moves_left == 0 or not has_queen(white):
		return (0, False)
	if moves_left >= CACHE_LIMIT:
		state = (frozenset(white), frozenset(black), turn)
		(path_len, res) = memo.get(state, (-1, False))
		if path_len != -1:
			if res and path_len <= moves_left:
				return (path_len, True)
			elif not res and path_len >= moves_left:
				return (path_len, False)
	(mine, other) = (white, black) if turn == WHITE else (black, white)
	for (piece, orig_y, orig_x) in tuple(mine):
		for direction in DIRECTIONS[piece]:
			for (delta_y, delta_x) in direction:
				(target_y, target_x) = (orig_y + delta_y, orig_x + delta_x)
				if target_y < 0 or target_y >= SIZE or target_x < 0 or (target_x >= SIZE):
					break
				target_cell = board[target_y][target_x]
				(target_owner, target_piece) = target_cell
				if target_owner == turn:
					break
				if target_piece == 'Q':
					path_len = 1
					res = turn == WHITE
				else:
					if target_cell != EMPTY:
						other.remove((target_piece, target_y, target_x))
					board[target_y][target_x] = board[orig_y][orig_x]
					board[orig_y][orig_x] = EMPTY
					mine.remove((piece, orig_y, orig_x))
					mine.add((piece, target_y, target_x))
					(path_len, res) = play(board, white, black, (turn + 1) % 2, moves_left - 1, memo)
					path_len += 1
					mine.remove((piece, target_y, target_x))
					mine.add((piece, orig_y, orig_x))
					board[orig_y][orig_x] = (turn, piece)
					board[target_y][target_x] = target_cell
					if target_cell != EMPTY:
						other.add((target_piece, target_y, target_x))
				if res and turn == WHITE:
					if moves_left >= CACHE_LIMIT:
						memo[state] = (path_len, True)
					return (path_len, True)
				elif not res and turn == BLACK:
					if moves_left >= CACHE_LIMIT:
						memo[state] = (path_len, False)
					return (path_len, False)
				if target_cell != EMPTY:
					break
	if moves_left >= CACHE_LIMIT:
		memo[state] = (moves_left, turn == BLACK)
	return (moves_left, turn == BLACK)

def has_queen(pieces):
	return any((piece == 'Q' for (piece, y, x) in pieces))

def read_pieces(n, player, pieces, board):
	for _ in range(n):
		(piece, x, y) = input().split()
		x = ord(x) - ord('A')
		y = SIZE - int(y)
		pieces.add((piece, y, x))
		board[y][x] = (player, piece)
for _ in range(int(input())):
	(w, b, m) = (int(x) for x in input().split())
	board = [[EMPTY] * SIZE for _ in range(SIZE)]
	(white, black) = (set(), set())
	read_pieces(w, WHITE, white, board)
	read_pieces(b, BLACK, black, board)
	print('YES' if play(board, white, black, WHITE, m, {})[1] else 'NO')


g = int(input())

def disp_board(occupied):
	d_occupied = [['_'.join(a) if not a is False else '___' for a in b] for b in occupied]
	print('\n'.join([' '.join(o) for o in d_occupied]))

def find_occupied(whites, blacks):
	occupied = [[False for _ in range(4)] for _ in range(4)]
	for (t, c, r) in whites:
		occupied[c][r] = ('W', t)
	for (t, c, r) in blacks:
		occupied[c][r] = ('B', t)
	return occupied

def moves(white_to_move, m, whites, blacks, occupied):
	recursion_counter = m - 1
	if m <= 0 or whites == []:
		return 'NotFound'
	if blacks == []:
		return 'Found'
	if white_to_move:
		pos_moves = possible_moves(whites, occupied, 'W')
		if pos_moves == 'Found':
			return pos_moves
		for move in pos_moves:
			executed_move = execute_move(move, occupied, whites)
			new_occupied = executed_move[0]
			new_whites = executed_move[2]
			new_blacks = blacks
			if executed_move[1]:
				new_blacks = [b for b in blacks if not b == executed_move[1]]
				if len(new_blacks) == len(blacks):
					print('DEBUG', blacks, executed_move[1])
			recurse = moves(False, recursion_counter, new_whites, new_blacks, new_occupied)
			if recurse == 'Found':
				return recurse
		return 'NotFound'
	else:
		pos_moves = possible_moves(blacks, occupied, 'B')
		if pos_moves == 'NotFound' or pos_moves == 'Found':
			return pos_moves
		for move in pos_moves:
			executed_move = execute_move(move, occupied, blacks)
			new_occupied = executed_move[0]
			new_whites = whites
			new_blacks = executed_move[2]
			if executed_move[1]:
				new_whites = [b for b in whites if not b == executed_move[1]]
				if len(new_whites) == len(whites):
					print('DEBUG', whites, executed_move[1])
			recurse = moves(True, recursion_counter, new_whites, new_blacks, new_occupied)
			if not recurse == 'Found':
				return 'NotFound'
		return 'Found'

def execute_move(move, occupied, pieces):
	((c, r), (target_c, target_r), _) = move
	new_pieces = [p if not (p[1] == c and p[2] == r) else (p[0], target_c, target_r) for p in pieces]
	ret_occup = [[occupied[c][r] for r in range(4)] for c in range(4)]
	removed = False
	if occupied[target_c][target_r]:
		removed = (occupied[target_c][target_r][1], target_c, target_r)
	ret_occup[target_c][target_r] = (occupied[c][r][0], occupied[c][r][1])
	ret_occup[c][r] = False
	return (ret_occup, removed, new_pieces)

def possible_moves(pieces, occupied, color):
	moves = []
	for (t, c, r) in pieces:
		if t == 'Q':
			for col in range(c - 1, -1, -1):
				allow = move_allowed(c, r, col, r, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for col in range(c + 1, 4):
				allow = move_allowed(c, r, col, r, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for row in range(r - 1, -1, -1):
				allow = move_allowed(c, r, c, row, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for row in range(r + 1, 4):
				allow = move_allowed(c, r, c, row, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for diag in range(1, min(r, c) + 1):
				allow = move_allowed(c, r, c - diag, r - diag, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for diag in range(1, 4 - max(r, c)):
				allow = move_allowed(c, r, c + diag, r + diag, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for diag in range(1, min(3 - r, c) + 1):
				allow = move_allowed(c, r, c - diag, r + diag, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for diag in range(1, 4 - max(3 - r, c)):
				allow = move_allowed(c, r, c + diag, r - diag, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
		if t == 'B':
			for diag in range(1, min(r, c) + 1):
				allow = move_allowed(c, r, c - diag, r - diag, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for diag in range(1, 4 - max(r, c)):
				allow = move_allowed(c, r, c + diag, r + diag, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for diag in range(1, min(3 - r, c) + 1):
				allow = move_allowed(c, r, c - diag, r + diag, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for diag in range(1, 4 - max(3 - r, c)):
				allow = move_allowed(c, r, c + diag, r - diag, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
		if t == 'R':
			for col in range(c - 1, -1, -1):
				allow = move_allowed(c, r, col, r, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for col in range(c + 1, 4):
				allow = move_allowed(c, r, col, r, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for row in range(r - 1, -1, -1):
				allow = move_allowed(c, r, c, row, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
			for row in range(r + 1, 4):
				allow = move_allowed(c, r, c, row, occupied, color)
				if allow == 'Found' or allow == 'NotFound':
					return allow
				if allow[0]:
					moves.append(allow[0])
				if allow[1]:
					break
		if t == 'N':
			for (colad, rowad) in [(-2, -1), (-2, 1), (2, -1), (2, 1), (1, -2), (-1, 2), (-1, -2), (1, 2)]:
				col = c + colad
				row = r + rowad
				if col >= 0 and col < 4 and (row >= 0) and (row < 4):
					allow = move_allowed(c, r, col, row, occupied, color)
					if allow == 'Found' or allow == 'NotFound':
						return allow
					if allow[0]:
						moves.append(allow[0])
	return moves

def move_allowed(c, r, target_c, target_r, occupied, color):
	if not occupied[target_c][target_r]:
		return (((c, r), (target_c, target_r), False), False)
	if occupied[target_c][target_r][0] == other_color(color):
		if occupied[target_c][target_r][0] == 'B' and occupied[target_c][target_r][1] == 'Q':
			return 'Found'
		if occupied[target_c][target_r][0] == 'W' and occupied[target_c][target_r][1] == 'Q':
			return 'NotFound'
		return (((c, r), (target_c, target_r), True), True)
	else:
		return (False, True)

def other_color(col):
	if col == 'W':
		return 'B'
	return 'W'

def let_to_num(let):
	if let == 'A':
		return 0
	if let == 'B':
		return 1
	if let == 'C':
		return 2
	if let == 'D':
		return 3
YES = 'Found'
NO = 'NotFound'
desired = [YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, NO, YES, YES, NO, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, NO, YES, YES, YES, YES, YES, YES, YES, NO, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, NO, NO, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, NO, YES, YES, YES, NO, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, NO, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES, NO, YES, YES, YES, YES, YES, YES, YES, NO, YES, YES, YES, YES, YES, YES, YES, YES, YES, YES]
for _game in range(g):
	(w, b, m) = map(int, input().split())
	whites = []
	for _white in range(w):
		(t, c, r) = input().split()
		whites.append((t, let_to_num(c), int(r) - 1))
	blacks = []
	for _black in range(b):
		(t, c, r) = input().split()
		blacks.append((t, let_to_num(c), int(r) - 1))
	occupied = find_occupied(whites, blacks)
	if moves(True, m, whites, blacks, occupied) == 'Found':
		print('YES')
	else:
		print('NO')


import sys

def piece_slays_other(pos, color_id, layout):
	for color in [color_id, abs(color_id - 1)]:
		for other_piece in layout[color]:
			if other_piece[1] == pos[0] and other_piece[2] == pos[1]:
				return ['self', other_piece] if color == color_id else ['other', other_piece]
	return ['nothing', None]

def get_next_positions(layout, piece, color_id):
	directions = []
	if piece[0] == 'Q':
		directions += [(0, -1), (1, 0), (0, 1), (-1, 0), (1, -1), (1, 1), (-1, 1), (-1, -1)]
	if piece[0] == 'N':
		directions += [(2, -1), (2, 1), (-2, -1), (-2, 1), (1, 2), (-1, 2), (1, -2), (-1, -2)]
	if piece[0] == 'B':
		directions += [(1, -1), (1, 1), (-1, 1), (-1, -1)]
	if piece[0] == 'R':
		directions += [(0, -1), (1, 0), (0, 1), (-1, 0)]
	next_pos_list = []
	for direction in directions:
		next_pos = [piece[1] + direction[0], piece[2] + direction[1]]
		if piece[0] != 'N':
			slay_id = piece_slays_other(next_pos, color_id, layout)
			while all((1 <= coor <= 4 for coor in next_pos)) and slay_id[0] == 'nothing':
				next_pos_list.append(list(next_pos) + slay_id)
				next_pos = [next_pos[0] + direction[0], next_pos[1] + direction[1]]
				slay_id = piece_slays_other(next_pos, color_id, layout)
			if all((1 <= coor <= 4 for coor in next_pos)) and slay_id[0] == 'other':
				next_pos_list.append(list(next_pos) + slay_id)
		elif all((1 <= coor <= 4 for coor in next_pos)):
			slay_id = piece_slays_other(next_pos, color_id, layout)
			if slay_id[0] != 'self':
				next_pos_list.append(list(next_pos) + slay_id)
	return next_pos_list

def get_new_layouts(layout, color_id):
	new_layout_list = []
	for piece in layout[color_id]:
		next_pos_list = get_next_positions(layout, piece, color_id)
		for next_pos in next_pos_list:
			new_layout_entry = [[], []]
			new_layout_entry[color_id] = {piece_i: piece_i for piece_i in layout[color_id] if piece_i is not piece}
			new_piece = (piece[0], next_pos[0], next_pos[1])
			new_layout_entry[color_id][new_piece] = new_piece
			other_color_id = abs(color_id - 1)
			if next_pos[2] == 'other':
				new_layout_entry[other_color_id] = {piece_i: piece_i for piece_i in layout[other_color_id] if piece_i is not next_pos[-1]}
			else:
				new_layout_entry[other_color_id] = {piece_i: piece_i for piece_i in layout[other_color_id]}
			new_layout_list.append(new_layout_entry)
	return new_layout_list

def no_queen(layout, color_id):
	try:
		layout[color_id]
	except IndexError:
		return False
	for piece_i in layout[color_id]:
		if piece_i[0] == 'Q':
			return False
	return True

def is_queen_changed(board1, board2, color_id):
	for piece in board1[color_id]:
		if piece[0] == 'Q':
			if piece in board2[color_id]:
				return False
			return True

def queen_can_be_slayed(board, color_id):
	other_color_id = abs(color_id - 1)
	for piece in board[other_color_id]:
		piece_positions_other_color = get_next_positions(board, piece, other_color_id)
		for position in piece_positions_other_color:
			if position[2] == 'other' and position[3][0] == 'Q':
				return True
	return False

def can_white_win(board_layout, turns):
	if turns > 0 and (not no_queen(board_layout, 0)):
		feasible_layouts_after_white = []
		feasible_layout_added = False
		all_layouts_after_white = get_new_layouts(board_layout, 0)
		for layout_after_white in all_layouts_after_white:
			if no_queen(layout_after_white, 1):
				return 'YES'
			queen_changed = is_queen_changed(board_layout, layout_after_white, 0)
			if not queen_changed or (queen_changed and (not queen_can_be_slayed(layout_after_white, 0))):
				feasible_layouts_after_white.append(layout_after_white)
				feasible_layout_added = True
		if not feasible_layout_added:
			return 'NO'
		turns -= 1
		if turns < 2:
			return 'NO'
		total_answers = []
		for layout_after_white in feasible_layouts_after_white:
			sub_answers = []
			for layout_after_black in get_new_layouts(layout_after_white, 1):
				if can_white_win(layout_after_black, turns - 1) == 'NO':
					sub_answers.append('NO')
					break
			if 'NO' in sub_answers:
				total_answers.append('winning')
			else:
				total_answers.append('losing')
		if 'losing' in total_answers:
			return 'YES'
	return 'NO'

def get_layout_str(init_layout):
	result_str = ''
	horz_line = '  ' + ' ---' * 4
	result_str += '\n%s\n%s' % ('\x1b[4mblack\x1b[0m' + ', white', horz_line)
	for row in range(4):
		printstr = str(row + 1) + ' '
		for column in range(4):
			piece_str = ' '
			for color in [0, 1]:
				for piece in init_layout[color]:
					if piece[1] == row + 1 and piece[2] == column + 1:
						piece_str = piece[0] if color == 0 else '\x1b[4m' + piece[0] + '\x1b[0m'
			printstr += '| ' + piece_str + ' '
		printstr += '|'
		result_str += '\n%s\n%s' % (printstr, horz_line)
	result_str += '\n    ' + '   '.join([str(colnum + 1) for colnum in range(4)])
	return result_str
try_case_n = 'all'
answer_list = []
for case_num in range(int(input().strip())):
	[w, b, max_turns] = list(map(int, input().strip().split()))
	layout_dict = {}
	initial_layout = [{}, {}]
	for color_n in range(2):
		num_pieces = w if color_n == 0 else b
		for __ in range(num_pieces):
			piece_info = input().strip().split()
			column = 1 if piece_info[1] == 'A' else 2 if piece_info[1] == 'B' else 3 if piece_info[1] == 'C' else 4
			piece_id = (piece_info[0], int(piece_info[2]), column)
			initial_layout[color_n].update({piece_id: piece_id})
	if try_case_n == 'evaluate':
		answer_list.append(can_white_win(initial_layout, max_turns))
		print(case_num + 1)
	elif case_num + 1 == try_case_n:
		print(get_layout_str(initial_layout))
		print(can_white_win(initial_layout, max_turns))
	elif not isinstance(try_case_n, int):
		print(can_white_win(initial_layout, max_turns))
if try_case_n == 'evaluate':
	from evaluate_answer import evaluate_with_correct_answer
	print(*evaluate_with_correct_answer(answer_list), sep='\n')


def toColumnNumber(c):
	return 1 + ord(c) - ord('A')

def toBoardIndex(row, column):
	return row + column * 4

def getTile(board, row, column):
	return board[toBoardIndex(row, column)]

def getMoves(piece, board):
	(color, ptype, column, row) = piece
	moves = []
	if ptype == 'R' or ptype == 'Q':
		x = column - 1
		while 0 <= x:
			if placeable(piece, board, row, x):
				moves.append((row, x))
			if getTile(board, row, x) is not None:
				break
			x -= 1
		x = column + 1
		while x < 4:
			if placeable(piece, board, row, x):
				moves.append((row, x))
			if getTile(board, row, x) is not None:
				break
			x += 1
		y = row - 1
		while 0 <= y:
			if placeable(piece, board, y, column):
				moves.append((y, column))
			if getTile(board, y, column) is not None:
				break
			y -= 1
		y = row + 1
		while 4 > y:
			if placeable(piece, board, y, column):
				moves.append((y, column))
			if getTile(board, y, column) is not None:
				break
			y += 1
	if ptype == 'Q' or ptype == 'B':
		x = column + 1
		y = row + 1
		while x < 4 and y < 4:
			if placeable(piece, board, y, x):
				moves.append((y, x))
			if getTile(board, y, x) is not None:
				break
			x += 1
			y += 1
		x = column + 1
		y = row - 1
		while x < 4 and y >= 0:
			if placeable(piece, board, y, x):
				moves.append((y, x))
			if getTile(board, y, x) is not None:
				break
			x += 1
			y -= 1
		x = column - 1
		y = row - 1
		while x >= 0 and y >= 0:
			if placeable(piece, board, y, x):
				moves.append((y, x))
			if getTile(board, y, x) is not None:
				break
			x -= 1
			y -= 1
		x = column - 1
		y = row + 1
		while x >= 0 and y < 4:
			if placeable(piece, board, y, x):
				moves.append((y, x))
			if getTile(board, y, x) is not None:
				break
			x -= 1
			y += 1
	if ptype == 'N':
		knight_moves = []
		for i in [1, -1, 2, -2]:
			for j in [1, -1, 2, -2]:
				if abs(i) + abs(j) == 3:
					knight_moves.append((i, j))
		for m in knight_moves:
			(m_x, m_y) = m
			x = column + m_x
			y = row + m_y
			if x < 4 and x >= 0 and (y < 4) and (y >= 0) and placeable(piece, board, y, x):
				moves.append((y, x))
	return moves

def printBoard(board):
	print('-' * 10)
	for i in range(3, -1, -1):
		print(i + 1, end='')
		for j in range(0, 4):
			tile = getTile(board, i, j)
			if tile is None:
				print(' - ', end='')
			else:
				print('{:>3}'.format(('B' if BLACK == tile[0] else 'W') + tile[1]), end='')
		print()
	print('  {:<3}{:<3}{:<3}{:<3}'.format('A', 'B', 'C', 'D'))

def placeable(piece, board, row, column):
	(pcolor, _, _, _) = piece
	tile_piece = getTile(board, row, column)
	if tile_piece is None:
		return True
	tpcolor = tile_piece[0]
	return pcolor != tpcolor
WHITE = 0
BLACK = 1

def addPieceToBoard(piece, board):
	(_, _, column, row) = piece
	board[toBoardIndex(row, column)] = piece

def updateBoard(piece, move, board, white_pieces, black_pieces, turn):
	(row, column) = move
	next_board = [tile for tile in board]
	next_white_pieces = [p for p in white_pieces]
	next_black_pieces = [p for p in black_pieces]
	next_turn = BLACK if turn == WHITE else WHITE
	if turn == WHITE:
		my_pieces = next_white_pieces
		op_pieces = next_black_pieces
	else:
		my_pieces = next_black_pieces
		op_pieces = next_white_pieces
	index = my_pieces.index(piece)
	(pcolor, ptype, pcolumn, prow) = piece
	my_pieces[index] = (pcolor, ptype, column, row)
	next_board[toBoardIndex(prow, pcolumn)] = None
	prev_piece = getTile(board, row, column)
	if prev_piece is not None:
		op_pieces.remove(prev_piece)
	next_board[toBoardIndex(row, column)] = my_pieces[index]
	return (next_board, next_white_pieces, next_black_pieces, next_turn)

def canQueenBeCapturedInOneMove(board, turn, black_pieces, white_pieces):
	if turn == WHITE:
		my_pieces = white_pieces
		op_pieces = black_pieces
	else:
		my_pieces = black_pieces
		op_pieces = white_pieces
	op_queen = [piece for piece in op_pieces if piece[1] == 'Q'][0]
	(op_color, _, column, row) = op_queen
	fake_rook = (op_color, 'R', column, row)
	for move in getMoves(fake_rook, board):
		piece = getTile(board, move[0], move[1])
		if piece is not None:
			(pcolor, ptype, _, _) = piece
			if pcolor == turn and (ptype == 'R' or ptype == 'Q'):
				return True
	fake_bishop = (op_color, 'B', column, row)
	for move in getMoves(fake_bishop, board):
		piece = getTile(board, move[0], move[1])
		if piece is not None:
			(pcolor, ptype, _, _) = piece
			if pcolor == turn and (ptype == 'B' or ptype == 'Q'):
				return True
	fake_knight = (op_color, 'N', column, row)
	for move in getMoves(fake_knight, board):
		piece = getTile(board, move[0], move[1])
		if piece is not None:
			(pcolor, ptype, _, _) = piece
			if pcolor == turn and ptype == 'N':
				return True
	return False

def canWhiteWin(board, white_pieces, black_pieces, turn, remaining_moves):
	if remaining_moves == 0:
		return False
	if canQueenBeCapturedInOneMove(board, turn, black_pieces, white_pieces):
		return WHITE == turn
	if turn == WHITE:
		my_pieces = white_pieces
		op_pieces = black_pieces
	else:
		my_pieces = black_pieces
		op_pieces = white_pieces
	if turn == WHITE:
		for piece in my_pieces:
			for move in getMoves(piece, board):
				(next_board, next_white_pieces, next_black_pieces, next_turn) = updateBoard(piece, move, board, white_pieces, black_pieces, turn)
				result = canWhiteWin(next_board, next_white_pieces, next_black_pieces, next_turn, remaining_moves - 1)
				if result:
					return True
		return False
	else:
		for piece in my_pieces:
			for move in getMoves(piece, board):
				(next_board, next_white_pieces, next_black_pieces, next_turn) = updateBoard(piece, move, board, white_pieces, black_pieces, turn)
				result = canWhiteWin(next_board, next_white_pieces, next_black_pieces, next_turn, remaining_moves - 1)
				if not result:
					return False
		return True
games = int(input())
for game in range(games):
	(w, b, m) = [int(s) for s in input().split()]
	white_pieces = []
	black_pieces = []
	board = [None] * 4 * 5
	turn = WHITE
	for i in range(w):
		(ptype, column, row) = input().split()
		piece = (WHITE, ptype, toColumnNumber(column) - 1, int(row) - 1)
		white_pieces.append(piece)
		addPieceToBoard(piece, board)
	for j in range(b):
		(ptype, column, row) = input().split()
		piece = (BLACK, ptype, toColumnNumber(column) - 1, int(row) - 1)
		black_pieces.append(piece)
		addPieceToBoard(piece, board)
	result = False
	m = m - (m + 1) % 2
	for i in range(1, m + 1):
		result = canWhiteWin(board, white_pieces, black_pieces, turn, m)
		if result:
			break
	if result:
		print('YES')
	else:
		print('NO')


import os
import sys

def isTherePiece(color, i, j):
	for (p, k, l) in color:
		if i == k and j == l:
			return [p, i, j]
	return ['None', i, j]

def isInGrid(i, j, n, m):
	return i >= 0 and j >= 0 and (i < n) and (j < m)

def movesFromList(l, repeat, p, i, j, color, others, n, m):
	mfl = []
	for (x, y) in l:
		k = i + x
		l = j + y
		while isInGrid(k, l, n, m) and isTherePiece(color, k, l)[0] == 'None':
			itp = isTherePiece(others, k, l)
			if itp[0] != 'None':
				mfl.insert(0, [p, k, l])
				if itp[0] == 'Q':
					return [1, [p, k, l]]
				break
			else:
				mfl.append([p, k, l])
			if not repeat:
				break
			k += x
			l += y
	return [0, mfl]

def possibleMovesPiece(p, i, j, color, others, n, m):
	pms = []
	if p == 'Q':
		pms = movesFromList([[1, 1], [1, -1], [-1, -1], [-1, 1], [1, 0], [0, -1], [-1, 0], [0, 1]], True, p, i, j, color, others, n, m)
	elif p == 'N':
		pms = movesFromList([[2, 1], [2, -1], [-2, 1], [-2, -1], [1, 2], [1, -2], [-1, 2], [-1, -2]], False, p, i, j, color, others, n, m)
	elif p == 'R':
		pms = movesFromList([[1, 0], [0, -1], [-1, 0], [0, 1]], True, p, i, j, color, others, n, m)
	elif p == 'B':
		pms = movesFromList([[1, 1], [1, -1], [-1, -1], [-1, 1]], True, p, i, j, color, others, n, m)
	return ([p, i, j], pms)

def possibleMoves(color, others, n, m):
	pms = []
	for (p, i, j) in color:
		pmp = possibleMovesPiece(p, i, j, color, others, n, m)
		if pmp[1][0] == 1:
			return [pmp]
		pms += [pmp]
	return pms

def play(color, others, moves, n, m, isw):
	if moves < 1 and isw:
		return False
	if moves < 1 and (not isw):
		return True
	pms = possibleMoves(color, others, n, m)
	copycolor = list((c for c in color))
	copyothers = list((o for o in others))
	if len(pms) == 1 and pms[0][1][0] == 1:
		return True
	for (b, pmp) in pms:
		for mv in pmp[1]:
			color.remove(b)
			color.append(mv)
			op = isTherePiece(others, mv[1], mv[2])
			if op[0] != 'None':
				others.remove(op)
			if not play(others, color, moves - 1, n, m, not isw):
				return True
			color = list((c for c in copycolor))
			others = list((o for o in copyothers))
	return False

def simplifiedChessEngine(whites, blacks, moves):
	n = m = 4
	if play(whites, blacks, moves, n, m, True):
		return 'YES'
	else:
		return 'NO'
g = int(input())
for g_itr in range(g):
	wbm = input().split()
	w = int(wbm[0])
	b = int(wbm[1])
	m = int(wbm[2])
	whites = []
	for i in range(w):
		whites.append(list(map(lambda x: x[0], input().rstrip().split())))
		whites[i][1] = ord(whites[i][1]) - ord('A')
		whites[i][2] = int(whites[i][2]) - 1
	blacks = []
	for i in range(b):
		blacks.append(list(map(lambda x: x[0], input().rstrip().split())))
		blacks[i][1] = ord(blacks[i][1]) - ord('A')
		blacks[i][2] = int(blacks[i][2]) - 1
	result = simplifiedChessEngine(whites, blacks, m)
	print(result)


rook_moves = ((1, 0), (-1, 0), (0, 1), (0, -1))
bishop_moves = ((1, 1), (1, -1), (-1, 1), (-1, -1))
queen_moves = rook_moves + bishop_moves
knight_moves = ((1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1))

def move_piece(board, player, i, moves, out):
	piece = board[i]
	board = board[:i] + '.' + board[i + 1:]
	win = False
	for (dx, dy) in moves:
		x = (i & 3) + dx
		y = (i >> 2) + dy
		while x & 4 == 0 and y & 4 == 0:
			j = y << 2 | x
			c = board[j]
			if c != '.' and c.isupper() == player:
				break
			if c.upper() == 'Q':
				win = True
			out.append(board[:j] + piece + board[j + 1:])
			if c != '.':
				break
			x += dx
			y += dy
	return win

def find_moves(board, player):
	win = False
	out = []
	for i in range(16):
		c = board[i]
		if c == '.' or c.isupper() != player:
			continue
		c = c.upper()
		if c == 'Q':
			win |= move_piece(board, player, i, queen_moves, out)
		elif c == 'N':
			win |= move_piece(board, player, i, knight_moves, out)
		elif c == 'B':
			win |= move_piece(board, player, i, bishop_moves, out)
		elif c == 'R':
			win |= move_piece(board, player, i, rook_moves, out)
	return (out, win)
cache = [{} for i in range(6)]

def search(board, turn):
	if board in cache[turn]:
		return cache[turn][board]
	(moves, win) = find_moves(board, turn & 1 == 0)
	if win:
		out = 2
	elif turn <= 0:
		out = 1
	else:
		out = 0
		for m in moves:
			s = search(m, turn - 1)
			if s == 0:
				out = 2
				break
			elif s == 1:
				out = 1
	cache[turn][board] = out
	return out

def read_board():
	(w, b, m) = map(int, input().split())
	board = ['.'] * 16
	player = m & 1 != 0
	for n in (w, b):
		for i in range(n):
			(piece, col, row) = input().split()
			if not player:
				piece = piece.lower()
			board[ord(col) - ord('A') | ord(row) - ord('1') << 2] = piece
		player = not player
	return (''.join(board), m)
g = int(input())
for G in range(g):
	(board, m) = read_board()
	print('YES' if search(board, m - 1) == 2 else 'NO')


def get_init_board(n_white, n_black):
	b = [0] * 16
	for i in range(n_white + n_black):
		(p, r, c) = input().split()
		if p == 'Q':
			v = 4
		if p == 'R':
			v = 3
		if p == 'B':
			v = 2
		if p == 'N':
			v = 1
		if i >= n_white:
			v *= -1
		idx = 0
		if r == 'A':
			idx = 0
		if r == 'B':
			idx = 4
		if r == 'C':
			idx = 8
		if r == 'D':
			idx = 12
		if c == '1':
			idx += 0
		if c == '2':
			idx += 1
		if c == '3':
			idx += 2
		if c == '4':
			idx += 3
		b[idx] = v
	return b
moves = [[-1 for i in range(16)] for j in range(8)]

def precompute_moves():
	for i in range(16):
		if i % 4 != 3:
			moves[0][i] = i + 1
		if i <= 11:
			moves[1][i] = i + 4
		if i % 4 != 0:
			moves[2][i] = i - 1
		if i >= 4:
			moves[3][i] = i - 4
		if i % 4 != 3 and i <= 11:
			moves[4][i] = i + 5
		if i % 4 != 0 and i <= 11:
			moves[5][i] = i + 3
		if i % 4 != 3 and i >= 4:
			moves[6][i] = i - 3
		if i % 4 != 0 and i >= 4:
			moves[7][i] = i - 5

def n_moves(b, i, rv):
	for s in range(4):
		j = moves[s][i]
		if j == -1:
			continue
		j = moves[s][j]
		if j == -1:
			continue
		for t in range(2):
			tt = (s + 2 * t + 1) % 4
			k = moves[tt][j]
			if k == -1:
				continue
			if b[k] <= 0:
				x = b[:]
				x[i] = 0
				x[k] = 1
				rv.append(x)

def dir_moves(b, i, d, rv):
	pos = i
	while True:
		pos = moves[d][pos]
		if pos == -1:
			return
		if b[pos] > 0:
			return
		x = b[:]
		x[pos] = x[i]
		x[i] = 0
		rv.append(x)
		if b[pos] < 0:
			return

def b_moves(b, i, rv):
	for d in range(4, 8):
		dir_moves(b, i, d, rv)

def r_moves(b, i, rv):
	for d in range(0, 4):
		dir_moves(b, i, d, rv)

def q_moves(b, i, rv):
	for d in range(0, 8):
		dir_moves(b, i, d, rv)

def new_boards(b):
	rv = []
	for i in range(16):
		if b[i] == 1:
			n_moves(b, i, rv)
		if b[i] == 2:
			b_moves(b, i, rv)
		if b[i] == 3:
			r_moves(b, i, rv)
		if b[i] == 4:
			q_moves(b, i, rv)
	return rv

def is_win(b):
	for p in b:
		if p == -4:
			return False
	return True
hist = {}

def board_value(b, depth):
	ggg = tuple(b + [depth])
	if ggg in hist:
		return hist[ggg]
	if depth == 0:
		return 0
	bb = new_boards(b)
	if len(bb) == 0:
		return 0
	for x in bb:
		if is_win(x):
			hist[ggg] = 1
			return 1
	best = -1
	for x in bb:
		y = [-p for p in x]
		v = -board_value(y, depth - 1)
		if v > best:
			best = v
		if best == 1:
			break
	hist[ggg] = best
	return best
num_prob = int(input())
for prob in range(num_prob):
	(n_white, n_black, depth) = (int(x) for x in input().split())
	b = get_init_board(n_white, n_black)
	precompute_moves()
	v = board_value(b, depth)
	if v == 1:
		print('YES')
	else:
		print('NO')


from copy import deepcopy
INDEX_1 = '1234'
INDEX_2 = 'ABCD'

def parse_piece(player, board):
	(type, column, row) = input().split()
	board[INDEX_1.index(row)][INDEX_2.index(column)] = player + type

def player_won(board, player):
	search_tile = invert_player(player) + 'Q'
	return not any((tile == search_tile for sub_board in board for tile in sub_board))

def invert_player(player):
	if player == 'W':
		return 'B'
	elif player == 'B':
		return 'W'
	else:
		raise ValueError("player can only be 'W' or 'B', not '%s'" % player)

def is_tile_obstructed(board, row, column, player):
	return row not in range(len(board)) or column not in range(len(board[row])) or player == board[row][column][0]

def generate_possible_moves(board, row, column):
	tile = board[row][column]
	player = tile[0]
	type = tile[1]
	if type == 'N':
		moves = [(1, 2), (-1, 2), (1, -2), (-1, -2), (2, 1), (-2, 1), (2, -1), (-2, -1)]
		for move in moves:
			dest_row = row + move[0]
			dest_col = column + move[1]
			if not is_tile_obstructed(board, dest_row, dest_col, player):
				yield (dest_row, dest_col)
	else:
		directions = []
		if type == 'Q' or type == 'R':
			directions += [(0, 1), (0, -1), (1, 0), (-1, 0)]
		if type == 'Q' or type == 'B':
			directions += [(1, 1), (-1, 1), (1, -1), (-1, -1)]
		for dir in directions:
			(dir_row, dir_col) = dir
			(cur_row, cur_col) = (row + dir_row, column + dir_col)
			while not is_tile_obstructed(board, cur_row, cur_col, player):
				yield (cur_row, cur_col)
				if board[cur_row][cur_col][0] == invert_player(player):
					break
				cur_row += dir_row
				cur_col += dir_col

def can_win(board, current_player, moves_left):
	if player_won(board, 'W'):
		return True
	if player_won(board, 'B'):
		return False
	if moves_left == 0:
		return False
	ret = current_player != 'W'
	for row in range(len(board)):
		for column in range(len(board[row])):
			tile = board[row][column]
			if current_player == tile[0]:
				for move in generate_possible_moves(board, row, column):
					(dest_row, dest_col) = move
					dest_tile = board[dest_row][dest_col]
					board[row][column] = '__'
					board[dest_row][dest_col] = tile
					stop = False
					if current_player == 'W':
						if ret == False:
							ret = can_win(board, invert_player(current_player), moves_left - 1)
							if ret == True:
								stop = True
					elif ret == True:
						ret = can_win(board, invert_player(current_player), moves_left - 1)
						if ret == False:
							stop = True
					board[row][column] = tile
					board[dest_row][dest_col] = dest_tile
					if stop:
						return ret
	return ret
for _ in range(int(input())):
	(num_white, num_black, max_moves) = map(int, input().split())
	board = [['__' for _ in range(4)] for _ in range(4)]
	for _ in range(num_white):
		parse_piece('W', board)
	for _ in range(num_black):
		parse_piece('B', board)
	if can_win(board, 'W', max_moves):
		print('YES')
	else:
		print('NO')


from copy import deepcopy
INDEX_1 = '1234'
INDEX_2 = 'ABCD'

def parse_piece(player, board):
	(type, column, row) = input().split()
	board[INDEX_1.index(row)][INDEX_2.index(column)] = player + type

def player_won(board, player):
	search_tile = invert_player(player) + 'Q'
	return not any((tile == search_tile for sub_board in board for tile in sub_board))

def invert_player(player):
	if player == 'W':
		return 'B'
	elif player == 'B':
		return 'W'
	else:
		raise ValueError("player can only be 'W' or 'B', not '%s'" % player)

def is_tile_obstructed(board, row, column, player):
	return row not in range(len(board)) or column not in range(len(board[row])) or player == board[row][column][0]

def generate_possible_moves(board, row, column):
	tile = board[row][column]
	player = tile[0]
	type = tile[1]
	if type == 'N':
		moves = [(1, 2), (-1, 2), (1, -2), (-1, -2), (2, 1), (-2, 1), (2, -1), (-2, -1)]
		for move in moves:
			dest_row = row + move[0]
			dest_col = column + move[1]
			if not is_tile_obstructed(board, dest_row, dest_col, player):
				yield (dest_row, dest_col)
	else:
		directions = []
		if type == 'Q' or type == 'R':
			directions += [(0, 1), (0, -1), (1, 0), (-1, 0)]
		if type == 'Q' or type == 'B':
			directions += [(1, 1), (-1, 1), (1, -1), (-1, -1)]
		for dir in directions:
			(dir_row, dir_col) = dir
			(cur_row, cur_col) = (row + dir_row, column + dir_col)
			while not is_tile_obstructed(board, cur_row, cur_col, player):
				yield (cur_row, cur_col)
				if board[cur_row][cur_col][0] == invert_player(player):
					break
				cur_row += dir_row
				cur_col += dir_col

def can_win(board, current_player, moves_left):
	if player_won(board, 'W'):
		return True
	if player_won(board, 'B'):
		return False
	if moves_left == 0:
		return False
	ret = current_player != 'W'
	for row in range(len(board)):
		for column in range(len(board[row])):
			tile = board[row][column]
			if current_player == tile[0]:
				for move in generate_possible_moves(board, row, column):
					(dest_row, dest_col) = move
					dest_tile = board[dest_row][dest_col]
					board[row][column] = '__'
					board[dest_row][dest_col] = tile
					stop = False
					if current_player == 'W':
						if ret == False:
							ret = can_win(board, invert_player(current_player), moves_left - 1)
							if ret == True:
								stop = True
					elif ret == True:
						ret = can_win(board, invert_player(current_player), moves_left - 1)
						if ret == False:
							stop = True
					board[row][column] = tile
					board[dest_row][dest_col] = dest_tile
					if stop:
						return ret
	return ret
for _ in range(int(input())):
	(num_white, num_black, max_moves) = map(int, input().split())
	board = [['__' for _ in range(4)] for _ in range(4)]
	for _ in range(num_white):
		parse_piece('W', board)
	for _ in range(num_black):
		parse_piece('B', board)
	if can_win(board, 'W', max_moves):
		print('YES')
	else:
		print('NO')


def knight(i, j, player):
	return set([((i, j), (a, b)) for (a, b) in [(i - 2, j + 1), (i - 1, j + 2), (i + 1, j + 2), (i + 2, j + 1), (i + 2, j - 1), (i + 1, j - 2), (i - 1, j - 2), (i - 2, j - 1)] if 0 <= a < 4 and 0 <= b < 4 and (grid[a][b][0] != player)])

def rook(i, j, player):
	res = set()
	for x in range(i + 1, 4):
		if grid[x][j][0] == 0 or grid[x][j][0] != player:
			res.add(((i, j), (x, j)))
		if grid[x][j][0] != 0:
			break
	for x in range(i - 1, -1, -1):
		if grid[x][j][0] == 0 or grid[x][j][0] != player:
			res.add(((i, j), (x, j)))
		if grid[x][j][0] != 0:
			break
	for x in range(j + 1, 4):
		if grid[i][x][0] == 0 or grid[i][x][0] != player:
			res.add(((i, j), (i, x)))
		if grid[i][x][0] != 0:
			break
	for x in range(j - 1, -1, -1):
		if grid[i][x][0] == 0 or grid[i][x][0] != player:
			res.add(((i, j), (i, x)))
		if grid[i][x][0] != 0:
			break
	return res

def bishop(i, j, player):
	res = set()
	for x in range(1, 4 - max(i, j)):
		if grid[i + x][j + x][0] == 0 or grid[i + x][j + x][0] != player:
			res.add(((i, j), (i + x, j + x)))
		if grid[i + x][j + x][0] != 0:
			break
	for x in range(1, 4 - max(3 - i, 3 - j)):
		if grid[i - x][j - x][0] == 0 or grid[i - x][j - x][0] != player:
			res.add(((i, j), (i - x, j - x)))
		if grid[i - x][j - x][0] != 0:
			break
	for x in range(1, 4 - max(i, 3 - j)):
		if grid[i + x][j - x][0] == 0 or grid[i + x][j - x][0] != player:
			res.add(((i, j), (i + x, j - x)))
		if grid[i + x][j - x][0] != 0:
			break
	for x in range(1, 4 - max(3 - i, j)):
		if grid[i - x][j + x][0] == 0 or grid[i - x][j + x][0] != player:
			res.add(((i, j), (i - x, j + x)))
		if grid[i - x][j + x][0] != 0:
			break
	return res

def queen(i, j, player):
	return rook(i, j, player) | bishop(i, j, player)

def play(before, after, left, player):
	((a, b), (c, d)) = (before, after)
	((e, f), (g, h)) = (grid[a][b], grid[c][d])
	if player == 1:
		if g == -1:
			B[h].remove((c, d))
		W[f].remove((a, b))
		W[f].add((c, d))
	else:
		if g == 1:
			W[h].remove((c, d))
		B[f].remove((a, b))
		B[f].add((c, d))
	(grid[a][b], grid[c][d]) = ((0, '#'), (e, f))
	res = search(left - 1, -player)
	if player == 1:
		if g == -1:
			B[h].add((c, d))
		W[f].remove((c, d))
		W[f].add((a, b))
	else:
		if g == 1:
			W[h].add((c, d))
		B[f].remove((c, d))
		B[f].add((a, b))
	(grid[a][b], grid[c][d]) = ((e, f), (g, h))
	return res
moves = {'Q': lambda a, b, c: queen(a, b, c), 'N': lambda a, b, c: knight(a, b, c), 'B': lambda a, b, c: bishop(a, b, c), 'R': lambda a, b, c: rook(a, b, c)}

def search(left, player):
	if not B['Q']:
		return True
	if left == 0 or not W['Q']:
		return False
	(possibles, (D1, D2)) = (set(), (W, B) if player == 1 else (B, W))
	for (k, v) in D1.items():
		for (i, j) in v:
			temp = moves[k](i, j, player)
			for (_, x) in temp:
				if x == next(iter(D2['Q'])):
					return player == 1
			possibles |= temp
	if player == 1:
		return any((play(x, y, left, player) for (x, y) in possibles))
	return all((play(x, y, left, player) for (x, y) in possibles))

def coords(D, val):
	(t, c, r) = input().split()
	(r, c) = (4 - int(r), 'ABCD'.index(c))
	D[t].add((r, c))
	grid[r][c] = (val, t)
for _ in range(int(input())):
	(w, b, m) = map(int, input().split())
	W = {'Q': set(), 'N': set(), 'B': set(), 'R': set()}
	B = {'Q': set(), 'N': set(), 'B': set(), 'R': set()}
	grid = [[(0, '#')] * 4 for _ in range(4)]
	for _ in range(w):
		coords(W, 1)
	for _ in range(b):
		coords(B, -1)
	print(('NO', 'YES')[search(m, 1)])


N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


def display(b):
	X = ['_', 'N', 'B', 'R', 'Q']
	Y = ['_', 'n', 'b', 'r', 'q']
	for i in range(16):
		if b[i] >= 0:
			print(X[b[i]], end=' ')
		else:
			print(Y[-b[i]], end=' ')
		if i % 4 == 3:
			print()
	print()

def get_init_board(n_white, n_black):
	b = [0] * 16
	for i in range(n_white + n_black):
		(p, r, c) = input().split()
		if p == 'Q':
			v = 4
		if p == 'R':
			v = 3
		if p == 'B':
			v = 2
		if p == 'N':
			v = 1
		if i >= n_white:
			v *= -1
		idx = 0
		if r == 'A':
			idx = 0
		if r == 'B':
			idx = 4
		if r == 'C':
			idx = 8
		if r == 'D':
			idx = 12
		if c == '1':
			idx += 0
		if c == '2':
			idx += 1
		if c == '3':
			idx += 2
		if c == '4':
			idx += 3
		b[idx] = v
	return b
moves = [[-1 for i in range(16)] for j in range(8)]

def precompute_moves():
	for i in range(16):
		if i % 4 != 3:
			moves[0][i] = i + 1
		if i <= 11:
			moves[1][i] = i + 4
		if i % 4 != 0:
			moves[2][i] = i - 1
		if i >= 4:
			moves[3][i] = i - 4
		if i % 4 != 3 and i <= 11:
			moves[4][i] = i + 5
		if i % 4 != 0 and i <= 11:
			moves[5][i] = i + 3
		if i % 4 != 3 and i >= 4:
			moves[6][i] = i - 3
		if i % 4 != 0 and i >= 4:
			moves[7][i] = i - 5

def n_moves(b, i, rv):
	for s in range(4):
		j = moves[s][i]
		if j == -1:
			continue
		j = moves[s][j]
		if j == -1:
			continue
		for t in range(2):
			tt = (s + 2 * t + 1) % 4
			k = moves[tt][j]
			if k == -1:
				continue
			if b[k] <= 0:
				x = b[:]
				x[i] = 0
				x[k] = 1
				rv.append(x)

def dir_moves(b, i, d, rv):
	pos = i
	while True:
		pos = moves[d][pos]
		if pos == -1:
			return
		if b[pos] > 0:
			return
		x = b[:]
		x[pos] = x[i]
		x[i] = 0
		rv.append(x)
		if b[pos] < 0:
			return

def b_moves(b, i, rv):
	for d in range(4, 8):
		dir_moves(b, i, d, rv)

def r_moves(b, i, rv):
	for d in range(0, 4):
		dir_moves(b, i, d, rv)

def q_moves(b, i, rv):
	for d in range(0, 8):
		dir_moves(b, i, d, rv)

def new_boards(b):
	rv = []
	for i in range(16):
		if b[i] == 1:
			n_moves(b, i, rv)
		if b[i] == 2:
			b_moves(b, i, rv)
		if b[i] == 3:
			r_moves(b, i, rv)
		if b[i] == 4:
			q_moves(b, i, rv)
	return rv

def is_win(b):
	for p in b:
		if p == -4:
			return False
	return True
hist = {}

def board_value(b, depth):
	ggg = tuple(b + [depth])
	if ggg in hist:
		return hist[ggg]
	if depth == 0:
		return 0
	bb = new_boards(b)
	if len(bb) == 0:
		return 0
	for x in bb:
		if is_win(x):
			hist[ggg] = 1
			return 1
	best = -1
	for x in bb:
		y = [-p for p in x]
		v = -board_value(y, depth - 1)
		if v > best:
			best = v
		if best == 1:
			break
	hist[ggg] = best
	return best
num_prob = int(input())
for prob in range(num_prob):
	(n_white, n_black, depth) = (int(x) for x in input().split())
	b = get_init_board(n_white, n_black)
	precompute_moves()
	v = board_value(b, depth)
	if v == 1:
		print('YES')
	else:
		print('NO')


from copy import deepcopy
INDEX_1 = '1234'
INDEX_2 = 'ABCD'

def parse_piece(player, board):
	(type, column, row) = input().split()
	board[INDEX_1.index(row)][INDEX_2.index(column)] = player + type

def player_won(board, player):
	search_tile = invert_player(player) + 'Q'
	return not any((tile == search_tile for sub_board in board for tile in sub_board))

def invert_player(player):
	if player == 'W':
		return 'B'
	elif player == 'B':
		return 'W'
	else:
		raise ValueError("player can only be 'W' or 'B', not '%s'" % player)

def is_tile_obstructed(board, row, column, player):
	return row not in range(len(board)) or column not in range(len(board[row])) or player == board[row][column][0]

def generate_possible_moves(board, row, column):
	tile = board[row][column]
	player = tile[0]
	type = tile[1]
	if type == 'N':
		moves = [(1, 2), (-1, 2), (1, -2), (-1, -2), (2, 1), (-2, 1), (2, -1), (-2, -1)]
		for move in moves:
			dest_row = row + move[0]
			dest_col = column + move[1]
			if not is_tile_obstructed(board, dest_row, dest_col, player):
				yield (dest_row, dest_col)
	else:
		directions = []
		if type == 'Q' or type == 'R':
			directions += [(0, 1), (0, -1), (1, 0), (-1, 0)]
		if type == 'Q' or type == 'B':
			directions += [(1, 1), (-1, 1), (1, -1), (-1, -1)]
		for dir in directions:
			(dir_row, dir_col) = dir
			(cur_row, cur_col) = (row + dir_row, column + dir_col)
			while not is_tile_obstructed(board, cur_row, cur_col, player):
				yield (cur_row, cur_col)
				if board[cur_row][cur_col][0] == invert_player(player):
					break
				cur_row += dir_row
				cur_col += dir_col

def can_win(board, current_player, moves_left):
	if player_won(board, 'W'):
		return True
	if player_won(board, 'B'):
		return False
	if moves_left == 0:
		return False
	ret = current_player != 'W'
	for row in range(len(board)):
		for column in range(len(board[row])):
			tile = board[row][column]
			if current_player == tile[0]:
				for move in generate_possible_moves(board, row, column):
					(dest_row, dest_col) = move
					dest_tile = board[dest_row][dest_col]
					board[row][column] = '__'
					board[dest_row][dest_col] = tile
					stop = False
					if current_player == 'W':
						if ret == False:
							ret = can_win(board, invert_player(current_player), moves_left - 1)
							if ret == True:
								stop = True
					elif ret == True:
						ret = can_win(board, invert_player(current_player), moves_left - 1)
						if ret == False:
							stop = True
					board[row][column] = tile
					board[dest_row][dest_col] = dest_tile
					if stop:
						return ret
	return ret
for _ in range(int(input())):
	(num_white, num_black, max_moves) = map(int, input().split())
	board = [['__' for _ in range(4)] for _ in range(4)]
	for _ in range(num_white):
		parse_piece('W', board)
	for _ in range(num_black):
		parse_piece('B', board)
	if can_win(board, 'W', max_moves):
		print('YES')
	else:
		print('NO')


SIZE = 4

def queen(row, col, p1, p2):
	return rook(row, col, p1, p2) + bishop(row, col, p1, p2)

def rook(row, col, p1, p2):
	moves = []
	for r in range(row - 1, -1, -1):
		if (r, col) in p1:
			break
		if (r, col) in p2:
			moves.append((r, col))
			break
		moves.append((r, col))
	for r in range(row + 1, SIZE):
		if (r, col) in p1:
			break
		if (r, col) in p2:
			moves.append((r, col))
			break
		moves.append((r, col))
	for c in range(col - 1, -1, -1):
		if (row, c) in p1:
			break
		if (row, c) in p2:
			moves.append((row, c))
			break
		moves.append((row, c))
	for c in range(col + 1, SIZE):
		if (row, c) in p1:
			break
		if (row, c) in p2:
			moves.append((row, c))
			break
		moves.append((row, c))
	return moves

def bishop(row, col, p1, p2):
	moves = []
	r = row - 1
	c = col - 1
	while r > -1 and c > -1:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r -= 1
		c -= 1
	r = row + 1
	c = col - 1
	while r < SIZE and c > -1:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r += 1
		c -= 1
	r = row - 1
	c = col + 1
	while r > -1 and c < SIZE:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r -= 1
		c += 1
	r = row + 1
	c = col + 1
	while r < SIZE and c < SIZE:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r += 1
		c += 1
	return moves

def knight(row, col, player):
	moves = []
	if row - 1 > 0:
		if col > 0 and (not (row - 2, col - 1) in player):
			moves.append((row - 2, col - 1))
		if col + 1 < SIZE and (not (row - 2, col + 1) in player):
			moves.append((row - 2, col + 1))
	if row + 2 < SIZE:
		if col > 0 and (not (row + 2, col - 1) in player):
			moves.append((row + 2, col - 1))
		if col + 1 < SIZE and (not (row + 2, col + 1) in player):
			moves.append((row + 2, col + 1))
	if col - 1 > 0:
		if row > 0 and (not (row - 1, col - 2) in player):
			moves.append((row - 1, col - 2))
		if row + 1 < SIZE and (not (row + 1, col - 2) in player):
			moves.append((row + 1, col - 2))
	if col + 2 < SIZE:
		if row > 0 and (not (row - 1, col + 2) in player):
			moves.append((row - 1, col + 2))
		if row + 1 < SIZE and (not (row + 1, col + 2) in player):
			moves.append((row + 1, col + 2))
	return moves

def canPlayer(W, B, m, rw, cw, rb, cb, isWhite):
	(movesQ, movesN, movesB, movesR, movesNX, movesBX, movesRX) = ([], [], [], [], [], [], [])
	white = [(r, c) for (r, c, _) in W]
	black = [(r, c) for (r, c, _) in B]
	for (row, col, pc) in W:
		if pc == 'Q':
			movesQ = queen(row, col, white, black)
			if (rb, cb) in movesQ:
				return True
		elif pc == 'N':
			movesN = knight(row, col, white)
			if (rb, cb) in movesN:
				return True
		elif pc == 'B':
			movesB = bishop(row, col, white, black)
			if (rb, cb) in movesB:
				return True
		elif pc == 'R':
			movesR = rook(row, col, white, black)
			if (rb, cb) in movesR:
				return True
		elif pc == 'NX':
			movesNX = knight(row, col, white)
			if (rb, cb) in movesNX:
				return True
		elif pc == 'BX':
			movesBX = bishop(row, col, white, black)
			if (rb, cb) in movesBX:
				return True
		elif pc == 'RX':
			movesRX = rook(row, col, white, black)
			if (rb, cb) in movesRX:
				return True
	if isWhite and m <= 2:
		return False
	for i in range(len(W)):
		for (r, c) in eval('moves' + W[i][2]):
			Wcopy = W[:]
			del Wcopy[i]
			Wcopy.append((r, c, W[i][2]))
			Bcopy = B[:]
			if (r, c) in black:
				for j in range(len(B)):
					if B[j][0] == r and B[j][1] == c:
						del Bcopy[j]
						break
			if W[i][2] == 'Q':
				blackWin = canPlayer(Bcopy, Wcopy, m - 1, rb, cb, r, c, isWhite ^ True)
			else:
				blackWin = canPlayer(Bcopy, Wcopy, m - 1, rb, cb, rw, cw, isWhite ^ True)
			if not blackWin:
				return True
	return False
for _ in range(int(input())):
	(w, b, moves) = map(int, input().strip().split())
	(W, B) = ([], [])
	typelist = []
	for playerw in range(w):
		(pc, col, row) = input().strip().split()
		if pc in typelist:
			pc = pc + 'X'
		W.append((int(row) - 1, ord(col) - 65, pc))
		typelist.append(pc)
		if pc == 'Q':
			qwr = int(row) - 1
			qwc = ord(col) - 65
	typelist = []
	for playerb in range(b):
		(pc, col, row) = input().strip().split()
		if pc in typelist:
			pc = pc + 'X'
		B.append((int(row) - 1, ord(col) - 65, pc))
		typelist.append(pc)
		if pc == 'Q':
			qbr = int(row) - 1
			qbc = ord(col) - 65
	if canPlayer(W, B, moves, qwr, qwc, qbr, qbc, True):
		print('YES')
	else:
		print('NO')


import os
import sys
import json

def simplifiedChessEngine(whites, blacks, moves):
	print('YES' if test(whites, blacks, moves) else 'NO')

def test(whites, blacks, limit):

	def assign(w, b):
		board = [['  ' for _ in range(4)] for _ in range(4)]
		for (i, j) in zip([w, b], 'WB'):
			for (a, b, c) in i:
				board[4 - int(c)]['ABCD'.index(b)] = j + a
		return board

	def display(p):
		for i in p:
			print(i)
	board = assign(whites, blacks)

	def is_valid(x, y):
		return 0 <= x < 4 and 0 <= y < 4

	def get_knight_moves(i, j, turn):
		moves = []
		for (k, l) in [(2, -1), (2, 1), (-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2)]:
			(ni, nj) = (i + k, j + l)
			if is_valid(ni, nj) and (board[ni][nj] == '  ' or board[ni][nj][0] == 'BW'[turn]):
				moves.append(((i, j), (ni, nj)))
		return moves

	def get_bishop_moves(i, j, turn):
		moves = set()
		for (k, l) in [(1, -1), (1, 1), (-1, 1), (-1, -1)]:
			(x, y) = (i + k, j + l)
			while is_valid(x, y) and board[x][y] == '  ':
				moves.add(((i, j), (x, y)))
				x += k
				y += l
			if is_valid(x, y) and board[x][y][0] == 'BW'[turn]:
				moves.add(((i, j), (x, y)))
		return list(moves)

	def get_rook_moves(i, j, turn):
		moves = set()
		for (k, l) in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
			(x, y) = (i + k, j + l)
			while is_valid(x, y) and board[x][y] == '  ':
				moves.add(((i, j), (x, y)))
				x += k
				y += l
			if is_valid(x, y) and board[x][y][0] == 'BW'[turn]:
				moves.add(((i, j), (x, y)))
		return list(moves)

	def get_queen_moves(i, j, turn):
		return get_bishop_moves(i, j, turn) + get_rook_moves(i, j, turn)

	def get_moves(board, turn):
		moves = []
		for (i, j) in enumerate(board):
			for (k, l) in enumerate(j):
				if l[0] == 'WB'[turn]:
					if l[1] == 'N':
						moves.extend(get_knight_moves(i, k, turn))
					elif l[1] == 'Q':
						moves.extend(get_queen_moves(i, k, turn))
					elif l[1] == 'B':
						moves.extend(get_bishop_moves(i, k, turn))
					elif l[1] == 'R':
						moves.extend(get_rook_moves(i, k, turn))
		return moves

	def make_move(i, j, k, l):
		(board[k][l], board[i][j]) = (board[i][j], '  ')

	def take_queen(moves, i, j):
		return any((k == i and l == j for (_, (k, l)) in moves))

	def find_queen(board, turn):
		for (i, j) in enumerate(board):
			for (k, l) in enumerate(j):
				if l[0] == 'WB'[turn] and l[1] == 'Q':
					return (i, k)
		return None

	def derive(board, turn, move_count):
		if move_count == limit:
			return False
		possible_moves = get_moves(board, turn)
		if take_queen(possible_moves, *find_queen(board, turn ^ 1)):
			return not turn
		if not turn:
			for (source, destination) in possible_moves:
				copy = json.loads(json.dumps(board))
				make_move(*source, *destination)
				if derive(board, turn ^ 1, move_count + 1):
					return True
				board[:] = copy
			return False
		else:
			for (source, destination) in possible_moves:
				copy = json.loads(json.dumps(board))
				make_move(*source, *destination)
				if not derive(board, turn ^ 1, move_count + 1):
					return False
				board[:] = copy
			return True
	return derive(board, 0, 0)
g = int(input())
for g_itr in range(g):
	wbm = input().split()
	w = int(wbm[0])
	b = int(wbm[1])
	m = int(wbm[2])
	whites = []
	for _ in range(w):
		whites.append(list(map(lambda x: x[0], input().rstrip().split())))
	blacks = []
	for _ in range(b):
		blacks.append(list(map(lambda x: x[0], input().rstrip().split())))
	result = simplifiedChessEngine(whites, blacks, m)


N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


import os
import sys
N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


SIZE = 4

def queen(row, col, p1, p2):
	return rook(row, col, p1, p2) + bishop(row, col, p1, p2)

def rook(row, col, p1, p2):
	moves = []
	for r in range(row - 1, -1, -1):
		if (r, col) in p1:
			break
		if (r, col) in p2:
			moves.append((r, col))
			break
		moves.append((r, col))
	for r in range(row + 1, SIZE):
		if (r, col) in p1:
			break
		if (r, col) in p2:
			moves.append((r, col))
			break
		moves.append((r, col))
	for c in range(col - 1, -1, -1):
		if (row, c) in p1:
			break
		if (row, c) in p2:
			moves.append((row, c))
			break
		moves.append((row, c))
	for c in range(col + 1, SIZE):
		if (row, c) in p1:
			break
		if (row, c) in p2:
			moves.append((row, c))
			break
		moves.append((row, c))
	return moves

def bishop(row, col, p1, p2):
	moves = []
	r = row - 1
	c = col - 1
	while r > -1 and c > -1:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r -= 1
		c -= 1
	r = row + 1
	c = col - 1
	while r < SIZE and c > -1:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r += 1
		c -= 1
	r = row - 1
	c = col + 1
	while r > -1 and c < SIZE:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r -= 1
		c += 1
	r = row + 1
	c = col + 1
	while r < SIZE and c < SIZE:
		if (r, c) in p1:
			break
		if (r, c) in p2:
			moves.append((r, c))
			break
		moves.append((r, c))
		r += 1
		c += 1
	return moves

def knight(row, col, player):
	moves = []
	if row - 1 > 0:
		if col > 0 and (not (row - 2, col - 1) in player):
			moves.append((row - 2, col - 1))
		if col + 1 < SIZE and (not (row - 2, col + 1) in player):
			moves.append((row - 2, col + 1))
	if row + 2 < SIZE:
		if col > 0 and (not (row + 2, col - 1) in player):
			moves.append((row + 2, col - 1))
		if col + 1 < SIZE and (not (row + 2, col + 1) in player):
			moves.append((row + 2, col + 1))
	if col - 1 > 0:
		if row > 0 and (not (row - 1, col - 2) in player):
			moves.append((row - 1, col - 2))
		if row + 1 < SIZE and (not (row + 1, col - 2) in player):
			moves.append((row + 1, col - 2))
	if col + 2 < SIZE:
		if row > 0 and (not (row - 1, col + 2) in player):
			moves.append((row - 1, col + 2))
		if row + 1 < SIZE and (not (row + 1, col + 2) in player):
			moves.append((row + 1, col + 2))
	return moves

def canPlayer(W, B, m, rw, cw, rb, cb, isWhite):
	(movesQ, movesN, movesB, movesR, movesNX, movesBX, movesRX) = ([], [], [], [], [], [], [])
	white = [(r, c) for (r, c, _) in W]
	black = [(r, c) for (r, c, _) in B]
	for (row, col, pc) in W:
		if pc == 'Q':
			movesQ = queen(row, col, white, black)
			if (rb, cb) in movesQ:
				return True
		elif pc == 'N':
			movesN = knight(row, col, white)
			if (rb, cb) in movesN:
				return True
		elif pc == 'B':
			movesB = bishop(row, col, white, black)
			if (rb, cb) in movesB:
				return True
		elif pc == 'R':
			movesR = rook(row, col, white, black)
			if (rb, cb) in movesR:
				return True
		elif pc == 'NX':
			movesNX = knight(row, col, white)
			if (rb, cb) in movesNX:
				return True
		elif pc == 'BX':
			movesBX = bishop(row, col, white, black)
			if (rb, cb) in movesBX:
				return True
		elif pc == 'RX':
			movesRX = rook(row, col, white, black)
			if (rb, cb) in movesRX:
				return True
	if isWhite and m <= 2:
		return False
	for i in range(len(W)):
		for (r, c) in eval('moves' + W[i][2]):
			Wcopy = W[:]
			del Wcopy[i]
			Wcopy.append((r, c, W[i][2]))
			Bcopy = B[:]
			if (r, c) in black:
				for j in range(len(B)):
					if B[j][0] == r and B[j][1] == c:
						del Bcopy[j]
						break
			if W[i][2] == 'Q':
				blackWin = canPlayer(Bcopy, Wcopy, m - 1, rb, cb, r, c, isWhite ^ True)
			else:
				blackWin = canPlayer(Bcopy, Wcopy, m - 1, rb, cb, rw, cw, isWhite ^ True)
			if not blackWin:
				return True
	return False
for _ in range(int(input())):
	(w, b, moves) = map(int, input().strip().split())
	(W, B) = ([], [])
	typelist = []
	for playerw in range(w):
		(pc, col, row) = input().strip().split()
		if pc in typelist:
			pc = pc + 'X'
		W.append((int(row) - 1, ord(col) - 65, pc))
		typelist.append(pc)
		if pc == 'Q':
			qwr = int(row) - 1
			qwc = ord(col) - 65
	typelist = []
	for playerb in range(b):
		(pc, col, row) = input().strip().split()
		if pc in typelist:
			pc = pc + 'X'
		B.append((int(row) - 1, ord(col) - 65, pc))
		typelist.append(pc)
		if pc == 'Q':
			qbr = int(row) - 1
			qbc = ord(col) - 65
	if canPlayer(W, B, moves, qwr, qwc, qbr, qbc, True):
		print('YES')
	else:
		print('NO')


import sys

def possible_moves(x, y, board):
	(player, piece) = (board[x][y][0], board[x][y][1])
	oposite = 'w' if player == 'b' else 'b'
	moves = []
	if piece == 'N':
		for (i, j) in [(-2, 1), (-2, -1), (2, 1), (2, -1), (-1, 2), (-1, -2), (1, -2), (1, 2)]:
			if 0 <= x + i < 4 and 0 <= y + j < 4:
				if board[x + i][y + j][1] != player:
					moves.append((x + i, y + j))
	dmoves = [(1, 1), (-1, 1), (-1, -1), (1, -1)]
	vmoves = [(0, 1), (-1, 0), (0, -1), (1, 0)]
	vectors = []
	if piece == 'B':
		vectors = dmoves
	elif piece == 'R':
		vectors = vmoves
	elif piece == 'Q':
		vectors = dmoves + vmoves
	for (c, d) in vectors:
		(i, j) = (x + c, y + d)
		while 0 <= i < 4 and 0 <= j < 4:
			if board[i][j][0] == player:
				break
			if board[i][j][0] == oposite:
				moves.append((i, j))
				break
			moves.append((i, j))
			(i, j) = (i + c, j + d)
	return moves

def whitewon(board):
	for i in range(4):
		for j in range(4):
			if board[i][j] == 'bQ':
				return False
	return True

def blackwon(board):
	for i in range(4):
		for j in range(4):
			if board[i][j] == 'wQ':
				return False
	return True

def g(player, turns, board):
	if player == 'b' and turns == 1:
		return whitewon(board)
	if turns == 0:
		return whitewon(board)
	if whitewon(board):
		return True
	if blackwon(board):
		return False
	for x in range(4):
		for y in range(4):
			if board[x][y][0] == player:
				for (mx, my) in possible_moves(x, y, board):
					cpy = [['' for _ in range(4)] for _ in range(4)]
					for a in range(4):
						for b in range(4):
							cpy[a][b] = board[a][b]
					cpy[mx][my] = cpy[x][y]
					cpy[x][y] = 'xx'
					nxt = g('w' if player == 'b' else 'b', turns - 1, cpy)
					if player == 'w':
						if nxt:
							return True
					elif not nxt:
						return False
	return True if player == 'b' else False
for _ in range(int(input())):
	(w, b, m) = map(int, input().split())
	board = [['xx' for _ in range(4)] for _ in range(4)]
	for _ in range(w):
		(f, y, x) = input().split()
		board[ord(x) - ord('1')][ord(y) - ord('A')] = 'w' + f
	for _ in range(b):
		(f, y, x) = input().split()
		board[ord(x) - ord('1')][ord(y) - ord('A')] = 'b' + f
	print('YES' if g('w', m, board) else 'NO')


import os
import sys
from itertools import repeat

class Piece:

	def __init__(self, colour):
		self.colour = colour

	def _straight_moves(self, x, y):
		yield zip(range(x + 1, 4), repeat(y))
		yield zip(range(x - 1, -1, -1), repeat(y))
		yield zip(repeat(x), range(y + 1, 4))
		yield zip(repeat(x), range(y - 1, -1, -1))

	def _diagonal_moves(self, x, y):
		yield zip(range(x + 1, 4), range(y + 1, 4))
		yield zip(range(x + 1, 4), range(y - 1, -1, -1))
		yield zip(range(x - 1, -1, -1), range(y + 1, 4))
		yield zip(range(x - 1, -1, -1), range(y - 1, -1, -1))

class Rook(Piece):
	get_moves = Piece._straight_moves

class Bishop(Piece):
	get_moves = Piece._diagonal_moves

class Queen(Piece):

	def get_moves(self, x, y):
		yield from self._straight_moves(x, y)
		yield from self._diagonal_moves(x, y)

class Knight(Piece):

	def get_moves(self, x, y):
		for (dx, dy) in [(2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1)]:
			nx = x + dx
			ny = y + dy
			if 0 <= nx < 4 and 0 <= ny < 4:
				yield [(nx, ny)]

def get_moves(pieces, colour):
	for ((x, y), piece) in pieces.items():
		if piece.colour != colour:
			continue
		for positions in piece.get_moves(x, y):
			for (nx, ny) in positions:
				target = pieces.get((nx, ny))
				if not target or target.colour != colour:
					new_pieces = pieces.copy()
					new_pieces[nx, ny] = pieces[x, y]
					del new_pieces[x, y]
					yield (new_pieces, target)
				if target:
					break

def can_win(pieces, moves, colour):
	if moves <= colour:
		return colour
	for (new_pieces, captured) in get_moves(pieces, colour):
		if isinstance(captured, Queen) or not can_win(new_pieces, moves - 1, not colour):
			return True
	return False

def add_piece(pieces, colour):
	(t, c, r) = input().split()
	t = {'Q': Queen, 'N': Knight, 'B': Bishop, 'R': Rook}[t]
	c = ord(c) - ord('A')
	r = int(r) - 1
	pieces[c, r] = t(colour)

def main():
	for i in range(int(input())):
		(w, b, m) = map(int, input().split())
		pieces = {}
		for j in range(w):
			add_piece(pieces, False)
		for j in range(b):
			add_piece(pieces, True)
		print('YES' if can_win(pieces, m, False) else 'NO')
main()


def getNumber(i, j):
	return i * 4 + j

def getCoords(n):
	return (int(n / 4), n % 4)

def getQueenMoves(p, player, opponent):
	moves = getRookMoves(p, player, opponent)
	bmoves = getBishopMoves(p, player, opponent)
	for m in bmoves:
		moves.add(m)
	return moves

def getKnightMoves(p, player, opponent):
	(i, j) = getCoords(p)
	moves = set()
	if i + 2 < 4:
		if j + 1 < 4:
			pos = getNumber(i + 2, j + 1)
			if pos not in player:
				moves.add(pos)
		if j - 1 > -1:
			pos = getNumber(i + 2, j - 1)
			if pos not in player:
				moves.add(pos)
	if i - 2 > -1:
		if j + 1 < 4:
			pos = getNumber(i - 2, j + 1)
			if pos not in player:
				moves.add(pos)
		if j - 1 > -1:
			pos = getNumber(i - 2, j - 1)
			if pos not in player:
				moves.add(pos)
	if j + 2 < 4:
		if i + 1 < 4:
			pos = getNumber(i + 1, j + 2)
			if pos not in player:
				moves.add(pos)
		if i - 1 > -1:
			pos = getNumber(i - 1, j + 2)
			if pos not in player:
				moves.add(pos)
	if j - 2 > -1:
		if i + 1 < 4:
			pos = getNumber(i + 1, j - 2)
			if pos not in player:
				moves.add(pos)
		if i - 1 > -1:
			pos = getNumber(i - 1, j - 2)
			if pos not in player:
				moves.add(pos)
	return moves

def getRookMoves(p, player, opponent):
	moves = set()
	(i, j) = getCoords(p)
	while j + 1 < 4 and getNumber(i, j + 1) not in player:
		j += 1
		if getNumber(i, j) in opponent:
			moves.add(getNumber(i, j))
			break
		else:
			moves.add(getNumber(i, j))
	(i, j) = getCoords(p)
	while j - 1 > -1 and getNumber(i, j - 1) not in player:
		j -= 1
		if getNumber(i, j) in opponent:
			moves.add(getNumber(i, j))
			break
		else:
			moves.add(getNumber(i, j))
	(i, j) = getCoords(p)
	while i + 1 < 4 and getNumber(i + 1, j) not in player:
		i += 1
		if getNumber(i, j) in opponent:
			moves.add(getNumber(i, j))
			break
		else:
			moves.add(getNumber(i, j))
	(i, j) = getCoords(p)
	while i - 1 > -1 and getNumber(i - 1, j) not in player:
		i -= 1
		if getNumber(i, j) in opponent:
			moves.add(getNumber(i, j))
			break
		else:
			moves.add(getNumber(i, j))
	return moves

def getBishopMoves(p, player, opponent):
	moves = set()
	(i, j) = getCoords(p)
	while i + 1 < 4 and j + 1 < 4 and (getNumber(i + 1, j + 1) not in player):
		i += 1
		j += 1
		if getNumber(i, j) in opponent:
			moves.add(getNumber(i, j))
			break
		else:
			moves.add(getNumber(i, j))
	(i, j) = getCoords(p)
	while i - 1 > -1 and j - 1 > -1 and (getNumber(i - 1, j - 1) not in player):
		i -= 1
		j -= 1
		if getNumber(i, j) in opponent:
			moves.add(getNumber(i, j))
			break
		else:
			moves.add(getNumber(i, j))
	(i, j) = getCoords(p)
	while i - 1 > -1 and j + 1 < 4 and (getNumber(i - 1, j + 1) not in player):
		i -= 1
		j += 1
		if getNumber(i, j) in opponent:
			moves.add(getNumber(i, j))
			break
		else:
			moves.add(getNumber(i, j))
	(i, j) = getCoords(p)
	while i + 1 < 4 and j - 1 > -1 and (getNumber(i + 1, j - 1) not in player):
		i += 1
		j -= 1
		if getNumber(i, j) in opponent:
			moves.add(getNumber(i, j))
			break
		else:
			moves.add(getNumber(i, j))
	return moves

def getQPosition(element):
	for e in element:
		if e[0] == 'Q':
			return e[1]

def FinishInAMove(player, Opponent):
	posQ = getQPosition(Opponent)
	pp = {p[1] for p in player}
	op = {o[1] for o in Opponent}
	for p in player:
		if posQ in getMoves(p, pp, op):
			return 1
	return 0

def evalOpponent(player, Opponent):
	nOpponent = list()
	Q = 0
	playerPositions = [p[1] for p in player]
	for opp in Opponent:
		if opp[1] not in playerPositions:
			nOpponent.append(opp)
		elif opp[0] == 'Q':
			Q = 1
	return (nOpponent, Q)

def getMoves(e, player, opponent):
	if e[0] == 'Q':
		moves = getQueenMoves(e[1], player, opponent)
	elif e[0] == 'N':
		moves = getKnightMoves(e[1], player, opponent)
	elif e[0] == 'R':
		moves = getRookMoves(e[1], player, opponent)
	else:
		moves = getBishopMoves(e[1], player, opponent)
	return moves

def play(whites, blacks, moves, turn):
	if moves > 0:
		if turn == 'W':
			if FinishInAMove(whites, blacks):
				return 1
			elif moves - 2 > 0:
				for i in range(len(whites)):
					wplayer = {w[1] for w in whites}
					wopponent = {b[1] for b in blacks}
					w = whites[i]
					wmoves = getMoves(w, wplayer, wopponent)
					for wm in wmoves:
						nwhites = whites.copy()
						nwhites[i] = [w[0], wm]
						(nblacks, bQ) = evalOpponent(nwhites, blacks)
						rV = play(nwhites, nblacks, moves - 1, 'B')
						if rV:
							return 1
						del nwhites
						del nblacks
				return 0
			else:
				return 0
		elif FinishInAMove(blacks, whites):
			return 0
		else:
			for j in range(len(blacks)):
				bplayer = {b[1] for b in blacks}
				bopponent = {w[1] for w in whites}
				b = blacks[j]
				bmoves = getMoves(b, bplayer, bopponent)
				for bm in bmoves:
					nblacks = blacks.copy()
					nblacks[j] = [b[0], bm]
					(nwhites, wQ) = evalOpponent(nblacks, whites)
					rV = play(nwhites, nblacks, moves - 1, 'W')
					if rV == 0:
						return 0
					del nblacks
					del nwhites
			return 1
	else:
		return 0
t = int(input())
for i in range(t):
	whites = list()
	blacks = list()
	strg = input().split(' ')
	wLen = int(strg[0])
	bLen = int(strg[1])
	moves = int(strg[2])
	for i in range(wLen):
		strg = input().split(' ')
		strg[1] = ord(strg[1]) - ord('A')
		strg[2] = int(strg[2]) - 1
		whites.append([strg[0], getNumber(strg[2], strg[1])])
	for i in range(bLen):
		strg = input().split(' ')
		strg[1] = ord(strg[1]) - ord('A')
		strg[2] = int(strg[2]) - 1
		blacks.append([strg[0], getNumber(strg[2], strg[1])])
	if play(whites, blacks, moves, 'W'):
		print('YES')
	else:
		print('NO')


import sys

def possible_moves(x, y, board):
	(player, piece) = (board[x][y][0], board[x][y][1])
	oposite = 'w' if player == 'b' else 'b'
	moves = []
	if piece == 'N':
		for (i, j) in [(-2, 1), (-2, -1), (2, 1), (2, -1), (-1, 2), (-1, -2), (1, -2), (1, 2)]:
			if 0 <= x + i < 4 and 0 <= y + j < 4:
				if board[x + i][y + j][1] != player:
					moves.append((x + i, y + j))
	dmoves = [(1, 1), (-1, 1), (-1, -1), (1, -1)]
	vmoves = [(0, 1), (-1, 0), (0, -1), (1, 0)]
	vectors = []
	if piece == 'B':
		vectors = dmoves
	elif piece == 'R':
		vectors = vmoves
	elif piece == 'Q':
		vectors = dmoves + vmoves
	for (c, d) in vectors:
		(i, j) = (x + c, y + d)
		while 0 <= i < 4 and 0 <= j < 4:
			if board[i][j][0] == player:
				break
			if board[i][j][0] == oposite:
				moves.append((i, j))
				break
			moves.append((i, j))
			(i, j) = (i + c, j + d)
	return moves

def whitewon(board):
	for i in range(4):
		for j in range(4):
			if board[i][j] == 'bQ':
				return False
	return True

def blackwon(board):
	for i in range(4):
		for j in range(4):
			if board[i][j] == 'wQ':
				return False
	return True

def g(player, turns, board):
	if turns == 0:
		return whitewon(board)
	if whitewon(board):
		return True
	if blackwon(board):
		return False
	for x in range(4):
		for y in range(4):
			if board[x][y][0] == player:
				for (mx, my) in possible_moves(x, y, board):
					bef_m = board[mx][my]
					bef = board[x][y]
					board[mx][my] = board[x][y]
					board[x][y] = 'xx'
					nxt = g('w' if player == 'b' else 'b', turns - 1, board)
					board[x][y] = bef
					board[mx][my] = bef_m
					if player == 'w':
						if nxt:
							return True
					elif not nxt:
						return False
	return True if player == 'b' else False
for _ in range(int(input())):
	(w, b, m) = map(int, input().split())
	board = [['xx' for _ in range(4)] for _ in range(4)]
	for _ in range(w):
		(f, y, x) = input().split()
		board[ord(x) - ord('1')][ord(y) - ord('A')] = 'w' + f
	for _ in range(b):
		(f, y, x) = input().split()
		board[ord(x) - ord('1')][ord(y) - ord('A')] = 'b' + f
	print('YES' if g('w', m, board) else 'NO')


N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


import os
import sys
N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


import math
import os
import random
import re
import sys

def validmoves(piece, posx, posy, whites, blacks, b):
	if piece == 'R':
		L = []
		i = 1
		while posx + i < 4 and (not (posx + i, posy) in whites):
			L += [('R', posx + i, posy)]
			if (posx + i, posy) in blacks:
				break
			i += 1
		i = 1
		while posx - i >= 0 and (not (posx - i, posy) in whites):
			L += [('R', posx - i, posy)]
			if (posx - i, posy) in blacks:
				break
			i += 1
		i = 1
		while posy + i < 4 and (not (posx, posy + i) in whites):
			L += [('R', posx, posy + i)]
			if (posx, posy + i) in blacks:
				break
			i += 1
		i = 1
		while posy - i >= 0 and (not (posx, posy - i) in whites):
			L += [('R', posx, posy - i)]
			if (posx, posy - i) in blacks:
				break
			i += 1
		return L
	elif piece == 'B':
		L = []
		i = 1
		while posx + i < 4 and posy + i < 4 and (not (posx + i, posy + i) in whites):
			L += [('B', posx + i, posy + i)]
			if (posx + i, posy + i) in blacks:
				break
			i += 1
		i = 1
		while posx - i >= 0 and posy + i < 4 and (not (posx - i, posy + i) in whites):
			L += [('B', posx - i, posy + i)]
			if (posx - i, posy + i) in blacks:
				break
			i += 1
		i = 1
		while posx + i < 4 and posy - i >= 0 and (not (posx + i, posy - i) in whites):
			L += [('B', posx + i, posy - i)]
			if (posx + i, posy - i) in blacks:
				break
			i += 1
		i = 1
		while posx - i >= 0 and posy - i >= 0 and (not (posx - i, posy - i) in whites):
			L += [('B', posx - i, posy - i)]
			if (posx - i, posy - i) in blacks:
				break
			i += 1
		return L
	elif piece == 'Q':
		return [('Q', z[1], z[2]) for z in validmoves('R', posx, posy, whites, blacks, b) + validmoves('B', posx, posy, whites, blacks, b)]
	elif piece == 'N':
		return [('N', z[0], z[1]) for z in [(posx + 2, posy + 1), (posx + 2, posy - 1), (posx + 1, posy + 2), (posx + 1, posy - 2), (posx - 1, posy + 2), (posx - 1, posy - 2), (posx - 2, posy + 1), (posx - 2, posy - 1)] if not z in whites and 0 <= z[0] <= 3 and (0 <= z[1] <= 3)]
	elif piece == 'P':
		posy += 1 - 2 * b
		l = []
		for i in [-1, 1]:
			if 0 <= posx + i <= 3 and (posx + i, posy) in blacks:
				l += [(posx + i, posy)]
		if not (posx, posy) in whites + blacks:
			l += [(posx, posy)]
		if posy in [0, 3]:
			return [('N', x[0], x[1]) for x in l] + [('B', x[0], x[1]) for x in l] + [('R', x[0], x[1]) for x in l]
		else:
			return [('P', x[0], x[1]) for x in l]

def simplifiedChessEngine(whites, blacks, moves, b):
	if moves == 0:
		if b:
			return 'YES'
		else:
			return 'NO'
	else:
		wh = [(x[1], x[2]) for x in whites]
		bl = [(x[1], x[2]) for x in blacks]
		(i, j) = [z[1:] for z in blacks if z[0] == 'Q'][0]
		l = sum([validmoves(x[0], x[1], x[2], wh, bl, b) for x in whites], [])
		if (i, j) in [x[1:] for x in l]:
			return 'YES'
		else:
			nextmove = []
			nextmove2 = []
			for i in range(len(whites)):
				for t in validmoves(whites[i][0], whites[i][1], whites[i][2], wh, bl, b):
					if (t[1], t[2]) in bl:
						nextmove.append((i, t))
					else:
						nextmove2.append((i, t))
			for x in nextmove + nextmove2:
				(i, t) = (x[0], x[1])
				(piece, posx, posy) = whites[i]
				taken = [z for z in blacks if (z[1], z[2]) == t[1:]]
				blacks = [z for z in blacks if not z in taken]
				whites[i] = t
				if simplifiedChessEngine(blacks, whites, moves - 1, 1 - b) == 'NO':
					whites[i] = (piece, posx, posy)
					blacks += taken
					return 'YES'
				else:
					whites[i] = (piece, posx, posy)
					blacks += taken
			return 'NO'
g = int(input())
for g_itr in range(g):
	wbm = input().split()
	w = int(wbm[0])
	b = int(wbm[1])
	m = int(wbm[2])
	whites = []
	for _ in range(w):
		whites.append(input().rstrip().split())
	blacks = []
	for _ in range(b):
		blacks.append(input().rstrip().split())
	whites = [[x[0], ord(x[1]) - 65, int(x[2]) - 1] for x in whites]
	blacks = [[x[0], ord(x[1]) - 65, int(x[2]) - 1] for x in blacks]
	result = simplifiedChessEngine(whites, blacks, m, 0)
	print(result)


import sys
PIECE_DICT = {'Q': 4, 'R': 3, 'B': 2, 'N': 1}
BOARD_DICT = {'A': {'1': 0, '2': 1, '3': 2, '4': 3}, 'B': {'1': 4, '2': 5, '3': 6, '4': 7}, 'C': {'1': 8, '2': 9, '3': 10, '4': 11}, 'D': {'1': 12, '2': 13, '3': 14, '4': 15}}
MOVE_LIST = ['r', 'd', 'l', 'u', 'dr', 'dl', 'ur', 'ul']
MOVE_DICT = dict(((x, [-1] * 16) for x in MOVE_LIST))

def get_init_board(n_white, n_black):
	board = [0] * 16
	for i in range(n_white + n_black):
		(pc, row, col) = sys.stdin.readline().split()
		piece = PIECE_DICT[pc] * (-1) ** (0 + (i >= n_white))
		position = BOARD_DICT[row][col]
		board[position] = piece
	return board

def precompute_moves():
	for i in range(16):
		okright = i % 4 != 3
		okleft = i % 4 != 0
		okup = i >= 4
		okdown = i <= 11
		if okright:
			MOVE_DICT['r'][i] = i + 1
		if okleft:
			MOVE_DICT['l'][i] = i - 1
		if okdown:
			MOVE_DICT['d'][i] = i + 4
		if okup:
			MOVE_DICT['u'][i] = i - 4
		if okright and okdown:
			MOVE_DICT['dr'][i] = i + 5
		if okleft and okdown:
			MOVE_DICT['dl'][i] = i + 3
		if okright and okup:
			MOVE_DICT['ur'][i] = i - 3
		if okleft and okup:
			MOVE_DICT['ul'][i] = i - 5

def n_moves(board, i, rv):
	for s in range(4):
		j = MOVE_DICT[MOVE_LIST[s]][i]
		if j == -1:
			continue
		j = MOVE_DICT[MOVE_LIST[s]][j]
		if j == -1:
			continue
		for t in range(2):
			tt = (s + 2 * t + 1) % 4
			k = MOVE_DICT[MOVE_LIST[tt]][j]
			if k == -1:
				continue
			if board[k] <= 0:
				x = board[:]
				x[i] = 0
				x[k] = 1
				rv.append(x)

def dir_moves(board, i, direction, rv):
	pos = i
	while True:
		pos = MOVE_DICT[direction][pos]
		if pos == -1:
			return
		if board[pos] > 0:
			return
		x = board[:]
		x[pos] = x[i]
		x[i] = 0
		rv.append(x)
		if board[pos] < 0:
			return

def b_moves(board, i, rv):
	for d in MOVE_LIST[4:]:
		dir_moves(board, i, d, rv)

def r_moves(board, i, rv):
	for d in MOVE_LIST[0:4]:
		dir_moves(board, i, d, rv)

def q_moves(board, i, rv):
	for d in MOVE_LIST:
		dir_moves(board, i, d, rv)

def new_boards(board):
	rv = []
	for i in range(16):
		if board[i] == 1:
			n_moves(board, i, rv)
		if board[i] == 2:
			b_moves(board, i, rv)
		if board[i] == 3:
			r_moves(board, i, rv)
		if board[i] == 4:
			q_moves(board, i, rv)
	return rv

def is_win(board):
	for p in board:
		if p == -4:
			return False
	return True
memodict = {}

def board_value(board, depth):
	state = tuple(board + [depth])
	if state in memodict:
		return memodict[state]
	if depth == 0:
		return 0
	bb = new_boards(board)
	if len(bb) == 0:
		return 0
	for x in bb:
		if is_win(x):
			memodict[state] = 1
			return 1
	best = -1
	for x in bb:
		y = [-p for p in x]
		v = -board_value(y, depth - 1)
		if v > best:
			best = v
		if best == 1:
			break
	memodict[state] = best
	return best
for _ in range(int(sys.stdin.readline())):
	(n_white, n_black, depth) = (int(x) for x in sys.stdin.readline().split())
	board = get_init_board(n_white, n_black)
	precompute_moves()
	value = board_value(board, depth)
	if value == 1:
		print('YES')
	else:
		print('NO')


N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


class Piece(object):

	def __init__(self, color, ptype, row, col):
		self.color = color
		self.ptype = ptype
		self.row = row
		self.col = col
		self.captured = False

	def valid_moves(self, board):
		pass

	def move_will_promote(self):
		return False

	def can_move_to(self, r, c):
		if r == self.row and c == self.col:
			return False
		if r < 0 or r > 3:
			return False
		if c < 0 or c > 3:
			return False
		if board.mat[r][c] is None:
			return True
		elif board.mat[r][c].color != self.color:
			return True
		return False

	def _straight_moves(self, board):
		possible = []
		for row in range(1, 4):
			(r, c) = (self.row - row, self.col)
			if self.can_move_to(r, c):
				possible.append((r, c))
			if not board.is_open(r, c):
				break
		for row in range(1, 4):
			(r, c) = (self.row + row, self.col)
			if self.can_move_to(r, c):
				possible.append((r, c))
			if not board.is_open(r, c):
				break
		for col in range(1, 4):
			(r, c) = (self.row, self.col - col)
			if self.can_move_to(r, c):
				possible.append((r, c))
			if not board.is_open(r, c):
				break
		for col in range(1, 4):
			(r, c) = (self.row, self.col + col)
			if self.can_move_to(r, c):
				possible.append((r, c))
			if not board.is_open(r, c):
				break
		return possible

	def _diagonal_moves(self, board):
		possible = []
		for rc in range(1, 4):
			(r, c) = (self.row - rc, self.col - rc)
			if self.can_move_to(r, c):
				possible.append((r, c))
			if not board.is_open(r, c):
				break
		for rc in range(1, 4):
			(r, c) = (self.row + rc, self.col - rc)
			if self.can_move_to(r, c):
				possible.append((r, c))
			if not board.is_open(r, c):
				break
		for rc in range(1, 4):
			(r, c) = (self.row - rc, self.col + rc)
			if self.can_move_to(r, c):
				possible.append((r, c))
			if not board.is_open(r, c):
				break
		for rc in range(1, 4):
			(r, c) = (self.row + rc, self.col + rc)
			if self.can_move_to(r, c):
				possible.append((r, c))
			if not board.is_open(r, c):
				break
		return possible

class Rook(Piece):

	def valid_moves(self, board):
		possible = self._straight_moves(board)
		return possible

class Queen(Piece):

	def valid_moves(self, board):
		possible = self._straight_moves(board) + self._diagonal_moves(board)
		return possible

class Knight(Piece):

	def valid_moves(self, board):
		(r, c) = (self.row, self.col)
		possible = [(r - 2, c - 1), (r - 2, c + 1), (r - 1, c + 2), (r - 1, c - 2), (r + 1, c + 2), (r + 1, c - 2), (r + 2, c - 1), (r + 2, c + 1)]
		return [(r, c) for (r, c) in possible if self.can_move_to(r, c)]

class Bishop(Piece):

	def valid_moves(self, board):
		possible = self._diagonal_moves(board)
		return possible

class Pawn(Piece):

	def can_move_to(self, r, c):
		if self.ptype == 'P':
			if r == self.row and c == self.col:
				return False
			if r < 0 or r > 3:
				return False
			if c < 0 or c > 3:
				return False
			if self.color == 'W' and r < self.row:
				return False
			elif self.color == 'B' and self.row < r:
				return False
			if c == self.col:
				if board.mat[r][c] is None:
					return True
			elif board.mat[r][c] is not None and board.mat[r][c].color != self.color:
				return True
			return False
		else:
			return Piece.can_move_to(self, r, c)

	def move_will_promote(self):
		if self.ptype == 'P':
			if self.color == 'W' and self.row == 2:
				return True
			elif self.color == 'B' and self.row == 1:
				return True
		return False

	def valid_moves(self, board):
		if self.ptype == 'P':
			(r, c) = (self.row, self.col)
			possible = [(r - 1, c), (r - 1, c - 1), (r - 1, c + 1), (r + 1, c), (r + 1, c - 1), (r + 1, c + 1)]
			return [(r, c) for (r, c) in possible if self.can_move_to(r, c)]
		elif self.ptype == 'N':
			return Knight.valid_moves(self, board)
		elif self.ptype == 'R':
			return Rook.valid_moves(self, board)
		elif self.ptype == 'B':
			return Bishop.valid_moves(self, board)

	def promote_to(self, pType):
		self.ptype = pType

	def undo_promote(self):
		self.ptype = 'P'

class Board(object):

	def __init__(self):
		self.mat = [[None for i in range(4)] for u in range(4)]
		self.white = []
		self.black = []

	def add_piece(self, color, ptype, row, col):
		if ptype == 'Q':
			piece = Queen(color, ptype, row, col)
		elif ptype == 'N':
			piece = Knight(color, ptype, row, col)
		elif ptype == 'B':
			piece = Bishop(color, ptype, row, col)
		elif ptype == 'R':
			piece = Rook(color, ptype, row, col)
		elif ptype == 'P':
			piece = Pawn(color, ptype, row, col)
		else:
			raise Exception('Invalid type')
		self.mat[row][col] = piece
		if color == 'W':
			self.white.append(piece)
		elif color == 'B':
			self.black.append(piece)

	def move_to(self, piece, row, col):
		self.mat[piece.row][piece.col] = None
		if self.mat[row][col] is not None:
			captured = self.mat[row][col]
			captured.captured = True
		self.mat[row][col] = piece
		piece.row = row
		piece.col = col

	def undo_move(self, captured, piece, prev_r, prev_c):
		self.move_to(piece, prev_r, prev_c)
		if captured:
			(cr, cc) = (captured.row, captured.col)
			self.mat[cr][cc] = captured
			captured.captured = False

	def is_open(self, r, c):
		if r < 0 or r > 3:
			return False
		if c < 0 or c > 3:
			return False
		if self.mat[r][c] is None:
			return True
		return False

	def white_can_win(self, turns_left):
		if turns_left <= 0:
			return False
		white_pieces = self.white
		q = []
		for piece in white_pieces:
			if piece.captured is True:
				continue
			valid_moves = piece.valid_moves(self)
			for (r, c) in valid_moves:
				captured = self.mat[r][c]
				if captured is not None and captured.ptype == 'Q':
					return True
				q.insert(0, (piece, r, c))
		for (piece, r, c) in q:
			(prev_r, prev_c) = (piece.row, piece.col)
			captured = self.mat[r][c]
			willPromote = piece.move_will_promote()
			self.move_to(piece, r, c)
			if willPromote:
				for pType in ['N', 'B', 'R']:
					piece.promote_to(pType)
					if self.black_cannot_avoid_loss(turns_left - 1):
						piece.undo_promote()
						self.undo_move(captured, piece, prev_r, prev_c)
						return True
					piece.undo_promote()
			elif self.black_cannot_avoid_loss(turns_left - 1):
				self.undo_move(captured, piece, prev_r, prev_c)
				return True
			self.undo_move(captured, piece, prev_r, prev_c)
		return False

	def black_cannot_avoid_loss(self, turns_left):
		if turns_left <= 0:
			return False
		black_pieces = self.black
		for piece in black_pieces:
			if piece.captured is True:
				continue
			valid_moves = piece.valid_moves(self)
			for (r, c) in valid_moves:
				(prev_r, prev_c) = (piece.row, piece.col)
				captured = self.mat[r][c]
				if captured is not None and captured.ptype == 'Q':
					return False
				willPromote = piece.move_will_promote()
				self.move_to(piece, r, c)
				if willPromote:
					for pType in ['N', 'B', 'R']:
						piece.promote_to(pType)
						if not self.white_can_win(turns_left - 1):
							piece.undo_promote()
							self.undo_move(captured, piece, prev_r, prev_c)
							return False
						piece.undo_promote()
				elif not self.white_can_win(turns_left - 1):
					self.undo_move(captured, piece, prev_r, prev_c)
					return False
				self.undo_move(captured, piece, prev_r, prev_c)
		return True
games = int(input())
for g in range(games):
	board = Board()
	cols = 'ABCD'
	(w, b, m) = map(int, input().split(' '))
	for i in range(w):
		(ptype, col, row) = input().split(' ')
		col = cols.index(col)
		row = int(row) - 1
		board.add_piece('W', ptype, row, col)
	for i in range(b):
		(ptype, col, row) = input().split(' ')
		col = cols.index(col)
		row = int(row) - 1
		board.add_piece('B', ptype, row, col)
	print('YES' if board.white_can_win(m) else 'NO')


N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')


N = 4
D = ((1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1))
FIGURES = 'QNBR'
RANGE = ((0, 8), (8, 16), (4, 8), (0, 4))

def solve():
	(w, b, m) = map(int, input().split())
	m -= (m + 1) % 2
	field = [[0] * N for _ in range(N)]
	for i in range(w + b):
		(figure, col, row) = input().split()
		col = ord(col) - ord('A')
		row = int(row) - 1
		figure = FIGURES.find(figure) + 1
		if i >= w:
			figure *= -1
		field[row][col] = figure
	return search(tuple(map(tuple, field)), m)

def search(field, m):
	if (field, m) in memo:
		return memo[field, m]
	white = m % 2 == 1
	for i in range(N):
		for j in range(N):
			f = field[i][j]
			if f == 0 or (f > 0) != white:
				continue
			for d in range(*RANGE[abs(f) - 1]):
				(dx, dy) = D[d]
				(x, y) = (i, j)
				while True:
					x += dx
					y += dy
					if x < 0 or x >= N or y < 0 or (y >= N):
						break
					g = field[x][y]
					if g != 0 and (g > 0) == (f > 0):
						break
					if abs(g) == 1:
						memo[field, m] = white
						return white
					if m > 1:
						new = list(map(list, field))
						new[i][j] = 0
						new[x][y] = f
						new = tuple(map(tuple, new))
						s = search(new, m - 1)
						if white == s:
							memo[field, m] = s
							return s
					if g:
						break
	memo[field, m] = not white
	return not white
memo = {}
for _ in range(int(input())):
	print('YES' if solve() else 'NO')