```go
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
var t int
reader := bufio.NewReader(os.Stdin)
fmt.Fscan(reader, &t)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
for idx := 0; idx < t; idx++ {
var n, m, k int
fmt.Fscan(reader, &n, &m, &k)
possible := true
if n%2 != 0 {
// n is odd, m must be even (since n*m is even)
// We must fill the first row with m/2 horizontal dominoes.
req := m / 2
target := k - req
// The remaining (n-1) x m grid must satisfy the even constraints
if target < 0 || target%2 != 0 {
possible = false
}
} else {
// n is even
// Total k must be even for valid tiling in strips of 2 rows
if k%2 != 0 {
possible = false
}
// If m is odd, we are restricted on max horizontal dominoes
if m%2 != 0 {
maxK := (n / 2) * (m - 1)
if k > maxK {
possible = false
}
}
}
if !possible {
fmt.Fprintln(writer, "NO")
continue
}
fmt.Fprintln(writer, "YES")
type cell struct {
r, c int
}
links := make([][]cell, n)
for i := range links {
links[i] = make([]cell, m)
}
remK := k
startRow := 0
// If n is odd, fill first row with horizontal dominoes
if n%2 != 0 {
for j := 0; j < m; j += 2 {
links[0][j] = cell{0, j + 1}
links[0][j+1] = cell{0, j}
}
remK -= m / 2
startRow = 1
}
// Fill remaining rows in pairs
for i := startRow; i < n; i += 2 {
limit := m
if m%2 != 0 {
limit = m - 1
}
for j := 0; j < limit; j += 2 {
if remK >= 2 {
// Place 2 horizontal dominoes in this 2x2 block
links[i][j] = cell{i, j + 1}
links[i][j+1] = cell{i, j}
links[i+1][j] = cell{i + 1, j + 1}
links[i+1][j+1] = cell{i + 1, j}
remK -= 2
} else {
// Place 2 vertical dominoes in this 2x2 block
links[i][j] = cell{i + 1, j}
links[i+1][j] = cell{i, j}
links[i][j+1] = cell{i + 1, j + 1}
links[i+1][j+1] = cell{i, j + 1}
}
}
// If m is odd, the last column must be vertical
if m%2 != 0 {
j := m - 1
links[i][j] = cell{i + 1, j}
links[i+1][j] = cell{i, j}
}
}
// Assign letters
ans := make([][]byte, n)
for i := range ans {
ans[i] = make([]byte, m)
}
dr := []int{-1, 1, 0, 0}
dc := []int{0, 0, -1, 1}
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if ans[i][j] != 0 {
continue
}
p := links[i][j]
r2, c2 := p.r, p.c
forbidden := make(map[byte]bool)
// Check neighbors of (i, j)
for d := 0; d < 4; d++ {
ni, nj := i+dr[d], j+dc[d]
if ni >= 0 && ni < n && nj >= 0 && nj < m {
if ans[ni][nj] != 0 {
forbidden[ans[ni][nj]] = true
}
}
}
// Check neighbors of (r2, c2)
for d := 0; d < 4; d++ {
ni, nj := r2+dr[d], c2+dc[d]
if ni >= 0 && ni < n && nj >= 0 && nj < m {
if ans[ni][nj] != 0 {
forbidden[ans[ni][nj]] = true
}
}
}
c := byte('a')
for forbidden[c] {
c++
}
ans[i][j] = c
ans[r2][c2] = c
}
}
for i := 0; i < n; i++ {
writer.Write(ans[i])
writer.WriteByte('\n')
}
}
}
```