package main
import (
"bufio"
"fmt"
"io"
"os"
"sort"
)
func main() {
input, _ := io.ReadAll(os.Stdin)
pos := 0
nextInt := func() int {
for pos < len(input) && input[pos] <= ' ' {
pos++
}
if pos >= len(input) {
return 0
}
res := 0
for pos < len(input) && input[pos] > ' ' {
res = res*10 + int(input[pos]-'0')
pos++
}
return res
}
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
t := nextInt()
if t == 0 {
return
}
for tc := 0; tc < t; tc++ {
n := nextInt()
m := nextInt()
a := make([]int, n*m)
for i := 0; i < n*m; i++ {
a[i] = nextInt()
}
sortedIdx := make([]int, n)
for i := 0; i < n; i++ {
sortedIdx[i] = i
}
sort.Slice(sortedIdx, func(i, j int) bool {
return a[sortedIdx[i]*m+0] < a[sortedIdx[j]*m+0]
})
sufMax := make([]int, n*m)
sufMin := make([]int, n*m)
for i := 0; i < n; i++ {
row := sortedIdx[i]
sufMax[i*m+m-1] = a[row*m+m-1]
sufMin[i*m+m-1] = a[row*m+m-1]
for j := m - 2; j >= 0; j-- {
val := a[row*m+j]
if val > sufMax[i*m+j+1] {
sufMax[i*m+j] = val
} else {
sufMax[i*m+j] = sufMax[i*m+j+1]
}
if val < sufMin[i*m+j+1] {
sufMin[i*m+j] = val
} else {
sufMin[i*m+j] = sufMin[i*m+j+1]
}
}
}
prefMax := make([]int, n)
prefMin := make([]int, n)
for i := 0; i < n; i++ {
row := sortedIdx[i]
prefMax[i] = a[row*m+0]
prefMin[i] = a[row*m+0]
}
topLmax := make([]int, n)
topRmin := make([]int, n)
botLmin := make([]int, n)
botRmax := make([]int, n)
found := false
ansP := 0
ansK := 0
for k := 0; k < m-1; k++ {
topLmax[0] = prefMax[0]
topRmin[0] = sufMin[0*m+k+1]
for i := 1; i < n; i++ {
if prefMax[i] > topLmax[i-1] {
topLmax[i] = prefMax[i]
} else {
topLmax[i] = topLmax[i-1]
}
if sufMin[i*m+k+1] < topRmin[i-1] {
topRmin[i] = sufMin[i*m+k+1]
} else {
topRmin[i] = topRmin[i-1]
}
}
botLmin[n-1] = prefMin[n-1]
botRmax[n-1] = sufMax[(n-1)*m+k+1]
for i := n - 2; i >= 0; i-- {
if prefMin[i] < botLmin[i+1] {
botLmin[i] = prefMin[i]
} else {
botLmin[i] = botLmin[i+1]
}
if sufMax[i*m+k+1] > botRmax[i+1] {
botRmax[i] = sufMax[i*m+k+1]
} else {
botRmax[i] = botRmax[i+1]
}
}
for p := 0; p < n-1; p++ {
if topLmax[p] < botLmin[p+1] && topRmin[p] > botRmax[p+1] {
found = true
ansP = p
ansK = k
break
}
}
if found {
break
}
if k < m-2 {
for i := 0; i < n; i++ {
row := sortedIdx[i]
val := a[row*m+k+1]
if val > prefMax[i] {
prefMax[i] = val
}
if val < prefMin[i] {
prefMin[i] = val
}
}
}
}
if found {
out.WriteString("YES\n")
colors := make([]byte, n)
for i := 0; i <= ansP; i++ {
colors[sortedIdx[i]] = 'B'
}
for i := ansP + 1; i < n; i++ {
colors[sortedIdx[i]] = 'R'
}
out.Write(colors)
out.WriteString(fmt.Sprintf(" %d\n", ansK+1))
} else {
out.WriteString("NO\n")
}
}
}