← Home
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))
	}
}