package main
import (
"bufio"
"fmt"
"os"
"sort"
"time"
)
var rngState uint64
func init() {
rngState = uint64(time.Now().UnixNano()) | 1
}
func nextRand() uint64 {
rngState += 0x9e3779b97f4a7c15
z := rngState
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9
z = (z ^ (z >> 27)) * 0x94d049bb133111eb
return z ^ (z >> 31)
}
type Candidate struct {
h1, h2 uint64
j, i int
}
func readInt(in *bufio.Reader) int {
var n int
var b byte
var err error
for {
b, err = in.ReadByte()
if err != nil || b > 32 {
break
}
}
if err != nil {
return 0
}
n = int(b - '0')
for {
b, err = in.ReadByte()
if err != nil || b <= 32 {
break
}
n = n*10 + int(b - '0')
}
return n
}
func readString(in *bufio.Reader) string {
var res []byte
var b byte
var err error
for {
b, err = in.ReadByte()
if err != nil || b > 32 {
break
}
}
if err != nil {
return ""
}
res = append(res, b)
for {
b, err = in.ReadByte()
if err != nil || b <= 32 {
break
}
res = append(res, b)
}
return string(res)
}
func main() {
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
t := readInt(in)
for tc := 0; tc < t; tc++ {
n := readInt(in)
m := readInt(in)
A := make([]string, n)
for i := 0; i < n; i++ {
A[i] = readString(in)
}
W1 := make([]uint64, n)
W2 := make([]uint64, n)
for i := 0; i < n; i++ {
W1[i] = nextRand()
W2[i] = nextRand()
}
H1 := make([]uint64, m)
H2 := make([]uint64, m)
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if A[i][j] == '1' {
H1[j] += W1[i]
H2[j] += W2[i]
}
}
}
candidates := make([]Candidate, n*m)
idx := 0
for j := 0; j < m; j++ {
for i := 0; i < n; i++ {
if A[i][j] == '0' {
candidates[idx] = Candidate{H1[j] + W1[i], H2[j] + W2[i], j, i}
} else {
candidates[idx] = Candidate{H1[j] - W1[i], H2[j] - W2[i], j, i}
}
idx++
}
}
sort.Slice(candidates, func(i, j int) bool {
if candidates[i].h1 != candidates[j].h1 {
return candidates[i].h1 < candidates[j].h1
}
return candidates[i].h2 < candidates[j].h2
})
maxFreq := 0
var best Candidate
currFreq := 0
for k := 0; k < len(candidates); k++ {
if k == 0 || candidates[k].h1 == candidates[k-1].h1 && candidates[k].h2 == candidates[k-1].h2 {
currFreq++
} else {
currFreq = 1
}
if currFreq > maxFreq {
maxFreq = currFreq
best = candidates[k]
}
}
ans := make([]byte, n)
for i := 0; i < n; i++ {
ans[i] = A[i][best.j]
}
if ans[best.i] == '0' {
ans[best.i] = '1'
} else {
ans[best.i] = '0'
}
fmt.Fprintln(out, maxFreq)
fmt.Fprintln(out, string(ans))
}
}