package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"sort"
)

// github.com/EndlessCheng/codeforces-go
func solve(reader io.Reader, writer io.Writer) {
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var n, k int64
	Fscan(in, &n, &k)
	arr := make([]int, n)
	for i := range arr {
		Fscan(in, &arr[i])
	}
	sort.Ints(arr)
	l, r := int64(0), n-1
	d := arr[r] - arr[l]
	for k > 0 && l < r {
		if l+1 <= n-r {
			if now, next := arr[l], arr[l+1]; now != next {
				if cost := int64(next-now) * (l + 1); cost <= k {
					k -= cost
					d -= next - now
				} else {
					d -= int(k / (l + 1))
					break
				}
			}
			l++
		} else {
			if now, next := arr[r], arr[r-1]; now != next {
				if cost := int64(now-next) * (n - r); cost <= k {
					k -= cost
					d -= now - next
				} else {
					d -= int(k / (n - r))
					break
				}
			}
			r--
		}
	}
	Fprint(out, d)
}

func main() {
	solve(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"sort"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func Sol1244E(reader io.Reader, writer io.Writer) {
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var n, k int64
	Fscan(in, &n, &k)
	arr := make([]int, n)
	for i := range arr {
		Fscan(in, &arr[i])
	}
	sort.Ints(arr)
	l, r := int64(0), n-1
	d := arr[r] - arr[l]
	for k > 0 && l < r {
		if l+1 <= n-r {
			if now, next := arr[l], arr[l+1]; now != next {
				if cost := int64(next-now) * (l + 1); cost <= k {
					k -= cost
					d -= next - now
				} else {
					d -= int(k / (l + 1))
					break
				}
			}
			l++
		} else {
			if now, next := arr[r], arr[r-1]; now != next {
				if cost := int64(now-next) * (n - r); cost <= k {
					k -= cost
					d -= now - next
				} else {
					d -= int(k / (n - r))
					break
				}
			}
			r--
		}
	}
	Fprint(out, d)
}

func main() {
	Sol1244E(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"sort"
)

// github.com/EndlessCheng/codeforces-go
func Sol1244E(reader io.Reader, writer io.Writer) {
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var n, k int64
	Fscan(in, &n, &k)
	arr := make([]int, n)
	for i := range arr {
		Fscan(in, &arr[i])
	}
	sort.Ints(arr)
	l, r := int64(0), n-1
	d := arr[r] - arr[l]
	for k > 0 && l < r {
		if l+1 <= n-r {
			if now, next := arr[l], arr[l+1]; now != next {
				if cost := int64(next-now) * (l + 1); cost <= k {
					k -= cost
					d -= next - now
				} else {
					d -= int(k / (l + 1))
					break
				}
			}
			l++
		} else {
			if now, next := arr[r], arr[r-1]; now != next {
				if cost := int64(now-next) * (n - r); cost <= k {
					k -= cost
					d -= now - next
				} else {
					d -= int(k / (n - r))
					break
				}
			}
			r--
		}
	}
	Fprint(out, d)
}

func main() {
	Sol1244E(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type point struct {
	x, y int
}

var ans int64

const (
	mod = int(1e9 + 7)
)

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()
	n, k := 0, int64(0)
	fmt.Fscanf(in, "%d %d\n", &n, &k)
	a := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(in, "%d", &a[i])
	}
	sort.Ints(a)
	from := 0
	to := n - 1
	effort := 1
	for k > 0 {
		if a[from] == a[to] {
			fmt.Fprintf(out, "0\n")
			return
		}
		if from == to-1 {
			if int64(effort)*int64(a[to]-a[from]) < k {
				fmt.Fprintf(out, "0\n")
				return
			}
			ans := int64(a[to]) - int64(a[from]) - k/int64(effort)
			fmt.Fprintf(out, "%d\n", ans)
			return
		}
		if k > int64(effort)*int64(a[to]-a[to-1]+a[from+1]-a[from]) {
			k -= int64(effort) * int64(a[to]-a[to-1]+a[from+1]-a[from])
			to--
			from++
			effort++
			continue
		} else {
			ans := int64(a[to]) - int64(a[from]) - k/int64(effort)
			fmt.Fprintf(out, "%d\n", ans)
			return
		}
	}
	return
}

func help(i int, n int, total int, t []int, g []int, cur int, c1, c2, c3 int, remaining int) {
	//fmt.Println(i, cur)
	if i == n {
		if cur == total {
			cal(c1, c2, c3)
		}
		return
	}
	if cur > total {
		return
	}
	if cur+remaining < total {
		return
	}
	switch g[i] {
	case 1:
		help(i+1, n, total, t, g, cur+t[i], c1+1, c2, c3, remaining-t[i])
	case 2:
		help(i+1, n, total, t, g, cur+t[i], c1, c2+1, c3, remaining-t[i])
	case 3:
		help(i+1, n, total, t, g, cur+t[i], c1, c2, c3+1, remaining-t[i])
	}
	help(i+1, n, total, t, g, cur, c1, c2, c3, remaining-t[i])
}

func cal(c1, c2, c3 int) {
	a := []int{c1, c2, c3}
	sort.Ints(a)
	tmp := int64(try(c1, c2, c3, 0))
	tmp %= int64(mod)
	for i := 1; i <= c1; i++ {
		tmp *= int64(i)
		tmp %= int64(mod)
	}
	for i := 1; i <= c2; i++ {
		tmp *= int64(i)
		tmp %= int64(mod)
	}
	for i := 1; i <= c3; i++ {
		tmp *= int64(i)
		tmp %= int64(mod)
	}
	ans += tmp
	ans %= int64(mod)
}

func try(a, b, c int, last int) int64 {
	if a == 0 && b == 0 && c == 0 {
		return 1
	}
	if a < 0 || b < 0 || c < 0 {
		return 0
	}
	if last == 0 {
		return try(a-1, b, c, 1) + try(a, b-1, c, 2) + try(a, b, c-1, 3)
	}
	if last == 1 {
		return try(a, b-1, c, 2) + try(a, b, c-1, 3)
	}
	if last == 2 {
		return try(a-1, b, c, 1) + try(a, b, c-1, 3)
	}
	return try(a-1, b, c, 1) + try(a, b-1, c, 2)
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type m struct {
	value int64
	count int64
}

func min(x, y int64) int64 {
	if x < y {
		return x
	}
	return y
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var n int
	var k int64
	fmt.Fscanln(in, &n, &k)

	as := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(in, &as[i])
	}
	sort.Ints(as)

	ms := make([]m, 0)
	prev := -1
	for _, val := range as {
		if val == prev {
			ms[len(ms)-1].count++
		} else {
			tmp := m{value: int64(val), count: 1}
			ms = append(ms, tmp)
			prev = val
		}
	}
	//fmt.Println(as)
	//fmt.Println(ms)

	for k > 0 && len(ms) != 1 {
		last := len(ms)-1
		if ms[0].count < ms[last].count {
			next := (ms[1].value - ms[0].value) * ms[0].count
			if k > next {
				ms[1].count += ms[0].count
				k -= next
				ms = ms[1:]
			} else {
				ms[0].value += k / ms[0].count
				k = 0
			}
		} else {
			next := (ms[last].value - ms[last-1].value) * ms[last].count
			if k > next {
				ms[last-1].count += ms[last].count
				k -= next
				ms = ms[:last]
			} else {
				ms[last].value -= k / ms[last].count
				k = 0
			}
		}
		//fmt.Println(ms)
	}

	fmt.Println(ms[len(ms)-1].value - ms[0].value)
}

package main

import (
	"bufio"
	. "fmt"
	"os"
	"sort"
	"strconv"
)

var (
	inn = bufio.NewScanner(os.Stdin)
	in  = bufio.NewReader(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

func main() {
	defer out.Flush()
	inn.Buffer([]byte{}, 10000000)
	inn.Split(bufio.ScanWords)

	var (
		n int
		k int64
	)
	Fscan(in, &n, &k)
	a := make([]int64, n)
	for i := range a {
		Fscan(in, &a[i])
	}
	sort.Slice(a, func(i, j int) bool {
		return a[i] < a[j]
	})
	b := make([]int64, n-1)
	for i := 0; i < n-1; i++ {
		b[i] = a[i+1] - a[i]
	}
	ans := a[len(a)-1] - a[0]
	l, r, p := 0, n-2, int64(1)
	for l < r {
		need := min(k, (b[l]+b[r])*p)
		ans -= need / p
		k -= need
		p++
		l++
		r--
	}
	if l == r {
		need := min(k, b[l]*p)
		ans -= need / p
		k -= need
	}
	Fprint(out, ans)
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
func min(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}
func rd() (x int) {
	inn.Scan()
	data := inn.Bytes()
	x, _ = strconv.Atoi(string(data))
	return x
}
func rdll() (x int64) {
	inn.Scan()
	data := inn.Bytes()
	x, _ = strconv.ParseInt(string(data), 10, 0)
	return x
}
func rds() string {
	inn.Scan()
	return string(inn.Bytes())
}

package main

import (
	"bufio"
	. "fmt"
	"os"
	"sort"
	"strconv"
)

var (
	inn = bufio.NewScanner(os.Stdin)
	in  = bufio.NewReader(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

func main() {
	defer out.Flush()
	inn.Buffer([]byte{}, 10000000)
	inn.Split(bufio.ScanWords)

	var (
		n int
		k int64
	)
	Fscan(in, &n, &k)
	a := make([]int64, n)
	for i := range a {
		Fscan(in, &a[i])
	}
	sort.Slice(a, func(i, j int) bool {
		return a[i] < a[j]
	})
	b := make([]int64, n-1)
	for i := 0; i < n-1; i++ {
		b[i] = a[i+1] - a[i]
	}
	ans := a[len(a)-1] - a[0]
	l, r, p := 0, n-2, int64(1)
	for l < r {
		need := min(k, (b[l]+b[r])*p)
		ans -= need / p
		k -= need
		p++
		l++
		r--
	}
	if l == r {
		need := min(k, b[l]*p)
		ans -= need / p
		k -= need
	}
	Fprint(out, ans)
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
func min(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}
func rd() (x int) {
	inn.Scan()
	data := inn.Bytes()
	x, _ = strconv.Atoi(string(data))
	return x
}
func rdll() (x int64) {
	inn.Scan()
	data := inn.Bytes()
	x, _ = strconv.ParseInt(string(data), 10, 64)
	return x
}
func rds() string {
	inn.Scan()
	return string(inn.Bytes())
}

package main

import (
	"bufio"
	. "fmt"
	"os"
	"sort"
	"strconv"
)

var (
	inn = bufio.NewScanner(os.Stdin)
	in  = bufio.NewReader(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

func main() {
	defer out.Flush()
	inn.Buffer([]byte{}, 10000000)
	inn.Split(bufio.ScanWords)

	var (
		n int
		k int64
	)
	Fscan(in, &n, &k)
	a := make([]int64, n)
	for i := range a {
		Fscan(in, &a[i])
	}
	sort.Slice(a, func(i, j int) bool {
		return a[i] < a[j]
	})
	b := make([]int64, n-1)
	for i := 0; i < n-1; i++ {
		b[i] = a[i+1] - a[i]
	}
	ans := a[len(a)-1] - a[0]
	l, r, p := 0, n-2, int64(1)
	for l < r {
		need := min(k, (b[l]+b[r])*p)
		ans -= need / p
		k -= need
		p++
		l++
		r--
	}
	if l == r {
		need := min(k, b[l]*p)
		ans -= need / p
		k -= need
	}
	Fprint(out, ans)
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
func min(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}
func rd() (x int) {
	inn.Scan()
	data := inn.Bytes()
	x, _ = strconv.Atoi(string(data))
	return x
}
func rdll() (x int64) {
	inn.Scan()
	data := inn.Bytes()
	if data[0] == '-' {
		for _, b := range data[1:] {
			x = x*10 + int64(b&15)
		}
		return -x
	}
	for _, b := range data {
		x = x*10 + int64(b&15)
	}
	return
}
func rds() string {
	inn.Scan()
	return string(inn.Bytes())
}

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"sort"
	"strconv"

)

func main() {
	var n, k int64
	_, err := fmt.Scanf("%d %d", &n, &k)
	if err != nil {
		panic(err)
	}
	in, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}
	i2 := bytes.Split(bytes.TrimSpace(in), []byte(" "))
	inp := make([]int, len(i2))
	for i := range i2 {
		inp[i], err = strconv.Atoi(string(i2[i]))
		if err != nil {
			panic(err)
		}
	}
	sort.Ints(inp)
	i := int64(0)
	j := n - 1
	minus := int64(0)
	for k > 0 && (k >= i+1 || k >= n-j) && i < j {
		if inp[i] == inp[i+1] {
			i++
			continue
		}
		if inp[j] == inp[j-1] {
			j--
			continue
		}
		if i+1 <= n-j {
			need := int64(inp[i+1] - inp[i])
			if need*(i+1) <= k {
				k -= need * (i + 1)
				i++
				continue
			} else {
				minus = k / (i + 1)
				k -= minus * (i + 1)
				break
			}
		} else {
			need := int64(inp[j] - inp[j-1])
			if need*(n-j) <= k {
				k -= need * (n - j)
				j--
				continue
			} else {
				minus = k / (n - j)
				k -= minus * (n - j)
				break
			}
		}
	}
	fmt.Printf("%d", inp[j]-inp[i]-int(minus))
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"sort"
)

// github.com/EndlessCheng/codeforces-go
func Sol1244E(reader io.Reader, writer io.Writer) {
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var n, k int64
	Fscan(in, &n, &k)
	arr := make([]int, n)
	for i := range arr {
		Fscan(in, &arr[i])
	}
	sort.Ints(arr)
	l, r := int64(0), n-1
	d := arr[r] - arr[l]
	for k > 0 && l < r {
		if l+1 <= n-r {
			if now, next := arr[l], arr[l+1]; now != next {
				if cost := int64(next-now) * (l + 1); cost <= k {
					k -= cost
					d -= next - now
				} else {
					d -= int(k / (l + 1))
					k = 0
				}
			}
			l++
		} else {
			if now, next := arr[r], arr[r-1]; now != next {
				if cost := int64(now-next) * (n - r); cost <= k {
					k -= cost
					d -= now - next
				} else {
					d -= int(k / (n - r))
					k = 0
				}
			}
			r--
		}
	}
	Fprint(out, d)
}

func main() {
	Sol1244E(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
	"sort"
)

// github.com/EndlessCheng/codeforces-go
func Sol1244E(reader io.Reader, writer io.Writer) {
	in := bufio.NewReader(reader)
	out := bufio.NewWriter(writer)
	defer out.Flush()

	var n, k int64
	Fscan(in, &n, &k)
	arr := make([]int, n)
	for i := range arr {
		Fscan(in, &arr[i])
	}
	sort.Ints(arr)
	l, r := int64(0), n-1
	d := arr[r] - arr[l]
	for k > 0 && l < r {
		if l+1 <= n-r {
			if now, next := arr[l], arr[l+1]; now != next {
				if cost := int64(next-now) * (l + 1); cost <= k {
					k -= cost
					d -= next - now
				} else {
					d -= int(k / (l + 1))
				}
			}
			l++
		} else {
			if now, next := arr[r], arr[r-1]; now != next {
				if cost := int64(now-next) * (n - r); cost <= k {
					k -= cost
					d -= now - next
				} else {
					d -= int(k / (n - r))
				}
			}
			r--
		}
	}
	Fprint(out, d)
}

func main() {
	Sol1244E(os.Stdin, os.Stdout)
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type m struct {
	value int64
	count int64
}

func min(x, y int64) int64 {
	if x < y {
		return x
	}
	return y
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var n int
	var k int64
	fmt.Fscanln(in, &n, &k)

	as := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(in, &as[i])
	}
	sort.Ints(as)

	ms := make([]m, 0)
	prev := -1
	for _, val := range as {
		if val == prev {
			ms[len(ms)-1].count++
		} else {
			tmp := m{value: int64(val), count: 1}
			ms = append(ms, tmp)
			prev = val
		}
	}
	//fmt.Println(as)
	//fmt.Println(ms)

	for k > 0 && len(ms) != 1 {
		last := len(ms)-1
		if ms[0].count < ms[last].count {
			next := (ms[1].value - ms[0].value) * ms[0].count
			if k > next {
				ms[1].count += ms[0].count
				k -= next
				ms = ms[1:]
			} else {
				ms[0].value += k / ms[0].count
				k = 0
			}
		} else {
			next := (ms[last].value - ms[last-1].value) * ms[last].count
			if k > next {
				ms[last-1].count += ms[last].count
				k -= next
				ms = ms[:last]
			} else {
				ms[last].value += k / ms[last].count
				k = 0
			}
		}
		//fmt.Println(ms)
	}

	fmt.Println(ms[len(ms)-1].value - ms[0].value)
}

package main

import (
	"bufio"
	. "fmt"
	"os"
	"sort"
	"strconv"
)

var (
	inn = bufio.NewScanner(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

func main() {
	defer out.Flush()
	inn.Buffer([]byte{}, 1000000)
	inn.Split(bufio.ScanWords)

	n, k := rd(), rdll()
	a := make([]int64, n)
	for i := range a {
		a[i] = rdll()
	}
	sort.Slice(a, func(i, j int) bool {
		return a[i] < a[j]
	})
	b := make([]int64, n-1)
	for i := 0; i < n-1; i++ {
		b[i] = a[i+1] - a[i]
	}
	ans := a[len(a)-1] - a[0]
	l, r, p := 0, n-2, int64(1)
	for l < r {
		need := min(k, (b[l]+b[r])*p)
		ans -= need / p
		k -= need
		p++
		l++
		r--
	}
	if l == r {
		need := min(k, b[l]*p)
		ans -= need / p
		k -= need
	}
	Fprint(out, ans)
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
func min(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}
func rd() (x int) {
	inn.Scan()
	data := inn.Bytes()
	x, _ = strconv.Atoi(string(data))
	return x
}
func rdll() (x int64) {
	inn.Scan()
	data := inn.Bytes()
	x, _ = strconv.ParseInt(string(data), 10, 0)
	return x
}
func rds() string {
	inn.Scan()
	return string(inn.Bytes())
}

package main

import (
	"bufio"
	. "fmt"
	"os"
	"sort"
	"strconv"
)

var (
	inn = bufio.NewScanner(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

func main() {
	defer out.Flush()
	inn.Buffer([]byte{}, 10000000)
	inn.Split(bufio.ScanWords)

	n, k := rd(), rdll()
	a := make([]int64, n)
	for i := range a {
		a[i] = rdll()
	}
	sort.Slice(a, func(i, j int) bool {
		return a[i] < a[j]
	})
	b := make([]int64, n-1)
	for i := 0; i < n-1; i++ {
		b[i] = a[i+1] - a[i]
	}
	ans := a[len(a)-1] - a[0]
	l, r, p := 0, n-2, int64(1)
	for l < r {
		need := min(k, (b[l]+b[r])*p)
		ans -= need / p
		k -= need
		p++
		l++
		r--
	}
	if l == r {
		need := min(k, b[l]*p)
		ans -= need / p
		k -= need
	}
	Fprint(out, ans)
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
func min(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}
func rd() (x int) {
	inn.Scan()
	data := inn.Bytes()
	x, _ = strconv.Atoi(string(data))
	return x
}
func rdll() (x int64) {
	inn.Scan()
	data := inn.Bytes()
	x, _ = strconv.ParseInt(string(data), 10, 0)
	return x
}
func rds() string {
	inn.Scan()
	return string(inn.Bytes())
}


package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
)

const (
	SCANNER_BUF_SIZE = 2 << 20

	INF = int64(math.MaxInt64)
	MOD = 1e9 + 7
)

var (
	writer  *bufio.Writer
	scanner *bufio.Scanner
)

func init() {
	writer = bufio.NewWriter(os.Stdout)
	scanner = bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, SCANNER_BUF_SIZE), SCANNER_BUF_SIZE)
}

func printf(f string, a ...interface{}) {
	fmt.Fprintf(writer, f, a...)
}

func sint64() int64 {
	scanner.Scan()
	bb := scanner.Bytes()
	i := int64(0)
	if bb[0] == '-' {
		for _, b := range bb[1:] {
			i *= 10
			i -= int64(b - '0')
		}
		return i
	}
	for _, b := range bb {
		i *= 10
		i += int64(b - '0')
	}
	return i
}

func suint64() uint64 {
	scanner.Scan()
	bb := scanner.Bytes()
	i := uint64(0)
	for _, b := range bb {
		i *= 10
		i += uint64(b - '0')
	}
	return i
}

func sstring() string {
	scanner.Scan()
	return scanner.Text()
}

func main() {
	defer writer.Flush()
	t := sint64()
	for ; t > 0; t-- {
		n, m := sint64(), sint64()
		grid := make([][]byte, n)
		for i := int64(0); i < n; i++ {
			grid[i] = []byte(sstring())
		}
		res := sol(grid, n, m)
		printf("%d\n", len(res))
		for _, r := range res {
			printf("%d %d %d %d %d %d\n", r[0]+1, r[1]+1, r[2]+1, r[3]+1, r[4]+1, r[5]+1)
		}
	}
}

func sol(grid [][]byte, n, m int64) [][6]int64 {

	var makeZero func(int64, int64) [][6]int64
	makeZero = func(y, x int64) [][6]int64 {
		r := [][6]int64{}
		s := string([]byte{grid[y][x], grid[y][x+1], grid[y+1][x], grid[y+1][x+1]})
		var nxt [6]int64
		switch s {
		case "0000":
			return r
		case "1111", "1110", "0101", "1001", "1000", "0100", "0010": // TL, TR, BL
			nxt = [6]int64{0, 0, 0, 1, 1, 0}
		case "1101", "0011", "0001": // TL, TR, BR
			nxt = [6]int64{0, 0, 0, 1, 1, 1}
		case "1011", "1100", "0110": // TL, BL, BR
			nxt = [6]int64{0, 0, 1, 0, 1, 1}
		case "0111", "1010": // TR, BL, BR
			nxt = [6]int64{0, 1, 1, 0, 1, 1}
		}
		r = append(r, [6]int64{
			y + nxt[0],
			x + nxt[1],
			y + nxt[2],
			x + nxt[3],
			y + nxt[4],
			x + nxt[5],
		})
		grid[y+nxt[0]][x+nxt[1]] = flip(grid[y+nxt[0]][x+nxt[1]])
		grid[y+nxt[2]][x+nxt[3]] = flip(grid[y+nxt[2]][x+nxt[3]])
		grid[y+nxt[4]][x+nxt[5]] = flip(grid[y+nxt[4]][x+nxt[5]])
		r = append(r, makeZero(y, x)...)
		return r
	}

	res := [][6]int64{}
	for i := int64(0); i < n; i += 2 {
		for j := int64(0); j < m; j += 2 {
			if i == n-1 && j == m-1 {
				res = append(res, makeZero(i-1, j-1)...)
			} else if i == n-1 {
				res = append(res, makeZero(i-1, j)...)
			} else if j == m-1 {
				res = append(res, makeZero(i, j-1)...)
			} else {
				res = append(res, makeZero(i, j)...)
			}
		}
	}
	return res
}

func flip(b byte) byte {
	if b == '0' {
		return '1'
	}
	return '0'
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func run(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	solve := func(Case int) {
		var n, m int
		Fscan(in, &n, &m)
		a := make([][]byte, n)
		for i := range a {
			Fscan(in, &a[i])
		}

		ans := [][][2]int{}
		add := func(ps [][2]int) {
			ans = append(ans, ps)
			for _, p := range ps {
				a[p[0]][p[1]] ^= 1
			}
		}
		for i, row := range a[:n-2] {
			for j, b := range row {
				if b == '1' {
					if j < m-1 {
						add([][2]int{{i, j}, {i + 1, j}, {i + 1, j + 1}})
					} else {
						add([][2]int{{i, j}, {i + 1, j}, {i + 1, j - 1}})
					}
				}
			}
		}
		for j := 0; j < m-2; j++ {
			for i := n - 2; i < n; i++ {
				if a[i][j] == '1' {
					add([][2]int{{i, j}, {n - 2, j + 1}, {n - 1, j + 1}})
				}
			}
		}

		c := [][2]int{{n - 2, m - 2}, {n - 2, m - 1}, {n - 1, m - 2}, {n - 1, m - 1}}
		var p0, p1 []int
		for i, p := range c {
			if a[p[0]][p[1]] == '0' {
				p0 = append(p0, i)
			} else {
				p1 = append(p1, i)
			}
		}
		if len(p1) == 4 {
			ans = append(ans, [][2]int{c[p1[0]], c[p1[1]], c[p1[2]]})
			p0, p1 = p1[:3], p1[3:]
		}
		if len(p1) == 1 {
			ans = append(ans, [][2]int{c[p1[0]], c[p0[0]], c[p0[1]]})
			p1, p0 = p0[:2], append(p0[2:], p1[0])
		}
		if len(p1) == 2 {
			ans = append(ans, [][2]int{c[p1[0]], c[p0[0]], c[p0[1]]})
			p1 = append(p1[1:], p0...)
		}
		if len(p1) == 3 {
			ans = append(ans, [][2]int{c[p1[0]], c[p1[1]], c[p1[2]]})
		}

		Fprintln(out, len(ans))
		for _, ps := range ans {
			for _, p := range ps {
				Fprint(out, p[0]+1, p[1]+1, " ")
			}
			Fprintln(out)
		}
	}

	var t int
	Fscan(in, &t)
	for Case := 1; Case <= t; Case++ {
		solve(Case)
	}
}

func main() { run(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func run(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	solve := func(Case int) {
		var n, m int
		Fscan(in, &n, &m)
		a := make([][]byte, n)
		for i := range a {
			Fscan(in, &a[i])
		}
		ans := [][]int{}
		for i := 0; i < n-2; i++ {
			for j, b := range a[i] {
				if b == '1' {
					if j < m-1 {
						ans = append(ans, []int{i, j, i + 1, j, i + 1, j + 1})
						a[i+1][j] ^= 1
						a[i+1][j+1] ^= 1
					} else {
						ans = append(ans, []int{i, j, i + 1, j, i + 1, j - 1})
						a[i+1][j] ^= 1
						a[i+1][j-1] ^= 1
					}
				}
			}
		}
		for j := 0; j < m-2; j++ {
			for i := n - 2; i < n; i++ {
				if a[i][j] == '1' {
					ans = append(ans, []int{i, j, n - 2, j + 1, n - 1, j + 1})
					a[n-2][j+1] ^= 1
					a[n-1][j+1] ^= 1
				}
			}
		}

		b := []byte{a[n-2][m-2], a[n-2][m-1], a[n-1][m-2], a[n-1][m-1]}
		ids := [][]int{{n - 2, m - 2}, {n - 2, m - 1}, {n - 1, m - 2}, {n - 1, m - 1}}

		p0, p1 := []int{}, []int{}
		for i, v := range b {
			if v == '0' {
				p0 = append(p0, i)
			} else {
				p1 = append(p1, i)
			}
		}
		if len(p1) == 4 {
			aa := []int{}
			for _, p := range p1[:3] {
				aa = append(aa, ids[p]...)
			}
			ans = append(ans, aa)
			p0 = p1[:3]
			p1 = p1[3:]
		}
		if len(p1) == 1 {
			aa := []int{}
			tmp := p1[0]
			aa = append(aa, ids[p1[0]]...)
			aa = append(aa, ids[p0[0]]...)
			aa = append(aa, ids[p0[1]]...)
			ans = append(ans, aa)
			p1 = p0[:2]
			p0 = p0[2:]
			p0 = append(p0, tmp)
		}
		if len(p1) == 2 {
			aa := []int{}
			//tmp := p1[0]
			aa = append(aa, ids[p0[0]]...)
			aa = append(aa, ids[p0[1]]...)
			aa = append(aa, ids[p1[0]]...)
			ans = append(ans, aa)
			p1 = append(p1, p0...)
			p0, p1 = p1[:1], p1[1:]
		}
		if len(p1) == 3 {
			aa := []int{}
			for _, p := range p1[:3] {
				aa = append(aa, ids[p]...)
			}
			ans = append(ans, aa)
		}

		Fprintln(out, len(ans))
		for _, a := range ans {
			for _, v := range a {
				Fprint(out, v+1, " ")
			}
			Fprintln(out)
		}
	}

	var t int
	Fscan(in, &t)
	for Case := 1; Case <= t; Case++ {
		solve(Case)
	}
}

func main() { run(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	"fmt"
	"os"
)

func invert(x rune) rune {
	if x == '1' {
		return '0'
	}
	return '1'
}

func main() {
	//rd, _ := os.Open("input")
	//in := bufio.NewReader(rd)
	in := bufio.NewReader(os.Stdin)

	var t, n, m int
	var s string
	fmt.Fscan(in, &t)

	for ; t > 0; t-- {
		fmt.Fscan(in, &n, &m)

		a := make([][]rune, n)
		for i := 0; i < n; i++ {
			fmt.Fscan(in, &s)
			a[i] = []rune(s)
		}

		opsX := make([]int, 0, 3*n*m)
		opsY := make([]int, 0, 3*n*m)
		// all rows except last
		for i := 0; i < n-1; i++ {
			// all columns except last
			for j := 0; j < m-1; j++ {
				if a[i][j] == '1' {
					a[i][j] = '0'
					opsX = append(opsX, i)
					opsY = append(opsY, j)
					if a[i][j+1] == '1' {
						a[i][j+1] = '0'
						opsX = append(opsX, i)
						opsY = append(opsY, j+1)
						if a[i+1][j] == '1' {
							a[i+1][j] = '0'
							opsX = append(opsX, i+1)
							opsY = append(opsY, j)
						} else {
							a[i+1][j+1] = invert(a[i+1][j+1])
							opsX = append(opsX, i+1)
							opsY = append(opsY, j+1)
						}
					} else {
						a[i+1][j] = invert(a[i+1][j])
						a[i+1][j+1] = invert(a[i+1][j+1])
						opsX = append(opsX, i+1, i+1)
						opsY = append(opsY, j, j+1)
					}
				}
			}
			// last column
			if a[i][m-1] == '1' {
				a[i][m-1] = '0'
				a[i+1][m-2] = invert(a[i+1][m-2])
				a[i+1][m-1] = invert(a[i+1][m-1])
				opsX = append(opsX, i, i+1, i+1)
				opsY = append(opsY, m-1, m-2, m-1)
			}
		}
		// last row except last column
		for i := 0; i < m-1; i++ {
			if a[n-1][i] == '1' {
				if a[n-2][i] == '1' {
					a[n-2][i] = '0'
					a[n-1][i] = '0'
					a[n-1][i+1] = invert(a[n-1][i+1])
					opsX = append(opsX, n-2, n-1, n-1)
					opsY = append(opsY, i, i, i+1)
				} else {
					if a[n-1][i+1] == '1' {
						a[n-1][i] = '0'
						a[n-1][i+1] = '0'
						opsX = append(opsX, n-2, n-2, n-1)
						opsY = append(opsY, i, i+1, i+1)
						opsX = append(opsX, n-2, n-2, n-1)
						opsY = append(opsY, i, i+1, i)
					} else {
						a[n-1][i] = '0'
						a[n-1][i+1] = '1'
						a[n-2][i+1] = '1'
						opsX = append(opsX, n-2, n-1, n-1)
						opsY = append(opsY, i+1, i, i+1)
					}
				}
			}
		}
		// latest elem
		if a[n-1][m-1] == '1' {
			if a[n-2][m-1] == '1' {
				opsX = append(opsX, n-2, n-2, n-1)
				opsY = append(opsY, m-2, m-1, m-2)
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-2, m-2, m-1)
			} else {
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-2, m-2, m-1)
				opsX = append(opsX, n-2, n-2, n-1)
				opsY = append(opsY, m-2, m-1, m-1)
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-1, m-2, m-1)
			}
		}
		opsCnt := len(opsX) / 3
		fmt.Println(opsCnt)
		for i := 0; i < opsCnt; i++ {
			fmt.Printf("%d %d %d %d %d %d\n", opsX[3*i]+1, opsY[3*i]+1, opsX[3*i+1]+1, opsY[3*i+1]+1, opsX[3*i+2]+1, opsY[3*i+2]+1)
		}
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func invert(x rune) rune {
	if x == '1' {
		return '0'
	}
	return '1'
}

func main() {
	//rd, _ := os.Open("input")
	//in := bufio.NewReader(rd)
	in := bufio.NewReader(os.Stdin)

	var t, n, m int
	var s string
	fmt.Fscan(in, &t)

	for ; t > 0; t-- {
		fmt.Fscan(in, &n, &m)
		a := make([][]rune, n)
		opsX := make([]int, 0, 3*n*m)
		opsY := make([]int, 0, 3*n*m)
		for i := 0; i < n; i++ {
			fmt.Fscan(in, &s)
			a[i] = []rune(s)
		}
		// all rows except last
		for i := 0; i < n-1; i++ {
			// all columns except last
			for j := 0; j < m-1; j++ {
				if a[i][j] == '1' {
					if a[i][j+1] == '1' {
						if a[i+1][j] == '1' {
							opsX = append(opsX, i, i, i+1)
							opsY = append(opsY, j, j+1, j)
							a[i][j], a[i][j+1], a[i+1][j] = '0', '0', '0'
						} else {
							opsX = append(opsX, i, i, i+1)
							opsY = append(opsY, j, j+1, j+1)
							a[i][j], a[i][j+1] = '0', '0'
							a[i+1][j+1] = invert(a[i+1][j+1])
						}
					} else {
						opsX = append(opsX, i, i+1, i+1)
						opsY = append(opsY, j, j, j+1)
						a[i][j] = '0'
						a[i+1][j] = invert(a[i+1][j])
						a[i+1][j+1] = invert(a[i+1][j+1])
					}
				}
			}
			// last column
			if a[i][m-1] == '1' {
				opsX = append(opsX, i, i+1, i+1)
				opsY = append(opsY, m-1, m-1, m-2)
				a[i][m-1] = '0'
				a[i+1][m-1] = invert(a[i+1][m-1])
				a[i+1][m-2] = invert(a[i+1][m-2])
			}
		}
		// last row except last column
		for i := 0; i < m-1; i++ {
			if a[n-1][i] == '1' {
				if a[n-2][i] == '1' {
					opsX = append(opsX, n-1, n-2, n-1)
					opsY = append(opsY, i, i, i+1)
					a[n-1][i], a[n-2][i] = '0', '0'
					a[n-1][i+1] = invert(a[n-1][i+1])
				} else {
					if a[n-1][i+1] == '1' {
						opsX = append(opsX, n-2, n-2, n-1)
						opsY = append(opsY, i, i+1, i+1)
						opsX = append(opsX, n-2, n-2, n-1)
						opsY = append(opsY, i, i+1, i)
						a[n-1][i], a[n-1][i+1] = '0', '0'
					} else {
						opsX = append(opsX, n-1, n-1, n-2)
						opsY = append(opsY, i, i+1, i+1)
						a[n-1][i], a[n-1][i+1], a[n-2][i+1] = '0', '1', '1'
					}
				}
			}
		}
		// latest elem
		if a[n-1][m-1] == '1' {
			opsX = append(opsX, n-2, n-1, n-1)
			opsY = append(opsY, m-2, m-2, m-1)
			opsX = append(opsX, n-2, n-2, n-1)
			opsY = append(opsY, m-2, m-1, m-1)
			opsX = append(opsX, n-2, n-1, n-1)
			opsY = append(opsY, m-1, m-1, m-2)
		}
		opsCnt := len(opsX) / 3
		fmt.Println(opsCnt)
		for i := 0; i < opsCnt; i++ {
			fmt.Printf("%d %d %d %d %d %d\n", opsX[3*i]+1, opsY[3*i]+1, opsX[3*i+1]+1, opsY[3*i+1]+1, opsX[3*i+2]+1, opsY[3*i+2]+1)
		}
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func invert(x rune) rune {
	if x == '1' {
		return '0'
	}
	return '1'
}

func main() {
	//rd, _ := os.Open("input")
	//in := bufio.NewReader(rd)
	in := bufio.NewReader(os.Stdin)

	var t, n, m int
	var s string
	fmt.Fscan(in, &t)

	for ; t > 0; t-- {
		fmt.Fscan(in, &n, &m)

		a := make([][]rune, n)
		for i := 0; i < n; i++ {
			fmt.Fscan(in, &s)
			a[i] = []rune(s)
		}

		// some juicy hardcode as I love
		if n == 2 {
			if a[0][0] == '0' && a[0][1] == '1' && a[1][0] == '0' && a[1][1] == '1' {
				fmt.Println(2)
				fmt.Println("1 1 1 2 2 1")
				fmt.Println("1 1 2 1 2 2")
				continue
			}
			if a[0][0] == '1' && a[0][1] == '0' && a[1][0] == '0' && a[1][1] == '1' {
				fmt.Println(2)
				fmt.Println("1 1 1 2 2 1")
				fmt.Println("1 2 2 1 2 2")
				continue
			}
		}

		opsX := make([]int, 0, 3*n*m)
		opsY := make([]int, 0, 3*n*m)
		// all rows except last
		for i := 0; i < n-1; i++ {
			// all columns except last
			for j := 0; j < m-1; j++ {
				if a[i][j] == '1' {
					a[i][j] = '0'
					opsX = append(opsX, i)
					opsY = append(opsY, j)
					if a[i][j+1] == '1' {
						a[i][j+1] = '0'
						opsX = append(opsX, i)
						opsY = append(opsY, j+1)
						if a[i+1][j] == '1' {
							a[i+1][j] = '0'
							opsX = append(opsX, i+1)
							opsY = append(opsY, j)
						} else {
							a[i+1][j+1] = invert(a[i+1][j+1])
							opsX = append(opsX, i+1)
							opsY = append(opsY, j+1)
						}
					} else {
						a[i+1][j] = invert(a[i+1][j])
						a[i+1][j+1] = invert(a[i+1][j+1])
						opsX = append(opsX, i+1, i+1)
						opsY = append(opsY, j, j+1)
					}
				}
			}
			// last column
			if a[i][m-1] == '1' {
				a[i][m-1] = '0'
				a[i+1][m-2] = invert(a[i+1][m-2])
				a[i+1][m-1] = invert(a[i+1][m-1])
				opsX = append(opsX, i, i+1, i+1)
				opsY = append(opsY, m-1, m-2, m-1)
			}
		}
		// last row except last column
		for i := 0; i < m-1; i++ {
			if a[n-1][i] == '1' {
				if a[n-2][i] == '1' {
					a[n-2][i] = '0'
					a[n-1][i] = '0'
					a[n-1][i+1] = invert(a[n-1][i+1])
					opsX = append(opsX, n-2, n-1, n-1)
					opsY = append(opsY, i, i, i+1)
				} else {
					if a[n-1][i+1] == '1' {
						a[n-1][i] = '0'
						a[n-1][i+1] = '0'
						opsX = append(opsX, n-2, n-2, n-1)
						opsY = append(opsY, i, i+1, i+1)
						opsX = append(opsX, n-2, n-2, n-1)
						opsY = append(opsY, i, i+1, i)
					} else {
						a[n-1][i] = '0'
						a[n-1][i+1] = '1'
						a[n-2][i+1] = '1'
						opsX = append(opsX, n-2, n-1, n-1)
						opsY = append(opsY, i+1, i, i+1)
					}
				}
			}
		}
		// latest elem
		if a[n-1][m-1] == '1' {
			if a[n-1][m-2] == '1' {
				opsX = append(opsX, n-2, n-2, n-1)
				opsY = append(opsY, m-2, m-1, m-2)
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-2, m-2, m-1)
			} else {
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-2, m-2, m-1)
				opsX = append(opsX, n-2, n-2, n-1)
				opsY = append(opsY, m-2, m-1, m-1)
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-1, m-1, m-2)
			}
		}
		opsCnt := len(opsX) / 3
		fmt.Println(opsCnt)
		for i := 0; i < opsCnt; i++ {
			fmt.Printf("%d %d %d %d %d %d\n", opsX[3*i]+1, opsY[3*i]+1, opsX[3*i+1]+1, opsY[3*i+1]+1, opsX[3*i+2]+1, opsY[3*i+2]+1)
		}
	}
}

package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func run(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var n int
	Fscan(in, &n)

}

func main() { run(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	"fmt"
	"os"
)

func invert(x rune) rune {
	if x == '1' {
		return '0'
	}
	return '1'
}

func main() {
	rd, _ := os.Open("input")
	in := bufio.NewReader(rd)
	//in := bufio.NewReader(os.Stdin)

	var t, n, m int
	var s string
	fmt.Fscan(in, &t)

	for ; t > 0; t-- {
		fmt.Fscan(in, &n, &m)

		a := make([][]rune, n)
		for i := 0; i < n; i++ {
			fmt.Fscan(in, &s)
			a[i] = []rune(s)
		}

		// some juicy hardcode as I love
		if n == 2 {
			if a[0][0] == '0' && a[0][1] == '1' && a[1][0] == '0' && a[1][1] == '1' {
				fmt.Println(2)
				fmt.Println("1 1 1 2 2 1")
				fmt.Println("1 1 2 1 2 2")
				continue
			}
			if a[0][0] == '1' && a[0][1] == '0' && a[1][0] == '0' && a[1][1] == '1' {
				fmt.Println(2)
				fmt.Println("1 1 1 2 2 1")
				fmt.Println("1 2 2 1 2 2")
				continue
			}
		}

		opsX := make([]int, 0, 3*n*m)
		opsY := make([]int, 0, 3*n*m)
		// all rows except last
		for i := 0; i < n-1; i++ {
			// all columns except last
			for j := 0; j < m-1; j++ {
				if a[i][j] == '1' {
					if a[i][j+1] == '1' {
						if a[i+1][j] == '1' {
							opsX = append(opsX, i, i, i+1)
							opsY = append(opsY, j, j+1, j)
							a[i][j], a[i][j+1], a[i+1][j] = '0', '0', '0'
						} else {
							opsX = append(opsX, i, i, i+1)
							opsY = append(opsY, j, j+1, j+1)
							a[i][j], a[i][j+1] = '0', '0'
							a[i+1][j+1] = invert(a[i+1][j+1])
						}
					} else {
						opsX = append(opsX, i, i+1, i+1)
						opsY = append(opsY, j, j, j+1)
						a[i][j] = '0'
						a[i+1][j] = invert(a[i+1][j])
						a[i+1][j+1] = invert(a[i+1][j+1])
					}
				}
			}
			// last column
			if a[i][m-1] == '1' {
				opsX = append(opsX, i, i+1, i+1)
				opsY = append(opsY, m-1, m-2, m-1)
				a[i][m-1] = '0'
				a[i+1][m-2] = invert(a[i+1][m-2])
				a[i+1][m-1] = invert(a[i+1][m-1])
			}
		}
		// last row except last column
		for i := 0; i < m-1; i++ {
			if a[n-1][i] == '1' {
				if a[n-2][i] == '1' {
					opsX = append(opsX, n-2, n-1, n-1)
					opsY = append(opsY, i, i, i+1)
					a[n-2][i], a[n-1][i] = '0', '0'
					a[n-1][i+1] = invert(a[n-1][i+1])
				} else {
					if a[n-1][i+1] == '1' {
						opsX = append(opsX, n-2, n-2, n-1)
						opsY = append(opsY, i, i+1, i+1)
						opsX = append(opsX, n-2, n-2, n-1)
						opsY = append(opsY, i, i+1, i)
						a[n-1][i], a[n-1][i+1] = '0', '0'
					} else {
						opsX = append(opsX, n-2, n-1, n-1)
						opsY = append(opsY, i+1, i, i+1)
						a[n-1][i], a[n-1][i+1], a[n-2][i+1] = '0', '1', '1'
					}
				}
			}
		}
		// latest elem
		if a[n-1][m-1] == '1' {
			if a[n-1][m-2] == '1' {
				opsX = append(opsX, n-2, n-2, n-1)
				opsY = append(opsY, m-2, m-1, m-2)
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-2, m-2, m-1)
			} else {
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-2, m-2, m-1)
				opsX = append(opsX, n-2, n-2, n-1)
				opsY = append(opsY, m-2, m-1, m-1)
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-1, m-1, m-2)
			}
		}
		opsCnt := len(opsX) / 3
		fmt.Println(opsCnt)
		for i := 0; i < opsCnt; i++ {
			fmt.Printf("%d %d %d %d %d %d\n", opsX[3*i]+1, opsY[3*i]+1, opsX[3*i+1]+1, opsY[3*i+1]+1, opsX[3*i+2]+1, opsY[3*i+2]+1)
		}
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func invert(x rune) rune {
	if x == '1' {
		return '0'
	}
	return '1'
}

func main() {
	//rd, _ := os.Open("input")
	//in := bufio.NewReader(rd)
	in := bufio.NewReader(os.Stdin)

	var t, n, m int
	var s string
	fmt.Fscan(in, &t)

	for ; t > 0; t-- {
		fmt.Fscan(in, &n, &m)

		a := make([][]rune, n)
		for i := 0; i < n; i++ {
			fmt.Fscan(in, &s)
			a[i] = []rune(s)
		}

		// some juicy hardcode as I love
		if n == 2 {
			if a[0][0] == '0' && a[0][1] == '1' && a[1][0] == '0' && a[1][1] == '1' {
				fmt.Println(2)
				fmt.Println("1 1 1 2 2 1")
				fmt.Println("1 1 2 1 2 2")
				continue
			}
			if a[0][0] == '1' && a[0][1] == '0' && a[1][0] == '0' && a[1][1] == '1' {
				fmt.Println(2)
				fmt.Println("1 1 1 2 2 1")
				fmt.Println("1 2 2 1 2 2")
				continue
			}
		}

		opsX := make([]int, 0, 3*n*m)
		opsY := make([]int, 0, 3*n*m)
		// all rows except last
		for i := 0; i < n-1; i++ {
			// all columns except last
			for j := 0; j < m-1; j++ {
				if a[i][j] == '1' {
					a[i][j] = '0'
					opsX = append(opsX, i)
					opsY = append(opsY, j)
					if a[i][j+1] == '1' {
						a[i][j+1] = '0'
						opsX = append(opsX, i)
						opsY = append(opsY, j+1)
						if a[i+1][j] == '1' {
							a[i+1][j] = '0'
							opsX = append(opsX, i+1)
							opsY = append(opsY, j)
						} else {
							a[i+1][j+1] = invert(a[i+1][j+1])
							opsX = append(opsX, i+1)
							opsY = append(opsY, j+1)
						}
					} else {
						a[i+1][j] = invert(a[i+1][j])
						a[i+1][j+1] = invert(a[i+1][j+1])
						opsX = append(opsX, i+1, i+1)
						opsY = append(opsY, j, j+1)
					}
				}
			}
			// last column
			if a[i][m-1] == '1' {
				a[i][m-1] = '0'
				a[i+1][m-2] = invert(a[i+1][m-2])
				a[i+1][m-1] = invert(a[i+1][m-1])
				opsX = append(opsX, i, i+1, i+1)
				opsY = append(opsY, m-1, m-2, m-1)
			}
		}
		// last row except last column
		for i := 0; i < m-1; i++ {
			if a[n-1][i] == '1' {
				if a[n-2][i] == '1' {
					a[n-2][i] = '0'
					a[n-1][i] = '0'
					a[n-1][i+1] = invert(a[n-1][i+1])
					opsX = append(opsX, n-2, n-1, n-1)
					opsY = append(opsY, i, i, i+1)
				} else {
					if a[n-1][i+1] == '1' {
						a[n-1][i] = '0'
						a[n-1][i+1] = '0'
						opsX = append(opsX, n-2, n-2, n-1)
						opsY = append(opsY, i, i+1, i+1)
						opsX = append(opsX, n-2, n-2, n-1)
						opsY = append(opsY, i, i+1, i)
					} else {
						a[n-1][i] = '0'
						a[n-1][i+1] = '1'
						a[n-2][i+1] = '1'
						opsX = append(opsX, n-2, n-1, n-1)
						opsY = append(opsY, i+1, i, i+1)
					}
				}
			}
		}
		// latest elem
		if a[n-1][m-1] == '1' {
			if a[n-2][m-1] == '1' {
				opsX = append(opsX, n-2, n-2, n-1)
				opsY = append(opsY, m-2, m-1, m-2)
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-2, m-2, m-1)
			} else {
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-2, m-2, m-1)
				opsX = append(opsX, n-2, n-2, n-1)
				opsY = append(opsY, m-2, m-1, m-1)
				opsX = append(opsX, n-2, n-1, n-1)
				opsY = append(opsY, m-1, m-1, m-2)
			}
		}
		opsCnt := len(opsX) / 3
		fmt.Println(opsCnt)
		for i := 0; i < opsCnt; i++ {
			fmt.Printf("%d %d %d %d %d %d\n", opsX[3*i]+1, opsY[3*i]+1, opsX[3*i+1]+1, opsY[3*i+1]+1, opsX[3*i+2]+1, opsY[3*i+2]+1)
		}
	}
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var (
	in  = bufio.NewScanner(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

var (
	MOD = 1000000007
)

var (
	n, m int
	a    [100][30]int64
	s    [100]string
)

func main() {
	defer out.Flush()
	in.Split(bufio.ScanWords)

	fmt.Scan(&n, &m)
	for i := 0; i < n; i++ {
		fmt.Scan(&s[i])
	}

	for i := 0; i < n; i++ {
		for j := 0; j < len(s[i]); j++ {
			a[j][s[i][j]-65] = 1
		}

	}

	ans := int64(1)
	for i := 0; i < m; i++ {
		cnt := int64(0)
		for j := 0; j < 26; j++ {
			cnt = cnt + a[i][j]

		}
		ans = (ans * cnt) % int64(MOD)
	}

	fmt.Printf("%d", uint64(ans))

}

func read(num ...*int) {
	for _, value := range num {
		in.Scan()
		*value, _ = strconv.Atoi(in.Text())
	}
}

func writeln(num ...int) {
	for _, value := range num {
		str := strconv.Itoa(value)
		out.WriteString(str)
	}
	out.WriteString("\n")
}

package main
import "fmt"

func main(){
	var n,m,i,u,count,ans int64
	fmt.Scan(&n,&m)
	s:=make([]string,n)
	for i=0; i<n; i++{ fmt.Scan(&s[i]) }
	ans = 1
	for i=0; i<m; i++{
		var dif [26]int
		count=0
		for u=0; u<n ; u++{
			x:= s[u][i]-'A'
			if dif[x] == 0{ dif[x]++}
		}
		for j:=0; j<26; j++{
			count+= int64(dif[j])
		}
		ans= (ans*count)%1000000007
	}
	fmt.Println(ans)
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	n, m, s := 0, 0, []string{}
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	raw := strings.Split(scanner.Text(), " ")
	n, _ = strconv.Atoi(raw[0])
	m, _ = strconv.Atoi(raw[1])
	for i := 0; i < n; i++ {
		scanner.Scan()
		s = append(s, scanner.Text())
	}
	r := int64(1)
	for i := 0; i < m; i++ {
		byteMap := map[byte]bool{}
		for j := 0; j < n; j++ {
			byteMap[s[j][i]] = true
		}
		r = r * int64(len(byteMap)) % int64(1000000007)
	}
	fmt.Println(r)
}

package main
import "fmt"

func main(){
	var n,m int
	fmt.Scan(&n,&m)
	s:=make([]string,n)
	for i:=0; i<n; i++{ fmt.Scan(&s[i]) }
	ans := 1
	for i:=0; i<m; i++{
		var dif [26]int
		count:=0
		for u:=0; u<n ; u++{
			x:= s[u][i]-'A'
			if dif[x] == 0{ dif[x]++}
		}
		for j:=0; j<26; j++{
			count+= dif[j]
		}
		ans*=count
	}
	fmt.Println(ans)
}

package main
import "fmt"

func main(){
	var n,m int
	fmt.Scan(&n,&m)
	s:=make([]string,n)
	for i:=0; i<n; i++{ fmt.Scan(&s[i]) }
	ans := 1
	for i:=0; i<m; i++{
		var dif [26]int
		count:=0
		for u:=0; u<n ; u++{
			x:= s[u][i]-'A'
			if dif[x] == 0{ dif[x]++}
		}
		for j:=0; j<26; j++{
			count+= dif[j]
		}
		ans*=count
	}
	fmt.Println(ans%1000000007)
}

package main
import "fmt"

func main(){
	var n,m,i,u,ans,count int64
	fmt.Scan(&n,&m)
	s:=make([]string,n)
	for i=0; i<n; i++{ fmt.Scan(&s[i]) }
	ans = 1
	for i=0; i<m; i++{
		var dif [26]int
		count=0
		for u=0; u<n ; u++{
			x:= s[u][i]-'A'
			if dif[x] == 0{ dif[x]++}
		}
		for j:=0; j<26; j++{
			count+= int64(dif[j])
		}
		ans*=count
	}
	fmt.Println(ans%1000000007)
}

package main
import "fmt"

func main(){
	var n,m int
	fmt.Scan(&n,&m)
	s:=make([]string,n)
	for i:=0; i<n; i++{ fmt.Scan(&s[i]) }
	ans := 1
	for i:=0; i<m; i++{
		var dif [26]int
		count:=0
		for u:=0; u<n ; u++{
			x:= s[u][i]-'A'
			if dif[x] == 0{ dif[x]++}
		}
		for j:=0; j<26; j++{
			count+= dif[j]
		}
		ans= (ans*count)%1000000007
	}
	fmt.Println(ans)
}

package main
import "fmt"

func main(){
	var n,m int
	fmt.Scan(&n,&m)
	s:=make([]string,n)
	for i:=0; i<n; i++{ fmt.Scan(&s[i]) }
	ans := 1
	for i:=0; i<m; i++{
		var dif [26]int
		count:=0
		for u:=0; u<n ; u++{
			x:= s[u][i]-'A'
			if dif[x] == 0{ dif[x]++}
		}
		for j:=0; j<26; j++{
			count+= dif[j]
		}
		if count<1{ count=1}
		ans*=count
	}
	fmt.Println(ans%1000000007)
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var (
	in  = bufio.NewScanner(os.Stdin)
	out = bufio.NewWriter(os.Stdout)
)

var (
	MOD = 1000000007
)

var (
	n, m int
	a    [100][30]int
	s    [100]string
)

func main() {
	defer out.Flush()
	in.Split(bufio.ScanWords)

	fmt.Scan(&n, &m)
	for i := 0; i < n; i++ {
		fmt.Scan(&s[i])
	}

	for i := 0; i < n; i++ {
		for j := 0; j < len(s[i]); j++ {
			a[j][s[i][j]-65] = 1
		}

	}

	ans := 1
	for i := 0; i < m; i++ {
		cnt := 0
		for j := 0; j < 26; j++ {
			cnt = cnt + a[i][j]

		}
		//writeln(cnt)
		ans = (ans * cnt) % MOD
	}

	writeln(ans)

}

func read(num ...*int) {
	for _, value := range num {
		in.Scan()
		*value, _ = strconv.Atoi(in.Text())
	}
}

func writeln(num ...int) {
	for _, value := range num {
		str := strconv.Itoa(value)
		out.WriteString(str)
	}
	out.WriteString("\n")
}