This is the easy version of the problem. The difference between the versions is in the number of possible operations that can be made. You can make hacks if and only if you solved both versions of the problem.

You are given a binary table of size n × m. This table consists of symbols 0 and 1.

You can make such operation: select 3 different cells that belong to one 2 × 2 square and change the symbols in these cells (change 0 to 1 and 1 to 0).

Your task is to make all symbols in the table equal to 0. You are allowed to make at most 3nm operations. You don't need to minimize the number of operations.

It can be proved that it is always possible.

Input

The first line contains a single integer t (1 ≤ t ≤ 5000) — the number of test cases. The next lines contain descriptions of test cases.

The first line of the description of each test case contains two integers n, m (2 ≤ n, m ≤ 100).

Each of the next n lines contains a binary string of length m, describing the symbols of the next row of the table.

It is guaranteed that the sum of nm for all test cases does not exceed 20000.

Output

For each test case print the integer k (0 ≤ k ≤ 3nm) — the number of operations.

In the each of the next k lines print 6 integers x_1, y_1, x_2, y_2, x_3, y_3 (1 ≤ x_1, x_2, x_3 ≤ n, 1 ≤ y_1, y_2, y_3 ≤ m) describing the next operation. This operation will be made with three cells (x_1, y_1), (x_2, y_2), (x_3, y_3). These three cells should be different. These three cells should belong into some 2 × 2 square.

Example

Input


5
2 2
10
11
3 3
011
101
110
4 4
1111
0110
0110
1111
5 5
01011
11001
00010
11011
10000
2 3
011
101


Output


1
1 1 2 1 2 2
2 
2 1 3 1 3 2
1 2 1 3 2 3
4
1 1 1 2 2 2 
1 3 1 4 2 3
3 2 4 1 4 2
3 3 4 3 4 4
4
1 2 2 1 2 2 
1 4 1 5 2 5 
4 1 4 2 5 1
4 4 4 5 3 4
2
1 3 2 2 2 3
1 2 2 1 2 2

Note

In the first test case, it is possible to make only one operation with cells (1, 1), (2, 1), (2, 2). After that, all symbols will be equal to 0.

In the second test case:

  * operation with cells (2, 1), (3, 1), (3, 2). After it the table will be: 
    
          
    011  
    001  
    000  
    

  * operation with cells (1, 2), (1, 3), (2, 3). After it the table will be: 
    
          
    000  
    000  
    000  
    




In the fifth test case:

  * operation with cells (1, 3), (2, 2), (2, 3). After it the table will be: 
    
          
    010  
    110  
    

  * operation with cells (1, 2), (2, 1), (2, 2). After it the table will be: 
    
          
    000  
    000

Difficulty: MEDIUM
Tags: Implementation

Constructive algorithms

Starter code:

Solutions:
import sys
input = sys.stdin.readline

def change(x1, x2, x3, y1, y2, y3, ll):
	ll[x1][y1] = 1 - ll[x1][y1]
	ll[x2][y2] = 1 - ll[x2][y2]
	ll[x3][y3] = 1 - ll[x3][y3]
t = int(input())
while t:
	(n, m) = map(int, input().split())
	ll = []
	for i in range(n):
		l = list(map(int, input().strip()))
		ll.append(l)
	ans = []
	for i in range(n - 1):
		for j in range(m):
			if i == n - 2 and j == m - 2:
				break
			if ll[i][j]:
				if j + 1 < m:
					ans.append((i + 1, i + 2, i + 2, j + 1, j + 1, j + 2))
					change(i, i + 1, i + 1, j, j, j + 1, ll)
				else:
					ans.append((i + 1, i + 2, i + 2, j + 1, j + 1, j))
					change(i, i + 1, i + 1, j, j, j - 1, ll)
	for i in range(m - 1):
		if ll[n - 1][i] and ll[n - 2][i]:
			ans.append((n - 1, n, n, i + 1, i + 1, i + 2))
			change(n - 2, n - 1, n - 1, i, i, i + 1, ll)
		elif ll[n - 1][i]:
			ans.append((n, n, n - 1, i + 1, i + 2, i + 2))
			change(n - 1, n - 1, n - 2, i, i + 1, i + 1, ll)
		elif ll[n - 2][i]:
			ans.append((n - 1, n - 1, n, i + 1, i + 2, i + 2))
			change(n - 2, n - 2, n - 1, i, i + 1, i + 1, ll)
	if ll[n - 1][m - 1] and ll[n - 2][m - 1]:
		ans.append((n, n - 1, n, m, m - 1, m - 1))
		ans.append((n, n - 1, n - 1, m - 1, m - 1, m))
	elif ll[n - 2][m - 1]:
		ans.append((n - 1, n, n, m, m, m - 1))
		change(n - 2, n - 1, n - 1, m - 1, m - 1, m - 2, ll)
		ans.append((n, n - 1, n - 1, m, m - 1, m))
		change(n - 1, n - 2, n - 2, m - 1, m - 2, m - 1, ll)
		ans.append((n, n - 1, n - 1, m - 1, m, m - 1))
		change(n - 1, n - 2, n - 2, m - 2, m - 1, m - 2, ll)
	elif ll[n - 1][m - 1]:
		ans.append((n, n, n - 1, m, m - 1, m - 1))
		ans.append((n - 1, n - 1, n, m - 1, m, m))
		ans.append((n, n, n - 1, m - 1, m, m))
	print(len(ans))
	for i in ans:
		(x1, x2, x3, y1, y2, y3) = i
		print(x1, y1, x2, y2, x3, y3)
	t -= 1


def aze(w):
	(x, y) = (w[0], w[1])
	s[x - 1][y - 1] ^= 1
	(x, y) = (w[2], w[3])
	s[x - 1][y - 1] ^= 1
	(x, y) = (w[4], w[5])
	s[x - 1][y - 1] ^= 1
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	s = [[] for i in range(n)]
	for i in range(n):
		s[i] = [int(j) for j in str(input())]
	an = []
	for i in range(n - 2):
		for j in range(m - 1):
			if s[i][j]:
				(x, y) = (i + 1, j + 1)
				an.append([x, y, x + 1, y, x + 1, y + 1])
				aze([x, y, x + 1, y, x + 1, y + 1])
		j = m - 1
		if s[i][-1]:
			(x, y) = (i + 1, j + 1)
			an.append([x, y, x + 1, y - 1, x + 1, y])
			aze([x, y, x + 1, y - 1, x + 1, y])
	i = n - 2
	for j in range(m - 2):
		(x, y) = (i + 1, j + 1)
		if s[i][j] and s[i + 1][j]:
			an.append([x, y, x + 1, y, x, y + 1])
			aze([x, y, x + 1, y, x, y + 1])
		elif s[i][j]:
			an.append([x, y, x, y + 1, x + 1, y + 1])
			aze([x, y, x, y + 1, x + 1, y + 1])
		elif s[i + 1][j]:
			an.append([x + 1, y, x, y + 1, x + 1, y + 1])
			aze([x + 1, y, x, y + 1, x + 1, y + 1])
	one = []
	zer = []
	(i, j) = (n - 2, m - 2)
	(x, y) = (i + 1, j + 1)
	if s[i][j]:
		one.append([x, y])
	else:
		zer.append([x, y])
	if s[i][j + 1]:
		one.append([x, y + 1])
	else:
		zer.append([x, y + 1])
	if s[i + 1][j]:
		one.append([x + 1, y])
	else:
		zer.append([x + 1, y])
	if s[i + 1][j + 1]:
		one.append([x + 1, y + 1])
	else:
		zer.append([x + 1, y + 1])
	if len(one) == 3:
		an.append(one[0] + one[1] + one[2])
		aze(one[0] + one[1] + one[2])
	elif len(one) == 2:
		an.append(one[0] + zer[0] + zer[1])
		aze(one[0] + zer[0] + zer[1])
		an.append(one[1] + zer[0] + zer[1])
		aze(one[1] + zer[0] + zer[1])
	elif len(one) == 1:
		an.append(one[0] + zer[0] + zer[1])
		aze(one[0] + zer[0] + zer[1])
		an.append(one[0] + zer[0] + zer[2])
		aze(one[0] + zer[0] + zer[2])
		an.append(one[0] + zer[1] + zer[2])
		aze(one[0] + zer[1] + zer[2])
	elif len(one) == 4:
		an.append(one[0] + one[1] + one[2])
		aze(one[0] + one[1] + one[2])
		an.append(one[3] + one[0] + one[1])
		aze(one[3] + one[0] + one[1])
		an.append(one[1] + one[2] + one[3])
		aze(one[1] + one[2] + one[3])
		an.append(one[0] + one[2] + one[3])
		aze(one[0] + one[2] + one[3])
	print(len(an))
	for i in an:
		print(*i)


t = int(input())
for i in range(t):
	(n, m) = map(int, input().split())
	b = []
	for j in range(n):
		s = input()
		c = []
		for j in s:
			c.append(int(j))
		b.append(c)
	res = []
	if n % 2 != 0 and m % 2 != 0 and (b[n - 1][m - 1] == 1):
		res.append([[n - 1, m - 1], [n - 2, m - 1], [n - 1, m - 2]])
		b[n - 1][m - 1] = 1 - b[n - 1][m - 1]
		b[n - 2][m - 1] = 1 - b[n - 2][m - 1]
		b[n - 1][m - 2] = 1 - b[n - 1][m - 2]
	i = 0
	while i < n:
		j = 0
		while j < m:
			if i < n - 1 and j < m - 1:
				pass
			elif i < n - 1 and j == m - 1:
				if b[i][m - 1] == 1 and b[i + 1][m - 1] == 0:
					res.append([[i, m - 2], [i + 1, m - 2], [i, m - 1]])
					b[i][m - 1] = 1 - b[i][m - 1]
					b[i][m - 2] = 1 - b[i][m - 2]
					b[i + 1][m - 2] = 1 - b[i + 1][m - 2]
				elif b[i][m - 1] == 0 and b[i + 1][m - 1] == 1:
					res.append([[i, m - 2], [i + 1, m - 2], [i + 1, m - 1]])
					b[i][m - 2] = 1 - b[i][m - 2]
					b[i + 1][m - 1] = 1 - b[i + 1][m - 1]
					b[i + 1][m - 2] = 1 - b[i + 1][m - 2]
				elif b[i][m - 1] == 1 and b[i + 1][m - 1] == 1:
					res.append([[i, m - 1], [i + 1, m - 1], [i, m - 2]])
					b[i][m - 2] = 1 - b[i][m - 2]
					b[i + 1][m - 1] = 1 - b[i + 1][m - 1]
					b[i][m - 1] = 1 - b[i][m - 1]
			elif i == n - 1 and j < m - 1:
				if b[n - 1][j] == 1 and b[n - 1][j + 1] == 0:
					res.append([[n - 2, j], [n - 2, j + 1], [n - 1, j]])
					b[n - 1][j] = 1 - b[n - 1][j]
					b[n - 2][j] = 1 - b[n - 2][j]
					b[n - 2][j + 1] = 1 - b[n - 2][j + 1]
				elif b[n - 1][j] == 0 and b[n - 1][j + 1] == 1:
					res.append([[n - 2, j], [n - 2, j + 1], [n - 1, j + 1]])
					b[n - 1][j + 1] = 1 - b[n - 1][j + 1]
					b[n - 2][j] = 1 - b[n - 2][j]
					b[n - 2][j + 1] = 1 - b[n - 2][j + 1]
				elif b[n - 1][j] == 1 and b[n - 1][j + 1] == 1:
					res.append([[n - 1, j], [n - 2, j], [n - 1, j + 1]])
					b[n - 1][j] = 1 - b[n - 1][j]
					b[n - 1][j + 1] = 1 - b[n - 1][j + 1]
					b[n - 2][j] = 1 - b[n - 2][j]
			j += 2
		i += 2
	i = 0
	while i < n:
		j = 0
		while j < m:
			if i < n - 1 and j < m - 1:
				ones = []
				zero = []
				on = 0
				z = 0
				for w in range(2):
					for e in range(2):
						if b[i + w][j + e] == 1:
							ones.append([i + w, j + e])
							on += 1
						else:
							zero.append([i + w, j + e])
							z += 1
						b[i + w][j + e] = 0
				if on == 4:
					f = ones[0]
					se = ones[1]
					th = ones[2]
					frth = ones[3]
					res.append([f, se, th])
					res.append([f, th, frth])
					res.append([f, se, frth])
					res.append([se, th, frth])
				elif on == 3:
					f = ones[0]
					se = ones[1]
					th = ones[2]
					frth = zero[0]
					res.append([f, se, th])
				elif on == 2:
					f = ones[0]
					th = ones[1]
					se = zero[0]
					frth = zero[1]
					res.append([f, se, frth])
					res.append([se, th, frth])
				elif on == 1:
					f = zero[0]
					se = zero[1]
					th = zero[2]
					frth = ones[0]
					res.append([f, th, frth])
					res.append([f, se, frth])
					res.append([se, th, frth])
			elif i < n - 1 and j == m - 1:
				ones = []
				zero = []
				on = 0
				z = 0
				for w in range(2):
					for e in range(2):
						if b[i + w][j + e - 1] == 1:
							ones.append([i + w, j + e - 1])
							on += 1
						else:
							zero.append([i + w, j + e - 1])
							z += 1
						b[i + w][j + e - 1] = 0
				if on == 4:
					f = ones[0]
					se = ones[1]
					th = ones[2]
					frth = ones[3]
					res.append([f, se, th])
					res.append([f, th, frth])
					res.append([f, se, frth])
					res.append([se, th, frth])
				elif on == 3:
					f = ones[0]
					se = ones[1]
					th = ones[2]
					frth = zero[0]
					res.append([f, se, th])
				elif on == 2:
					f = ones[0]
					th = ones[1]
					se = zero[0]
					frth = zero[1]
					res.append([f, se, frth])
					res.append([se, th, frth])
				elif on == 1:
					f = zero[0]
					se = zero[1]
					th = zero[2]
					frth = ones[0]
					res.append([f, th, frth])
					res.append([f, se, frth])
					res.append([se, th, frth])
			elif i == n - 1 and j < m - 1:
				ones = []
				zero = []
				on = 0
				z = 0
				for w in range(2):
					for e in range(2):
						if b[i + w - 1][j + e] == 1:
							ones.append([i + w - 1, j + e])
							on += 1
						else:
							zero.append([i + w - 1, j + e])
							z += 1
						b[i + w - 1][j + e] = 0
				if on == 4:
					f = ones[0]
					se = ones[1]
					th = ones[2]
					frth = ones[3]
					res.append([f, se, th])
					res.append([f, th, frth])
					res.append([f, se, frth])
					res.append([se, th, frth])
				elif on == 3:
					f = ones[0]
					se = ones[1]
					th = ones[2]
					frth = zero[0]
					res.append([f, se, th])
				elif on == 2:
					f = ones[0]
					th = ones[1]
					se = zero[0]
					frth = zero[1]
					res.append([f, se, frth])
					res.append([se, th, frth])
				elif on == 1:
					f = zero[0]
					se = zero[1]
					th = zero[2]
					frth = ones[0]
					res.append([f, th, frth])
					res.append([f, se, frth])
					res.append([se, th, frth])
			else:
				ones = []
				zero = []
				on = 0
				z = 0
				for w in range(2):
					for e in range(2):
						if b[i + w - 1][j + e - 1] == 1:
							ones.append([i + w - 1, j + e - 1])
							on += 1
						else:
							zero.append([i + w - 1, j + e - 1])
							z += 1
						b[i + w - 1][j + e - 1] = 0
				if on == 4:
					f = ones[0]
					se = ones[1]
					th = ones[2]
					frth = ones[3]
					res.append([f, se, th])
					res.append([f, th, frth])
					res.append([f, se, frth])
					res.append([se, th, frth])
				elif on == 3:
					f = ones[0]
					se = ones[1]
					th = ones[2]
					frth = zero[0]
					res.append([f, se, th])
				elif on == 2:
					f = ones[0]
					th = ones[1]
					se = zero[0]
					frth = zero[1]
					res.append([f, se, frth])
					res.append([se, th, frth])
				elif on == 1:
					f = zero[0]
					se = zero[1]
					th = zero[2]
					frth = ones[0]
					res.append([f, th, frth])
					res.append([f, se, frth])
					res.append([se, th, frth])
			j += 2
		i += 2
	print(len(res))
	for j in res:
		s = []
		for k in j:
			s.append(k[0] + 1)
			s.append(k[1] + 1)
		print(*s)


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush, nsmallest
from math import ceil, floor, gcd, fabs, factorial, fmod, sqrt, inf
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
from decimal import Decimal
mod = pow(10, 9) + 7

def data():
	return sys.stdin.readline().strip()

def out(var):
	sys.stdout.write(str(var) + '\n')

def outa(*var, end='\n'):
	sys.stdout.write(' '.join(map(str, var)) + end)

def l():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]

def perform(z, o):
	answer.append([])
	for (first, second) in nei:
		if z and mat[first][second] == '0':
			answer[-1].append((first + 1, second + 1))
			z -= 1
			mat[first][second] = '1'
		elif o and mat[first][second] == '1':
			answer[-1].append((first + 1, second + 1))
			o -= 1
			mat[first][second] = '0'
for _ in range(int(data())):
	(n, m) = sp()
	mat = [list(data()) for __ in range(n)]
	answer = []
	if n & 1 or m & 1:
		i = 0
		j = m - 1
		while i < n:
			if mat[i][j] == mat[i + 1][j] == '0':
				i += (1, 2)[i != n - 3]
				continue
			answer.append([])
			if mat[i][j] == '1':
				mat[i][j] = '0'
				answer[-1].append([i + 1, j + 1])
			if mat[i + 1][j] == '1':
				mat[i + 1][j] = '0'
				answer[-1].append([i + 2, j + 1])
			if len(answer[-1]) == 1:
				answer[-1].append([i + 1, j])
				answer[-1].append([i + 2, j])
				mat[i][j - 1] = ('0', '1')[mat[i][j - 1] == '0']
				mat[i + 1][j - 1] = ('0', '1')[mat[i + 1][j - 1] == '0']
			elif len(answer[-1]) == 2:
				answer[-1].append([i + 2, j])
				mat[i + 1][j - 1] = ('0', '1')[mat[i + 1][j - 1] == '0']
			i += (1, 2)[i != n - 3]
		j = 0
		i = n - 1
		while j < m:
			if mat[i][j] == mat[i][j + 1] == '0':
				j += (1, 2)[j != m - 3]
				continue
			answer.append([])
			if mat[i][j] == '1':
				mat[i][j] = '0'
				answer[-1].append([i + 1, j + 1])
			if mat[i][j + 1] == '1':
				mat[i][j + 1] = '0'
				answer[-1].append([i + 1, j + 2])
			if len(answer[-1]) == 1:
				answer[-1].append([i, j + 1])
				answer[-1].append([i, j + 2])
				mat[i - 1][j] = ('0', '1')[mat[i - 1][j] == '0']
				mat[i - 1][j + 1] = ('0', '1')[mat[i - 1][j + 1] == '0']
			elif len(answer[-1]) == 2:
				answer[-1].append([i, j + 2])
				mat[i - 1][j + 1] = ('0', '1')[mat[i - 1][j + 1] == '0']
			j += (1, 2)[j != m - 3]
	i = 0
	while i < n:
		j = 0
		while j < m:
			nei = [[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]]
			j += (1, 2)[j != m - 3]
			cnt = 0
			for (u, v) in nei:
				cnt += int(mat[u][v])
			if cnt == 0:
				continue
			if cnt == 1:
				perform(2, 1)
				perform(2, 1)
				perform(0, 3)
			elif cnt == 2:
				perform(2, 1)
				perform(0, 3)
			elif cnt == 3:
				perform(0, 3)
			else:
				perform(0, 3)
				perform(2, 1)
				perform(2, 1)
				perform(0, 3)
		i += (1, 2)[i != n - 3]
	out(len(answer))
	for i in answer:
		for (a, b) in i:
			outa(a, b, end=' ')
		outa()


import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__
import math

def gift():
	for _ in range(t):
		(n, m) = list(map(int, input().split()))
		arys = []
		for i in range(n):
			tem = [int(x) for x in input()]
			arys.append(tem)
		ans = []
		irange = []
		if m == 2:
			j = 0
			for i in range(n - 1):
				x1 = arys[i][j]
				x2 = arys[i][j + 1]
				x3 = arys[i + 1][j]
				x4 = arys[i + 1][j + 1]
				if i != n - 2:
					diu = []
					if x1 + x2 != 0:
						if x1 == 1:
							diu.append(i)
							diu.append(j)
						if x2 == 1:
							diu.append(i)
							diu.append(j + 1)
						if x1 + x2 == 2:
							diu.append(i + 1)
							diu.append(j)
						else:
							diu.append(i + 1)
							diu.append(j)
							diu.append(i + 1)
							diu.append(j + 1)
						if len(diu) != 0:
							ans.append(diu)
							for z in range(3):
								x = diu[z * 2]
								y = diu[z * 2 + 1]
								arys[x][y] = 1 - arys[x][y]
				elif sum([x1, x2, x3, x4]) == 4:
					ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
					ans.append([i, j, i, j + 1, i + 1, j])
					ans.append([i, j, i, j + 1, i + 1, j + 1])
					ans.append([i, j, i + 1, j, i + 1, j + 1])
					arys[i][j] = 0
					arys[i][j + 1] = 0
					arys[i + 1][j] = 0
					arys[i + 1][j + 1] = 0
				elif sum([x1, x2, x3, x4]) == 0:
					continue
				else:
					while sum([x1, x2, x3, x4]) != 0:
						x1 = arys[i][j]
						x2 = arys[i][j + 1]
						x3 = arys[i + 1][j]
						x4 = arys[i + 1][j + 1]
						diu = []
						if sum([x1, x2, x3, x4]) == 1:
							if x1 == 1:
								diu.extend([i, j])
							elif x2 == 1:
								diu.extend([i, j + 1])
							elif x3 == 1:
								diu.extend([i + 1, j])
							else:
								diu.extend([i + 1, j + 1])
							if x1 == 0:
								diu.extend([i, j])
							if x2 == 0:
								diu.extend([i, j + 1])
							if len(diu) == 4:
								if x3 == 0:
									diu.extend([i + 1, j])
								else:
									diu.extend([i + 1, j + 1])
							elif len(diu) == 2:
								diu.extend([i + 1, j])
								diu.extend([i + 1, j + 1])
						elif sum([x1, x2, x3, x4]) == 2:
							if x1 == 0:
								diu.extend([i, j])
							if x2 == 0:
								diu.extend([i, j + 1])
							if x3 == 0:
								diu.extend([i + 1, j])
							if x4 == 0:
								diu.extend([i + 1, j + 1])
							if x1 == 1:
								diu.extend([i, j])
							elif x2 == 1:
								diu.extend([i, j + 1])
							elif x3 == 1:
								diu.extend([i + 1, j])
							else:
								diu.extend([i + 1, j + 1])
						elif sum([x1, x2, x3, x4]) == 3:
							if x1 == 1:
								diu.extend([i, j])
							if x2 == 1:
								diu.extend([i, j + 1])
							if x3 == 1:
								diu.extend([i + 1, j])
							if x4 == 1:
								diu.extend([i + 1, j + 1])
						if len(diu) > 6:
							print(sum([x1, x2, x3, x4]))
							print(diu, 'lat')
						if len(diu) != 0:
							ans.append(diu)
							for z in range(3):
								x = diu[z * 2]
								y = diu[z * 2 + 1]
								arys[x][y] = 1 - arys[x][y]
		else:
			for kap in range(n // 2):
				irange.append(kap * 2)
			if n % 2:
				irange.append(n - 2)
			for i in irange:
				for j in range(m - 1):
					x1 = arys[i][j]
					x2 = arys[i][j + 1]
					x3 = arys[i + 1][j]
					x4 = arys[i + 1][j + 1]
					if j != m - 2:
						if sum([x1, x3]) == 0:
							continue
						else:
							diu = []
							if x1 == 1:
								diu.append(i)
								diu.append(j)
							if x3 == 1:
								diu.append(i + 1)
								diu.append(j)
							if len(diu) == 2:
								diu.append(i)
								diu.append(j + 1)
								diu.append(i + 1)
								diu.append(j + 1)
							else:
								if x2 == 1:
									diu.append(i)
									diu.append(j + 1)
								if len(diu) == 4:
									diu.append(i + 1)
									diu.append(j + 1)
							ans.append(diu)
							for z in range(3):
								x = diu[z * 2]
								y = diu[z * 2 + 1]
								arys[x][y] = 1 - arys[x][y]
					elif sum([x1, x2, x3, x4]) == 4:
						ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
						ans.append([i, j, i, j + 1, i + 1, j])
						ans.append([i, j, i, j + 1, i + 1, j + 1])
						ans.append([i, j, i + 1, j, i + 1, j + 1])
						arys[i][j] = 0
						arys[i][j + 1] = 0
						arys[i + 1][j] = 0
						arys[i + 1][j + 1] = 0
					elif sum([x1, x2, x3, x4]) == 0:
						continue
					else:
						while sum([x1, x2, x3, x4]) != 0:
							x1 = arys[i][j]
							x2 = arys[i][j + 1]
							x3 = arys[i + 1][j]
							x4 = arys[i + 1][j + 1]
							diu = []
							if sum([x1, x2, x3, x4]) == 1:
								if x1 == 1:
									diu.extend([i, j])
								elif x2 == 1:
									diu.extend([i, j + 1])
								elif x3 == 1:
									diu.extend([i + 1, j])
								else:
									diu.extend([i + 1, j + 1])
								if x1 == 0:
									diu.extend([i, j])
								if x2 == 0:
									diu.extend([i, j + 1])
								if len(diu) == 4:
									if x3 == 0:
										diu.extend([i + 1, j])
									else:
										diu.extend([i + 1, j + 1])
								elif len(diu) == 2:
									diu.extend([i + 1, j])
									diu.extend([i + 1, j + 1])
							elif sum([x1, x2, x3, x4]) == 2:
								if x1 == 0:
									diu.extend([i, j])
								if x2 == 0:
									diu.extend([i, j + 1])
								if x3 == 0:
									diu.extend([i + 1, j])
								if x4 == 0:
									diu.extend([i + 1, j + 1])
								if x1 == 1:
									diu.extend([i, j])
								elif x2 == 1:
									diu.extend([i, j + 1])
								elif x3 == 1:
									diu.extend([i + 1, j])
								else:
									diu.extend([i + 1, j + 1])
							elif sum([x1, x2, x3, x4]) == 3:
								if x1 == 1:
									diu.extend([i, j])
								if x2 == 1:
									diu.extend([i, j + 1])
								if x3 == 1:
									diu.extend([i + 1, j])
								if x4 == 1:
									diu.extend([i + 1, j + 1])
							if len(diu) > 6:
								print(sum([x1, x2, x3, x4]))
								print(diu, 'lat')
							if len(diu) != 0:
								ans.append(diu)
								for z in range(3):
									x = diu[z * 2]
									y = diu[z * 2 + 1]
									arys[x][y] = 1 - arys[x][y]
		yield len(ans)
		for ele in ans:
			yield ' '.join([str(x + 1) for x in ele])
t = int(input())
ans = gift()
print(*ans, sep='\n')


import sys
Z = sys.stdin.readline
O = []
for _ in range(int(Z())):
	(n, m) = map(int, Z().split())
	c = []
	o = []
	for i in range(n):
		c.append(list(map(int, Z().strip())))
	for i in range(n):
		for j in range(m):
			v = [(i + a, j + b) for a in (1, 2 * (i < n - 1)) for b in (1, 2 * (j < m - 1))]
			if c[i][j]:
				o += [sum(v[:i] + v[i + 1:], ()) for i in (1, 2, 3)]
	O += [str(len(o))]
	O += ['\n'.join((' '.join(map(str, i)) for i in o))]
print('\n'.join(O))


import sys
input = sys.stdin.readline
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = [input() for i in range(n)]
	a = [[a[i][j] for j in range(m)] for i in range(n)]
	res = []
	if n % 2 and m % 2:
		(i, j) = (n - 2, m - 2)
		if a[i + 1][j + 1] == '1':
			if a[i + 1][j] == '1':
				if a[i][j + 1] == '1':
					res.append((i + 1, j + 1, i, j))
					(a[i + 1][j], a[i][j + 1], a[i + 1][j + 1]) = ('0', '0', '0')
				else:
					res.append((i + 1, j, i, j))
					(a[i + 1][j], a[i][j + 1], a[i + 1][j + 1]) = ('0', '0', '0')
					if a[i][j] == '1':
						a[i][j] = '0'
					else:
						a[i][j] = '1'
			elif a[i][j + 1] == '1':
				res.append((i, j + 1, i, j))
				(a[i + 1][j], a[i][j + 1], a[i + 1][j + 1]) = ('0', '0', '0')
				if a[i][j] == '1':
					a[i][j] = '0'
				else:
					a[i][j] = '1'
			else:
				res.append((i, j, i, j))
				res.append((i + 1, j + 1, i, j))
				(a[i + 1][j], a[i][j + 1], a[i + 1][j + 1]) = ('0', '0', '0')
				if a[i][j] == '1':
					a[i][j] = '0'
				else:
					a[i][j] = '1'
	if n % 2:
		i = n - 1
		for j in range(0, 2 * (m // 2), 2):
			if a[n - 1][j] == '1':
				res.append((i - 1, j, i - 1, j))
				a[n - 1][j] = '0'
				if a[i - 1][j] == '1':
					a[i - 1][j] = '0'
				else:
					a[i - 1][j] = '1'
				if a[i - 1][j + 1] == '1':
					a[i - 1][j + 1] = '0'
				else:
					a[i - 1][j + 1] = '1'
			if a[n - 1][j + 1] == '1':
				res.append((i - 1, j + 1, i - 1, j))
				a[n - 1][j + 1] = '0'
				if a[i - 1][j] == '1':
					a[i - 1][j] = '0'
				else:
					a[i - 1][j] = '1'
				if a[i - 1][j + 1] == '1':
					a[i - 1][j + 1] = '0'
				else:
					a[i - 1][j + 1] = '1'
	if m % 2:
		j = m - 1
		for i in range(0, 2 * (n // 2), 2):
			if a[i][m - 1] == '1':
				res.append((i, j - 1, i, j - 1))
				a[i][m - 1] = '0'
				if a[i][j - 1] == '1':
					a[i][j - 1] = '0'
				else:
					a[i][j - 1] = '1'
				if a[i + 1][j - 1] == '1':
					a[i + 1][j - 1] = '0'
				else:
					a[i + 1][j - 1] = '1'
			if a[i + 1][m - 1] == '1':
				res.append((i + 1, j - 1, i, j - 1))
				a[i + 1][m - 1] = '0'
				if a[i][j - 1] == '1':
					a[i][j - 1] = '0'
				else:
					a[i][j - 1] = '1'
				if a[i + 1][j - 1] == '1':
					a[i + 1][j - 1] = '0'
				else:
					a[i + 1][j - 1] = '1'
	for x in range(0, n, 2):
		for y in range(0, m, 2):
			if x < n - 1:
				if y < m - 1:
					(i, j) = (x, y)
				else:
					(i, j) = (x, y - 1)
					continue
			elif y < m - 1:
				(i, j) = (x - 1, y)
				continue
			else:
				(i, j) = (x - 1, y - 1)
				continue
			tmp = int(a[i][j]) + int(a[i + 1][j]) + int(a[i][j + 1]) + int(a[i + 1][j + 1])
			if tmp == 1:
				if a[i][j] == '1':
					res.append((i, j, i, j))
					res.append((i + 1, j, i, j))
					res.append((i, j + 1, i, j))
				elif a[i + 1][j] == '1':
					res.append((i + 1, j, i, j))
					res.append((i, j, i, j))
					res.append((i + 1, j + 1, i, j))
				elif a[i][j + 1] == '1':
					res.append((i, j + 1, i, j))
					res.append((i, j, i, j))
					res.append((i + 1, j + 1, i, j))
				elif a[i + 1][j + 1] == '1':
					res.append((i + 1, j + 1, i, j))
					res.append((i + 1, j, i, j))
					res.append((i, j + 1, i, j))
			elif tmp == 2:
				if a[i][j] == '1' and a[i + 1][j] == '1':
					res.append((i, j + 1, i, j))
					res.append((i + 1, j + 1, i, j))
				elif a[i][j] == '1' and a[i][j + 1] == '1':
					res.append((i + 1, j, i, j))
					res.append((i + 1, j + 1, i, j))
				elif a[i][j] == '1' and a[i + 1][j + 1] == '1':
					res.append((i, j, i, j))
					res.append((i + 1, j + 1, i, j))
				elif a[i + 1][j] == '1' and a[i][j + 1] == '1':
					res.append((i + 1, j, i, j))
					res.append((i, j + 1, i, j))
				elif a[i + 1][j] == '1' and a[i + 1][j + 1] == '1':
					res.append((i, j, i, j))
					res.append((i, j + 1, i, j))
				elif a[i][j + 1] == '1' and a[i + 1][j + 1] == '1':
					res.append((i, j, i, j))
					res.append((i + 1, j, i, j))
			elif tmp == 3:
				if a[i][j] == '0':
					res.append((i + 1, j + 1, i, j))
				elif a[i + 1][j] == '0':
					res.append((i, j + 1, i, j))
				elif a[i][j + 1] == '0':
					res.append((i + 1, j, i, j))
				else:
					res.append((i, j, i, j))
			elif tmp == 4:
				res.append((i, j, i, j))
				res.append((i + 1, j, i, j))
				res.append((i, j + 1, i, j))
				res.append((i + 1, j + 1, i, j))
			(a[i][j], a[i + 1][j], a[i][j + 1], a[i + 1][j + 1]) = ('0', '0', '0', '0')
	print(len(res))
	assert len(res) <= 3 * n * m
	for (x, y, bx, by) in res:
		tmp = []
		d_x = bx + (1 - (x - bx) % 2)
		d_y = by + (1 - (y - by) % 2)
		for i in range(2):
			for j in range(2):
				if bx + i != d_x or by + j != d_y:
					tmp.append(bx + i + 1)
					tmp.append(by + j + 1)
		print(*tmp)


import copy
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))

def input():
	return sys.stdin.readline().rstrip('\r\n')

def exgcd(a, b):
	if not b:
		return (1, 0)
	(y, x) = exgcd(b, a % b)
	y -= a // b * x
	return (x, y)

def getinv(a, m):
	(x, y) = exgcd(a, m)
	return --1 if x == 1 else x % m

def comb(n, b):
	res = 1
	b = min(b, n - b)
	for i in range(b):
		res = res * (n - i) * getinv(i + 1, mo) % mo
	return res % mo

def ch(a, b, c, d, e, f, li, ans):
	li[a][b] = not li[a][b]
	li[c][d] = not li[c][d]
	li[e][f] = not li[e][f]
	ans.append((a, b, c, d, e, f))

def reshape3(li, ans):
	tmp = []
	for (x, y) in se:
		if li[x][y]:
			tmp.append(x)
			tmp.append(y)
	ch(*tmp, li, ans)

def reshape2(li, ans):
	tmp = []
	for (x, y) in se:
		if not li[x][y]:
			tmp.append(x)
			tmp.append(y)
	for (x, y) in se:
		if li[x][y] and len(tmp) < 6:
			tmp.append(x)
			tmp.append(y)
	ch(*tmp, li, ans)
	reshape3(li, ans)

def reshape1(li, ans):
	tmp = []
	for (x, y) in se:
		if li[x][y]:
			tmp.append(x)
			tmp.append(y)
	for (x, y) in se:
		if not li[x][y] and len(tmp) < 6:
			tmp.append(x)
			tmp.append(y)
	ch(*tmp, li, ans)
	reshape2(li, ans)

def reshape0(li, ans):
	pass
fd = {0: reshape0, 1: reshape1, 2: reshape2, 3: reshape3}
t = int(input())
for ti in range(t):
	(n, m) = map(int, input().split())
	se = ((n - 2, m - 2), (n - 2, m - 1), (n - 1, m - 2), (n - 1, m - 1))
	li = []
	for i in range(n):
		li.append([bool(int(j)) for j in input()])
	ans = []
	for (i, ii) in enumerate(li[:-1]):
		for (j, jj) in enumerate(ii[:-1]):
			if li[i][j]:
				if li[i][j + 1]:
					ch(i, j, i, j + 1, i + 1, j, li, ans)
				else:
					ch(i, j, i + 1, j + 1, i + 1, j, li, ans)
			elif li[i][j + 1]:
				ch(i, j + 1, i + 1, j + 1, i + 1, j, li, ans)
	for j in range(m - 1):
		if li[n - 2][j]:
			if li[n - 1][j]:
				ch(n - 2, j, n - 1, j, n - 1, j + 1, li, ans)
			else:
				ch(n - 2, j, n - 2, j + 1, n - 1, j + 1, li, ans)
		elif li[n - 1][j]:
			ch(n - 1, j, n - 2, j + 1, n - 1, j + 1, li, ans)
	fd[[li[n - 2][m - 2], li[n - 2][m - 1], li[n - 1][m - 2], li[n - 1][m - 1]].count(True)](li, ans)
	print(len(ans))
	for i in ans:
		print(*(j + 1 for j in i))


def inverse_1_2x2(i, j):
	res = []
	fstr = '{} {} {} {} {} {}'
	(step_i, step_j) = (1, 1)
	if i % 2 == 0:
		step_i = -1
	if j % 2 == 0:
		step_j = -1
	res.append(fstr.format(i + step_i, j + step_j, i + step_i, j, i, j))
	res.append(fstr.format(i + step_i, j, i, j, i, j + step_j))
	res.append(fstr.format(i, j, i, j + step_j, i + step_i, j + step_j))
	return res

def inverse_2_2x2(i, j, x1, x2):
	delta = (x2[0] - x1[0], x2[1] - x1[1])
	if delta[0] == 0 or delta[1] == 0:
		if x1[0] == i and x1[1] == j:
			x3 = (x1[0] + delta[1], x1[1] + delta[0])
		else:
			x3 = (x1[0] - delta[1], x1[1] - delta[0])
	else:
		x3 = (x1[0] + 1, x1[1])
	res = []
	fstr = '{} {} {} {} {} {}'
	res.append(fstr.format(*x1, *x2, *x3))
	res += inverse_1_2x2(*x3)
	return res

def inverce_cell(i, j, a):
	i -= 1
	j -= 1
	if a[i][j] == '1':
		a[i][j] = '0'
	else:
		a[i][j] = '1'

def process_last_row(a):
	res = []
	fstr = '{} {} {} {} {} {}'
	i = len(a)
	j = 1
	while j < len(a[-1]) - 1:
		if a[i - 1][j - 1] == '1':
			res.append(fstr.format(i, j, i - 1, j, i - 1, j + 1))
			inverce_cell(i - 1, j, a)
			inverce_cell(i - 1, j + 1, a)
		j += 1
	if a[i - 1][j - 1] == '1':
		if a[i - 1][j] == '1':
			res.append(fstr.format(i, j, i, j + 1, i - 1, j))
			inverce_cell(i - 1, j, a)
		else:
			res.append(fstr.format(i, j, i - 1, j, i - 1, j + 1))
			inverce_cell(i - 1, j, a)
			inverce_cell(i - 1, j + 1, a)
	elif a[i - 1][j] == '1':
		res.append(fstr.format(i, j + 1, i - 1, j + 1, i - 1, j))
		inverce_cell(i - 1, j + 1, a)
		inverce_cell(i - 1, j, a)
	return res

def process_last_col(a):
	res = []
	fstr = '{} {} {} {} {} {}'
	j = len(a[0])
	for i in range(1, len(a), 2):
		if a[i - 1][j - 1] == '1' and a[i][j - 1] == '1':
			res.append(fstr.format(i, j, i, j - 1, i + 1, j - 1))
			res.append(fstr.format(i, j - 1, i + 1, j - 1, i + 1, j))
		elif a[i - 1][j - 1] == '1':
			res.append(fstr.format(i, j, i, j - 1, i + 1, j - 1))
			inverce_cell(i, j - 1, a)
			inverce_cell(i + 1, j - 1, a)
		elif a[i][j - 1] == '1':
			res.append(fstr.format(i, j - 1, i + 1, j - 1, i + 1, j))
			inverce_cell(i, j - 1, a)
			inverce_cell(i + 1, j - 1, a)
	return res
for _ in range(int(input())):
	(n, m) = list(map(int, input().split(' ')))
	a = [list(input()) for _ in range(n)]
	out = []
	if n % 2 == 1:
		out += process_last_row(a)
	if m % 2 == 1:
		out += process_last_col(a)
	for blk_i in range(n // 2):
		i = 2 * blk_i + 1
		for blk_j in range(m // 2):
			j = 2 * blk_j + 1
			ones = [(i + ii, j + jj) for ii in range(2) for jj in range(2) if a[i + ii - 1][j + jj - 1] == '1']
			if len(ones) == 1:
				x1 = ones.pop()
				out += inverse_1_2x2(*x1)
			elif len(ones) == 2:
				out += inverse_2_2x2(i, j, *ones)
			elif len(ones) == 3:
				(x1, x2, x3) = ones
				out.append('{} {} {} {} {} {}'.format(*x1, *x2, *x3))
			elif len(ones) == 4:
				(x1, x2, x3, x4) = ones
				out.append('{} {} {} {} {} {}'.format(*x1, *x2, *x3))
				out += inverse_1_2x2(*x4)
	print(len(out))
	print('\n'.join(out))


import sys
from array import array
import typing as Tp

def input():
	return sys.stdin.buffer.readline().decode('utf-8')

def output(*args):
	sys.stdout.buffer.write(('\n'.join(map(str, args)) + '\n').encode('utf-8'))

def hoge(mat, i1, j1, i2, j2, i3, j3):
	mat[i1][j1] ^= 1
	mat[i2][j2] ^= 1
	mat[i3][j3] ^= 1
	return f'{i1 + 1} {j1 + 1} {i2 + 1} {j2 + 1} {i3 + 1} {j3 + 1}'

def solve(mat, i, j, flag=0):
	res = []
	while True:
		zero = [(k, l) for k in (i, i + 1) for l in (j, j + 1) if mat[k][l] == 0]
		one = [(k, l) for k in (i, i + 1) for l in (j, j + 1) if mat[k][l] == 1]
		if not one or (flag == 0 and mat[i][j] == 0) or (flag == 1 and mat[i][j] == mat[i][j + 1] == 0) or (flag == 2 and mat[i][j] == mat[i + 1][j] == 0):
			break
		elif len(one) == 3:
			res.append(hoge(mat, one[0][0], one[0][1], one[1][0], one[1][1], one[2][0], one[2][1]))
		elif len(one) == 4:
			res.append(hoge(mat, i, j, i + 1, j, i, j + 1))
		elif len(one) == 1:
			if one[0][0] == i:
				res.append(hoge(mat, one[0][0], one[0][1], i + 1, j, i + 1, j + 1))
			else:
				res.append(hoge(mat, one[0][0], one[0][1], zero[0][0], zero[0][1], zero[1][0], zero[1][1]))
		elif len(one) == 2:
			res.append(hoge(mat, one[0][0], one[0][1], zero[0][0], zero[0][1], zero[1][0], zero[1][1]))
	return res

def main():
	t = int(input())
	ans_a = [''] * t
	for ti in range(t):
		(n, m) = map(int, input().split())
		ans = []
		matrix = [list(map(int, input().rstrip())) for _ in range(n)]
		for i in list(range(0, n - 1)):
			for j in range(0, m - 1):
				ans.extend(solve(matrix, i, j, (2 if i == n - 2 else 0) + (1 if j == m - 2 else 0)))
		assert all((sum(row) == 0 for row in matrix))
		if len(ans) > n * m:
			while True:
				...
		ans_a[ti] = f'{len(ans)}' + ('\n' + '\n'.join(ans) if ans else '')
	output(*ans_a)
main()


mod = 10 ** 9 + 7

def count(v):
	ret = 0
	for x in v:
		for val in x:
			if val == 1:
				ret += 1
	return ret

def check(v):
	cnt = count(v)
	v1 = []
	v0 = []
	for i in range(2):
		for j in range(2):
			if v[i][j] == 1:
				v1.append([i, j])
			else:
				v0.append([i, j])
	if cnt == 1:
		return v1 + v0[:2]
	elif cnt == 2:
		return v1[:1] + v0
	elif cnt == 3:
		return v1
	else:
		return v1[:3]

def solve():
	(n, m) = map(int, input().split())
	s = []
	for i in range(n):
		t = list(input())
		v = []
		for j in range(m):
			v.append(int(t[j]))
		s.append(v)
	ans = []
	for i in range(n - 2):
		for j in range(m - 2):
			if s[i][j] == 1:
				ans.append([i, j, i, j + 1, i + 1, j])
				s[i][j] = 1 - s[i][j]
				s[i][j + 1] = 1 - s[i][j + 1]
				s[i + 1][j] = 1 - s[i + 1][j]
	for i in range(n - 2):
		if s[i][m - 2] == 1 and s[i][m - 1] == 1:
			s[i][m - 2] = 0
			s[i][m - 1] = 0
			s[i + 1][m - 2] = 1 - s[i + 1][m - 2]
			ans.append([i, m - 2, i, m - 1, i + 1, m - 2])
		elif s[i][m - 2] == 1:
			s[i][m - 2] = 0
			s[i + 1][m - 2] = 1 - s[i + 1][m - 2]
			s[i + 1][m - 1] = 1 - s[i + 1][m - 1]
			ans.append([i, m - 2, i + 1, m - 2, i + 1, m - 1])
		elif s[i][m - 1] == 1:
			s[i][m - 1] = 0
			s[i + 1][m - 2] = 1 - s[i + 1][m - 2]
			s[i + 1][m - 1] = 1 - s[i + 1][m - 1]
			ans.append([i, m - 1, i + 1, m - 2, i + 1, m - 1])
	for j in range(m - 2):
		if s[n - 2][j] == 1 and s[n - 1][j] == 1:
			s[n - 2][j] = 0
			s[n - 1][j] = 0
			s[n - 2][j + 1] = 1 - s[n - 2][j + 1]
			ans.append([n - 2, j, n - 1, j, n - 2, j + 1])
		elif s[n - 2][j] == 1:
			s[n - 2][j] = 0
			s[n - 2][j + 1] = 1 - s[n - 2][j + 1]
			s[n - 1][j + 1] = 1 - s[n - 1][j + 1]
			ans.append([n - 2, j, n - 2, j + 1, n - 1, j + 1])
		elif s[n - 1][j] == 1:
			s[n - 1][j] = 0
			s[n - 2][j + 1] = 1 - s[n - 2][j + 1]
			s[n - 1][j + 1] = 1 - s[n - 1][j + 1]
			ans.append([n - 1, j, n - 2, j + 1, n - 1, j + 1])
	while s[n - 1][m - 1] + s[n - 1][m - 2] + s[n - 2][m - 1] + s[n - 2][m - 2] > 0:
		v = check([[s[n - 2][m - 2], s[n - 2][m - 1]], [s[n - 1][m - 2], s[n - 1][m - 1]]])
		for i in range(3):
			s[n - 2 + v[i][0]][m - 2 + v[i][1]] = 1 - s[n - 2 + v[i][0]][m - 2 + v[i][1]]
		ans.append([n - 2 + v[0][0], m - 2 + v[0][1], n - 2 + v[1][0], m - 2 + v[1][1], n - 2 + v[2][0], m - 2 + v[2][1]])
	print(len(ans))
	for x in ans:
		for val in x:
			print(val + 1, end=' ')
		print()
t = 1
t = int(input())
while t > 0:
	solve()
	t -= 1


from collections import defaultdict
t = int(input().strip())

def return_pos(x1, y1, x2, y2, x3, y3, x4, y4):
	return [[x1, y1, x2, y2, x3, y3], [x1, y1, x2, y2, x4, y4], [x1, y1, x3, y3, x4, y4]]
for _ in range(t):
	(n, m) = map(int, input().strip().split())
	nums = []
	for i in range(n):
		nums.append(input().strip())
	ans = []
	for i in range(n):
		for j in range(m):
			(x1, y1) = (i, j)
			if nums[i][j] == '1':
				if i >= n - 1:
					(x2, y2) = (i - 1, j)
					if j >= m - 1:
						(x3, y3) = (i - 1, j - 1)
						(x4, y4) = (i, j - 1)
					else:
						(x3, y3) = (i - 1, j + 1)
						(x4, y4) = (i, j + 1)
				elif j >= m - 1:
					(x2, y2) = (i, j - 1)
					(x3, y3) = (i + 1, j - 1)
					(x4, y4) = (i + 1, j)
				else:
					(x2, y2) = (i + 1, j)
					(x3, y3) = (i, j + 1)
					(x4, y4) = (i + 1, j + 1)
				ans.extend(return_pos(x1, y1, x2, y2, x3, y3, x4, y4))
	print(len(ans))
	for i in ans:
		print(' '.join((str(j + 1) for j in i)))


import sys

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for k in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e] * d for k in range(c)] for k in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
INF = 10 ** 19
MOD = 10 ** 9 + 7
EPS = 10 ** (-10)

def check(i, j):
	res = []
	cnt = grid[i][j] + grid[i][j + 1] + grid[i + 1][j] + grid[i + 1][j + 1]
	if cnt == 1:
		if grid[i][j]:
			res.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 1))
			res.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 2))
			res.append((i + 1, j + 1, i + 2, j + 1, i + 2, j + 2))
		elif grid[i + 1][j]:
			res.append((i + 2, j + 1, i + 1, j + 2, i + 1, j + 1))
			res.append((i + 2, j + 1, i + 1, j + 2, i + 2, j + 2))
			res.append((i + 2, j + 1, i + 1, j + 1, i + 2, j + 2))
		elif grid[i][j + 1]:
			res.append((i + 1, j + 2, i + 1, j + 1, i + 2, j + 1))
			res.append((i + 1, j + 2, i + 1, j + 1, i + 2, j + 2))
			res.append((i + 1, j + 2, i + 2, j + 1, i + 2, j + 2))
		elif grid[i + 1][j + 1]:
			res.append((i + 2, j + 2, i + 1, j + 2, i + 2, j + 1))
			res.append((i + 2, j + 2, i + 1, j + 2, i + 1, j + 1))
			res.append((i + 2, j + 2, i + 2, j + 1, i + 1, j + 1))
	elif cnt == 2:
		if grid[i][j] and grid[i + 1][j + 1]:
			res.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 1))
			res.append((i + 2, j + 2, i + 1, j + 2, i + 2, j + 1))
		elif grid[i + 1][j] and grid[i][j + 1]:
			res.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 2))
			res.append((i + 1, j + 1, i + 2, j + 1, i + 2, j + 2))
		elif grid[i][j] and grid[i + 1][j]:
			res.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 2))
			res.append((i + 2, j + 1, i + 1, j + 2, i + 2, j + 2))
		elif grid[i][j + 1] and grid[i + 1][j + 1]:
			res.append((i + 1, j + 2, i + 1, j + 1, i + 2, j + 1))
			res.append((i + 2, j + 2, i + 1, j + 1, i + 2, j + 1))
		elif grid[i][j] and grid[i][j + 1]:
			res.append((i + 1, j + 1, i + 2, j + 1, i + 2, j + 2))
			res.append((i + 1, j + 2, i + 2, j + 1, i + 2, j + 2))
		elif grid[i + 1][j] and grid[i + 1][j + 1]:
			res.append((i + 2, j + 2, i + 1, j + 2, i + 1, j + 1))
			res.append((i + 2, j + 1, i + 1, j + 2, i + 1, j + 1))
	elif cnt == 3:
		if grid[i][j] and grid[i][j + 1] and grid[i + 1][j + 1]:
			res.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 2))
		elif grid[i][j + 1] and grid[i + 1][j + 1] and grid[i + 1][j]:
			res.append((i + 1, j + 2, i + 2, j + 2, i + 2, j + 1))
		elif grid[i + 1][j + 1] and grid[i + 1][j] and grid[i][j]:
			res.append((i + 2, j + 2, i + 2, j + 1, i + 1, j + 1))
		elif grid[i + 1][j] and grid[i][j] and grid[i][j + 1]:
			res.append((i + 2, j + 1, i + 1, j + 1, i + 1, j + 2))
	elif cnt == 4:
		res.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 1))
		res.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 2))
		res.append((i + 1, j + 1, i + 2, j + 1, i + 2, j + 2))
		res.append((i + 1, j + 2, i + 2, j + 1, i + 2, j + 2))
	grid[i][j] = grid[i][j + 1] = grid[i + 1][j] = grid[i + 1][j + 1] = 0
	return res

def checkh(i, j):
	res = []
	if grid[i][j] and grid[i + 1][j]:
		res.append((i + 1, j + 1, i + 1, j + 0, i + 2, j + 0))
		res.append((i + 2, j + 1, i + 1, j + 0, i + 2, j + 0))
	elif grid[i][j]:
		res.append((i + 1, j + 1, i + 1, j + 0, i + 2, j + 0))
		grid[i][j - 1] ^= 1
		grid[i + 1][j - 1] ^= 1
	elif grid[i + 1][j]:
		res.append((i + 2, j + 1, i + 1, j + 0, i + 2, j + 0))
		grid[i][j - 1] ^= 1
		grid[i + 1][j - 1] ^= 1
	grid[i][j] = grid[i + 1][j] = 0
	return res

def checkw(i, j):
	res = []
	if grid[i][j] and grid[i][j + 1]:
		res.append((i + 1, j + 1, i + 0, j + 1, i + 0, j + 2))
		res.append((i + 1, j + 2, i + 0, j + 1, i + 0, j + 2))
	elif grid[i][j]:
		res.append((i + 1, j + 1, i + 0, j + 1, i + 0, j + 2))
		grid[i - 1][j] ^= 1
		grid[i - 1][j + 1] ^= 1
	elif grid[i][j + 1]:
		res.append((i + 1, j + 2, i + 0, j + 1, i + 0, j + 2))
		grid[i - 1][j] ^= 1
		grid[i - 1][j + 1] ^= 1
	grid[i][j] = grid[i][j + 1] = 0
	return res
for _ in range(INT()):
	(H, W) = MAP()
	grid = [[]] * H
	for i in range(H):
		grid[i] = list(map(int, input()))
	ans = []
	if H % 2 == 1:
		for j in range(W - 1):
			ans += checkw(H - 1, j)
	if W % 2 == 1:
		for i in range(H - 1):
			ans += checkh(i, W - 1)
	for i in range(0, H - H % 2, 2):
		for j in range(0, W - W % 2, 2):
			ans += check(i, j)
	print(len(ans))
	for a in ans:
		print(*a)


for _ in range(int(input())):
	(n, m) = [int(x) for x in input().split(' ')]
	a = []
	for i in range(n):
		ls = [int(x) for x in input()]
		a.append(list(ls))
	anss = []
	b1 = n % 2 == 0
	b2 = m % 2 == 0

	def flip(i, j):
		global a
		a[i][j] = 1 - a[i][j]

	def L0(i, j):
		global anss
		global a
		anss.append((i, j, i + 1, j, i, j + 1))

	def L1(i, j):
		global anss
		global a
		anss.append((i, j, i + 1, j + 1, i, j + 1))

	def L2(i, j):
		global anss
		global a
		anss.append((i + 1, j + 1, i + 1, j, i, j + 1))

	def L3(i, j):
		global anss
		global a
		anss.append((i, j, i + 1, j, i + 1, j + 1))

	def solve11(i, j):
		global a
		global anss
		if a[i][j]:
			anss.append((i, j, i, j + 1, i + 1, j))
			flip(i, j)
			flip(i, j + 1)
			flip(i + 1, j)
		return

	def solve12(i, j):
		global anss
		global a
		if a[i][j] and a[i][j + 1]:
			anss.append((i, j, i, j + 1, i + 1, j))
			flip(i, j)
			flip(i, j + 1)
			flip(i + 1, j)
		elif a[i][j]:
			anss.append((i, j, i + 1, j, i + 1, j + 1))
			flip(i, j)
			flip(i + 1, j)
			flip(i + 1, j + 1)
		elif a[i][j + 1]:
			anss.append((i, j + 1, i + 1, j, i + 1, j + 1))
			flip(i, j + 1)
			flip(i + 1, j)
			flip(i + 1, j + 1)
		else:
			pass
		return

	def solve21(i, j):
		global anss
		global a
		if a[i][j] and a[i + 1][j]:
			anss.append((i, j, i + 1, j, i + 1, j + 1))
			flip(i, j)
			flip(i + 1, j)
			flip(i + 1, j + 1)
		elif a[i][j]:
			anss.append((i, j, i, j + 1, i + 1, j + 1))
			flip(i, j)
			flip(i, j + 1)
			flip(i + 1, j + 1)
		elif a[i + 1][j]:
			anss.append((i + 1, j, i + 1, j + 1, i, j + 1))
			flip(i + 1, j)
			flip(i + 1, j + 1)
			flip(i, j + 1)
		else:
			pass
		return

	def solve22(i, j):
		cnt = a[i][j] + a[i + 1][j] + a[i][j + 1] + a[i + 1][j + 1]
		if cnt == 0:
			pass
		elif cnt == 1:
			if a[i][j] == 1:
				L0(i, j)
				L1(i, j)
				L3(i, j)
			elif a[i + 1][j] == 1:
				L0(i, j)
				L2(i, j)
				L3(i, j)
			elif a[i][j + 1] == 1:
				L0(i, j)
				L1(i, j)
				L2(i, j)
			elif a[i + 1][j + 1] == 1:
				L1(i, j)
				L2(i, j)
				L3(i, j)
			else:
				assert 0
		elif cnt == 2:
			crossSum = max(a[i][j] + a[i + 1][j + 1], a[i + 1][j] + a[i][j + 1])
			if crossSum == 1:
				if a[i][j] == 0:
					L0(i, j)
				if a[i + 1][j] == 0:
					L3(i, j)
				if a[i][j + 1] == 0:
					L1(i, j)
				if a[i + 1][j + 1] == 0:
					L2(i, j)
			elif crossSum == 2:
				if a[i][j] == 1:
					L0(i, j)
				if a[i + 1][j] == 1:
					L3(i, j)
				if a[i][j + 1] == 1:
					L1(i, j)
				if a[i + 1][j + 1] == 1:
					L2(i, j)
			else:
				assert 0
		elif cnt == 3:
			if a[i][j] == 0:
				L2(i, j)
			elif a[i + 1][j] == 0:
				L1(i, j)
			elif a[i][j + 1] == 0:
				L3(i, j)
			elif a[i + 1][j + 1] == 0:
				L0(i, j)
			else:
				assert 0
		else:
			L0(i, j)
			L1(i, j)
			L2(i, j)
			L3(i, j)
		a[i][j] = 0
		a[i + 1][j] = 0
		a[i][j + 1] = 0
		a[i + 1][j + 1] = 0
		return
	if b1 and b2:
		i = 0
		while i < len(a) - 2:
			j = 0
			while j < len(a[0]):
				solve12(i, j)
				j += 2
			i += 1
		j = 0
		while j < len(a[0]):
			solve22(i, j)
			j += 2
	elif b1:
		j = 0
		while j < len(a[0]) - 2:
			i = 0
			while i < len(a):
				solve21(i, j)
				i += 2
			j += 1
		i = 0
		while i < len(a):
			solve22(i, j)
			i += 2
	elif b2:
		i = 0
		while i < len(a) - 2:
			j = 0
			while j < len(a[0]):
				solve12(i, j)
				j += 2
			i += 1
		j = 0
		while j < len(a[0]):
			solve22(i, j)
			j += 2
	else:
		i = 0
		while i < len(a) - 2:
			solve11(i, 0)
			j = 1
			while j < len(a[0]):
				solve12(i, j)
				j += 2
			i += 1
		j = 0
		while j < len(a[0]) - 2:
			solve21(i, j)
			j += 1
		solve22(i, j)
	print(len(anss))
	for x in anss:
		for y in x:
			print(int(y) + 1, end=' ')
		print()


import bisect
import collections
import copy
import functools
import heapq
import itertools
import math
import sys
import string
import random
from typing import List
sys.setrecursionlimit(99999)
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	arr = []
	for _ in range(n):
		arr.append(list(map(int, list(input()))))
	ans = []

	def add(x1, y1, x2, y2, x3, y3):
		ans.append([x1 + 1, y1 + 1, x2 + 1, y2 + 1, x3 + 1, y3 + 1])
		arr[x1][y1] ^= 1
		arr[x2][y2] ^= 1
		arr[x3][y3] ^= 1
	for i in range(n - 1, 1, -1):
		for j in range(m):
			if arr[i][j] == 1:
				if j < m - 1 and arr[i][j + 1] == 1:
					if arr[i - 1][j] == 1:
						add(i, j, i, j + 1, i - 1, j)
					else:
						add(i, j, i, j + 1, i - 1, j + 1)
				else:
					nj = j + 1 if j < m - 1 else j - 1
					add(i, j, i - 1, j, i - 1, nj)
	for j in range(m - 1, 1, -1):
		if arr[0][j] == 1 and arr[1][j] == 1:
			add(0, j, 1, j, 0, j - 1)
		elif arr[0][j] == 1:
			add(0, j, 0, j - 1, 1, j - 1)
		elif arr[1][j] == 1:
			add(1, j, 0, j - 1, 1, j - 1)
	while sum(arr[0][:2] + arr[1][:2]) != 0:
		if sum(arr[0][:2] + arr[1][:2]) in (3, 4):
			ps = []
			for i in range(2):
				for j in range(2):
					if arr[i][j] == 1:
						ps.append(i)
						ps.append(j)
			add(*ps[:6])
		elif sum(arr[0][:2] + arr[1][:2]) in (1, 2):
			ps1 = []
			ps0 = []
			for i in range(2):
				for j in range(2):
					if arr[i][j] == 1:
						ps1.append(i)
						ps1.append(j)
					else:
						ps0.append(i)
						ps0.append(j)
			add(*ps1[:2] + ps0[:4])
	print(len(ans))
	for i in range(len(ans)):
		print(*ans[i])


t = int(input())

def solve3(zeroes, ones, moves):
	p1 = ones.pop()
	p2 = ones.pop()
	p3 = ones.pop()
	moves.append([p1, p2, p3])

def solve2(zeroes, ones, moves):
	(p1, p2, p3) = (ones.pop(), zeroes.pop(), zeroes.pop())
	moves.append([p1, p2, p3])
	zeroes.append(p1)
	ones.append(p2)
	ones.append(p3)
	solve3(zeroes, ones, moves)

def solve1(zeroes, ones, moves):
	(p1, p2, p3) = (ones.pop(), zeroes.pop(), zeroes.pop())
	moves.append([p1, p2, p3])
	zeroes.append(p1)
	ones.append(p2)
	ones.append(p3)
	solve2(zeroes, ones, moves)

def solve4(zeroes, ones, moves):
	(p1, p2, p3) = (ones.pop(), ones.pop(), ones.pop())
	moves.append([p1, p2, p3])
	zeroes.append(p1)
	zeroes.append(p2)
	zeroes.append(p3)
	solve1(zeroes, ones, moves)

def solve(n, m, grid):
	moves = []
	for i in range(n - 1):
		for j in range(m - 1):
			zeroes = []
			ones = []
			if grid[i][j] == 0:
				zeroes.append((i, j))
			else:
				ones.append((i, j))
			if grid[i + 1][j] == 0:
				zeroes.append((i + 1, j))
			else:
				ones.append((i + 1, j))
			if grid[i][j + 1] == 0:
				zeroes.append((i, j + 1))
			else:
				ones.append((i, j + 1))
			if grid[i + 1][j + 1] == 0:
				zeroes.append((i + 1, j + 1))
			else:
				ones.append((i + 1, j + 1))
			if len(ones) == 0:
				continue
			if len(ones) == 1:
				solve1(zeroes, ones, moves)
			elif len(ones) == 2:
				solve2(zeroes, ones, moves)
			elif len(ones) == 3:
				solve3(zeroes, ones, moves)
			elif len(ones) == 4:
				solve4(zeroes, ones, moves)
			grid[i][j] = 0
			grid[i + 1][j] = 0
			grid[i][j + 1] = 0
			grid[i + 1][j + 1] = 0
	print(len(moves))
	for move in moves:
		m = []
		for (x, y) in move:
			m.append(str(x + 1))
			m.append(str(y + 1))
		print(' '.join(m))
for _ in range(t):
	(n, m) = list(map(int, input().split()))
	grid = []
	for __ in range(n):
		grid.append(list(map(int, input())))
	solve(n, m, grid)


for _ in range(int(input())):
	(n, m) = map(int, input().split(' '))
	a = [list(map(int, list(input()))) for x in range(n)]
	ans = []

	def getone(arr):
		for xx in range(2):
			for yy in range(2):
				if arr[xx][yy] == 1:
					return (xx, yy)

	def getzero(arr):
		for xx in range(2):
			for yy in range(2):
				if arr[xx][yy] == 0:
					return (xx, yy)
	for x in range(n):
		for y in range(m):
			if x + 1 < n and y + 1 < m:
				temp = list([a[x][y:y + 2], a[x + 1][y:y + 2]])
				sm = 0
				for xxx in temp:
					sm = sm + sum(xxx)
				if sm == 0:
					continue
				if sm == 1:
					(xx, yy) = getone(temp)
					ans.append([x + 1 + xx, y + 1 + yy])
					ans.append([x + 1 + (xx + 1) % 2, y + 1 + yy])
					ans.append([x + 1 + xx, y + 1 + (yy + 1) % 2])
					tempx = xx
					xx = (xx + 1) % 2
					ans.append([x + 1 + xx, y + 1 + yy])
					ans.append([x + 1 + (xx + 1) % 2, y + 1 + yy])
					ans.append([x + 1 + xx, y + 1 + (yy + 1) % 2])
					yy = (yy + 1) % 2
					xx = (xx + 1) % 2
					ans.append([x + 1 + xx, y + 1 + yy])
					ans.append([x + 1 + (xx + 1) % 2, y + 1 + yy])
					ans.append([x + 1 + xx, y + 1 + (yy + 1) % 2])
					a[x][y] = 0
					a[x + 1][y] = 0
					a[x][y + 1] = 0
					a[x + 1][y + 1] = 0
				elif sm == 3:
					for xx in range(2):
						for yy in range(2):
							if temp[xx][yy] == 1:
								ans.append([x + 1 + xx, y + 1 + yy])
					a[x][y] = 0
					a[x + 1][y] = 0
					a[x][y + 1] = 0
					a[x + 1][y + 1] = 0
				elif sm == 4:
					for xx in range(2):
						for yy in range(2):
							if temp[xx][yy] == 1:
								ans.append([x + 1 + xx, y + 1 + yy])
					ans.pop()
					(xx, yy) = (1, 1)
					ans.append([x + 1 + xx, y + 1 + yy])
					ans.append([x + 1 + (xx + 1) % 2, y + 1 + yy])
					ans.append([x + 1 + xx, y + 1 + (yy + 1) % 2])
					tempx = xx
					xx = (xx + 1) % 2
					ans.append([x + 1 + xx, y + 1 + yy])
					ans.append([x + 1 + (xx + 1) % 2, y + 1 + yy])
					ans.append([x + 1 + xx, y + 1 + (yy + 1) % 2])
					yy = (yy + 1) % 2
					xx = (xx + 1) % 2
					ans.append([x + 1 + xx, y + 1 + yy])
					ans.append([x + 1 + (xx + 1) % 2, y + 1 + yy])
					ans.append([x + 1 + xx, y + 1 + (yy + 1) % 2])
					a[x][y] = 0
					a[x + 1][y] = 0
					a[x][y + 1] = 0
					a[x + 1][y + 1] = 0
				elif sm == 2:
					for xx in range(2):
						for yy in range(2):
							if temp[xx][yy] == 1:
								ans.append([x + 1 + xx, y + 1 + yy])
					(xx, yy) = getzero(temp)
					ans.append([x + 1 + xx, y + 1 + yy])
					ans.append([x + 1 + xx, y + 1 + yy])
					ans.append([x + 1 + (xx + 1) % 2, y + 1 + yy])
					ans.append([x + 1 + xx, y + 1 + (yy + 1) % 2])
					tempx = xx
					xx = (xx + 1) % 2
					ans.append([x + 1 + xx, y + 1 + yy])
					ans.append([x + 1 + (xx + 1) % 2, y + 1 + yy])
					ans.append([x + 1 + xx, y + 1 + (yy + 1) % 2])
					yy = (yy + 1) % 2
					xx = (xx + 1) % 2
					ans.append([x + 1 + xx, y + 1 + yy])
					ans.append([x + 1 + (xx + 1) % 2, y + 1 + yy])
					ans.append([x + 1 + xx, y + 1 + (yy + 1) % 2])
					a[x][y] = 0
					a[x + 1][y] = 0
					a[x][y + 1] = 0
					a[x + 1][y + 1] = 0
	print(len(ans) // 3)
	cnt = 0
	for x in range(len(ans)):
		print(*ans[x], end=' ')
		cnt += 1
		if cnt == 3:
			print()
			cnt = 0


from sys import stdin, stdout
import math, bisect
from collections import Counter, deque, defaultdict
L = lambda : list(map(int, stdin.readline().strip().split()))
M = lambda : map(int, stdin.readline().strip().split())
I = lambda : int(stdin.readline().strip())
S = lambda : stdin.readline().strip()
C = lambda : stdin.readline().strip().split()

def pr(a):
	print(' '.join(list(map(str, a))))

def solve():
	(n, m) = M()
	a = [S() for i in range(n)]
	b = []
	ans = []
	for i in range(n):
		x = []
		for j in range(m):
			if a[i][j] == '1':
				x += [1]
			else:
				x += [0]
		b += [x]
	for i in range(n - 1):
		for j in range(m - 1):
			if b[i][j] == 1:
				b[i][j] = 0
				b[i + 1][j] ^= 1
				b[i][j + 1] ^= 1
				ans += [[i + 1, j + 1, i + 2, j + 1, i + 1, j + 2]]
	for i in range(m - 1):
		if b[-1][i] == 1:
			b[-1][i] = 0
			b[-1][i + 1] ^= 1
			ans += [[n - 1, i + 2, n - 1, i + 1, n, i + 1]]
			ans += [[n - 1, i + 2, n - 1, i + 1, n, i + 2]]
	for i in range(n - 1):
		if b[i][-1] == 1:
			b[i][-1] = 0
			b[i + 1][-1] ^= 1
			ans += [[i + 2, m - 1, i + 1, m - 1, i + 1, m]]
			ans += [[i + 2, m - 1, i + 1, m - 1, i + 2, m]]
	if b[-1][-1] == 1:
		ans += [[n, m, n - 1, m, n, m - 1]]
		ans += [[n, m, n - 1, m - 1, n, m - 1]]
		ans += [[n, m, n - 1, m - 1, n - 1, m]]
	print(len(ans))
	for i in ans:
		pr(i)
for _ in range(I()):
	solve()


from sys import stdin, stdout
t = int(stdin.readline())

def flip(c):
	if c == '0':
		return '1'
	else:
		return '0'
lookup = {(0, 0, 0, 0): 'NIL', (0, 0, 0, 1): (['1', '1', '1', '2', '2', '2'], (1, 1, 0, 0)), (0, 0, 1, 0): (['1', '2', '2', '1', '2', '2'], (0, 1, 0, 1)), (0, 0, 1, 1): (['1', '1', '1', '2', '2', '2'], (1, 1, 1, 0)), (0, 1, 0, 0): (['1', '1', '1', '2', '2', '1'], (1, 0, 1, 0)), (0, 1, 0, 1): (['1', '1', '1', '2', '2', '1'], (1, 0, 1, 1)), (0, 1, 1, 0): (['1', '1', '1', '2', '2', '1'], (1, 0, 0, 0)), (0, 1, 1, 1): (['2', '1', '1', '2', '2', '2'], (0, 0, 0, 0)), (1, 0, 0, 0): (['1', '1', '2', '1', '2', '2'], (0, 0, 1, 1)), (1, 0, 0, 1): (['1', '1', '1', '2', '2', '2'], (0, 1, 0, 0)), (1, 0, 1, 0): (['1', '2', '2', '1', '2', '2'], (1, 1, 0, 1)), (1, 0, 1, 1): (['1', '1', '2', '1', '2', '2'], (0, 0, 0, 0)), (1, 1, 0, 0): (['1', '1', '2', '1', '2', '2'], (0, 1, 1, 1)), (1, 1, 0, 1): (['1', '1', '1', '2', '2', '2'], (0, 0, 0, 0)), (1, 1, 1, 0): (['1', '1', '1', '2', '2', '1'], (0, 0, 0, 0)), (1, 1, 1, 1): (['1', '1', '1', '2', '2', '1'], (0, 0, 0, 1))}
for _ in range(t):
	(n, m) = [int(x) for x in stdin.readline().split()]
	table = []
	for foo in range(n):
		table.append([c for c in stdin.readline().strip()])
	answer = []
	for i in range(n - 1, 1, -1):
		for j in range(m):
			if j == 0:
				if table[i][j] == '1':
					answer.append([str(i + 1), str(j + 1), str(i), str(j + 1), str(i), str(j + 2)])
					table[i - 1][j] = flip(table[i - 1][j])
					table[i - 1][j + 1] = flip(table[i - 1][j + 1])
			elif table[i][j] == '1':
				answer.append([str(i + 1), str(j + 1), str(i), str(j + 1), str(i), str(j)])
				table[i - 1][j] = flip(table[i - 1][j])
				table[i - 1][j - 1] = flip(table[i - 1][j - 1])
	for j in range(m - 1, 1, -1):
		if table[0][j] == '1':
			answer.append(['1', str(j + 1), '1', str(j), '2', str(j)])
			table[0][j - 1] = flip(table[0][j - 1])
			table[1][j - 1] = flip(table[1][j - 1])
		if table[1][j] == '1':
			answer.append(['2', str(j + 1), '1', str(j), '2', str(j)])
			table[0][j - 1] = flip(table[0][j - 1])
			table[1][j - 1] = flip(table[1][j - 1])
	current = (int(table[0][0]), int(table[0][1]), int(table[1][0]), int(table[1][1]))
	while lookup[current] != 'NIL':
		answer.append(lookup[current][0])
		current = lookup[current][1]
	stdout.write(str(len(answer)) + '\n')
	for a in answer:
		stdout.write(' '.join(a) + '\n')


from sys import stdin, stdout

def solve(x, y):
	c = 0
	for i in range(x, x + 2):
		for j in range(y, y + 2):
			if s[i][j] == '1':
				c += 1
	if c == 0:
		return 1
	if c == 4 or c == 3:
		aux = []
		z = 0
		for i in range(x, x + 2):
			for j in range(y, y + 2):
				if s[i][j] == '1' and z <= 2:
					aux.append(i + 1)
					aux.append(j + 1)
					s[i][j] = '0'
					z += 1
		ans.append(aux.copy())
		return 0
	if c == 1 or c == 2:
		y1 = 0
		z = 0
		aux = []
		for i in range(x, x + 2):
			for j in range(y, y + 2):
				if s[i][j] == '1' and y1 == 0:
					aux.append(i + 1)
					aux.append(j + 1)
					s[i][j] = '0'
					y1 += 1
					continue
				if s[i][j] == '0' and z <= 1:
					aux.append(i + 1)
					aux.append(j + 1)
					s[i][j] = '1'
					z += 1
					continue
		ans.append(aux.copy())
		return 0

def clean1(x, y):
	if x + 1 == n:
		return 0
	c = 0
	aux = []
	if s[x][y + 1] == '1':
		aux.append(x + 1)
		aux.append(y + 2)
		s[x][y + 1] = '0'
		c += 1
	if s[x + 1][y + 1] == '1':
		aux.append(x + 2)
		aux.append(y + 2)
		s[x + 1][y + 1] = '0'
		c += 1
	if c == 0:
		return
	if c <= 2:
		aux.append(x + 2)
		aux.append(y + 1)
		if s[x + 1][y] == '1':
			s[x + 1][y] = '0'
		else:
			s[x + 1][y] = '1'
	if c <= 1:
		aux.append(x + 1)
		aux.append(y + 1)
		if s[x][y] == '1':
			s[x][y] = '0'
		else:
			s[x][y] = '1'
	ans.append(aux.copy())

def clean2(x, y):
	if y + 1 == m:
		return 0
	c = 0
	aux = []
	if s[x + 1][y] == '1':
		aux.append(x + 2)
		aux.append(y + 1)
		s[x + 1][y] = '0'
		c += 1
	if s[x + 1][y + 1] == '1':
		aux.append(x + 2)
		aux.append(y + 2)
		s[x + 1][y + 1] = '0'
		c += 1
	if c == 0:
		return
	if c <= 2:
		aux.append(x + 1)
		aux.append(y + 1)
		if s[x][y] == '1':
			s[x][y] = '0'
		else:
			s[x][y] = '1'
	if c <= 1:
		aux.append(x + 1)
		aux.append(y + 2)
		if s[x][y + 1] == '1':
			s[x][y + 1] = '0'
		else:
			s[x][y + 1] = '1'
	ans.append(aux.copy())
T = int(stdin.readline().strip())
for caso in range(T):
	(n, m) = map(int, stdin.readline().strip().split())
	s = [list(stdin.readline().strip()) for i in range(n)]
	ans = []
	x = n - 2
	y = m - 2
	if n % 2 != 0 and m % 2 != 0:
		q = solve(x, y)
		while q != 1:
			q = solve(x, y)
	x = n - 2
	y = m - 2
	if m % 2 != 0:
		for i in range(0, n, 2):
			clean1(i, m - 2)
	if n % 2 != 0:
		for i in range(0, m, 2):
			clean2(n - 2, i)
	for i in range(0, n - 1, 2):
		for j in range(0, m - 1, 2):
			x = solve(i, j)
			while x != 1:
				x = solve(i, j)
	stdout.write('%d\n' % len(ans))
	for i in ans:
		stdout.write('%d %d %d %d %d %d\n' % (i[0], i[1], i[2], i[3], i[4], i[5]))


from sys import stdin, stdout

def INI():
	return int(stdin.readline())

def INL():
	return [int(_) for _ in stdin.readline().split()]

def INS():
	return stdin.readline()

def MOD():
	return pow(10, 9) + 7

def OPS(ans):
	stdout.write(str(ans) + '\n')

def OPL(ans):
	[stdout.write(str(_) + ' ') for _ in ans]
	stdout.write('\n')

def one():
	if T[0] == '1':
		ANS.extend([I[0], I[1], I[2]])
		ANS.extend([I[0], I[2], I[3]])
		ANS.extend([I[0], I[1], I[3]])
	elif T[1] == '1':
		ANS.extend([I[0], I[1], I[2]])
		ANS.extend([I[2], I[1], I[3]])
		ANS.extend([I[3], I[1], I[0]])
	elif T[2] == '1':
		ANS.extend([I[0], I[2], I[1]])
		ANS.extend([I[1], I[2], I[3]])
		ANS.extend([I[3], I[2], I[0]])
	else:
		ANS.extend([I[0], I[3], I[1]])
		ANS.extend([I[1], I[3], I[2]])
		ANS.extend([I[2], I[3], I[0]])

def two():
	if T[0] == '1' and T[1] == '1':
		ANS.extend([I[0], I[2], I[3]])
		ANS.extend([I[1], I[2], I[3]])
	elif T[0] == '1' and T[2] == '1':
		ANS.extend([I[0], I[1], I[3]])
		ANS.extend([I[2], I[1], I[3]])
	elif T[0] == '1' and T[3] == '1':
		ANS.extend([I[0], I[1], I[2]])
		ANS.extend([I[3], I[1], I[2]])
	elif T[1] == '1' and T[2] == '1':
		ANS.extend([I[1], I[0], I[3]])
		ANS.extend([I[2], I[0], I[3]])
	elif T[1] == '1' and T[3] == '1':
		ANS.extend([I[1], I[0], I[2]])
		ANS.extend([I[3], I[0], I[2]])
	elif T[2] == '1' and T[3] == '1':
		ANS.extend([I[2], I[0], I[1]])
		ANS.extend([I[3], I[0], I[1]])

def three():
	if T[0] == '0':
		ANS.extend([I[1], I[2], I[3]])
	elif T[1] == '0':
		ANS.extend([I[0], I[2], I[3]])
	elif T[2] == '0':
		ANS.extend([I[0], I[1], I[3]])
	else:
		ANS.extend([I[0], I[1], I[2]])

def four():
	ANS.extend([I[1], I[2], I[3]])
	ANS.extend([I[0], I[1], I[2]])
	ANS.extend([I[0], I[2], I[3]])
	ANS.extend([I[0], I[1], I[3]])
for _ in range(INI()):
	(n, m) = INL()
	X = []
	for _ in range(n):
		x = input()
		X.append(list(x))
	ANS = []
	ans = 0
	for _ in range(n - 1):
		for __ in range(m - 1):
			T = [X[_][__], X[_][__ + 1], X[_ + 1][__], X[_ + 1][__ + 1]]
			I = [[_, __], [_, __ + 1], [_ + 1, __], [_ + 1, __ + 1]]
			if T.count('1') == 1:
				one()
			elif T.count('1') == 2:
				two()
			elif T.count('1') == 3:
				three()
			elif T.count('1') == 4:
				four()
			for i in I:
				X[i[0]][i[1]] = '0'
	ans = (len(ANS) + 2) // 3
	print(ans)
	for _ in range(0, len(ANS), 3):
		for __ in range(3):
			print(ANS[_ + __][0] + 1, ANS[_ + __][1] + 1, end=' ')
		print()


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	(cnt, A) = (0, [])
	for i in range(n):
		A.append(input())
		cnt += A[i].count('1')
	print(3 * cnt)
	for i in range(n):
		for j in range(m):
			if A[i][j] == '1':
				(x, y) = (1, 1)
				if i == n - 1:
					x = -1
				if j == m - 1:
					y = -1
				print(i + 1, j + 1, i + x + 1, j + 1, i + 1, j + y + 1)
				print(i + 1, j + 1, i + x + 1, j + y + 1, i + 1, j + y + 1)
				print(i + 1, j + 1, i + x + 1, j + 1, i + x + 1, j + y + 1)


def multiLineArrayOfArraysPrint(arr):
	print('\n'.join([' '.join([str(x) for x in y]) for y in arr]))

def fix2by2(x, y):
	cnt = 0
	for i in range(x, x + 2):
		for j in range(y, y + 2):
			if arr[i][j] == 1:
				cnt += 1
	if cnt == 0:
		return []
	if cnt == 1:
		return fixOne(x, y)
	if cnt == 2:
		return fixTwo(x, y)
	if cnt == 3:
		return fixThree(x, y)
	if cnt == 4:
		return fixFour(x, y)

def getOneTwoThreeFour(x, y):
	blx = x + 1
	bly = y + 1
	one = [blx + 1, bly, blx, bly, blx, bly + 1]
	two = [blx, bly, blx, bly + 1, blx + 1, bly + 1]
	three = [blx, bly + 1, blx + 1, bly + 1, blx + 1, bly]
	four = [blx, bly, blx + 1, bly, blx + 1, bly + 1]
	return [one, two, three, four]

def fixOne(x, y):
	(one, two, three, four) = getOneTwoThreeFour(x, y)
	if arr[x][y] == 1:
		return [one, two, four]
	if arr[x + 1][y] == 1:
		return [one, three, four]
	if arr[x + 1][y + 1] == 1:
		return [two, three, four]
	if arr[x][y + 1] == 1:
		return [one, two, three]

def fixTwo(x, y):
	(one, two, three, four) = getOneTwoThreeFour(x, y)
	if arr[x][y] == arr[x][y + 1] == 1:
		return [three, four]
	if arr[x][y] == arr[x + 1][y] == 1:
		return [two, three]
	if arr[x][y] == arr[x + 1][y + 1] == 1:
		return [one, three]
	if arr[x + 1][y] == arr[x + 1][y + 1] == 1:
		return [one, two]
	if arr[x][y + 1] == arr[x + 1][y + 1] == 1:
		return [one, four]
	if arr[x + 1][y] == arr[x][y + 1] == 1:
		return [two, four]

def fixThree(x, y):
	(one, two, three, four) = getOneTwoThreeFour(x, y)
	if arr[x][y] == 0:
		return [three]
	if arr[x + 1][y] == 0:
		return [two]
	if arr[x][y + 1] == 0:
		return [four]
	if arr[x + 1][y + 1] == 0:
		return [one]

def fixFour(x, y):
	(one, two, three, four) = getOneTwoThreeFour(x, y)
	return [one, two, three, four]
import sys
input = lambda : sys.stdin.readline().rstrip('\r\n')
t = int(input())
for _ in range(t):
	(n, m) = [int(x) for x in input().split()]
	arr = []
	for _ in range(n):
		arr.append([int(x) for x in list(input())])
	ans = []
	starti = 0 if n % 2 == 0 else 1
	startj = 0 if m % 2 == 0 else 1
	if n % 2 == 1 and m % 2 == 1:
		starti = 1
		startj = 1
		if arr[0][0] == 1:
			ans.append([1, 1, 1, 2, 2, 1])
			arr[0][0] = 0
			arr[0][1] = 1 - arr[0][1]
			arr[1][0] = 1 - arr[1][0]
	if n % 2 == 1:
		i = 0
		for j in range(startj, m):
			if arr[i][j] == 1:
				if j == 0:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					arr[i][j] = 0
					arr[i + 1][j] = 1 - arr[i + 1][j]
					arr[i + 1][j + 1] = 1 - arr[i + 1][j + 1]
				else:
					ans.append([i + 1, j + 1, i + 2, j, i + 2, j + 1])
					arr[i][j] = 0
					arr[i + 1][j] = 1 - arr[i + 1][j]
					arr[i + 1][j - 1] = 1 - arr[i + 1][j - 1]
	if m % 2 == 1:
		j = 0
		for i in range(starti, n):
			if arr[i][j] == 1:
				if i != n - 1:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					arr[i][j] = 0
					arr[i][j + 1] = 1 - arr[i][j + 1]
					arr[i + 1][j + 1] = 1 - arr[i + 1][j + 1]
				else:
					ans.append([i + 1, j + 1, i + 1, j + 2, i, j + 2])
					arr[i][j] = 0
					arr[i][j + 1] = 1 - arr[i][j + 1]
					arr[i - 1][j + 1] = 1 - arr[i - 1][j + 1]
	for i in range(starti, n, 2):
		for j in range(startj, m, 2):
			for res in fix2by2(i, j):
				ans.append(res)
	print(len(ans))
	multiLineArrayOfArraysPrint(ans)


t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	S = []
	for i in range(n):
		s = list(str(input()))
		s = [int(i) for i in s]
		S.append(s)
	ans = []
	for i in range(n - 1):
		for j in range(m - 1):
			X0 = []
			X1 = []
			if S[i][j] == 0:
				X0.append((i + 1, j + 1))
			else:
				X1.append((i + 1, j + 1))
			if S[i + 1][j] == 0:
				X0.append((i + 2, j + 1))
			else:
				X1.append((i + 2, j + 1))
			if S[i][j + 1] == 0:
				X0.append((i + 1, j + 2))
			else:
				X1.append((i + 1, j + 2))
			if S[i + 1][j + 1] == 0:
				X0.append((i + 2, j + 2))
			else:
				X1.append((i + 2, j + 2))
			if len(X1) == 1:
				temp = list(X0[0]) + list(X0[1]) + list(X1[0])
				ans.append(temp)
				temp = list(X0[0]) + list(X0[2]) + list(X1[0])
				ans.append(temp)
				temp = list(X0[1]) + list(X0[2]) + list(X1[0])
				ans.append(temp)
			elif len(X1) == 2:
				temp = list(X0[0]) + list(X0[1]) + list(X1[0])
				ans.append(temp)
				temp = list(X0[0]) + list(X0[1]) + list(X1[1])
				ans.append(temp)
			elif len(X1) == 3:
				temp = list(X1[0]) + list(X1[1]) + list(X1[2])
				ans.append(temp)
			elif len(X1) == 4:
				temp = list(X1[1]) + list(X1[2]) + list(X1[3])
				ans.append(temp)
				temp = list(X1[0]) + list(X1[1]) + list(X1[2])
				ans.append(temp)
				temp = list(X1[0]) + list(X1[1]) + list(X1[3])
				ans.append(temp)
				temp = list(X1[0]) + list(X1[2]) + list(X1[3])
				ans.append(temp)
			else:
				pass
			S[i][j] = 0
			S[i + 1][j] = 0
			S[i][j + 1] = 0
			S[i + 1][j + 1] = 0
	print(len(ans))
	for i in range(len(ans)):
		print(*ans[i])


t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	table = [list(input()) for row in range(n)]
	operations = []

	def make_op(x1, y1, x2, y2, x3, y3):
		if table[x1][y1] == '1':
			table[x1][y1] = '0'
		else:
			table[x1][y1] = '1'
		if table[x2][y2] == '1':
			table[x2][y2] = '0'
		else:
			table[x2][y2] = '1'
		if table[x3][y3] == '1':
			table[x3][y3] = '0'
		else:
			table[x3][y3] = '1'
		operations.append([x1 + 1, y1 + 1, x2 + 1, y2 + 1, x3 + 1, y3 + 1])
	if n != 2:
		for i in range(n - 2):
			for j in range(0, m, 2):
				if j == m - 1:
					if table[i][j] == '1':
						make_op(i, j, i + 1, j, i + 1, j - 1)
				elif table[i][j] == '1':
					if table[i][j + 1] == '1':
						make_op(i, j, i, j + 1, i + 1, j + 1)
					else:
						make_op(i, j, i + 1, j, i + 1, j + 1)
				elif table[i][j + 1] == '1':
					make_op(i, j + 1, i + 1, j, i + 1, j + 1)
	if m != 1:
		for i in range(m - 1):
			if table[n - 2][i] == '1':
				if table[n - 1][i] == '1':
					make_op(n - 2, i, n - 1, i, n - 2, i + 1)
				else:
					make_op(n - 2, i, n - 2, i + 1, n - 1, i + 1)
			elif table[n - 1][i] == '1':
				make_op(n - 1, i, n - 2, i + 1, n - 1, i + 1)
	square1 = table[n - 2][m - 1] == '1'
	square2 = table[n - 1][m - 1] == '1'
	if square1:
		if square2:
			make_op(n - 2, m - 2, n - 1, m - 2, n - 2, m - 1)
			make_op(n - 2, m - 2, n - 1, m - 2, n - 1, m - 1)
		else:
			make_op(n - 2, m - 1, n - 2, m - 2, n - 1, m - 1)
			make_op(n - 2, m - 2, n - 1, m - 2, n - 2, m - 1)
			make_op(n - 2, m - 1, n - 1, m - 1, n - 1, m - 2)
	elif square2:
		make_op(n - 1, m - 1, n - 2, m - 1, n - 1, m - 2)
		make_op(n - 2, m - 2, n - 1, m - 2, n - 1, m - 1)
		make_op(n - 2, m - 1, n - 2, m - 2, n - 1, m - 1)
	print(len(operations))
	for op in operations:
		print(*op)


from sys import stdin, stdout
from math import gcd, sqrt, factorial
from collections import deque, defaultdict
input = stdin.readline
R = lambda : map(int, input().split())
I = lambda : int(input())
S = lambda : input().rstrip('\n')
L = lambda : list(R())
P = lambda x: stdout.write(x)
lcm = lambda x, y: x * y // gcd(x, y)
hg = lambda x, y: (y + x - 1) // x * x
pw = lambda x: 0 if x == 1 else 1 + pw(x // 2)
chk = lambda x: chk(x // 2) if not x % 2 else True if x == 1 else False
sm = lambda x: (x ** 2 + x) // 2
N = 10 ** 9 + 7

def op1(x):
	ans = []
	cnt = 3
	for (i, j) in x[:2]:
		if a[i][j]:
			ans.extend([i + 1, j + 1])
			a[i][j] = 0
			cnt -= 1
	for (i, j) in x[2:]:
		if cnt:
			ans.extend([i + 1, j + 1])
			a[i][j] ^= 1
			cnt -= 1
	return ans

def op(x, flg):
	cnt = 3 - flg
	ans = []
	for (i, j) in x:
		if flg and a[i][j]:
			a[i][j] = 0
			ans.extend([i + 1, j + 1])
			flg -= 1
		elif cnt and (not a[i][j]):
			a[i][j] = 1
			ans.extend([i + 1, j + 1])
			cnt -= 1
	return ans
for i in range(I()):
	(n, m) = R()
	a = [list(map(int, S())) for i in range(n)]
	ans = []
	for i in range(n - 1):
		for j in range(m - 1):
			x = [(i, j), (i + 1, j), (i, j + 1), (i + 1, j + 1)]
			if j != m - 2 or i != n - 2:
				if j != m - 2:
					if sum([a[p][q] for (p, q) in x[:2]]):
						ans += (op1(x),)
				elif a[i][j] + a[i][j + 1]:
					ans += (op1([(i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1)]),)
				continue
			else:
				cnt = sum([a[p][q] for (p, q) in x])
				if cnt == 0:
					continue
				if cnt == 4:
					ans += (op(x, 4),)
					cnt = 1
				if cnt == 1:
					ans += (op(x, 1),)
					cnt = 2
				if cnt == 2:
					ans += (op(x, 1),)
					cnt = 3
				if cnt == 3:
					ans += (op(x, 3),)
	print(len(ans))
	for i in ans:
		print(*i)


import io, os
from math import *

def move(i, j, n, m):
	if i < n - 1 and j < m - 1:
		return [(i + 1, j + 1, i + 2, j + 1, i + 1, j + 2), (i + 1, j + 1, i + 2, j + 1, i + 2, j + 2), (i + 1, j + 1, i + 2, j + 2, i + 1, j + 2)]
	elif i > 0 and j > 0:
		return [(i + 1, j + 1, i + 1, j, i, j + 1), (i, j, i + 1, j, i + 1, j + 1), (i, j, i + 1, j + 1, i, j + 1)]
	elif i == 0 and j == m - 1:
		return [(i + 1, j + 1, i + 2, j + 1, i + 2, j), (i + 1, j + 1, i + 1, j, i + 2, j), (i + 1, j + 1, i + 2, j + 1, i + 1, j)]
	else:
		return [(i + 1, j + 1, i, j + 1, i + 1, j + 2), (i + 1, j + 1, i + 1, j + 2, i, j + 2), (i + 1, j + 1, i, j + 1, i, j + 2)]

def fix_square(i, j, n, m, a):
	tl = int(a[i][j])
	tr = int(a[i][j + 1])
	bl = int(a[i + 1][j])
	br = int(a[i + 1][j + 1])
	total = tl + tr + bl + br
	if total == 0:
		return []
	elif total == 1:
		if tl == 1:
			return move(i, j, n, m)
		elif tr == 1:
			return move(i, j + 1, n, m)
		elif bl == 1:
			return move(i + 1, j, n, m)
		else:
			return move(i + 1, j + 1, n, m)
	elif total == 2:
		if tl == 1 and tr == 1:
			return [(i + 1, j + 1, i + 2, j + 1, i + 2, j + 2), (i + 2, j + 2, i + 2, j + 1, i + 1, j + 2)]
		elif tl == 1 and bl == 1:
			return [(i + 1, j + 1, i + 1, j + 2, i + 2, j + 2), (i + 2, j + 2, i + 2, j + 1, i + 1, j + 2)]
		elif tl == 1 and br == 1:
			return [(i + 1, j + 1, i + 2, j + 1, i + 1, j + 2), (i + 2, j + 2, i + 2, j + 1, i + 1, j + 2)]
		elif tr == 1 and bl == 1:
			return [(i + 1, j + 1, i + 1, j + 2, i + 2, j + 2), (i + 2, j + 2, i + 2, j + 1, i + 1, j + 1)]
		elif bl == 1 and br == 1:
			return [(i + 1, j + 1, i + 2, j + 1, i + 1, j + 2), (i + 2, j + 2, i + 1, j + 1, i + 1, j + 2)]
		else:
			return [(i + 1, j + 1, i + 2, j + 1, i + 1, j + 2), (i + 2, j + 2, i + 1, j + 1, i + 2, j + 1)]
	elif total == 3:
		if tl == 0:
			return [(i + 1, j + 2, i + 2, j + 1, i + 2, j + 2)]
		elif tr == 0:
			return [(i + 1, j + 1, i + 2, j + 1, i + 2, j + 2)]
		elif bl == 0:
			return [(i + 1, j + 2, i + 1, j + 1, i + 2, j + 2)]
		else:
			return [(i + 1, j + 2, i + 2, j + 1, i + 1, j + 1)]
	elif total == 4:
		return [(i + 1, j + 2, i + 2, j + 1, i + 2, j + 2), (i + 1, j + 1, i + 2, j + 1, i + 2, j + 2), (i + 1, j + 2, i + 1, j + 1, i + 2, j + 2), (i + 1, j + 2, i + 2, j + 1, i + 1, j + 1)]

def push_right(a, n, m):
	res = []
	for j in range(m - 2):
		for i in range(n):
			if a[i][j] == 1:
				if i > 0:
					res.append((i + 1, j + 1, i + 1, j + 2, i, j + 2))
					a[i][j] = 1 - a[i][j]
					a[i][j + 1] = 1 - a[i][j + 1]
					a[i - 1][j + 1] = 1 - a[i - 1][j + 1]
				else:
					res.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 2))
					a[i][j] = 1 - a[i][j]
					a[i][j + 1] = 1 - a[i][j + 1]
					a[i + 1][j + 1] = 1 - a[i + 1][j + 1]
	return (res, a)

def fix_corner(a, n, m):
	left = a[n - 1][m - 2]
	right = a[n - 1][m - 1]
	res = []
	if left == 1:
		res.append((n, m - 1, n - 1, m - 1, n - 1, m))
		a[n - 1][m - 2] = 1 - a[n - 1][m - 2]
		a[n - 2][m - 2] = 1 - a[n - 2][m - 2]
		a[n - 2][m - 1] = 1 - a[n - 2][m - 1]
	if right == 1:
		res.append((n, m, n - 1, m - 1, n - 1, m))
		a[n - 1][m - 1] = 1 - a[n - 1][m - 1]
		a[n - 2][m - 2] = 1 - a[n - 2][m - 2]
		a[n - 2][m - 1] = 1 - a[n - 2][m - 1]
	return (res, a)

def main():
	t = int(input())
	for _ in range(t):
		(n, m) = list(map(int, input().split()))
		a = [list(map(int, list(input()))) for _ in range(n)]
		(moves, a) = push_right(a, n, m)
		if n % 2 == 0:
			for i in range(0, n, 2):
				moves = moves + fix_square(i, m - 2, n, m, a)
		else:
			(moves2, a) = fix_corner(a, n, m)
			moves = moves + moves2
			for i in range(0, n - 1, 2):
				moves = moves + fix_square(i, m - 2, n, m, a)
		print(len(moves))
		for m in moves:
			print(str(m).replace(',', '').replace('(', '').replace(')', ''))
main()


from __future__ import division, print_function
import os
import sys
from io import BytesIO, IOBase
if sys.version_info[0] < 3:
	from __builtin__ import xrange as range
	from future_builtins import ascii, filter, hex, map, oct, zip

def main():
	t = int(input())

	def make_op(table, op):
		table[op[0]][op[1]] = 1 - table[op[0]][op[1]]
		table[op[2]][op[3]] = 1 - table[op[2]][op[3]]
		table[op[4]][op[5]] = 1 - table[op[4]][op[5]]
	for _ in range(t):
		(n, m) = map(int, input().split())
		table = [list(map(int, input())) for _ in range(n)]
		ops = []
		for i in range(n - 1):
			for j in range(m - 1):
				if table[i][j] and table[i + 1][j]:
					op = [i, j, i + 1, j, i, j + 1]
					ops.append(op)
					make_op(table, op)
				elif table[i][j]:
					op = [i, j, i, j + 1, i + 1, j + 1]
					ops.append(op)
					make_op(table, op)
				elif table[i + 1][j]:
					op = [i + 1, j, i, j + 1, i + 1, j + 1]
					ops.append(op)
					make_op(table, op)
		j = m - 2
		for i in range(n - 1):
			if table[i][j] and table[i][j + 1]:
				op = [i, j, i, j + 1, i + 1, j]
				ops.append(op)
				make_op(table, op)
			elif table[i][j]:
				op = [i, j, i + 1, j, i + 1, j + 1]
				ops.append(op)
				make_op(table, op)
			elif table[i][j + 1]:
				op = [i, j + 1, i + 1, j, i + 1, j + 1]
				ops.append(op)
				make_op(table, op)
		while True:
			ones = []
			zeros = []
			for i in range(n - 2, n):
				for j in range(m - 2, m):
					if table[i][j]:
						ones.append([i, j])
					else:
						zeros.append([i, j])
			if len(ones) == 0:
				break
			elif len(ones) <= 2:
				op = [*ones.pop(), *zeros.pop(), *zeros.pop()]
				ops.append(op)
				make_op(table, op)
			elif len(ones) >= 3:
				op = [*ones.pop(), *ones.pop(), *ones.pop()]
				ops.append(op)
				make_op(table, op)
		print(len(ops))
		for op in ops:
			print(*[i + 1 for i in op])
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import copy
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	mat = []
	for i in range(n):
		s = input()
		mat += [[x for x in s]]
	ans = []
	for i in range(0, n - 1, 2):
		for j in range(0, m - 1, 2):
			oneind = []
			zeroind = []
			for x in range(i, i + 2):
				for y in range(j, j + 2):
					if mat[x][y] == '1':
						oneind += [[x, y]]
					else:
						zeroind += [[x, y]]
			if len(oneind) == 0:
				continue
			if len(oneind) == 4:
				newoneind = [oneind[0][:]]
				newzeroind = [oneind[1][:], oneind[2][:], oneind[3][:]]
				ans += [[oneind[1][:], oneind[2][:], oneind[3][:]]]
				oneind = copy.deepcopy(newoneind)
				zeroind = copy.deepcopy(newzeroind)
			if len(oneind) == 1:
				newoneind = [zeroind[0][:], zeroind[1][:]]
				newzeroind = [zeroind[2][:], oneind[0][:]]
				ans += [[zeroind[0][:], zeroind[1][:], oneind[0][:]]]
				oneind = copy.deepcopy(newoneind)
				zeroind = copy.deepcopy(newzeroind)
			if len(oneind) == 2:
				newoneind = [zeroind[0][:], zeroind[1][:], oneind[0][:]]
				newzeroind = [oneind[1][:]]
				ans += [[zeroind[0][:], zeroind[1][:], oneind[1][:]]]
				oneind = copy.deepcopy(newoneind)
				zeroind = copy.deepcopy(newzeroind)
			if len(oneind) == 3:
				ans += [[oneind[0][:], oneind[1][:], oneind[2][:]]]
			for x in range(i, i + 2):
				for y in range(j, j + 2):
					mat[x][y] = '0'
	if n % 2 == 1:
		i = n - 2
		for j in range(0, m - 1, 2):
			oneind = []
			zeroind = []
			for x in range(i, i + 2):
				for y in range(j, j + 2):
					if mat[x][y] == '1':
						oneind += [[x, y]]
					else:
						zeroind += [[x, y]]
			if len(oneind) == 0:
				continue
			if len(oneind) == 4:
				newoneind = [oneind[0][:]]
				newzeroind = [oneind[1][:], oneind[2][:], oneind[3][:]]
				ans += [[oneind[1][:], oneind[2][:], oneind[3][:]]]
				oneind = copy.deepcopy(newoneind)
				zeroind = copy.deepcopy(newzeroind)
			if len(oneind) == 1:
				newoneind = [zeroind[0][:], zeroind[1][:]]
				newzeroind = [zeroind[2][:], oneind[0][:]]
				ans += [[zeroind[0][:], zeroind[1][:], oneind[0][:]]]
				oneind = copy.deepcopy(newoneind)
				zeroind = copy.deepcopy(newzeroind)
			if len(oneind) == 2:
				newoneind = [zeroind[0][:], zeroind[1][:], oneind[0][:]]
				newzeroind = [oneind[1][:]]
				ans += [[zeroind[0][:], zeroind[1][:], oneind[1][:]]]
				oneind = copy.deepcopy(newoneind)
				zeroind = copy.deepcopy(newzeroind)
			if len(oneind) == 3:
				ans += [[oneind[0][:], oneind[1][:], oneind[2][:]]]
			for x in range(i, i + 2):
				for y in range(j, j + 2):
					mat[x][y] = '0'
	if m % 2 == 1:
		j = m - 2
		for i in range(0, n - 1, 2):
			oneind = []
			zeroind = []
			for x in range(i, i + 2):
				for y in range(j, j + 2):
					if mat[x][y] == '1':
						oneind += [[x, y]]
					else:
						zeroind += [[x, y]]
			if len(oneind) == 0:
				continue
			if len(oneind) == 4:
				newoneind = [oneind[0][:]]
				newzeroind = [oneind[1][:], oneind[2][:], oneind[3][:]]
				ans += [[oneind[1][:], oneind[2][:], oneind[3][:]]]
				oneind = copy.deepcopy(newoneind)
				zeroind = copy.deepcopy(newzeroind)
			if len(oneind) == 1:
				newoneind = [zeroind[0][:], zeroind[1][:]]
				newzeroind = [zeroind[2][:], oneind[0][:]]
				ans += [[zeroind[0][:], zeroind[1][:], oneind[0][:]]]
				oneind = copy.deepcopy(newoneind)
				zeroind = copy.deepcopy(newzeroind)
			if len(oneind) == 2:
				newoneind = [zeroind[0][:], zeroind[1][:], oneind[0][:]]
				newzeroind = [oneind[1][:]]
				ans += [[zeroind[0][:], zeroind[1][:], oneind[1][:]]]
				oneind = copy.deepcopy(newoneind)
				zeroind = copy.deepcopy(newzeroind)
			if len(oneind) == 3:
				ans += [[oneind[0][:], oneind[1][:], oneind[2][:]]]
			for x in range(i, i + 2):
				for y in range(j, j + 2):
					mat[x][y] = '0'
	if n % 2 == 1 and m % 2 == 1:
		i = n - 2
		j = m - 2
		oneind = []
		zeroind = []
		for x in range(i, i + 2):
			for y in range(j, j + 2):
				if mat[x][y] == '1':
					oneind += [[x, y]]
				else:
					zeroind += [[x, y]]
		if len(oneind) == 4:
			newoneind = [oneind[0][:]]
			newzeroind = [oneind[1][:], oneind[2][:], oneind[3][:]]
			ans += [[oneind[1][:], oneind[2][:], oneind[3][:]]]
			oneind = copy.deepcopy(newoneind)
			zeroind = copy.deepcopy(newzeroind)
		if len(oneind) == 1:
			newoneind = [zeroind[0][:], zeroind[1][:]]
			newzeroind = [zeroind[2][:], oneind[0][:]]
			ans += [[zeroind[0][:], zeroind[1][:], oneind[0][:]]]
			oneind = copy.deepcopy(newoneind)
			zeroind = copy.deepcopy(newzeroind)
		if len(oneind) == 2:
			newoneind = [zeroind[0][:], zeroind[1][:], oneind[0][:]]
			newzeroind = [oneind[1][:]]
			ans += [[zeroind[0][:], zeroind[1][:], oneind[1][:]]]
			oneind = copy.deepcopy(newoneind)
			zeroind = copy.deepcopy(newzeroind)
		if len(oneind) == 3:
			ans += [[oneind[0][:], oneind[1][:], oneind[2][:]]]
		for x in range(i, i + 2):
			for y in range(j, j + 2):
				mat[x][y] = '0'
	print(len(ans))
	for x in ans:
		for y in x:
			print(y[0] + 1, y[1] + 1, end=' ')
		print('')


import sys
t = int(input())
for test in range(t):
	[n, m] = list(map(int, input().split(' ')))
	a = []
	for i in range(n):
		a.append(input())
	res = []
	r = 0
	for i in range(n - 1):
		for j in range(m - 1):
			if a[i][j] == '1':
				res.append([str(i + 1), str(j + 1), str(i + 2), str(j + 1), str(i + 1), str(j + 2)])
				res.append([str(i + 1), str(j + 1), str(i + 2), str(j + 1), str(i + 2), str(j + 2)])
				res.append([str(i + 1), str(j + 1), str(i + 2), str(j + 2), str(i + 1), str(j + 2)])
				r = r + 3
		if a[i][m - 1] == '1':
			res.append([str(i + 1), str(m), str(i + 2), str(m), str(i + 1), str(m - 1)])
			res.append([str(i + 1), str(m), str(i + 2), str(m), str(i + 2), str(m - 1)])
			res.append([str(i + 1), str(m), str(i + 2), str(m - 1), str(i + 1), str(m - 1)])
			r = r + 3
	for j in range(m - 1):
		if a[n - 1][j] == '1':
			res.append([str(n), str(j + 1), str(n - 1), str(j + 1), str(n), str(j + 2)])
			res.append([str(n), str(j + 1), str(n - 1), str(j + 1), str(n - 1), str(j + 2)])
			res.append([str(n), str(j + 1), str(n - 1), str(j + 2), str(n), str(j + 2)])
			r = r + 3
	if a[n - 1][m - 1] == '1':
		res.append([str(n), str(m), str(n - 1), str(m), str(n), str(m - 1)])
		res.append([str(n), str(m), str(n - 1), str(m), str(n - 1), str(m - 1)])
		res.append([str(n), str(m), str(n - 1), str(m - 1), str(n), str(m - 1)])
		r = r + 3
	print(r)
	for i in range(r):
		print(' '.join(res[i]))


from sys import stdin
input = stdin.readline

def getAns(n, m, g):
	moves = [[]] * (m * n)
	move = [0]

	def flip(r1, c1, r2, c2, r3, c3):
		g[r1][c1] = not g[r1][c1]
		g[r2][c2] = not g[r2][c2]
		g[r3][c3] = not g[r3][c3]
		moves[move[0]] = [r1 + 1, c1 + 1, r2 + 1, c2 + 1, r3 + 1, c3 + 1]
		move[0] += 1
	for r in range(0, n - 2, 2):
		for c in range(0, m - 2):
			if not g[r][c] and g[r + 1][c]:
				flip(r + 1, c, r + 1, c + 1, r, c + 1)
			elif g[r][c] and (not g[r + 1][c]):
				flip(r, c, r + 1, c + 1, r, c + 1)
			elif g[r][c] and g[r + 1][c]:
				flip(r, c, r + 1, c, r + 1, c + 1)
	for r in range(0, n - 2):
		if not g[r][m - 2] and g[r][m - 1]:
			flip(r, m - 1, r + 1, m - 1, r + 1, m - 2)
		elif g[r][m - 2] and (not g[r][m - 1]):
			flip(r, m - 2, r + 1, m - 1, r + 1, m - 2)
		elif g[r][m - 2] and g[r][m - 1]:
			flip(r, m - 2, r, m - 1, r + 1, m - 1)
	for c in range(0, m - 1):
		if not g[n - 2][c] and g[n - 1][c]:
			flip(n - 1, c, n - 1, c + 1, n - 2, c + 1)
		elif g[n - 2][c] and (not g[n - 1][c]):
			flip(n - 2, c, n - 2, c + 1, n - 1, c + 1)
		elif g[n - 2][c] and g[n - 1][c]:
			flip(n - 2, c, n - 1, c, n - 1, c + 1)
	if g[n - 1][m - 1] and g[n - 2][m - 1]:
		flip(n - 2, m - 1, n - 1, m - 2, n - 2, m - 2)
		flip(n - 2, m - 2, n - 1, m - 2, n - 1, m - 1)
	elif g[n - 1][m - 1] and (not g[n - 2][m - 1]):
		flip(n - 2, m - 2, n - 1, m - 2, n - 1, m - 1)
		flip(n - 2, m - 2, n - 1, m - 1, n - 2, m - 1)
		flip(n - 1, m - 2, n - 1, m - 1, n - 2, m - 1)
	elif not g[n - 1][m - 1] and g[n - 2][m - 1]:
		flip(n - 2, m - 2, n - 2, m - 1, n - 1, m - 2)
		flip(n - 2, m - 2, n - 2, m - 1, n - 1, m - 1)
		flip(n - 2, m - 1, n - 1, m - 2, n - 1, m - 1)
	print(move[0])
	for i in range(move[0]):
		print(*moves[i])
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	g = [0] * n
	for i in range(n):
		g[i] = [bool(int(x)) for x in input().rstrip()]
	getAns(n, m, g)


import io, os
from math import *
J = input
input = lambda : J().encode()
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = [[0 if c == ord('0') else 1 for c in input()] for _ in range(n)]
	r = []
	i = j = 0
	amt = 0
	z = []
	o = []
	t = []

	def calc():
		global r, t, amt, z, o
		t = [a[i][j], a[i][j + 1], a[i + 1][j], a[i + 1][j + 1]]
		amt = t.count(1)
		z = [x for x in range(4) if t[x] == 0]
		o = [x for x in range(4) if t[x] == 1]

	def do(m):
		global r, t, amt, z, o
		r += [m]
		(x1, y1, x2, y2, x3, y3) = m
		a[x1 - 1][y1 - 1] ^= 1
		a[x2 - 1][y2 - 1] ^= 1
		a[x3 - 1][y3 - 1] ^= 1
		calc()
	UR = lambda : do([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
	UL = lambda : do([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
	LR = lambda : do([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
	LL = lambda : do([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
	calc()
	if n % 2 == 1:
		i = n - 2
		for j in range(0, m, 2):
			j = min(j, m - 2)
			b = [a[i + 1][j], a[i + 1][j + 1]]
			if b == [1, 0]:
				UL()
			elif b == [0, 1]:
				UR()
			elif b == [1, 1]:
				LL()
	if m % 2 == 1:
		j = m - 2
		for i in range(0, n - 1, 2):
			b = [a[i][j + 1], a[i + 1][j + 1]]
			if b == [1, 0]:
				UL()
			elif b == [0, 1]:
				LL()
			elif b == [1, 1]:
				UR()
	for i in range(0, n - 1, 2):
		for j in range(0, m - 1, 2):
			t = [a[i][j], a[i][j + 1], a[i + 1][j], a[i + 1][j + 1]]
			amt = t.count(1)
			z = [x for x in range(4) if t[x] == 0]
			o = z = [x for x in range(4) if t[x] == 1]

			def do(m):
				global r, t, amt, z, o
				r += [m]
				(x1, y1, x2, y2, x3, y3) = m
				a[x1 - 1][y1 - 1] ^= 1
				a[x2 - 1][y2 - 1] ^= 1
				a[x3 - 1][y3 - 1] ^= 1
				t = [a[i][j], a[i][j + 1], a[i + 1][j], a[i + 1][j + 1]]
				amt = t.count(1)
				z = [x for x in range(4) if t[x] == 0]
				o = [x for x in range(4) if t[x] == 1]
			z = [x for x in range(4) if t[x] == 0]
			if amt == 4:
				LR()
			if amt == 1:
				[UL, UR, LL, LR][o[0]]()
			if amt == 2:
				[LR, LL, UR, UL][o[0]]()
			if amt == 3:
				[LR, LL, UR, UL][z[0]]()
	print(len(r))
	for x in r:
		print(*x)


def revab(b):
	for i in range(3):
		rev(b[2 * i], b[2 * i + 1])

def rev(x, y):
	global c
	if c[x - 1][y - 1] == '1':
		c[x - 1][y - 1] = '0'
	else:
		c[x - 1][y - 1] = '1'
import sys
for _ in range(int(sys.stdin.readline())):
	a = list(map(int, sys.stdin.readline().strip().split(' ')))
	c = []
	for i in range(a[0]):
		c.append(list(sys.stdin.readline().strip()))
	opn = 0
	ops = []
	a[0] -= 1
	while a[0] > 1:
		for i in range(a[1] - 1):
			if c[a[0]][i] == '1':
				opn += 1
				ops.append([a[0] + 1, i + 1, a[0], i + 1, a[0], i + 2])
				revab(ops[-1])
		if c[a[0]][a[1] - 1] == '1':
			opn += 1
			ops.append([a[0] + 1, a[1], a[0], a[1] - 1, a[0], a[1]])
			revab(ops[-1])
		a[0] -= 1
	a[1] -= 1
	while a[1] > 1:
		if c[0][a[1]] == '1' and c[1][a[1]] == '1':
			opn += 1
			ops.append([1, a[1] + 1, 2, a[1] + 1, 1, a[1]])
			revab(ops[-1])
		elif c[0][a[1]] == '1':
			opn += 1
			ops.append([1, a[1], 2, a[1], 1, a[1] + 1])
			revab(ops[-1])
		elif c[1][a[1]] == '1':
			opn += 1
			ops.append([2, a[1], 1, a[1], 2, a[1] + 1])
			revab(ops[-1])
		a[1] -= 1
	if c[0:2][0].count('1') + c[0:2][1].count('1') == 3 or c[0:2][0].count('1') + c[0:2][1].count('1') == 1:
		if c[0][0] == '0':
			opn += 1
			ops.append([1, 2, 2, 1, 2, 2])
		if c[1][0] == '0':
			opn += 1
			ops.append([1, 2, 1, 1, 2, 2])
		if c[0][1] == '0':
			opn += 1
			ops.append([1, 1, 2, 1, 2, 2])
		if c[1][1] == '0':
			opn += 1
			ops.append([1, 2, 2, 1, 1, 1])
	else:
		if c[0][0] == '1':
			opn += 1
			ops.append([1, 2, 2, 1, 2, 2])
		if c[1][0] == '1':
			opn += 1
			ops.append([1, 2, 1, 1, 2, 2])
		if c[0][1] == '1':
			opn += 1
			ops.append([1, 1, 2, 1, 2, 2])
		if c[1][1] == '1':
			opn += 1
			ops.append([1, 2, 2, 1, 1, 1])
	print(opn)
	for i in ops:
		print(' '.join(list(map(str, i))))


import sys
input = sys.stdin.readline
t = int(input())
for you in range(t):
	l = input().split()
	n = int(l[0])
	m = int(l[1])
	l = []
	for i in range(n):
		s = input()
		s = s[:-1]
		op = [int(i) for i in s]
		l.append(op)
	ok = []
	for i in range(n - 1, 1, -1):
		for j in range(m - 1):
			if l[i][j] == 1:
				ok.append((i, j, i - 1, j, i - 1, j + 1))
				l[i][j] ^= 1
				l[i - 1][j] ^= 1
				l[i - 1][j + 1] ^= 1
		if l[i][m - 1] == 1:
			ok.append((i, m - 1, i - 1, m - 2, i - 1, m - 1))
			l[i][m - 1] ^= 1
			l[i - 1][m - 2] ^= 1
			l[i - 1][m - 1] ^= 1
	for j in range(m - 1, 1, -1):
		for i in range(1, n):
			if l[i][j] == 1:
				ok.append((i, j, i, j - 1, i - 1, j - 1))
				l[i][j] ^= 1
				l[i][j - 1] ^= 1
				l[i - 1][j - 1] ^= 1
		if l[0][j] == 1:
			ok.append((0, j, 0, j - 1, 1, j - 1))
			l[0][j] ^= 1
			l[0][j - 1] ^= 1
			l[1][j - 1] ^= 1
	n = 2
	m = 2
	dx = [-1, 1]
	dy = [-1, 1]
	for i in range(n):
		for j in range(m):
			if l[i][j] == 0:
				continue
			done = 0
			for p in dx:
				for q in dy:
					if i + p < n and i + p >= 0 and (j + q < m) and (j + q >= 0):
						if l[i + p][j] == 1 and l[i][j + q] == 1:
							done = 1
							l[i][j] ^= 1
							l[i + p][j] ^= 1
							l[i][j + q] ^= 1
							ok.append((i, j, i + p, j, i, j + q))
							break
				if done:
					break
	for i in range(n - 1):
		for j in range(m):
			if l[i][j] == 1 and l[i + 1][j] == 1:
				if j > 0:
					ok.append((i, j, i, j - 1, i + 1, j - 1))
					ok.append((i + 1, j, i + 1, j - 1, i, j - 1))
				else:
					ok.append((i, j, i, j + 1, i + 1, j + 1))
					ok.append((i + 1, j, i + 1, j + 1, i, j + 1))
				l[i][j] = 0
				l[i + 1][j] = 0
	for i in range(n):
		for j in range(m - 1):
			if l[i][j] == 1 and l[i][j + 1] == 1:
				if i > 0:
					ok.append((i, j, i - 1, j, i - 1, j + 1))
					ok.append((i, j + 1, i - 1, j + 1, i - 1, j))
				else:
					ok.append((i, j, i + 1, j, i + 1, j + 1))
					ok.append((i, j + 1, i + 1, j + 1, i + 1, j))
				l[i][j] = 0
				l[i][j + 1] = 0
	for i in range(n - 1):
		for j in range(m - 1):
			if l[i][j] == 1 and l[i + 1][j + 1] == 1:
				ok.append((i, j, i, j + 1, i + 1, j))
				ok.append((i + 1, j + 1, i + 1, j, i, j + 1))
				l[i][j] = 0
				l[i + 1][j + 1] = 0
	for i in range(1, n):
		for j in range(m - 1):
			if l[i][j] == 1 and l[i - 1][j + 1] == 1:
				ok.append((i, j, i, j + 1, i - 1, j))
				ok.append((i - 1, j + 1, i - 1, j, i, j + 1))
				l[i][j] = 0
				l[i - 1][j + 1] = 0
	for i in range(n - 1):
		for j in range(m - 1):
			if l[i][j] == 1:
				ok.append((i, j, i, j + 1, i + 1, j))
				ok.append((i, j, i + 1, j, i + 1, j + 1))
				ok.append((i, j, i, j + 1, i + 1, j + 1))
	for i in range(n - 1):
		if l[i][m - 1] == 1:
			ok.append((i, m - 1, i, m - 2, i + 1, m - 1))
			ok.append((i, m - 1, i, m - 2, i + 1, m - 2))
			ok.append((i, m - 1, i + 1, m - 1, i + 1, m - 2))
	for i in range(m - 1):
		if l[n - 1][i] == 1:
			ok.append((n - 1, i, n - 2, i, n - 1, i + 1))
			ok.append((n - 1, i, n - 1, i + 1, n - 2, i + 1))
			ok.append((n - 1, i, n - 2, i, n - 2, i + 1))
	if l[n - 1][m - 1] == 1:
		ok.append((n - 1, m - 1, n - 2, m - 1, n - 1, m - 2))
		ok.append((n - 1, m - 1, n - 1, m - 2, n - 2, m - 2))
		ok.append((n - 1, m - 1, n - 2, m - 1, n - 2, m - 2))
	print(len(ok))
	for i in ok:
		print(i[0] + 1, i[1] + 1, i[2] + 1, i[3] + 1, i[4] + 1, i[5] + 1)


def concat(mat):
	l = []
	for i in range(len(mat)):
		l += mat[i]
	return l

def trnwt3_1(arr3_1, poss):
	ind3 = [[]]
	t = arr3_1
	for i in range(len(t)):
		if t[i] == 1:
			t[i] = 0
			ind3[0] += poss[i]
	return ind3

def trnwt2_1(arr2_1, poss):
	ind2 = [[]]
	t = arr2_1
	for k in range(len(t)):
		if t[k] == 1:
			t[k] = 0
			ind2[0] += poss[k]
			break
	for i in range(len(t)):
		if i != k and t[i] == 0:
			t[i] = 1
			ind2[0] += poss[i]
	ind2 += trnwt3_1(t, poss)
	return ind2

def trnwt1_1(arr1_1, poss):
	ind1 = [[]]
	count = 0
	t = arr1_1
	for i in range(len(t)):
		if t[i] == 0:
			count += 1
			if count <= 2:
				t[i] = 1
				ind1[0] += poss[i]
		else:
			t[i] = 0
			ind1[0] += poss[i]
	ind1 += trnwt2_1(t, poss)
	return ind1

def trnwt4_1(arr4_1, poss):
	ind4 = [[]]
	t = arr4_1
	for i in range(3):
		if t[i] == 1:
			t[i] = 0
			ind4[0] += poss[i]
	ind4 += trnwt1_1(t, poss)
	return ind4
T = int(input())
for t in range(T):
	(n, m) = map(int, input().split())
	prob = []
	for p in range(n):
		s = input()
		prob.append(list(map(int, s)))
	ans = []
	i = 0
	while i < n - 1:
		j = 0
		while j < m - 1:
			postn = [[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]]
			to_arr = [prob[i][j], prob[i][j + 1], prob[i + 1][j], prob[i + 1][j + 1]]
			if to_arr.count(1) == 3:
				ans += trnwt3_1(to_arr, postn)
				prob[i][j] = 0
				prob[i][j + 1] = 0
				prob[i + 1][j] = 0
				prob[i + 1][j + 1] = 0
			if to_arr.count(1) == 2:
				ans += trnwt2_1(to_arr, postn)
				prob[i][j] = 0
				prob[i][j + 1] = 0
				prob[i + 1][j] = 0
				prob[i + 1][j + 1] = 0
			if to_arr.count(1) == 1:
				ans += trnwt1_1(to_arr, postn)
				prob[i][j] = 0
				prob[i][j + 1] = 0
				prob[i + 1][j] = 0
				prob[i + 1][j + 1] = 0
			if to_arr.count(1) == 4:
				ans += trnwt4_1(to_arr, postn)
				prob[i][j] = 0
				prob[i][j + 1] = 0
				prob[i + 1][j] = 0
				prob[i + 1][j + 1] = 0
			j += 2
			if m % 2 == 1 and j == m - 1:
				j -= 1
		i += 2
		if n % 2 == 1 and i == n - 1:
			i -= 1
	print(len(ans))
	for u in range(len(ans)):
		for v in ans[u]:
			print(v + 1, end=' ')
		print()


t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = [list(map(int, input())) for i in range(n)]

	def add(p):
		a[p[0]][p[1]] ^= 1
		a[p[2]][p[3]] ^= 1
		a[p[4]][p[5]] ^= 1
		ans.append(' '.join(map(lambda x: str(x + 1), p)))
	ans = []
	for i in range(n - 1, 1, -1):
		for j in range(m):
			if a[i][j]:
				add((i, j, i - 1, j, i - 1, j + (1 if j < m - 1 else -1)))
	for j in range(m - 1, 1, -1):
		for i in (0, 1):
			if a[i][j]:
				add((i, j, 0, j - 1, 1, j - 1))
	for i in (0, 1):
		for j in (0, 1):
			if (a[0][0] + a[0][1] + a[1][0] + a[1][1] + a[i][j]) % 2:
				add((i ^ 1, j, i, j ^ 1, i ^ 1, j ^ 1))
	print(len(ans))
	print('\n'.join(ans))


import os
import sys
from io import BytesIO, IOBase
_str = str
BUFSIZE = 8192

def str(x=b''):
	return x if type(x) is bytes else _str(x).encode()

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def inp():
	return sys.stdin.readline().rstrip()

def mpint():
	return map(int, inp().split(' '))

def itg():
	return int(inp())

class State:

	def __init__(self, state, operations):
		self.states_num = {state: 0}
		self.states = [state]
		self._path = {}
		self.DIAMETER = 0
		new_sts = [0]
		while new_sts:
			self.DIAMETER += 1
			(cur_sts, new_sts) = (new_sts, [])
			for i in cur_sts:
				for (op, f) in enumerate(operations):
					state = f(self.states[i])
					if state not in self.states_num:
						j = self.states_num[state] = len(self.states)
						self.states.append(state)
						new_sts.append(j)
					else:
						j = self.states_num[state]
					self._path[i, j] = (i, op)
		self.SIZE = n = len(self.states_num)
		self.distance = dis = [[0 if i == j else 10 ** 6 for i in range(n)] for j in range(n)]
		for (i, j) in self._path.keys():
			self.distance[i][j] = 1
		for k in range(n):
			for i in range(n):
				for j in range(n):
					if dis[i][k] + dis[k][j] < dis[i][j]:
						dis[i][j] = dis[i][k] + dis[k][j]
						self._path[i, j] = self._path[k, j]

	def path(self, st1, st2):
		u = self.states_num[st1]
		v = self.states_num[st2]
		result = []
		while u != v:
			(v, op) = self._path[u, v]
			result.append(op)
		return result[::-1]

	def min_path(self, st1, states):
		result = [-1] * self.DIAMETER
		choice = -1
		for (i, st2) in enumerate(states):
			path = self.path(st1, st2)
			if len(path) < len(result):
				result = path
				choice = i
		return (result, choice)

def op0(st):
	return (st[0], st[1] ^ 1, st[2] ^ 1, st[3] ^ 1)

def op1(st):
	return (st[0] ^ 1, st[1], st[2] ^ 1, st[3] ^ 1)

def op2(st):
	return (st[0] ^ 1, st[1] ^ 1, st[2], st[3] ^ 1)

def op3(st):
	return (st[0] ^ 1, st[1] ^ 1, st[2] ^ 1, st[3])
zero = (0, 0, 0, 0)
ST = State(zero, (op0, op1, op2, op3))
right_zero = (zero, (0, 0, 1, 0), (1, 0, 0, 0), (1, 0, 1, 0))
bottom_zero = (zero, (0, 1, 0, 0), (1, 0, 0, 0), (1, 1, 0, 0))

def solve():
	(n, m) = mpint()
	matrix = [list(map(int, inp())) for _ in range(n)]
	output = []
	if m & 1:
		for i in range(n - 1):
			(y, x) = (i, m - 2)
			st = (matrix[y][x], matrix[y][x + 1], matrix[y + 1][x], matrix[y + 1][x + 1])
			(path, choice) = ST.min_path(st, right_zero)
			(matrix[y][x], matrix[y][x + 1], matrix[y + 1][x], matrix[y + 1][x + 1]) = right_zero[choice]
			y += 1
			x += 1
			for op in path:
				pos = [y, x, y, x + 1, y + 1, x, y + 1, x + 1]
				del pos[op << 1], pos[op << 1]
				output.append(pos)
	if n & 1:
		for j in range(m - 1 - (m & 1)):
			(y, x) = (n - 2, j)
			st = (matrix[y][x], matrix[y][x + 1], matrix[y + 1][x], matrix[y + 1][x + 1])
			(path, choice) = ST.min_path(st, bottom_zero)
			(matrix[y][x], matrix[y][x + 1], matrix[y + 1][x], matrix[y + 1][x + 1]) = bottom_zero[choice]
			y += 1
			x += 1
			for op in path:
				pos = [y, x, y, x + 1, y + 1, x, y + 1, x + 1]
				del pos[op << 1], pos[op << 1]
				output.append(pos)
	for i in range(n >> 1):
		for j in range(m >> 1):
			(y, x) = (i << 1, j << 1)
			st = (matrix[y][x], matrix[y][x + 1], matrix[y + 1][x], matrix[y + 1][x + 1])
			pos = [y, x, y, x + 1, y + 1, x, y + 1, x + 1]
			for k in range(4):
				matrix[pos[k * 2]][pos[k * 2 + 1]] = 0
			y += 1
			x += 1
			for op in ST.path(st, zero):
				pos = [y, x, y, x + 1, y + 1, x, y + 1, x + 1]
				del pos[op << 1], pos[op << 1]
				output.append(pos)
	assert len(output) <= n * m
	print(len(output))
	for out in output:
		print(*out)

def main():
	for _ in range(itg()):
		solve()
DEBUG = 0
URL = ''
if DEBUG == 1:
	import requests
	from ACgenerator.Y_Test_Case_Runner import TestCaseRunner
	runner = TestCaseRunner(main, URL)
	inp = runner.input_stream
	print = runner.output_stream
	runner.checking()
elif DEBUG == 2:
	main()
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
	main()


for _ in range(0, int(input())):
	(n, m) = map(int, input().split())
	mat = [[char for char in input()] for _ in range(0, n)]
	answer = []

	def update(changes):
		answer.append((changes[0], changes[1], changes[2]))
		for (x, y) in changes:
			if mat[x][y] == '0':
				mat[x][y] = '1'
			else:
				mat[x][y] = '0'

	def change(a, b, c, vec0, vec1):
		answer.append((a, b, c))
		for (x, y) in [a, b, c]:
			if mat[x][y] == '0':
				vec0.remove((x, y))
				vec1.append((x, y))
				mat[x][y] = '1'
			else:
				vec0.append((x, y))
				vec1.remove((x, y))
				mat[x][y] = '0'
		return (vec0, vec1)
	if n > 2 or m > 2:
		for x in range(0, n, 2):
			for j in range(0, m - 1, 1):
				i = min(n - 2, x)
				if mat[i][j] == '0' and mat[i + 1][j] == '0':
					continue
				changes = []
				if mat[i][j] == '1':
					changes.append((i, j))
				if mat[i + 1][j] == '1':
					changes.append((i + 1, j))
				if len(changes) < 3:
					changes.append((i, j + 1))
				if len(changes) < 3:
					changes.append((i + 1, j + 1))
				update(changes)
		for x in range(0, n - 2):
			i = x
			j = m - 2
			if mat[i][j] == '0' and mat[i][j + 1] == '0':
				continue
			changes = []
			if mat[i][j] == '1':
				changes.append((i, j))
			if mat[i][j + 1] == '1':
				changes.append((i, j + 1))
			if len(changes) < 3:
				changes.append((i + 1, j))
			if len(changes) < 3:
				changes.append((i + 1, j + 1))
			update(changes)
	a = n - 2
	b = m - 2
	vec0 = [(x, y) for x in range(a, a + 2) for y in range(b, b + 2) if mat[x][y] == '0']
	vec1 = [(x, y) for x in range(a, a + 2) for y in range(b, b + 2) if mat[x][y] == '1']
	cnt = 0
	while len(vec1) > 0:
		if len(vec1) == 4:
			(vec0, vec1) = change(vec1[0], vec1[1], vec1[2], vec0, vec1)
		elif len(vec1) == 3:
			(vec0, vec1) = change(vec1[0], vec1[1], vec1[2], vec0, vec1)
		else:
			(vec0, vec1) = change(vec0[0], vec0[1], vec1[0], vec0, vec1)
	print(len(answer))
	for (x, y, z) in answer:
		print(x[0] + 1, x[1] + 1, y[0] + 1, y[1] + 1, z[0] + 1, z[1] + 1)


import sys
from collections import defaultdict
input = lambda : sys.stdin.readline().rstrip()

def comp(t):
	return (t[0] << 50) + (t[1] << 40) + (t[2] << 30) + (t[3] << 20) + (t[4] << 10) + t[5]

def decomp(n):
	ret = []
	for _ in range(6):
		ret.append(n & (1 << 10) - 1)
		n >>= 10
	return tuple(reversed(ret))
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	field = [list(map(int, input())) for _ in range(n)]
	ans = defaultdict(int)
	for i in range(n - 1):
		j = 0
		while j < m:
			while j < m and field[i][j] == 0:
				j += 1
			if j < m:
				if j + 1 < m:
					if field[i][j + 1] == 1:
						ans[comp((i, j, i, j + 1, i + 1, j))] ^= 1
						field[i][j] ^= 1
						field[i][j + 1] ^= 1
						field[i + 1][j] ^= 1
					else:
						ans[comp((i, j, i + 1, j, i + 1, j + 1))] ^= 1
						field[i][j] ^= 1
						field[i + 1][j + 1] ^= 1
						field[i + 1][j] ^= 1
				else:
					ans[comp((i, j, i + 1, j - 1, i + 1, j))] ^= 1
					field[i][j] ^= 1
					field[i + 1][j - 1] ^= 1
					field[i + 1][j] ^= 1
			j += 2
	i = n - 1
	j = 0
	while j < m:
		while j < m and field[i][j] == 0:
			j += 1
		if j < m:
			if j + 1 < m:
				if field[i][j + 1] == 1:
					t = (i - 1, j, i - 1, j + 1, i, j)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans[comp(t)] ^= 1
					t = (i - 1, j, i - 1, j + 1, i, j + 1)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans[comp(t)] ^= 1
				elif j + 2 < m and field[i][j + 2] == 1:
					t = (i - 1, j + 1, i, j, i, j + 1)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans[comp(t)] ^= 1
					t = (i - 1, j + 1, i, j + 1, i, j + 2)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans[comp(t)] ^= 1
				else:
					t = (i - 1, j, i - 1, j + 1, i, j)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans[comp(t)] ^= 1
					t = (i - 1, j, i, j, i, j + 1)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans[comp(t)] ^= 1
					t = (i - 1, j + 1, i, j, i, j + 1)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans[comp(t)] ^= 1
			else:
				t = (i - 1, j - 1, i - 1, j, i, j)
				it = iter(t)
				for (ni, nj) in zip(it, it):
					field[ni][nj] ^= 1
				ans[comp(t)] ^= 1
				t = (i - 1, j, i, j - 1, i, j)
				it = iter(t)
				for (ni, nj) in zip(it, it):
					field[ni][nj] ^= 1
				ans[comp(t)] ^= 1
				t = (i - 1, j - 1, i, j - 1, i, j)
				it = iter(t)
				for (ni, nj) in zip(it, it):
					field[ni][nj] ^= 1
				ans[comp(t)] ^= 1
			j += 2
	newans = []
	for (k, v) in ans.items():
		if v:
			newans.append(decomp(k))
	print(len(newans))
	for line in newans:
		print(*[l + 1 for l in line])


import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
T = int(input())
r = 1

def swi(i1, j1, i2, j2, matrix, man):
	temp = []
	for i in range(i1, i1 + 2):
		for j in range(j1, j1 + 2):
			if i == i2 and j == j2:
				continue
			matrix[i][j] = 1 - matrix[i][j]
			temp += [i + 1, j + 1]
	man.append(list(temp))

def getdone(i1, j1, matrix, man):
	tot = matrix[i1][j1] + matrix[i1][j1 + 1] + matrix[i1 + 1][j1] + matrix[i1 + 1][j1 + 1]
	if tot == 0:
		return
	elif tot == 1:
		for i in range(i1, i1 + 2):
			for j in range(j1, j1 + 2):
				if matrix[i][j] == 1:
					single = [i, j]
		for i in range(i1, i1 + 2):
			for j in range(j1, j1 + 2):
				if i == single[0] and j == single[1]:
					continue
				swi(i1, j1, i, j, matrix, man)
	elif tot == 2:
		twin = []
		for i in range(i1, i1 + 2):
			for j in range(j1, j1 + 2):
				if matrix[i][j] == 1:
					twin.append([i, j])
		swi(i1, j1, twin[0][0], twin[0][1], matrix, man)
		swi(i1, j1, twin[1][0], twin[1][1], matrix, man)
	elif tot == 3:
		for i in range(i1, i1 + 2):
			for j in range(j1, j1 + 2):
				if matrix[i][j] == 0:
					single = [i, j]
		for i in range(i1, i1 + 2):
			for j in range(j1, j1 + 2):
				if i == single[0] and j == single[1]:
					swi(i1, j1, i, j, matrix, man)
	else:
		for i in range(i1, i1 + 2):
			for j in range(j1, j1 + 2):
				swi(i1, j1, i, j, matrix, man)
while r <= T:
	(m, n) = map(int, input().split())
	matrix = [[0 for j in range(n)] for i in range(m)]
	for i in range(m):
		s = input()
		for j in range(n):
			matrix[i][j] = int(s[j]) - 48
	man = []
	for i in range(m - 2):
		for j in range(n - 2):
			if matrix[i][j] == 1:
				swi(i, j, i + 1, j + 1, matrix, man)
			else:
				swi(i, j, i, j, matrix, man)
		if matrix[i][n - 2] == 0 and matrix[i][n - 1] == 0:
			continue
		elif matrix[i][n - 2] == 1 and matrix[i][n - 1] == 0:
			swi(i, n - 2, i, n - 1, matrix, man)
		elif matrix[i][n - 2] == 0 and matrix[i][n - 1] == 1:
			swi(i, n - 2, i, n - 2, matrix, man)
		elif matrix[i][n - 2] == 1 and matrix[i][n - 1] == 1:
			swi(i, n - 2, i + 1, n - 1, matrix, man)
	for j in range(n - 2):
		if matrix[m - 2][j] == 0 and matrix[m - 1][j] == 0:
			continue
		elif matrix[m - 2][j] == 1 and matrix[m - 1][j] == 0:
			swi(m - 2, j, m - 1, j, matrix, man)
		elif matrix[m - 2][j] == 0 and matrix[m - 1][j] == 1:
			swi(m - 2, j, m - 2, j, matrix, man)
		elif matrix[m - 2][j] == 1 and matrix[m - 1][j] == 1:
			swi(m - 2, j, m - 1, j + 1, matrix, man)
	getdone(m - 2, n - 2, matrix, man)
	print(len(man))
	for ele in man:
		print(ele[0], ele[1], ele[2], ele[3], ele[4], ele[5])
	r += 1


t = int(input())
for i in range(t):
	(n, m) = input().strip().split(' ')
	(n, m) = [int(n), int(m)]
	p = []
	for i in range(n):
		s = input()
		p.append(list(s))
	ans = []
	for i in range(0, n - 1, 2):
		for j in range(0, m - 1, 2):
			a = int(p[i][j])
			b = int(p[i][j + 1])
			c = int(p[i + 1][j])
			d = int(p[i + 1][j + 1])
			rts = a + b + c + d
			if rts == 0:
				pass
			elif rts == 3:
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
			elif rts == 2:
				if a and b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					c = 1
					p[i + 1][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					c = 1
					p[i + 1][j] = '1'
				elif b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					c = 0
					p[i + 1][j] = '0'
					a = 1
					p[i][j] = '1'
					b = 1
					p[i][j + 1] = '1'
				elif b and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					c = 1
					p[i + 1][j] = '1'
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
			elif rts == 1:
				if a:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					b = 1
					c = 1
					p[i][j + 1] = '1'
					p[i][j] = '0'
					p[i + 1][j] = '1'
				elif b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 0
					c = 1
					p[i][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				elif c:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 1
					c = 0
					p[i][j + 1] = '1'
					p[i][j] = '1'
					p[i + 1][j] = '0'
				elif d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 1
					c = 1
					d = 0
					p[i + 1][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				if a and b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					c = 1
					p[i + 1][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					c = 1
					p[i + 1][j] = '1'
				elif b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					c = 0
					p[i + 1][j] = '0'
					a = 1
					p[i][j] = '1'
					b = 1
					p[i][j + 1] = '1'
				elif b and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					c = 1
					p[i + 1][j] = '1'
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
			elif rts == 4:
				ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
				a = 0
				b = 0
				c = 0
				p[i][j] = '0'
				p[i + 1][j] = '0'
				p[i][j + 1] = '0'
				if a:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					b = 1
					c = 1
					p[i][j + 1] = '1'
					p[i][j] = '0'
					p[i + 1][j] = '1'
				elif b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 0
					c = 1
					p[i][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				elif c:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 1
					c = 0
					p[i][j + 1] = '1'
					p[i][j] = '1'
					p[i + 1][j] = '0'
				elif d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 1
					c = 1
					d = 0
					p[i + 1][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				if a and b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					c = 1
					p[i + 1][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					c = 1
					p[i + 1][j] = '1'
				elif b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					c = 0
					p[i + 1][j] = '0'
					a = 1
					p[i][j] = '1'
					b = 1
					p[i][j + 1] = '1'
				elif b and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					c = 1
					p[i + 1][j] = '1'
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
	if n % 2:
		i = n - 2
		for j in range(0, m - 1):
			a = int(p[i][j])
			b = int(p[i][j + 1])
			c = int(p[i + 1][j])
			d = int(p[i + 1][j + 1])
			rts = a + b + c + d
			if rts == 0:
				pass
			elif rts == 3:
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
			elif rts == 2:
				if a and b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					c = 1
					p[i + 1][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					c = 1
					p[i + 1][j] = '1'
				elif b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					c = 0
					p[i + 1][j] = '0'
					a = 1
					p[i][j] = '1'
					b = 1
					p[i][j + 1] = '1'
				elif b and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					c = 1
					p[i + 1][j] = '1'
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
			elif rts == 1:
				if a:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					b = 1
					c = 1
					p[i][j + 1] = '1'
					p[i][j] = '0'
					p[i + 1][j] = '1'
				elif b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 0
					c = 1
					p[i][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				elif c:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 1
					c = 0
					p[i][j + 1] = '1'
					p[i][j] = '1'
					p[i + 1][j] = '0'
				elif d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 1
					c = 1
					d = 0
					p[i + 1][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				if a and b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					c = 1
					p[i + 1][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					c = 1
					p[i + 1][j] = '1'
				elif b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					c = 0
					p[i + 1][j] = '0'
					a = 1
					p[i][j] = '1'
					b = 1
					p[i][j + 1] = '1'
				elif b and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					c = 1
					p[i + 1][j] = '1'
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
			elif rts == 4:
				ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
				a = 0
				b = 0
				c = 0
				p[i][j] = '0'
				p[i + 1][j] = '0'
				p[i][j + 1] = '0'
				if a:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					b = 1
					c = 1
					p[i][j + 1] = '1'
					p[i][j] = '0'
					p[i + 1][j] = '1'
				elif b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 0
					c = 1
					p[i][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				elif c:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 1
					c = 0
					p[i][j + 1] = '1'
					p[i][j] = '1'
					p[i + 1][j] = '0'
				elif d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 1
					c = 1
					d = 0
					p[i + 1][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				if a and b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					c = 1
					p[i + 1][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					c = 1
					p[i + 1][j] = '1'
				elif b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					c = 0
					p[i + 1][j] = '0'
					a = 1
					p[i][j] = '1'
					b = 1
					p[i][j + 1] = '1'
				elif b and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					c = 1
					p[i + 1][j] = '1'
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
	if m % 2:
		j = m - 2
		for i in range(0, n - 1):
			a = int(p[i][j])
			b = int(p[i][j + 1])
			c = int(p[i + 1][j])
			d = int(p[i + 1][j + 1])
			rts = a + b + c + d
			if rts == 0:
				pass
			elif rts == 3:
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
			elif rts == 2:
				if a and b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					c = 1
					p[i + 1][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					c = 1
					p[i + 1][j] = '1'
				elif b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					c = 0
					p[i + 1][j] = '0'
					a = 1
					p[i][j] = '1'
					b = 1
					p[i][j + 1] = '1'
				elif b and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					c = 1
					p[i + 1][j] = '1'
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
			elif rts == 1:
				if a:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					b = 1
					c = 1
					p[i][j + 1] = '1'
					p[i][j] = '0'
					p[i + 1][j] = '1'
				elif b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 0
					c = 1
					p[i][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				elif c:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 1
					c = 0
					p[i][j + 1] = '1'
					p[i][j] = '1'
					p[i + 1][j] = '0'
				elif d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 1
					c = 1
					d = 0
					p[i + 1][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				if a and b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					c = 1
					p[i + 1][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					c = 1
					p[i + 1][j] = '1'
				elif b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					c = 0
					p[i + 1][j] = '0'
					a = 1
					p[i][j] = '1'
					b = 1
					p[i][j + 1] = '1'
				elif b and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					c = 1
					p[i + 1][j] = '1'
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
			elif rts == 4:
				ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
				a = 0
				b = 0
				c = 0
				p[i][j] = '0'
				p[i + 1][j] = '0'
				p[i][j + 1] = '0'
				if a:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					b = 1
					c = 1
					p[i][j + 1] = '1'
					p[i][j] = '0'
					p[i + 1][j] = '1'
				elif b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 0
					c = 1
					p[i][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				elif c:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 1
					b = 1
					c = 0
					p[i][j + 1] = '1'
					p[i][j] = '1'
					p[i + 1][j] = '0'
				elif d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 1
					c = 1
					d = 0
					p[i + 1][j + 1] = '0'
					p[i][j] = '1'
					p[i + 1][j] = '1'
				if a and b:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					c = 1
					p[i + 1][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif a and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					a = 0
					p[i][j] = '0'
					b = 1
					p[i][j + 1] = '1'
					c = 1
					p[i + 1][j] = '1'
				elif b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					d = 1
					p[i + 1][j + 1] = '1'
				elif c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					c = 0
					p[i + 1][j] = '0'
					a = 1
					p[i][j] = '1'
					b = 1
					p[i][j + 1] = '1'
				elif b and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					b = 0
					p[i][j + 1] = '0'
					a = 1
					p[i][j] = '1'
					c = 1
					p[i + 1][j] = '1'
				if a and b and c:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
				elif a and c and d:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					p[i][j] = '0'
					p[i + 1][j] = '0'
					p[i + 1][j + 1] = '0'
				elif a and b and d:
					ans.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					p[i][j] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j + 1] = '0'
				elif b and c and d:
					ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					p[i + 1][j + 1] = '0'
					p[i][j + 1] = '0'
					p[i + 1][j] = '0'
	print(len(ans))
	for j in ans:
		print(*j)


def main():
	from sys import stdin
	from random import randint, choice, shuffle
	from functools import lru_cache
	input = stdin.readline
	dx = [0, 0, 1, 1]
	dy = [0, 1, 0, 1]

	def g(i, j, a):
		return (i + dx[a] + 1, j + dy[a] + 1)

	def f(i, j, a, b, c):
		return (g(i, j, a), g(i, j, b), g(i, j, c))
	for _ in range(int(input())):
		ans = []
		(n, m) = map(int, input().split())
		s = [0] * n
		for i in range(n):
			s[i] = [int(c) for c in input()[:-1]]
		if n & 1 and m & 1 and s[n - 1][m - 1]:
			ans.append(f(n - 1 - 1, m - 1 - 1, 1, 2, 3))
			s[n - 1][m - 1] ^= 1
			s[n - 2][m - 1] ^= 1
			s[n - 1][m - 2] ^= 1
		if n & 1:
			for j in range(m - (m & 1)):
				if s[n - 1][j]:
					if not j:
						ans.append(f(n - 1 - 1, j, 0, 1, 2))
						s[n - 1][j] ^= 1
						s[n - 2][j] ^= 1
						s[n - 2][j + 1] ^= 1
					else:
						ans.append(f(n - 1 - 1, j - 1, 0, 1, 3))
						s[n - 1][j] ^= 1
						s[n - 2][j] ^= 1
						s[n - 2][j - 1] ^= 1
		if m & 1:
			for i in range(n - (n & 1)):
				if s[i][m - 1]:
					if not i:
						ans.append(f(i, m - 1 - 1, 0, 1, 2))
						s[i][m - 1] ^= 1
						s[i][m - 2] ^= 1
						s[i + 1][m - 2] ^= 1
					else:
						ans.append(f(i - 1, m - 1 - 1, 0, 2, 3))
						s[i][m - 1] ^= 1
						s[i][m - 2] ^= 1
						s[i - 1][m - 2] ^= 1
		for i in range(n - (n & 1)):
			for j in range(m - (m & 1)):
				if s[i][j] == 0:
					continue
				if 2 * (i & 1) + (j & 1) == 0:
					ans.append(f(i, j, 0, 1, 3))
					ans.append(f(i, j, 0, 2, 3))
					ans.append(f(i, j, 0, 1, 2))
				elif 2 * (i & 1) + (j & 1) == 1:
					ans.append(f(i, j - 1, 0, 1, 2))
					ans.append(f(i, j - 1, 1, 2, 3))
					ans.append(f(i, j - 1, 0, 1, 3))
				elif 2 * (i & 1) + (j & 1) == 2:
					ans.append(f(i - 1, j, 0, 1, 2))
					ans.append(f(i - 1, j, 1, 2, 3))
					ans.append(f(i - 1, j, 0, 2, 3))
				else:
					ans.append(f(i - 1, j - 1, 0, 1, 3))
					ans.append(f(i - 1, j - 1, 0, 2, 3))
					ans.append(f(i - 1, j - 1, 1, 2, 3))
		ans.sort()
		p = []
		c = 0
		ans1 = []
		for i in ans:
			if i == p:
				c += 1
			else:
				if c & 1:
					ans1.append(p)
				c = 1
				p = i
		if c & 1:
			ans1.append(p)
		print(len(ans1))
		for i in ans1:
			for j in i:
				print(*j, end=' ')
			print()
main()


t = int(input())
grid = None

def steps(i, j):
	ones = []
	zeros = []
	for x in range(2):
		for y in range(2):
			if grid[i + x][j + y] == '1':
				ones.append((i + x, j + y))
			else:
				zeros.append((i + x, j + y))
	val = len(ones)
	if val == 0:
		return (0, [])
	elif val == 1:
		return (3, [(ones[0], zeros[0], zeros[1]), (ones[0], zeros[2], zeros[0]), (zeros[2], ones[0], zeros[1])])
	elif val == 2:
		return (2, [(zeros[0], zeros[1], ones[0]), (zeros[0], zeros[1], ones[1])])
	elif val == 3:
		return (1, [tuple(ones)])
	else:
		ones = [(i, j)]
		zeros = [(i, j + 1), (i + 1, j), (i + 1, j + 1)]
		return (4, [tuple(zeros), (ones[0], zeros[0], zeros[1]), (ones[0], zeros[2], zeros[0]), (zeros[2], ones[0], zeros[1])])
for _ in range(t):
	(n, m) = map(int, input().split())
	grid = [[ch for ch in input()] for __ in range(n)]
	tot = 0
	stepslist = []
	for i in range(0, n - 1):
		for j in range(0, m - 1):
			(t, ss) = steps(i, j)
			tot += t
			stepslist.extend(ss)
			for x in range(2):
				for y in range(2):
					grid[i + x][j + y] = '0'
	idx = 0
	print(tot)
	for s in stepslist:
		print(s[0][0] + 1, s[0][1] + 1, s[1][0] + 1, s[1][1] + 1, s[2][0] + 1, s[2][1] + 1)


import collections
import math
from heapq import *
for t in range(int(input())):
	(n, m) = map(int, input().split())
	mat = []
	ans = []
	for i in range(n):
		s = list(input())
		s = list(map(int, s))
		mat.append(s)

	def cal(r, c):
		count = mat[r][c] + mat[r + 1][c] + mat[r][c + 1] + mat[r + 1][c + 1]
		if count == 4:
			mat[r][c] = mat[r + 1][c] = mat[r][c + 1] = 0
			ans.append([r + 1, c + 1, r + 2, c + 1, r + 1, c + 2])
			count = 1
		if count == 3:
			temp = []
			for (x, y) in [(r, c), (r + 1, c), (r, c + 1), (r + 1, c + 1)]:
				if mat[x][y] == 1:
					temp.append(x + 1)
					temp.append(y + 1)
			ans.append(temp)
		if count == 1:
			if mat[r][c] == 1 or mat[r + 1][c + 1]:
				if mat[r][c] == 1:
					ans.append([r + 1, c + 1, r + 2, c + 1, r + 1, c + 2])
				else:
					ans.append([r + 2, c + 2, r + 2, c + 1, r + 1, c + 2])
				mat[r][c] = mat[r + 1][c + 1] = 0
				mat[r + 1][c] = mat[r][c + 1] = 1
			else:
				if mat[r + 1][c] == 1:
					ans.append([r + 2, c + 1, r + 1, c + 1, r + 2, c + 2])
				else:
					ans.append([r + 1, c + 2, r + 1, c + 1, r + 2, c + 2])
				mat[r + 1][c] = mat[r][c + 1] = 0
				mat[r][c] = mat[r + 1][c + 1] = 1
			count = 2
		if count == 2:
			if mat[r][c] == 1 and mat[r + 1][c + 1] == 1:
				ans.append([r + 1, c + 1, r + 2, c + 1, r + 1, c + 2])
				ans.append([r + 2, c + 2, r + 2, c + 1, r + 1, c + 2])
			elif mat[r][c + 1] == mat[r + 1][c] == 1:
				ans.append([r + 1, c + 1, r + 2, c + 1, r + 2, c + 2])
				ans.append([r + 1, c + 1, r + 1, c + 2, r + 2, c + 2])
			else:
				one = []
				zero = []
				for (x, y) in [(r, c), (r + 1, c), (r, c + 1), (r + 1, c + 1)]:
					if mat[x][y] == 1:
						one.append(x + 1)
						one.append(y + 1)
					else:
						zero.append(x + 1)
						zero.append(y + 1)
				ans.append([one[0], one[1]] + zero)
				ans.append([one[2], one[3]] + zero)
		mat[r + 1][c] = mat[r][c + 1] = mat[r][c] = mat[r + 1][c + 1] = 0
	for r in range(0, n - 1, 2):
		for c in range(0, m - 1, 2):
			cal(r, c)
	if n % 2:
		for c in range(0, m - 1, 2):
			cal(n - 2, c)
	if m % 2:
		for r in range(0, n - 1, 2):
			cal(r, m - 2)
	if n % 2 and m % 2:
		cal(n - 2, m - 2)
	print(len(ans))
	for i in ans:
		print(*i)


import sys
input = sys.stdin.readline
testcase = int(input())

def op(s):
	if s == '1':
		return '0'
	else:
		return '1'
for _ in range(testcase):
	(h, w) = map(int, input().split())
	grid = [list(input().rstrip()) for i in range(h)]
	ans = []
	for i in range(h - 2):
		for j in range(w):
			if grid[i][j] == '1':
				if j < w - 1:
					grid[i][j] = op(grid[i][j])
					grid[i][j + 1] = op(grid[i][j + 1])
					grid[i + 1][j] = op(grid[i + 1][j])
					ans.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 1))
				else:
					grid[i][j] = op(grid[i][j])
					grid[i + 1][j] = op(grid[i + 1][j])
					grid[i + 1][j - 1] = op(grid[i + 1][j - 1])
					ans.append((i + 1, j + 1, i + 2, j + 1, i + 2, j))
	for j in range(w - 2):
		if grid[h - 2][j] == '1':
			i = h - 2
			grid[i][j] = op(grid[i][j])
			grid[i][j + 1] = op(grid[i][j + 1])
			grid[i + 1][j] = op(grid[i + 1][j])
			ans.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 1))
		if grid[h - 1][j] == '1':
			i = h - 1
			grid[i][j] = op(grid[i][j])
			grid[i][j + 1] = op(grid[i][j + 1])
			grid[i - 1][j + 1] = op(grid[i - 1][j + 1])
			ans.append((i + 1, j + 1, i + 1, j + 2, i, j + 2))
	ls = [grid[h - 2][w - 2], grid[h - 2][w - 1], grid[h - 1][w - 2], grid[h - 1][w - 1]]
	for i in range(16):
		lsc = ls[:]
		ope = []
		for j in range(4):
			if i & 1 << j:
				ope.append(j)
		for x in ope:
			for k in range(4):
				if x != k:
					lsc[k] = op(lsc[k])
		if lsc.count('0') == 4:
			for x in ope:
				if x == 0:
					ans.append((h, w - 1, h - 1, w, h, w))
				if x == 1:
					ans.append((h - 1, w - 1, h, w - 1, h, w))
				if x == 2:
					ans.append((h - 1, w - 1, h - 1, w, h, w))
				if x == 3:
					ans.append((h - 1, w - 1, h, w - 1, h - 1, w))
			break
	print(len(ans))
	for row in ans:
		print(*row)


t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	l = []
	for i in range(n):
		l.append(list(input()))
		for j in range(m):
			l[-1][j] = int(l[-1][j])
	ans = []
	for i in range(n):
		for j in range(m):
			if i == n - 1:
				if j == m - 1:
					if l[i][j] == 0:
						pass
					else:
						ans.append([i, j, i - 1, j, i - 1, j - 1])
						l[i - 1][j] ^= 1
						l[i][j] ^= 1
						l[i - 1][j - 1] ^= 1
						ans.append([i, j, i, j - 1, i - 1, j - 1])
						l[i][j] ^= 1
						l[i][j - 1] ^= 1
						l[i - 1][j - 1] ^= 1
						ans.append([i, j, i - 1, j, i, j - 1])
						l[i][j] ^= 1
						l[i][j - 1] ^= 1
						l[i - 1][j] ^= 1
				elif l[i][j] == 0:
					pass
				else:
					ans.append([i, j, i - 1, j, i - 1, j + 1])
					l[i - 1][j] ^= 1
					l[i][j] ^= 1
					l[i - 1][j + 1] ^= 1
					ans.append([i, j, i, j + 1, i - 1, j + 1])
					l[i][j] ^= 1
					l[i][j + 1] ^= 1
					l[i - 1][j + 1] ^= 1
					ans.append([i, j, i - 1, j, i, j + 1])
					l[i][j] ^= 1
					l[i][j + 1] ^= 1
					l[i - 1][j] ^= 1
			elif j == m - 1:
				if l[i][j] == 0:
					pass
				else:
					ans.append([i, j, i + 1, j, i + 1, j - 1])
					l[i + 1][j] ^= 1
					l[i][j] ^= 1
					l[i + 1][j - 1] ^= 1
					ans.append([i, j, i, j - 1, i + 1, j - 1])
					l[i][j] ^= 1
					l[i][j - 1] ^= 1
					l[i + 1][j - 1] ^= 1
					ans.append([i, j, i + 1, j, i, j - 1])
					l[i][j] ^= 1
					l[i][j - 1] ^= 1
					l[i + 1][j] ^= 1
			elif l[i][j] == 0:
				pass
			else:
				ans.append([i, j, i + 1, j, i + 1, j + 1])
				l[i + 1][j] ^= 1
				l[i][j] ^= 1
				l[i + 1][j + 1] ^= 1
				ans.append([i, j, i, j + 1, i + 1, j + 1])
				l[i][j] ^= 1
				l[i][j + 1] ^= 1
				l[i + 1][j + 1] ^= 1
				ans.append([i, j, i + 1, j, i, j + 1])
				l[i][j] ^= 1
				l[i][j + 1] ^= 1
				l[i + 1][j] ^= 1
	print(len(ans))
	for i in ans:
		for j in range(6):
			if j == 5:
				print(i[j] + 1, end='')
			else:
				print(i[j] + 1, end=' ')
		print()


import os
import sys
from io import BytesIO, IOBase

def main():
	for t in range(int(input())):
		(n, m) = map(int, input().split())
		a = []
		for i in range(n):
			a.append(list(input()))
		ops = []

		def f(b, c, e, f2, g, h):
			ops.append((b + 1, c + 1, e + 1, f2 + 1, g + 1, h + 1))
			a[b][c] = '1' if a[b][c] == '0' else '0'
			a[e][f2] = '1' if a[e][f2] == '0' else '0'
			a[g][h] = '1' if a[g][h] == '0' else '0'
		if m % 2 == 1:
			for i in range(n - 1):
				if a[i][0] == '1':
					f(i, 0, i, 1, i + 1, 1)
			if a[n - 1][0] == '1':
				f(n - 1, 0, n - 1, 1, n - 2, 1)
		for j in range(m % 2, m, 2):
			for i in range(n - 2):
				if a[i][j] == '1':
					f(i, j, i + 1, j, i + 1, j + 1)
				if a[i][j + 1] == '1':
					f(i, j + 1, i + 1, j, i + 1, j + 1)
			q = ''.join([a[n - 2][j], a[n - 2][j + 1], a[n - 1][j], a[n - 1][j + 1]])
			if q == '1111':
				f(n - 2, j, n - 2, j + 1, n - 1, j)
				f(n - 2, j, n - 2, j + 1, n - 1, j + 1)
				f(n - 2, j, n - 1, j, n - 1, j + 1)
				f(n - 2, j + 1, n - 1, j, n - 1, j + 1)
			elif q == '1110':
				f(n - 2, j, n - 2, j + 1, n - 1, j)
			elif q == '1011':
				f(n - 2, j, n - 1, j, n - 1, j + 1)
			elif q == '1101':
				f(n - 2, j, n - 2, j + 1, n - 1, j + 1)
			elif q == '0111':
				f(n - 2, j + 1, n - 1, j, n - 1, j + 1)
			elif q == '1010':
				f(n - 2, j, n - 2, j + 1, n - 1, j + 1)
				f(n - 2, j + 1, n - 1, j, n - 1, j + 1)
			elif q == '1001':
				f(n - 2, j, n - 2, j + 1, n - 1, j)
				f(n - 2, j + 1, n - 1, j, n - 1, j + 1)
			elif q == '1100':
				f(n - 2, j, n - 1, j, n - 1, j + 1)
				f(n - 2, j + 1, n - 1, j, n - 1, j + 1)
			elif q == '0101':
				f(n - 2, j, n - 2, j + 1, n - 1, j)
				f(n - 2, j, n - 1, j, n - 1, j + 1)
			elif q == '0110':
				f(n - 2, j, n - 2, j + 1, n - 1, j + 1)
				f(n - 2, j, n - 1, j, n - 1, j + 1)
			elif q == '0011':
				f(n - 2, j, n - 2, j + 1, n - 1, j)
				f(n - 2, j, n - 2, j + 1, n - 1, j + 1)
			elif q == '1000':
				f(n - 2, j, n - 2, j + 1, n - 1, j)
				f(n - 2, j, n - 2, j + 1, n - 1, j + 1)
				f(n - 2, j, n - 1, j, n - 1, j + 1)
			elif q == '0100':
				f(n - 2, j, n - 2, j + 1, n - 1, j)
				f(n - 2, j, n - 2, j + 1, n - 1, j + 1)
				f(n - 2, j + 1, n - 1, j, n - 1, j + 1)
			elif q == '0010':
				f(n - 2, j, n - 2, j + 1, n - 1, j)
				f(n - 2, j, n - 1, j, n - 1, j + 1)
				f(n - 2, j + 1, n - 1, j, n - 1, j + 1)
			elif q == '0001':
				f(n - 2, j, n - 2, j + 1, n - 1, j + 1)
				f(n - 2, j, n - 1, j, n - 1, j + 1)
				f(n - 2, j + 1, n - 1, j, n - 1, j + 1)
		print(len(ops))
		for op in ops:
			print(op[0], op[1], op[4], op[5], op[2], op[3])
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import os, sys
from io import BytesIO, IOBase

def main():
	for _ in range(int(input())):
		(n, m) = map(int, input().split())
		arr = [list(input().strip()) for _ in range(n)]
		q = []
		(i, j) = (0, 0)
		while i < n:
			if i >= n - 1:
				i = n - 2
			if j >= m - 1:
				j = m - 2
			(a, b, c, d) = ((i, j), (i + 1, j), (i, j + 1), (i + 1, j + 1))
			(on, ze) = ([], [])
			if arr[a[0]][a[1]] == '1':
				on.append(a)
			else:
				ze.append(a)
			if arr[b[0]][b[1]] == '1':
				on.append(b)
			else:
				ze.append(b)
			if arr[c[0]][c[1]] == '1':
				on.append(c)
			else:
				ze.append(c)
			if arr[d[0]][d[1]] == '1':
				on.append(d)
			else:
				ze.append(d)
			if len(on) == 3:
				q.append(on)
			elif len(on) == 2:
				q.append(ze + [on[0]])
				q.append(ze + [on[1]])
			elif len(on) == 1:
				q.append(on + [ze[0], ze[1]])
				q.append([on[0], ze[2], ze[1]])
				q.append([on[0], ze[2], ze[0]])
			elif len(on) == 4:
				q.append(on[:3])
				ze = on[:3]
				on = [on[-1]]
				q.append(on + [ze[0], ze[1]])
				q.append([on[0], ze[2], ze[1]])
				q.append([on[0], ze[2], ze[0]])
			arr[a[0]][a[1]] = '0'
			arr[b[0]][b[1]] = '0'
			arr[c[0]][c[1]] = '0'
			arr[d[0]][d[1]] = '0'
			j += 2
			if j >= m:
				i += 2
				j = 0
		print(len(q))
		for i in q:
			print(i[0][0] + 1, i[0][1] + 1, i[1][0] + 1, i[1][1] + 1, i[2][0] + 1, i[2][1] + 1)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


from sys import stdin

def c(x1, y1, x2, y2, x3, y3):
	ans.append((x1 + 1, y1 + 1, x2 + 1, y2 + 1, x3 + 1, y3 + 1))
	a[x1][y1] ^= 1
	a[x2][y2] ^= 1
	a[x3][y3] ^= 1
	return
tt = int(stdin.readline())
for loop in range(tt):
	(n, m) = map(int, stdin.readline().split())
	a = []
	ans = []
	for i in range(n):
		tmp = list(map(int, list(stdin.readline()[:-1])))
		a.append(tmp)
	for i in range(n - 2):
		for j in range(m):
			if j != m - 1:
				if a[i][j] == 1 and a[i][j + 1] == 1:
					if a[i + 1][j] == 1:
						c(i, j, i, j + 1, i + 1, j)
					else:
						c(i, j, i, j + 1, i + 1, j + 1)
				elif a[i][j] == 1:
					c(i, j, i + 1, j, i + 1, j + 1)
				else:
					continue
			elif a[i][j] == 1:
				c(i, j, i + 1, j, i + 1, j - 1)
	for i in range(n - 2, n - 1):
		for j in range(m - 1):
			if a[i][j] == 1 and a[i + 1][j] == 1:
				if a[i][j + 1] == 1:
					c(i, j, i + 1, j, i, j + 1)
				else:
					c(i, j, i + 1, j, i + 1, j + 1)
			elif a[i][j] == 1:
				c(i, j, i, j + 1, i + 1, j + 1)
			elif a[i + 1][j] == 1:
				c(i + 1, j, i, j + 1, i + 1, j + 1)
			else:
				continue
	if a[n - 1][m - 1] == 0 and a[n - 2][m - 1] == 0:
		pass
	elif a[n - 1][m - 1] == 1 and a[n - 2][m - 1] == 0:
		c(n - 1, m - 1, n - 2, m - 1, n - 2, m - 2)
		c(n - 1, m - 1, n - 1, m - 2, n - 2, m - 2)
		c(n - 1, m - 1, n - 1, m - 2, n - 2, m - 1)
	elif a[n - 1][m - 1] == 0 and a[n - 2][m - 1] == 1:
		c(n - 1, m - 1, n - 1, m - 2, n - 2, m - 1)
		c(n - 1, m - 1, n - 2, m - 1, n - 2, m - 2)
		c(n - 2, m - 2, n - 1, m - 2, n - 2, m - 1)
	else:
		c(n - 1, m - 1, n - 1, m - 2, n - 2, m - 2)
		c(n - 2, m - 2, n - 1, m - 2, n - 2, m - 1)
	print(len(ans))
	for i in ans:
		print(*i)


from copy import deepcopy

def get_moves(matrix_orig, n, m, down, forward):
	matrix = deepcopy(matrix_orig)
	moves = []
	if down:
		delta_i = 1
		i_range = range(n - 1)
		last_i = n - 1
	else:
		delta_i = -1
		i_range = range(n - 1, 0, -1)
		last_i = 0
	if forward:
		delta_j = 1
		j_range = range(m - 1)
		last_j = m - 1
	else:
		delta_j = -1
		j_range = range(m - 1, 0, -1)
		last_j = 0
	for i in i_range:
		for j in j_range:
			if matrix[i][j] == 1 and matrix[i + delta_i][j] == 0:
				matrix[i][j] = 0
				matrix[i][j + delta_j] ^= 1
				matrix[i + delta_i][j + delta_j] ^= 1
				moves.append((i, j, i, j + delta_j, i + delta_i, j + delta_j))
			elif matrix[i][j] == 1 and matrix[i + delta_i][j] == 1 and (matrix[i + delta_i][j + delta_j] == 1):
				matrix[i][j] = 0
				matrix[i + delta_i][j] ^= 1
				matrix[i + delta_i][j + delta_j] ^= 1
				moves.append((i, j, i + delta_i, j, i + delta_i, j + delta_j))
			elif matrix[i][j] == 1:
				matrix[i][j] = 0
				matrix[i + delta_i][j] ^= 1
				matrix[i][j + delta_j] ^= 1
				moves.append((i, j, i + delta_i, j, i, j + delta_j))
		j = last_j
		if matrix[i][j] == 1:
			matrix[i][j] = 0
			matrix[i + delta_i][j] ^= 1
			matrix[i + delta_i][j - delta_j] ^= 1
			moves.append((i, j, i + delta_i, j, i + delta_i, j - delta_j))
	i = last_i
	for j in j_range:
		if matrix[i][j] == 1 and matrix[i][j + delta_j] == 1:
			matrix[i][j] = 0
			matrix[i][j + delta_j] = 0
			moves.append((i, j, i - delta_i, j, i - delta_i, j + delta_j))
			moves.append((i, j + delta_j, i - delta_i, j, i - delta_i, j + delta_j))
		elif matrix[i][j] == 1:
			matrix[i][j] = 0
			moves.append((i, j, i - delta_i, j, i - delta_i, j + delta_j))
			moves.append((i, j, i, j + delta_j, i - delta_i, j + delta_j))
			moves.append((i, j, i - delta_i, j, i, j + delta_j))
	j = last_j
	if matrix[i][j] == 1:
		matrix[i][j] = 0
		moves.append((i, j, i - delta_i, j, i - delta_i, j - delta_j))
		moves.append((i, j, i, j - delta_j, i - delta_i, j - delta_j))
		moves.append((i, j, i - delta_i, j, i, j - delta_j))
	return moves
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	matrix = []
	for _ in range(n):
		matrix.append([int(i) for i in input()])
	moves_1 = get_moves(matrix, n, m, True, True)
	moves_2 = get_moves(matrix, n, m, True, False)
	moves_3 = get_moves(matrix, n, m, False, True)
	moves_4 = get_moves(matrix, n, m, False, False)
	moves = moves_1
	for mvs in [moves_2, moves_3, moves_4]:
		if len(mvs) < len(moves):
			moves = mvs
	print(len(moves))
	for move in moves:
		print(' '.join([str(i + 1) for i in move]))


import sys

def printm():
	for row in M:
		print(''.join(map(str, row)))

def change1(i, j):
	if i:
		di = -1
	else:
		di = 1
	if j:
		dj = -1
	else:
		dj = 1
	out = []
	out.append((i, j, i + di, j, i + di, j + dj))
	out.append((i, j, i, j + dj, i + di, j + dj))
	out.append((i, j, i + di, j, i, j + dj))
	return out

def change3(i, j, pos):
	if pos == 0:
		return [(i, j + 1, i + 1, j, i + 1, j + 1)]
	if pos == 1:
		return [(i, j, i + 1, j, i + 1, j + 1)]
	if pos == 2:
		return [(i, j, i, j + 1, i + 1, j + 1)]
	if pos == 3:
		return [(i, j, i, j + 1, i + 1, j)]

def change2(i, j, pos):
	out = []
	if pos == 0:
		out.append((i, j, i + 1, j, i, j + 1))
		out.append((i + 1, j + 1, i + 1, j, i, j + 1))
	elif pos == 1:
		out.append((i, j, i, j + 1, i + 1, j + 1))
		out.append((i + 1, j, i, j, i + 1, j + 1))
	elif pos == 2:
		out.append((i, j, i, j + 1, i + 1, j + 1))
		out.append((i, j + 1, i + 1, j, i + 1, j + 1))
	elif pos == 3:
		out.append((i, j, i + 1, j, i, j + 1))
		out.append((i, j, i + 1, j, i + 1, j + 1))
	elif pos == 4:
		out.append((i, j, i + 1, j, i + 1, j + 1))
		out.append((i, j + 1, i + 1, j, i + 1, j + 1))
	elif pos == 5:
		out.append((i, j, i + 1, j, i, j + 1))
		out.append((i, j, i, j + 1, i + 1, j + 1))
	return out
t = int(input())
for _t in range(t):
	(n, m) = map(int, sys.stdin.readline().split())
	M = []
	out = []
	for i in range(n):
		M.append(list(map(int, list(sys.stdin.readline().strip()))))
	if n % 2:
		start_i = 1
		for j in range(m):
			if M[0][j]:
				if j == m - 1:
					M[0][j] = 0
					M[1][j] = 1 - M[1][j]
					M[1][j - 1] = 1 - M[1][j - 1]
					out.append((0, j, 1, j, 1, j - 1))
				elif M[0][j + 1]:
					M[0][j] = 0
					M[0][j + 1] = 0
					M[1][j] = 1 - M[1][j]
					out.append((0, j, 0, j + 1, 1, j))
				else:
					M[0][j] = 0
					M[1][j] = 1 - M[1][j]
					M[1][j + 1] = 1 - M[1][j + 1]
					out.append((0, j, 1, j, 1, j + 1))
	else:
		start_i = 0
	if m % 2:
		start_j = 1
		for i in range(start_i, n):
			if M[i][0]:
				if i == n - 1:
					M[i][0] = 0
					M[i][1] = 1 - M[i][1]
					M[i - 1][1] = 1 - M[i - 1][1]
					out.append((i, 0, i, 1, i - 1, 1))
				elif M[i + 1][0]:
					M[i][0] = 0
					M[i + 1][0] = 0
					M[i][1] = 1 - M[i][1]
					out.append((i, 0, i + 1, 0, i, 1))
				else:
					M[i][0] = 0
					M[i][1] = 1 - M[i][1]
					M[i + 1][1] = 1 - M[i + 1][1]
					out.append((i, 0, i, 1, i + 1, 1))
	else:
		start_j = 0
	for i in range(start_i, n, 2):
		for j in range(start_j, m, 2):
			(a, b, c, d) = (M[i][j], M[i][j + 1], M[i + 1][j], M[i + 1][j + 1])
			if a + b + c + d == 1:
				if a:
					out += change1(i, j)
				elif b:
					out += change1(i, j + 1)
				elif c:
					out += change1(i + 1, j)
				else:
					out += change1(i + 1, j + 1)
			elif a + b + c + d == 2:
				if a and d:
					out += change2(i, j, 0)
				elif b and c:
					out += change2(i, j, 1)
				elif a and c:
					out += change2(i, j, 2)
				elif b and d:
					out += change2(i, j, 3)
				elif a and b:
					out += change2(i, j, 4)
				else:
					out += change2(i, j, 5)
			elif a + b + c + d == 3:
				if not a:
					out += change3(i, j, 0)
				elif not b:
					out += change3(i, j, 1)
				elif not c:
					out += change3(i, j, 2)
				else:
					out += change3(i, j, 3)
			elif a + b + c + d == 4:
				out += change3(i, j, 0)
				out += change1(i, j)
	print(len(out))
	for row in out:
		for elem in row:
			print(elem + 1, end=' ')
		print()


t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = []
	for i in range(n):
		l = input()
		l = list(l)
		a.append(l)
	cnt = 0
	l = []
	for i in range(n - 1):
		for j in range(m - 1):
			v1 = int(a[i][j])
			v2 = int(a[i][j + 1])
			v3 = int(a[i + 1][j])
			v4 = int(a[i + 1][j + 1])
			if v1 + v2 + v3 + v4 == 3:
				cnt += 1
				if v2 == 0:
					l.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a[i][j] = '0'
					a[i + 1][j] = '0'
					a[i + 1][j + 1] = '0'
				elif v1 == 0:
					l.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					a[i][j + 1] = '0'
					a[i + 1][j] = '0'
					a[i + 1][j + 1] = '0'
				elif v3 == 0:
					l.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					a[i][j] = '0'
					a[i][j + 1] = '0'
					a[i + 1][j + 1] = '0'
				else:
					l.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					a[i][j] = '0'
					a[i + 1][j] = '0'
					a[i][j + 1] = '0'
			if v1 + v2 + v3 + v4 == 2:
				cnt += 2
				if v1 == 0 and v2 == 0:
					l.append([i + 2, j + 1, i + 1, j + 1, i + 1, j + 2])
					l.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					a[i + 1][j] = '0'
					a[i + 1][j + 1] = '0'
				if v1 == 0 and v3 == 0:
					l.append([i + 1, j + 2, i + 1, j + 1, i + 2, j + 1])
					l.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a[i][j + 1] = '0'
					a[i + 1][j + 1] = '0'
				if v1 == 0 and v4 == 0:
					l.append([i + 1, j + 2, i + 1, j + 1, i + 2, j + 2])
					l.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a[i + 1][j] = '0'
					a[i][j + 1] = '0'
				if v2 == 0 and v3 == 0:
					l.append([i + 2, j + 1, i + 1, j + 1, i + 1, j + 2])
					l.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					a[i][j] = '0'
					a[i + 1][j + 1] = '0'
				if v2 == 0 and v4 == 0:
					l.append([i + 1, j + 2, i + 1, j + 1, i + 2, j + 2])
					l.append([i + 2, j + 1, i + 1, j + 2, i + 2, j + 2])
					a[i][j] = '0'
					a[i + 1][j] = '0'
				if v3 == 0 and v4 == 0:
					l.append([i + 2, j + 1, i + 1, j + 1, i + 2, j + 2])
					l.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					a[i][j] = '0'
					a[i][j + 1] = '0'
			if v1 + v2 + v3 + v4 == 1:
				cnt += 3
				if v1 == 1:
					l.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					l.append([i + 1, j + 2, i + 1, j + 1, i + 2, j + 1])
					l.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					a[i][j] = '0'
				if v2 == 1:
					l.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					l.append([i + 1, j + 2, i + 1, j + 1, i + 2, j + 1])
					l.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					a[i][j + 1] = '0'
				if v3 == 1:
					l.append([i + 2, j + 1, i + 1, j + 1, i + 2, j + 2])
					l.append([i + 1, j + 2, i + 1, j + 1, i + 2, j + 1])
					l.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					a[i + 1][j] = '0'
				if v4 == 1:
					l.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					l.append([i + 2, j + 2, i + 1, j + 1, i + 2, j + 1])
					l.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					a[i + 1][j + 1] = '0'
			if v1 + v2 + v3 + v4 == 4:
				cnt += 4
				l.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
				l.append([i + 2, j + 1, i + 1, j + 1, i + 2, j + 2])
				l.append([i + 1, j + 2, i + 1, j + 1, i + 2, j + 1])
				l.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
				a[i][j] = '0'
				a[i][j + 1] = '0'
				a[i + 1][j] = '0'
				a[i + 1][j + 1] = '0'
	print(cnt)
	for i in range(len(l)):
		print(*l[i])


(s, res) = ([], [])

def solve1(x, y, c1, c2, c3, c4):
	if c1 == '1':
		res.append([x, y, x, y + 1, x + 1, y])
		solve2(x, y, '0', '1', '1', '0')
	elif c2 == '1':
		res.append([x, y, x, y + 1, x + 1, y])
		solve2(x, y, '1', '0', '1', '0')
	elif c3 == '1':
		res.append([x, y, x, y + 1, x + 1, y])
		solve2(x, y, '1', '1', '0', '0')
	elif c4 == '1':
		res.append([x, y, x, y + 1, x + 1, y + 1])
		solve2(x, y, '1', '1', '0', '0')

def solve2(x, y, c1, c2, c3, c4):
	if c1 == '0' and c2 == '0':
		res.append([x, y, x, y + 1, x + 1, y])
		solve3(x, y, '1', '1', '0', '1')
	elif c1 == '0' and c3 == '0':
		res.append([x, y, x + 1, y, x, y + 1])
		solve3(x, y, '1', '0', '1', '1')
	elif c1 == '0' and c4 == '0':
		res.append([x, y, x + 1, y, x + 1, y + 1])
		solve3(x, y, '1', '1', '0', '1')
	elif c2 == '0' and c3 == '0':
		res.append([x, y, x + 1, y, x, y + 1])
		solve3(x, y, '0', '1', '1', '1')
	elif c2 == '0' and c4 == '0':
		res.append([x, y, x, y + 1, x + 1, y + 1])
		solve3(x, y, '0', '1', '1', '1')
	elif c3 == '0' and c4 == '0':
		res.append([x, y, x + 1, y, x + 1, y + 1])
		solve3(x, y, '0', '1', '1', '1')

def solve3(x, y, c1, c2, c3, c4):
	if c1 == '0':
		res.append([x + 1, y, x, y + 1, x + 1, y + 1])
	elif c2 == '0':
		res.append([x + 1, y, x, y, x + 1, y + 1])
	elif c3 == '0':
		res.append([x, y, x, y + 1, x + 1, y + 1])
	elif c4 == '0':
		res.append([x + 1, y, x, y + 1, x, y])

def solve4(x, y):
	res.append([x, y, x, y + 1, x + 1, y])
	solve1(x, y, '0', '0', '0', '1')

def trans(x1, y1, x2, y2, x3, y3):
	s[x1][y1] = '1' if s[x1][y1] == '0' else '0'
	s[x2][y2] = '1' if s[x2][y2] == '0' else '0'
	s[x3][y3] = '1' if s[x3][y3] == '0' else '0'
	res.append([x1 + 1, y1 + 1, x2 + 1, y2 + 1, x3 + 1, y3 + 1])
T = int(input())
for _ in range(T):
	(n, m) = map(int, input().split())
	s.clear()
	res.clear()
	for i in range(n):
		s.append(list(input()))
	if m % 2:
		for i in range(n - 1):
			if s[i][m - 1] == '1' and s[i + 1][m - 1] == '0':
				trans(i, m - 1, i, m - 2, i + 1, m - 2)
			elif s[i][m - 1] == '0' and s[i + 1][m - 1] == '1':
				trans(i + 1, m - 1, i, m - 2, i + 1, m - 2)
			elif s[i][m - 1] == '1' and s[i + 1][m - 1] == '1':
				trans(i + 1, m - 1, i, m - 1, i + 1, m - 2)
	for j in range(0, m - 1, 2):
		if n % 2:
			if s[n - 1][j] == '1' and s[n - 1][j + 1] == '0':
				trans(n - 1, j, n - 2, j, n - 2, j + 1)
			elif s[n - 1][j] == '0' and s[n - 1][j + 1] == '1':
				trans(n - 1, j + 1, n - 2, j, n - 2, j + 1)
			elif s[n - 1][j] == '1' and s[n - 1][j + 1] == '1':
				trans(n - 1, j, n - 2, j, n - 1, j + 1)
		for i in range(0, n - 1, 2):
			num = 0
			if s[i][j] == '1':
				num += 1
			if s[i][j + 1] == '1':
				num += 1
			if s[i + 1][j] == '1':
				num += 1
			if s[i + 1][j + 1] == '1':
				num += 1
			if num == 1:
				solve1(i + 1, j + 1, s[i][j], s[i][j + 1], s[i + 1][j], s[i + 1][j + 1])
			if num == 2:
				solve2(i + 1, j + 1, s[i][j], s[i][j + 1], s[i + 1][j], s[i + 1][j + 1])
			if num == 3:
				solve3(i + 1, j + 1, s[i][j], s[i][j + 1], s[i + 1][j], s[i + 1][j + 1])
			if num == 4:
				solve4(i + 1, j + 1)
	print(len(res))
	for arr in res:
		print(' '.join(('%s' % d for d in arr)))


def generate(x1, x2, n1, n2):
	ans = []
	if x1 != n1 or x2 != n2:
		ans.append(x1)
		ans.append(x2)
	if x1 + 1 != n1 or x2 != n2:
		ans.append(x1 + 1)
		ans.append(x2)
	if x1 != n1 or x2 + 1 != n2:
		ans.append(x1)
		ans.append(x2 + 1)
	if x1 + 1 != n1 or x2 + 1 != n2:
		ans.append(x1 + 1)
		ans.append(x2 + 1)
	return ans

def gen_seq(x1, x2, c):
	ans = []
	x1 += 1
	x2 += 1
	for i in c:
		if i == 1:
			ans.append(generate(x1, x2, x1, x2))
		elif i == 2:
			ans.append(generate(x1, x2, x1, x2 + 1))
		elif i == 3:
			ans.append(generate(x1, x2, x1 + 1, x2))
		else:
			ans.append(generate(x1, x2, x1 + 1, x2 + 1))
	return ans
for t in range(int(input())):
	(n, m) = map(int, input().split())
	arr = [list(map(int, list(input()))) for i in range(n)]
	ans = []
	count = 0
	for row in range(n):
		for col in range(m):
			r = row
			c = col
			if arr[row][col] == 0:
				continue
			if c == 0 and r == 0:
				for i in gen_seq(r, c, (3, 2, 4)):
					ans.append(i)
			elif row == 0:
				for i in gen_seq(r, c - 1, (4, 1, 3)):
					ans.append(i)
			elif col == 0:
				for i in gen_seq(r - 1, c, (4, 1, 2)):
					ans.append(i)
			else:
				for i in gen_seq(r - 1, c - 1, (3, 2, 1)):
					ans.append(i)
			count += 3
	print(count)
	for i in ans:
		print(' '.join(map(str, i)))


def convert(x, y):
	return str(x) + ' ' + str(y)

def solve(arr, x1, y1, x2, y2, x3, y3, x4, y4, ty):
	dict = {}
	for i in arr:
		dict[convert(i[0], i[1])] = 1
	arr2 = []
	if convert(x1, y1) not in dict:
		arr2.append([x1, y1])
	if convert(x2, y2) not in dict:
		arr2.append([x2, y2])
	if convert(x3, y3) not in dict:
		arr2.append([x3, y3])
	if convert(x4, y4) not in dict:
		arr2.append([x4, y4])
	final = []
	if ty == 2:
		temp = []
		temp.append([arr2[0], arr2[1], arr[0]])
		temp.append([arr2[0], arr2[1], arr[1]])
	if ty == 1:
		temp = []
		temp.append([arr2[0], arr2[1], arr[0]])
		temp.append([arr2[0], arr[0], arr2[2]])
		temp.append([arr2[1], arr[0], arr2[2]])
	return temp
t = int(input())

def tolist(s):
	arr = []
	for i in s:
		arr.append(i)
	return arr
for test in range(t):
	(n, m) = map(int, input().split())
	arr = []
	for i in range(n):
		s = input()
		te = tolist(s)
		arr.append(te)
	ans = []
	count = 0
	for i in range(n - 1):
		for j in range(m - 1):
			temp = []
			c = 0
			if arr[i][j] == '1':
				c += 1
				temp.append([i, j])
			if arr[i + 1][j] == '1':
				c += 1
				temp.append([i + 1, j])
			if arr[i][j + 1] == '1':
				c += 1
				temp.append([i, j + 1])
			if arr[i + 1][j + 1] == '1':
				c += 1
				temp.append([i + 1, j + 1])
			if c >= 3:
				count += 1
				ans.append(temp[:3])
				for ind in range(3):
					x = temp[ind][0]
					y = temp[ind][1]
					arr[x][y] = '0'
	for i in range(n - 1):
		for j in range(m - 1):
			temp = []
			c = 0
			if arr[i][j] == '1':
				c += 1
				temp.append([i, j])
			if arr[i + 1][j] == '1':
				c += 1
				temp.append([i + 1, j])
			if arr[i][j + 1] == '1':
				c += 1
				temp.append([i, j + 1])
			if arr[i + 1][j + 1] == '1':
				c += 1
				temp.append([i + 1, j + 1])
			if c == 2:
				count += 2
				ans.extend(solve(temp, i, j, i + 1, j, i, j + 1, i + 1, j + 1, 2))
				for ind in range(2):
					x = temp[ind][0]
					y = temp[ind][1]
					arr[x][y] = '0'
	for i in range(n - 1):
		for j in range(m - 1):
			temp = []
			c = 0
			if arr[i][j] == '1':
				c += 1
				temp.append([i, j])
			if arr[i + 1][j] == '1':
				c += 1
				temp.append([i + 1, j])
			if arr[i][j + 1] == '1':
				c += 1
				temp.append([i, j + 1])
			if arr[i + 1][j + 1] == '1':
				c += 1
				temp.append([i + 1, j + 1])
			if c == 1:
				count += 3
				ans.extend(solve(temp, i, j, i + 1, j, i, j + 1, i + 1, j + 1, 1))
				for ind in range(1):
					x = temp[ind][0]
					y = temp[ind][1]
					arr[x][y] = '0'
	print(count)
	for i in ans:
		for j in i:
			print(j[0] + 1, j[1] + 1, end=' ')
		print()


import math

def selectTiles(mepas, x, y):
	ans = []
	if mepas[x][y] == 1:
		ans.append(x + 1)
		ans.append(y + 1)
		mepas[x][y] = 0 if mepas[x][y] else 1
	if mepas[x][y + 1] == 1 or len(ans) < 2:
		ans.append(x + 1)
		ans.append(y + 2)
		mepas[x][y + 1] = 0 if mepas[x][y + 1] else 1
	if mepas[x + 1][y] == 1 or len(ans) < 4:
		ans.append(x + 2)
		ans.append(y + 1)
		mepas[x + 1][y] = 0 if mepas[x + 1][y] else 1
	if len(ans) < 6:
		ans.append(x + 2)
		ans.append(y + 2)
		mepas[x + 1][y + 1] = 0 if mepas[x + 1][y + 1] else 1
	return (mepas, tuple(ans))

def selectTiles2(mepas, x, y):
	ans = []
	if mepas[x][y] == 1:
		ans.append(x + 1)
		ans.append(y + 1)
		mepas[x][y] = 0 if mepas[x][y] else 1
	if mepas[x + 1][y] == 1 or len(ans) < 2:
		ans.append(x + 2)
		ans.append(y + 1)
		mepas[x + 1][y] = 0 if mepas[x + 1][y] else 1
	if mepas[x][y + 1] == 1 or len(ans) < 4:
		ans.append(x + 1)
		ans.append(y + 2)
		mepas[x][y + 1] = 0 if mepas[x][y + 1] else 1
	if len(ans) < 6:
		ans.append(x + 2)
		ans.append(y + 2)
		mepas[x + 1][y + 1] = 0 if mepas[x + 1][y + 1] else 1
	return (mepas, tuple(ans))

def countOnes(mepas, x, y):
	m = 0
	m += mepas[x][y]
	m += mepas[x + 1][y]
	m += mepas[x][y + 1]
	m += mepas[x + 1][y + 1]
	return m

def finishingTouch(mepas, x, y):
	ans = []
	c = countOnes(mepas, x, y)
	if c == 1:
		(mepas, a1) = oneLeft(mepas, x, y)
		(mepas, a2) = twoLeft(mepas, x, y)
		(mepas, a3) = selectTiles(mepas, x, y)
		ans.append(a1)
		ans.append(a2)
		ans.append(a3)
	elif c == 2:
		(mepas, a2) = twoLeft(mepas, x, y)
		(mepas, a3) = selectTiles(mepas, x, y)
		ans.append(a2)
		ans.append(a3)
	elif c == 3:
		(mepas, a3) = selectTiles(mepas, x, y)
		ans.append(a3)
	elif c == 4:
		(mepas, a0) = selectTiles(mepas, x, y)
		(mepas, a1) = oneLeft(mepas, x, y)
		(mepas, a2) = twoLeft(mepas, x, y)
		(mepas, a3) = selectTiles(mepas, x, y)
		ans.append(a0)
		ans.append(a1)
		ans.append(a2)
		ans.append(a3)
	return (mepas, ans)

def oneLeft(mepas, x, y):
	ones = 1
	zeros = 2
	ans = []
	for xx in range(2):
		for yy in range(2):
			if mepas[x + xx][y + yy] == 1 and ones > 0:
				ones -= 1
				ans.append(x + xx + 1)
				ans.append(y + yy + 1)
				mepas[x + xx][y + yy] = 0
			elif mepas[x + xx][y + yy] == 0 and zeros > 0:
				zeros -= 1
				ans.append(x + xx + 1)
				ans.append(y + yy + 1)
				mepas[x + xx][y + yy] = 1
	return (mepas, tuple(ans))

def twoLeft(mepas, x, y):
	ones = 1
	zeros = 2
	ans = []
	for xx in range(2):
		for yy in range(2):
			if mepas[x + xx][y + yy] == 1 and ones > 0:
				ones -= 1
				ans.append(x + xx + 1)
				ans.append(y + yy + 1)
				mepas[x + xx][y + yy] = 0
			elif mepas[x + xx][y + yy] == 0 and zeros > 0:
				zeros -= 1
				ans.append(x + xx + 1)
				ans.append(y + yy + 1)
				mepas[x + xx][y + yy] = 1
	return (mepas, tuple(ans))
T = int(input())
for t in range(T):
	(X, Y) = map(int, input().split())
	mepas = []
	ANS = []
	for x in range(X):
		y = [int(c) for c in input()]
		mepas.append(y)
	if X % 2 == 1:
		x = 0
		for y in range(Y - 1):
			if mepas[x][y] == 1 or (y == Y - 2 and mepas[x][y + 1] == 1):
				(mepas, temporary) = selectTiles(mepas, x, y)
				ANS.append(temporary)
	if Y % 2 == 1:
		y = 0
		for x in range(X - 1):
			if mepas[x][y] == 1 or (x == X - 2 and mepas[x + 1][y] == 1):
				(mepas, temporary) = selectTiles2(mepas, x, y)
				ANS.append(temporary)
	for x in range(0, X - 1, 2):
		x += X % 2
		for y in range(0, Y - 1, 2):
			y += Y % 2
			(mepas, temporary) = finishingTouch(mepas, x, y)
			ANS = ANS + temporary
	print(len(ANS))
	for a in ANS:
		print(*a)


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	l = []
	for i in range(n):
		l.append(input())
	ll = []
	for i in range(n):
		for j in range(m):
			if l[i][j] == '1':
				if i != n - 1 and j != m - 1:
					ll.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					ll.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					ll.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
				elif i == n - 1 and j != m - 1:
					ll.append([i + 1, j + 1, i, j + 1, i + 1, j + 2])
					ll.append([i + 1, j + 1, i, j + 1, i, j + 2])
					ll.append([i + 1, j + 1, i + 1, j + 2, i, j + 2])
				elif i != n - 1 and j == m - 1:
					ll.append([i + 1, j + 1, i + 1, j, i + 2, j + 1])
					ll.append([i + 1, j + 1, i + 1, j, i + 2, j])
					ll.append([i + 1, j + 1, i + 2, j + 1, i + 2, j])
				elif i == n - 1 and j == m - 1:
					ll.append([i + 1, j + 1, i + 1, j, i, j + 1])
					ll.append([i + 1, j + 1, i + 1, j, i, j])
					ll.append([i + 1, j + 1, i, j + 1, i, j])
	print(len(ll))
	for i in ll:
		print(*i)


import sys
input = sys.stdin.readline

def main():
	(n, m) = map(int, input().split())
	alst = [list(input().strip()) for _ in range(n)]
	rev = {'1': '0', '0': '1'}
	ans = []
	for i in range(n - 2):
		for j in range(m - 2):
			if alst[i][j] == '1':
				alst[i][j] = '0'
				alst[i + 1][j] = rev[alst[i + 1][j]]
				alst[i][j + 1] = rev[alst[i][j + 1]]
				ans.append((i + 1, j + 1, i + 2, j + 1, i + 1, j + 2))
	i = n - 1
	for j in range(m - 2):
		if alst[i][j] == '1' and alst[i - 1][j] == '1':
			alst[i][j] = '0'
			alst[i - 1][j] = '0'
			alst[i][j + 1] = rev[alst[i][j + 1]]
			ans.append((i + 1, j + 1, i, j + 1, i + 1, j + 2))
		elif alst[i][j] == '1':
			alst[i][j] = '0'
			alst[i - 1][j + 1] = rev[alst[i - 1][j + 1]]
			alst[i][j + 1] = rev[alst[i][j + 1]]
			ans.append((i + 1, j + 1, i, j + 2, i + 1, j + 2))
		elif alst[i - 1][j] == '1':
			alst[i - 1][j] = '0'
			alst[i - 1][j + 1] = rev[alst[i - 1][j + 1]]
			alst[i][j + 1] = rev[alst[i][j + 1]]
			ans.append((i, j + 1, i, j + 2, i + 1, j + 2))
	j = m - 1
	for i in range(n - 2):
		if alst[i][j] == '1' and alst[i][j - 1] == '1':
			alst[i][j] = '0'
			alst[i][j - 1] = '0'
			alst[i + 1][j] = rev[alst[i + 1][j]]
			ans.append((i + 1, j + 1, i + 1, j, i + 2, j + 1))
		elif alst[i][j] == '1':
			alst[i][j] = '0'
			alst[i + 1][j - 1] = rev[alst[i + 1][j - 1]]
			alst[i + 1][j] = rev[alst[i + 1][j]]
			ans.append((i + 1, j + 1, i + 2, j, i + 2, j + 1))
		elif alst[i][j - 1] == '1':
			alst[i][j - 1] = '0'
			alst[i + 1][j - 1] = rev[alst[i + 1][j - 1]]
			alst[i + 1][j] = rev[alst[i + 1][j]]
			ans.append((i + 1, j, i + 2, j, i + 2, j + 1))
	blst = [alst[-2][-2:], alst[-1][-2:]]
	cnt = 0
	one = []
	for i in range(2):
		for j in range(2):
			if blst[i][j] == '1':
				one.append((i, j))
				cnt += 1
	lst = [(0, 0), (0, 1), (1, 0), (1, 1)]
	if cnt == 0:
		pass
	if cnt == 4:
		one = [(1, 1)]
		tmp = []
		tmp.append(n - 1)
		tmp.append(m - 1)
		tmp.append(n)
		tmp.append(m - 1)
		tmp.append(n - 1)
		tmp.append(m)
		cnt = 1
		ans.append(tmp)
	if cnt == 1:
		tmp = [n - 1 + one[0][0], m - 1 + one[0][1]]
		sub = 1
		for l in lst:
			if l == one[0]:
				continue
			tmp.append(n - 1 + l[0])
			tmp.append(m - 1 + l[1])
			one.append(l)
			sub += 1
			if sub == 3:
				break
		ans.append(tmp)
		one = one[1:]
		cnt = 2
	if cnt == 2:
		tmp = [n - 1 + one[0][0], m - 1 + one[0][1]]
		for l in lst:
			if l in one:
				continue
			tmp.append(n - 1 + l[0])
			tmp.append(m - 1 + l[1])
			one.append(l)
		ans.append(tmp)
		one = one[1:]
		cnt = 3
	if cnt == 3:
		tmp = []
		for (ii, jj) in one:
			tmp.append(n - 1 + ii)
			tmp.append(m - 1 + jj)
		ans.append(tmp)
		cnt = 0
	print(len(ans))
	for row in ans:
		print(*row)
for _ in range(int(input())):
	main()


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	grid = []
	for _ in range(n):
		row = [int(x) for x in input()]
		grid.append(row)

	def get1(i, j):
		ret = []
		zero = 0
		for (si, sj) in [(i, j), (i + 1, j), (i, j + 1), (i + 1, j + 1)]:
			if grid[si][sj]:
				grid[si][sj] = 0
				ret.append((si, sj))
			elif zero < 2:
				zero += 1
				grid[si][sj] = 1
				ret.append((si, sj))
		assert len(ret) == 3
		return ret + get2(i, j)

	def get2(i, j):
		ret = []
		done = False
		for (si, sj) in [(i, j), (i + 1, j), (i, j + 1), (i + 1, j + 1)]:
			if not grid[si][sj]:
				grid[si][sj] = 1
				ret.append((si, sj))
			elif not done:
				done = True
				grid[si][sj] = 0
				ret.append((si, sj))
		assert len(ret) == 3
		return ret + get3(i, j)

	def get3(i, j):
		ret = []
		for (si, sj) in [(i, j), (i + 1, j), (i, j + 1), (i + 1, j + 1)]:
			if grid[si][sj]:
				grid[si][sj] = 0
				ret.append((si, sj))
		assert len(ret) == 3
		return ret

	def get4(i, j):
		ret = []
		for (si, sj) in [(i, j), (i + 1, j), (i, j + 1)]:
			grid[si][sj] = 0
			ret.append((si, sj))
		assert len(ret) == 3
		return ret + get1(i, j)
	ans = []
	for i in range(n - 1):
		for j in range(m - 1):
			(p1, p2, p3, p4) = (grid[i][j], grid[i + 1][j], grid[i][j + 1], grid[i + 1][j + 1])
			s = p1 + p2 + p3 + p4
			if s == 0:
				continue
			elif s == 1:
				ans.extend(get1(i, j))
			elif s == 2:
				ans.extend(get2(i, j))
			elif s == 3:
				ans.extend(get3(i, j))
			else:
				ans.extend(get4(i, j))
	print(len(ans) // 3)
	for i in range(0, len(ans), 3):
		print(ans[i][0] + 1, ans[i][1] + 1, ans[i + 1][0] + 1, ans[i + 1][1] + 1, ans[i + 2][0] + 1, ans[i + 2][1] + 1)


res = []

def move(table, tup):
	(a, b, c, d, e, f) = tup
	res.append((a, b, c, d, e, f))
	table[a][b] = 1 - table[a][b]
	table[c][d] = 1 - table[c][d]
	table[e][f] = 1 - table[e][f]

def solve22(n1, m1, n, m, table):
	cur = [table[n1][m1], table[n1][m1 + 1], table[n1 + 1][m1], table[n1 + 1][m1 + 1]]
	if cur == [0, 0, 0, 0]:
		return
	cnt1 = 0
	for c in cur:
		if c == 1:
			cnt1 += 1
	l = []
	if cnt1 == 3:
		for n2 in range(n1, n):
			for m2 in range(m1, m):
				if table[n2][m2] == 1:
					l += [n2, m2]
		move(table, tuple(l))
	else:
		for n2 in range(n1, n):
			for m2 in range(m1, m):
				if table[n2][m2] == 1:
					l += [n2, m2]
					if n2 - 1 >= n1:
						l += [n2 - 1, m2]
					if n2 + 1 < n:
						l += [n2 + 1, m2]
					if m2 - 1 >= m1:
						l += [n2, m2 - 1]
					if m2 + 1 < m:
						l += [n2, m2 + 1]
					move(table, tuple(l))
					solve22(n1, m1, n, m, table)
					return

def solve2m(n1, m1, n, m, table):
	if m - m1 == 2:
		solve22(n1, m1, n, m, table)
		return
	if table[n1][m1] == 1 and table[n1 + 1][m1] == 1:
		t = (n1, m1, n1 + 1, m1, n1, m1 + 1)
		move(table, t)
	elif table[n1][m1] == 1 and table[n1 + 1][m1] == 0:
		t = (n1, m1, n1 + 1, m1 + 1, n1, m1 + 1)
		move(table, t)
	elif table[n1][m1] == 0 and table[n1 + 1][m1] == 1:
		t = (n1 + 1, m1, n1 + 1, m1 + 1, n1, m1 + 1)
		move(table, t)
	solve2m(n1, m1 + 1, n, m, table)

def solve(n1, m1, n, m, table):
	if n - n1 == 2:
		solve2m(n1, m1, n, m, table)
		return
	for j in range(0, m - 1):
		if table[n1][j] == 1:
			t = (n1, j, n1 + 1, j, n1 + 1, j + 1)
			move(table, t)
	if table[n1][m - 1] == 1:
		t = (n1, m - 1, n1 + 1, m - 1, n1 + 1, m - 2)
		move(table, t)
	solve(n1 + 1, m1, n, m, table)
t = int(input())
for tt in range(t):
	(n, m) = map(int, input().split())
	table = []
	res = []
	for i in range(n):
		row = input()
		table.append(row)
	table = [[ord(c) - ord('0') for c in row] for row in table]
	solve(0, 0, n, m, table)
	print(len(res))
	for (a, b, c, d, e, f) in res:
		print(a + 1, b + 1, c + 1, d + 1, e + 1, f + 1)


import os
from io import BytesIO, IOBase
import sys
from collections import defaultdict, deque, Counter
from bisect import *
from math import sqrt, pi, ceil, log, inf, gcd, floor
from itertools import permutations
from copy import deepcopy
from heapq import *

def lcm(a, b):
	return a * b // gcd(a, b)

def main():
	for _ in range(int(input())):
		(n, m) = map(int, input().split())
		a = []
		for i in range(n):
			a.append(list(map(int, input().rstrip())))
		b = []
		for i in range(n - 1):
			for j in range(m):
				if j != m - 1:
					if a[i][j] == 1:
						b.append([i, j])
						b.append([i + 1, j])
						b.append([i + 1, j + 1])
						a[i][j] = int(not a[i][j])
						a[i + 1][j] = int(not a[i + 1][j])
						a[i + 1][j + 1] = int(not a[i + 1][j + 1])
				elif a[i][j] == 1:
					b.append([i, j])
					b.append([i + 1, j])
					b.append([i + 1, j - 1])
					a[i][j] = int(not a[i][j])
					a[i + 1][j] = int(not a[i + 1][j])
					a[i + 1][j - 1] = int(not a[i + 1][j - 1])
		i = n - 1
		x = 0
		for j in range(m - 2):
			if a[i][j] == 1 or a[i - 1][j] == 1:
				if a[i][j] == 1 and a[i - 1][j] == 1:
					b.append([i, j])
					b.append([i - 1, j])
					a[i][j] = int(not a[i][j])
					a[i - 1][j] = int(not a[i - 1][j])
				elif a[i][j] == 1:
					b.append([i, j])
					b.append([i - 1, j + 1])
					a[i][j] = int(not a[i][j])
					a[i - 1][j + 1] = int(not a[i - 1][j + 1])
				else:
					b.append([i - 1, j])
					b.append([i - 1, j + 1])
					a[i - 1][j] = int(not a[i - 1][j])
					a[i - 1][j + 1] = int(not a[i - 1][j + 1])
				b.append([i, j + 1])
				a[i][j + 1] = int(not a[i][j + 1])
				x += 1
		z = (a[-1][-1] == 0) + (a[-1][-2] == 0) + (a[-2][-1] == 0) + (a[-2][-2] == 0)
		f = 0
		if z == 3 and len(b) // 3 == n * m - 2:
			f = 1
			b[-3 * (x + 2)] = [-1, -1]
			a[-2][-2] = int(not a[-2][-2])
			a[-1][-2] = int(not a[-1][-2])
			a[-1][-1] = int(not a[-1][-1])
		z = (a[-1][-1] == 0) + (a[-1][-2] == 0) + (a[-2][-1] == 0) + (a[-2][-2] == 0)
		if z == 1:
			b.append([n - 1, m - 1])
			b.append([n - 1, m - 2])
			b.append([n - 2, m - 2])
		elif z == 2 or z == 3:
			if z == 3:
				a[n - 1][m - 2] = int(not a[n - 1][m - 2])
				a[n - 1][m - 1] = int(not a[n - 1][m - 1])
				a[n - 2][m - 2] = int(not a[n - 2][m - 2])
				b.append([n - 2, m - 2])
				b.append([n - 1, m - 2])
				b.append([n - 1, m - 1])
			if a[-2][-2] == 0:
				b.append([n - 2, m - 2])
				b.append([n - 2, m - 1])
				b.append([n - 1, m - 2])
				b.append([n - 1, m - 1])
				b.append([n - 2, m - 2])
				b.append([n - 2, m - 1])
			elif a[-1][-2] == 0:
				b.append([n - 2, m - 2])
				b.append([n - 1, m - 2])
				b.append([n - 2, m - 1])
				b.append([n - 1, m - 1])
				b.append([n - 1, m - 2])
				b.append([n - 2, m - 1])
			elif a[-1][-1] == 0:
				b.append([n - 2, m - 1])
				b.append([n - 1, m - 1])
				b.append([n - 2, m - 2])
				b.append([n - 1, m - 1])
				b.append([n - 2, m - 1])
				b.append([n - 1, m - 2])
		print(len(b) // 3 - f)
		for i in range(0, len(b), 3):
			if b[i][0] != -1:
				print(b[i][0] + 1, b[i][1] + 1, b[i + 1][0] + 1, b[i + 1][1] + 1, b[i + 2][0] + 1, b[i + 2][1] + 1)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	l = []
	for i in range(n):
		it = list(input())
		for kt in range(m):
			if it[kt] == '0':
				it[kt] = '1'
			else:
				it[kt] = '0'
		l.append(it)
	ans = []

	def help(i, j, h, k):
		if i == h and j == k:
			ans.append((i, j, i + 1, j, i, j + 1))
			ans.append((i, j, i + 1, j, i + 1, j + 1))
			ans.append((i, j, i, j + 1, i + 1, j + 1))
			l[h][k] = '1'
		elif i == h and j + 1 == k:
			ans.append((i, j, i, j + 1, i + 1, j + 1))
			ans.append((i, j, i + 1, j, i, j + 1))
			ans.append((i, j + 1, i + 1, j, i + 1, j + 1))
			l[h][k] = '1'
		elif i + 1 == h and j == k:
			ans.append((i, j, i + 1, j, i + 1, j + 1))
			ans.append((i, j, i, j + 1, i + 1, j))
			ans.append((i + 1, j, i, j + 1, i + 1, j + 1))
			l[h][k] = '1'
		elif i + 1 == h and j + 1 == k:
			ans.append((i, j + 1, i + 1, j, i + 1, j + 1))
			ans.append((i, j, i + 1, j, i + 1, j + 1))
			ans.append((i, j, i, j + 1, i + 1, j + 1))
			l[h][k] = '1'

	def helper(x, y):
		if l[i][j] == '0' and l[i][j + 1] == '0' and (l[i + 1][j] == '0') and (l[i + 1][j + 1] == '0'):
			l[i][j] = '1'
			l[i][j + 1] = '1'
			l[i + 1][j] = '1'
			ans.append((i, j, i, j + 1, i + 1, j))
			help(i, j, i + 1, j + 1)
		elif l[i][j] == '0' and l[i][j + 1] == '1' and (l[i + 1][j] == '1') and (l[i + 1][j + 1] == '1'):
			help(i, j, i, j)
		elif l[i][j] == '1' and l[i][j + 1] == '0' and (l[i + 1][j] == '1') and (l[i + 1][j + 1] == '1'):
			help(i, j, i, j + 1)
		elif l[i][j] == '1' and l[i][j + 1] == '1' and (l[i + 1][j] == '0') and (l[i + 1][j + 1] == '1'):
			help(i, j, i + 1, j)
		elif l[i][j] == '1' and l[i][j + 1] == '1' and (l[i + 1][j] == '1') and (l[i + 1][j + 1] == '0'):
			help(i, j, i + 1, j + 1)
		elif l[i][j] == '0' and l[i][j + 1] == '0' and (l[i + 1][j] == '1') and (l[i + 1][j + 1] == '1'):
			l[i][j] = '1'
			l[i][j + 1] = '1'
			l[i + 1][j + 1] = '0'
			ans.append((i, j, i, j + 1, i + 1, j + 1))
			help(i, j, i + 1, j + 1)
		elif l[i][j] == '1' and l[i][j + 1] == '0' and (l[i + 1][j] == '1') and (l[i + 1][j + 1] == '0'):
			l[i][j] = '0'
			l[i][j + 1] = '1'
			l[i + 1][j + 1] = '1'
			ans.append((i, j, i, j + 1, i + 1, j + 1))
			help(i, j, i, j)
		elif l[i][j] == '1' and l[i][j + 1] == '1' and (l[i + 1][j] == '0') and (l[i + 1][j + 1] == '0'):
			l[i][j] = '0'
			l[i + 1][j] = '1'
			l[i + 1][j + 1] = '1'
			ans.append((i, j, i + 1, j, i + 1, j + 1))
			help(i, j, i, j)
		elif l[i][j] == '0' and l[i][j + 1] == '1' and (l[i + 1][j] == '0') and (l[i + 1][j + 1] == '1'):
			l[i][j] = '1'
			l[i][j + 1] = '0'
			l[i + 1][j] = '1'
			ans.append((i, j, i, j + 1, i + 1, j))
			help(i, j, i, j + 1)
		elif l[i][j] == '0' and l[i][j + 1] == '1' and (l[i + 1][j] == '1') and (l[i + 1][j + 1] == '0'):
			l[i][j] = '1'
			l[i + 1][j + 1] = '1'
			ans.append((i, j, i, j + 1, i + 1, j))
			ans.append((i, j + 1, i + 1, j, i + 1, j + 1))
		elif l[i][j] == '1' and l[i][j + 1] == '0' and (l[i + 1][j] == '0') and (l[i + 1][j + 1] == '1'):
			l[i][j + 1] = '1'
			l[i + 1][j] = '1'
			ans.append((i, j, i + 1, j, i + 1, j + 1))
			ans.append((i, j, i, j + 1, i + 1, j + 1))
		elif l[i][j] == '1' and l[i][j + 1] == '0' and (l[i + 1][j] == '0') and (l[i + 1][j + 1] == '0'):
			l[i][j + 1] = '1'
			l[i + 1][j] = '1'
			l[i + 1][j + 1] = '1'
			ans.append((i, j + 1, i + 1, j, i + 1, j + 1))
		elif l[i][j] == '0' and l[i][j + 1] == '1' and (l[i + 1][j] == '0') and (l[i + 1][j + 1] == '0'):
			l[i][j] = '1'
			l[i + 1][j] = '1'
			l[i + 1][j + 1] = '1'
			ans.append((i, j, i + 1, j, i + 1, j + 1))
		elif l[i][j] == '0' and l[i][j + 1] == '0' and (l[i + 1][j] == '1') and (l[i + 1][j + 1] == '0'):
			l[i][j] = '1'
			l[i][j + 1] = '1'
			l[i + 1][j + 1] = '1'
			ans.append((i, j, i, j + 1, i + 1, j + 1))
		elif l[i][j] == '0' and l[i][j + 1] == '0' and (l[i + 1][j] == '0') and (l[i + 1][j + 1] == '1'):
			l[i][j] = '1'
			l[i + 1][j] = '1'
			l[i][j + 1] = '1'
			ans.append((i, j, i + 1, j, i, j + 1))
	i = 0
	while i < n:
		j = 0
		while j < m:
			helper(i, j)
			j += 2
			if m % 2 == 1 and j == m - 1:
				j -= 1
		i += 2
		if n % 2 == 1 and i == n - 1:
			i -= 1
	print(len(ans))
	for w in ans:
		for r in w:
			print(r + 1, end=' ')
		print()


global mat

def calc(a, b, c, d, e, f):
	mat[a - 1][b - 1] = str(int(mat[a - 1][b - 1]) ^ 1)
	mat[c - 1][d - 1] = str(int(mat[c - 1][d - 1]) ^ 1)
	mat[e - 1][f - 1] = str(int(mat[e - 1][f - 1]) ^ 1)
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	mat = []
	for i in range(n):
		row = list(input())
		mat.append(row)
	k = 0
	ans = []
	for i in range(1, n):
		for j in range(1, m):
			if i == n - 1 and j == m - 1:
				temp = int(mat[i - 1][j - 1]) + int(mat[i][j - 1]) + int(mat[i - 1][j]) + int(mat[i][j])
				tlist = [[i - 1, j - 1], [i, j - 1], [i - 1, j], [i, j]]
				if temp != 0:
					if temp == 4:
						k += 1
						ans.append([i, j, i + 1, j, i, j + 1])
						calc(i, j, i + 1, j, i, j + 1)
						temp = 1
					if temp == 1:
						k += 1
						tans = []
						zc = 0
						for x in tlist:
							if mat[x[0]][x[1]] == '1':
								tans.append(x[0] + 1)
								tans.append(x[1] + 1)
							elif zc < 2:
								tans.append(x[0] + 1)
								tans.append(x[1] + 1)
								zc += 1
						ans.append(tans)
						calc(tans[0], tans[1], tans[2], tans[3], tans[4], tans[5])
						temp = 2
					if temp == 2:
						k += 1
						tans = []
						zo = 0
						for x in tlist:
							if mat[x[0]][x[1]] == '1' and zo < 1:
								tans.append(x[0] + 1)
								tans.append(x[1] + 1)
								zo += 1
							elif mat[x[0]][x[1]] == '0':
								tans.append(x[0] + 1)
								tans.append(x[1] + 1)
						ans.append(tans)
						calc(tans[0], tans[1], tans[2], tans[3], tans[4], tans[5])
						temp = 3
					if temp == 3:
						k += 1
						tans = []
						for x in tlist:
							if mat[x[0]][x[1]] == '1':
								tans.append(x[0] + 1)
								tans.append(x[1] + 1)
						ans.append(tans)
						calc(tans[0], tans[1], tans[2], tans[3], tans[4], tans[5])
			elif i == n - 1:
				if mat[i - 1][j - 1] == '1' and mat[i][j - 1] == '1':
					k += 1
					ans.append([i, j, i + 1, j, i, j + 1])
					calc(i, j, i + 1, j, i, j + 1)
				elif mat[i - 1][j - 1] == '1' and mat[i][j - 1] == '0':
					k += 1
					ans.append([i, j, i, j + 1, i + 1, j + 1])
					calc(i, j, i, j + 1, i + 1, j + 1)
				elif mat[i - 1][j - 1] == '0' and mat[i][j - 1] == '1':
					k += 1
					ans.append([i + 1, j, i, j + 1, i + 1, j + 1])
					calc(i + 1, j, i, j + 1, i + 1, j + 1)
			elif j == m - 1:
				if mat[i - 1][j - 1] == '1' and mat[i - 1][j] == '1':
					k += 1
					ans.append([i, j, i, j + 1, i + 1, j])
					calc(i, j, i, j + 1, i + 1, j)
				elif mat[i - 1][j - 1] == '1' and mat[i - 1][j] == '0':
					k += 1
					ans.append([i, j, i + 1, j, i + 1, j + 1])
					calc(i, j, i + 1, j, i + 1, j + 1)
				elif mat[i - 1][j - 1] == '0' and mat[i - 1][j] == '1':
					k += 1
					ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
					calc(i, j + 1, i + 1, j, i + 1, j + 1)
			elif mat[i - 1][j - 1] == '1':
				k += 1
				ans.append([i, j, i, j + 1, i + 1, j])
				calc(i, j, i, j + 1, i + 1, j)
	print(k)
	for i in ans:
		for j in i:
			print(j, end=' ')
		print()


def flip(x, y):
	global mat
	if mat[x][y]:
		mat[x][y] = 0
	else:
		mat[x][y] = 1

def func(x1, y1, x2, y2):
	global mat, k
	(ones, z) = ([], [])
	if mat[x1][y1] == 1:
		ones.append((x1 + 1, y1 + 1))
	else:
		z.append((x1 + 1, y1 + 1))
	if mat[x2][y1] == 1:
		ones.append((x2 + 1, y1 + 1))
	else:
		z.append((x2 + 1, y1 + 1))
	if mat[x1][y2] == 1:
		ones.append((x1 + 1, y2 + 1))
	else:
		z.append((x1 + 1, y2 + 1))
	if mat[x2][y2] == 1:
		ones.append((x2 + 1, y2 + 1))
	else:
		z.append((x2 + 1, y2 + 1))
	while len(ones) != 0:
		if len(ones) == 4:
			k += 1
			t = []
			for (x, y) in ones[:-1]:
				mat[x - 1][y - 1] = 0
				t.append(x)
				t.append(y)
			out.append(t)
		elif len(ones) == 3:
			k += 1
			t = []
			for (x, y) in ones:
				mat[x - 1][y - 1] = 0
				t.append(x)
				t.append(y)
			out.append(t)
		elif len(ones) == 2:
			k += 1
			t = []
			for (x, y) in ones[:-1]:
				mat[x - 1][y - 1] = 0
				t.append(x)
				t.append(y)
			for (x, y) in z:
				mat[x - 1][y - 1] = 1
				t.append(x)
				t.append(y)
			out.append(t)
		else:
			k += 1
			t = []
			for (x, y) in ones:
				mat[x - 1][y - 1] = 0
				t.append(x)
				t.append(y)
			for (x, y) in z[:-1]:
				mat[x - 1][y - 1] = 1
				t.append(x)
				t.append(y)
			out.append(t)
		(ones, z) = ([], [])
		if mat[x1][y1] == 1:
			ones.append((x1 + 1, y1 + 1))
		else:
			z.append((x1 + 1, y1 + 1))
		if mat[x2][y1] == 1:
			ones.append((x2 + 1, y1 + 1))
		else:
			z.append((x2 + 1, y1 + 1))
		if mat[x1][y2] == 1:
			ones.append((x1 + 1, y2 + 1))
		else:
			z.append((x1 + 1, y2 + 1))
		if mat[x2][y2] == 1:
			ones.append((x2 + 1, y2 + 1))
		else:
			z.append((x2 + 1, y2 + 1))
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	mat = []
	for i in range(n):
		mat.append(list(map(int, list(input()))))
	k = 0
	out = []
	i = 0
	if n % 2:
		j = 0
		if m % 2:
			func(n - 2, m - 2, n - 1, m - 1)
		while j < m - 1:
			if mat[n - 1][j] == 1:
				flip(n - 1, j)
				flip(n - 2, j)
				flip(n - 2, j + 1)
				k += 1
				out.append([n, j + 1, n - 1, j + 1, n - 1, j + 2])
			if mat[n - 1][j + 1] == 1:
				flip(n - 1, j + 1)
				flip(n - 2, j)
				flip(n - 2, j + 1)
				k += 1
				out.append([n, j + 2, n - 1, j + 1, n - 1, j + 2])
			j += 2
	while i < n - 1:
		j = 0
		if m % 2:
			if mat[i][m - 1]:
				flip(i, m - 1)
				flip(i, m - 2)
				flip(i + 1, m - 2)
				k += 1
				out.append([i + 1, m, i + 1, m - 1, i + 2, m - 1])
			if mat[i + 1][m - 1]:
				flip(i + 1, m - 1)
				flip(i, m - 2)
				flip(i + 1, m - 2)
				k += 1
				out.append([i + 2, m, i + 1, m - 1, i + 2, m - 1])
		while j < m - 1:
			func(i, j, i + 1, j + 1)
			j += 2
		i += 2
	print(k)
	for i in out:
		print(*i)


from itertools import product
result = []

def count_one(bd, r, c, rsz, csz):
	cc = 0
	for (i, j) in product(range(rsz), range(csz)):
		cc += bd[r + i][c + j] == '1'
	return cc

def apply_change(bd, res):
	for (u, v) in res:
		bd[u][v] = '0' if bd[u][v] == '1' else '1'

def print_res(res):
	result.append(res)

def pick_one(bd, r, c, one):
	(res, zero) = ([], 3 - one)
	for (i, j) in product(range(2), range(2)):
		if bd[r + i][c + j] == '1' and one:
			res.append((r + i, c + j))
			one -= 1
		elif bd[r + i][c + j] == '0' and zero:
			res.append((r + i, c + j))
			zero -= 1
	apply_change(bd, res)
	print_res(res)

def remove_one(bd, r, c, dir):
	res = []
	if dir == 'top':
		if bd[r][c] == '0' and bd[r][c + 1] == '1':
			res = [(r, c + 1), (r + 1, c), (r + 1, c + 1)]
		elif bd[r][c] == '1' and bd[r][c + 1] == '0':
			res = [(r, c), (r + 1, c), (r + 1, c + 1)]
		elif bd[r][c] == '1' and bd[r][c + 1] == '1':
			res = [(r, c), (r, c + 1), (r + 1, c)]
	elif bd[r][c] == '0' and bd[r + 1][c] == '1':
		res = [(r + 1, c), (r, c + 1), (r + 1, c + 1)]
	elif bd[r][c] == '1' and bd[r + 1][c] == '0':
		res = [(r, c), (r, c + 1), (r + 1, c + 1)]
	elif bd[r][c] == '1' and bd[r + 1][c] == '1':
		res = [(r + 1, c), (r, c), (r, c + 1)]
	apply_change(bd, res)
	print_res(res)

def make_zero(bd, r, c, rsz, csz):
	if rsz == 2 and csz == 2:
		one = count_one(bd, r, c, 2, 2)
		if one == 0:
			return
		if one == 1 or one == 2:
			pick_one(bd, r, c, 1)
		elif one == 3 or one == 4:
			pick_one(bd, r, c, 3)
		make_zero(bd, r, c, 2, 2)
	elif rsz == 3 and csz == 2:
		one = count_one(bd, r, c, 1, 2)
		if one == 0:
			make_zero(bd, r + 1, c, 2, 2)
		else:
			remove_one(bd, r, c, 'top')
			make_zero(bd, r + 1, c, 2, 2)
	elif rsz == 2 and csz == 3:
		one = count_one(bd, r, c, 2, 1)
		if one == 0:
			make_zero(bd, r, c + 1, 2, 2)
		else:
			remove_one(bd, r, c, 'left')
			make_zero(bd, r, c + 1, 2, 2)
	else:
		one = count_one(bd, r, c, 1, 3)
		if one == 0:
			make_zero(bd, r + 1, c, 2, 3)
		elif bd[r][c] == '0':
			remove_one(bd, r, c + 1, 'top')
			make_zero(bd, r, c, 3, 3)
		else:
			remove_one(bd, r, c, 'top')
			make_zero(bd, r, c, 3, 3)
T = int(input())
for _ in range(T):
	(n, m) = map(int, input().split())
	bd = [list(input()) for _ in range(n)]
	for (i, j) in product(range(n // 2), range(m // 2)):
		(r, c) = (i * 2, j * 2)
		rsz = 3 if n % 2 and i == n // 2 - 1 else 2
		csz = 3 if m % 2 and j == m // 2 - 1 else 2
		make_zero(bd, r, c, rsz, csz)
	print(len(result))
	for res in result:
		ls = []
		for (u, v) in res:
			ls.append(u + 1)
			ls.append(v + 1)
		print(*ls)
	result.clear()


from bisect import *
from collections import *
from math import gcd, ceil, sqrt, floor, inf
from heapq import *
from itertools import *
from operator import add, mul, sub, xor, truediv, floordiv
from functools import *
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
farr = [1]
ifa = []

def fact(x, mod=0):
	if mod:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr) % mod)
	else:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr))
	return farr[x]

def ifact(x, mod):
	global ifa
	ifa.append(pow(farr[-1], mod - 2, mod))
	for i in range(x, 0, -1):
		ifa.append(ifa[-1] * i % mod)
	ifa = ifa[::-1]

def per(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return fact(i) // fact(i - j)
	return farr[i] * ifa[i - j] % mod

def com(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return per(i, j) // fact(j)
	return per(i, j, mod) * ifa[j] % mod

def catalan(n):
	return com(2 * n, n) // (n + 1)

def linc(f, t, l, r):
	while l < r:
		mid = (l + r) // 2
		if t > f(mid):
			l = mid + 1
		else:
			r = mid
	return l

def rinc(f, t, l, r):
	while l < r:
		mid = (l + r + 1) // 2
		if t < f(mid):
			r = mid - 1
		else:
			l = mid
	return l

def ldec(f, t, l, r):
	while l < r:
		mid = (l + r) // 2
		if t < f(mid):
			l = mid + 1
		else:
			r = mid
	return l

def rdec(f, t, l, r):
	while l < r:
		mid = (l + r + 1) // 2
		if t > f(mid):
			r = mid - 1
		else:
			l = mid
	return l

def isprime(n):
	for i in range(2, int(n ** 0.5) + 1):
		if n % i == 0:
			return False
	return True

def binfun(x):
	c = 0
	for w in arr:
		c += ceil(w / x)
	return c

def lowbit(n):
	return n & -n

def inverse(a, m):
	a %= m
	if a <= 1:
		return a
	return (1 - inverse(m, a) * m) // a % m

class BIT:

	def __init__(self, arr):
		self.arr = arr
		self.n = len(arr) - 1

	def update(self, x, v):
		while x <= self.n:
			self.arr[x] += v
			x += x & -x

	def query(self, x):
		ans = 0
		while x:
			ans += self.arr[x]
			x &= x - 1
		return ans

class DSU:

	def __init__(self, n):
		self.c = [-1] * n

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def find(self, x):
		if self.c[x] < 0:
			return x
		self.c[x] = self.find(self.c[x])
		return self.c[x]

	def union(self, u, v):
		(u, v) = (self.find(u), self.find(v))
		if u == v:
			return False
		if self.c[u] < self.c[v]:
			(u, v) = (v, u)
		self.c[u] += self.c[v]
		self.c[v] = u
		return True

	def size(self, x):
		return -self.c[self.find(x)]

class UFS:

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.ranks = [0] * n

	def find(self, x):
		if x != self.parent[x]:
			self.parent[x] = self.find(self.parent[x])
		return self.parent[x]

	def union(self, u, v):
		(pu, pv) = (self.find(u), self.find(v))
		if pu == pv:
			return False
		if self.ranks[pu] >= self.ranks[pv]:
			self.parent[pv] = pu
			if self.ranks[pv] == self.ranks[pu]:
				self.ranks[pu] += 1
		else:
			self.parent[pu] = pv

def Prime(n):
	c = 0
	prime = []
	flag = [0] * (n + 1)
	for i in range(2, n + 1):
		if not flag[i]:
			prime.append(i)
			c += 1
		for j in range(c):
			if i * prime[j] > n:
				break
			flag[i * prime[j]] = prime[j]
			if i % prime[j] == 0:
				break
	return prime

def dij(s, graph):
	d = {}
	d[s] = 0
	heap = [(0, s)]
	seen = set()
	while heap:
		(dis, u) = heappop(heap)
		if u in seen:
			continue
		for v in graph[u]:
			if v not in d or d[v] > d[u] + graph[u][v]:
				d[v] = d[u] + graph[u][v]
				heappush(heap, (d[v], v))
	return d

def GP(it):
	return [(ch, len(list(g))) for (ch, g) in groupby(it)]

class DLN:

	def __init__(self, val):
		self.val = val
		self.pre = None
		self.next = None

class Trie:

	def __init__(self, d):
		if d >= 0:
			self.left = Trie(d - 1)
		else:
			self.right = Trie(d - 1)
		self.c = 0

	def put(self, x, i):
		if i == -1:
			self.c = 1
			return
		if x & 1 << i:
			self.left.put(x, i - 1)
		else:
			self.right.put(x, i - 1)

def con(i, j, x):
	i += 1
	j += 1
	if x == 0:
		return [i, j, i, j + 1, i + 1, j]
	if x == 1:
		return [i, j, i, j + 1, i + 1, j + 1]
	if x == 2:
		return [i, j, i + 1, j, i + 1, j + 1]
	if x == 3:
		return [i, j + 1, i + 1, j, i + 1, j + 1]

def f(i, j):
	if i < n - 1 and j < m - 1:
		res = a[i][j:j + 2] + a[i + 1][j:j + 2]
		if res == '1111':
			for d in range(4):
				ans.append(con(i, j, d))
		elif res == '1110':
			ans.append(con(i, j, 0))
		elif res == '1101':
			ans.append(con(i, j, 1))
		elif res == '1011':
			ans.append(con(i, j, 2))
		elif res == '0111':
			ans.append(con(i, j, 3))
		elif res == '1000':
			for d in range(4):
				if d != 3:
					ans.append(con(i, j, d))
		elif res == '0100':
			for d in range(4):
				if d != 2:
					ans.append(con(i, j, d))
		elif res == '0010':
			for d in range(4):
				if d != 1:
					ans.append(con(i, j, d))
		elif res == '0001':
			for d in range(4):
				if d != 0:
					ans.append(con(i, j, d))
		elif res == '1100':
			ans.append(con(i, j, 2))
			ans.append(con(i, j, 3))
		elif res == '1010':
			ans.append(con(i, j, 1))
			ans.append(con(i, j, 3))
		elif res == '0101':
			ans.append(con(i, j, 0))
			ans.append(con(i, j, 2))
		elif res == '0011':
			ans.append(con(i, j, 0))
			ans.append(con(i, j, 1))
		elif res == '1001':
			ans.append(con(i, j, 0))
			ans.append(con(i, j, 3))
		elif res == '0110':
			ans.append(con(i, j, 1))
			ans.append(con(i, j, 2))
	elif i == n - 1 and j == m - 1:
		if a[i][j] == '1':
			for d in range(4):
				if d != 0:
					ans.append(con(i - 1, j - 1, d))
	elif i == n - 1:
		tmp = a[i][j] + a[i][j + 1]
		if tmp == '11':
			ans.append(con(i - 1, j, 0))
			ans.append(con(i - 1, j, 1))
		elif tmp == '10':
			for d in range(4):
				if d != 1:
					ans.append(con(i - 1, j, d))
		elif tmp == '01':
			for d in range(4):
				if d != 0:
					ans.append(con(i - 1, j, d))
	else:
		tmp = a[i][j] + a[i + 1][j]
		if tmp == '11':
			ans.append(con(i, j - 1, 0))
			ans.append(con(i, j - 1, 2))
		elif tmp == '10':
			for d in range(4):
				if d != 2:
					ans.append(con(i, j - 1, d))
		elif tmp == '01':
			for d in range(4):
				if d != 0:
					ans.append(con(i, j - 1, d))
t = N()
for i in range(t):
	(n, m) = RL()
	a = []
	ans = []
	for i in range(n):
		a.append(input())
	for i in range(0, n, 2):
		for j in range(0, m, 2):
			f(i, j)
	print(len(ans))
	for i in range(len(ans)):
		print(*ans[i])


import sys, io, os
Z = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def solve(sq, x, y):
	s = sum((sum(i) for i in sq))
	v = [(x, y, x + 1, y, x, y + 1), (x, y, x + 1, y + 1, x, y + 1), (x, y, x + 1, y, x + 1, y + 1), (x + 1, y + 1, x + 1, y, x, y + 1)]
	if s > 3:
		return v
	if s > 2:
		if sq[0][0] < 1:
			return [v[3]]
		if sq[0][1] < 1:
			return [v[2]]
		if sq[1][0] < 1:
			return [v[1]]
		return [v[0]]
	if s > 1:
		if sq[0][0] < 1 and sq[0][1] < 1:
			return v[:2]
		if sq[0][0] < 1 and sq[1][1] < 1:
			return v[1:3]
		if sq[0][0] < 1 and sq[1][0] < 1:
			return [v[0], v[2]]
		if sq[0][1] < 1 and sq[1][1] < 1:
			return [v[1], v[3]]
		if sq[0][1] < 1 and sq[1][0] < 1:
			return [v[0], v[3]]
		if sq[1][0] < 1 and sq[1][1] < 1:
			return v[2:]
	if s:
		if sq[0][0]:
			k = 3
		elif sq[0][1]:
			k = 2
		elif sq[1][0]:
			k = 1
		else:
			k = 0
		return v[:k] + v[k + 1:]
	return []
O = []
for _ in range(int(Z())):
	(n, m) = map(int, Z().split())
	a = []
	o = []
	for i in range(n):
		a.append(list(map(lambda x: x % 2, Z().strip())))
	if n % 2:
		for y in range(m // 2):
			i = y * 2
			if a[-1][i]:
				if a[-1][i + 1]:
					o += [(n, i + 1, n, i + 2, n - 1, i + 1)]
					a[-2][i] = 1 - a[-2][i]
				else:
					o += [(n, i + 1, n - 1, i + 2, n - 1, i + 1)]
					a[-2][i] = 1 - a[-2][i]
					a[-2][i + 1] = 1 - a[-2][i + 1]
			elif a[-1][i + 1]:
				o += [(n, i + 2, n - 1, i + 2, n - 1, i + 1)]
				a[-2][i] = 1 - a[-2][i]
				a[-2][i + 1] = 1 - a[-2][i + 1]
		if m % 2 and a[-1][-1]:
			o += [(n, m, n - 1, m, n - 1, m - 1)]
			a[-2][-1] = 1 - a[-2][-1]
			a[-2][-2] = 1 - a[-2][-2]
	if m % 2:
		for x in range(n // 2):
			i = x * 2
			if a[i][-1]:
				if a[i + 1][-1]:
					o += [(i + 1, m, i + 2, m, i + 1, m - 1)]
					a[i][-2] = 1 - a[i][-2]
				else:
					o += [(i + 1, m, i + 2, m - 1, i + 1, m - 1)]
					a[i][-2] = 1 - a[i][-2]
					a[i + 1][-2] = 1 - a[i + 1][-2]
			elif a[i + 1][-1]:
				o += [(i + 2, m - 1, i + 2, m, i + 1, m - 1)]
				a[i][-2] = 1 - a[i][-2]
				a[i + 1][-2] = 1 - a[i + 1][-2]
	for i in range(n // 2):
		for j in range(m // 2):
			(x, y) = (2 * i, 2 * j)
			o += solve(((a[x][y], a[x][y + 1]), (a[x + 1][y], a[x + 1][y + 1])), x + 1, y + 1)
	O.append(str(len(o)))
	O.append('\n'.join((' '.join(map(str, i)) for i in o)))
print('\n'.join(O))


from sys import stdin, stdout
from collections import deque

def binary_table(n, m, tbl):
	r_a = []
	for i in range(n - 2):
		for j in range(m):
			if tbl[i][j] == 0:
				continue
			r = [i + 1, j + 1, i + 2, j + 1, i + 2]
			if j == m - 1:
				r.append(j)
			else:
				r.append(j + 2)
			r_a.append(r)
			change_tbl(r, tbl)
	for j in range(m - 2):
		for i in range(n - 2, n):
			if tbl[i][j] == 0:
				continue
			r = [i + 1, j + 1, i + 1, j + 2]
			if i == n - 2:
				r.append(i + 2)
			else:
				r.append(i)
			r.append(j + 2)
			r_a.append(r)
			change_tbl(r, tbl)
	a0 = deque()
	a1 = deque()
	for i in range(n - 2, n):
		for j in range(m - 2, m):
			if tbl[i][j] == 0:
				a0.append([i + 1, j + 1])
			else:
				a1.append([i + 1, j + 1])
	tbl_corner(a0, a1, r_a)
	return r_a

def tbl_corner(a0, a1, r_a):
	cnt1 = len(a1)
	if cnt1 == 0:
		return
	if cnt1 == 3:
		return step_1(a0, a1, r_a)
	if cnt1 == 2:
		return step_2(a0, a1, r_a)
	if cnt1 == 1:
		return step_3(a0, a1, r_a)
	if cnt1 == 4:
		return step_4(a0, a1, r_a)

def step_1(a0, a1, r_a):
	r = []
	while a1:
		c = a1.popleft()
		r.append(c[0])
		r.append(c[1])
		a0.append(c)
	r_a.append(r)

def step_2(a0, a1, r_a):
	c0_0 = a0.popleft()
	c0_1 = a0.popleft()
	c1_0 = a1.popleft()
	r = [c0_0[0], c0_0[1], c0_1[0], c0_1[1], c1_0[0], c1_0[1]]
	r_a.append(r)
	a1.append(c0_0)
	a1.append(c0_1)
	a0.append(c1_0)
	step_1(a0, a1, r_a)

def step_3(a0, a1, r_a):
	c1_0 = a1.popleft()
	c0_0 = a0.popleft()
	c0_1 = a0.popleft()
	r = [c1_0[0], c1_0[1], c0_0[0], c0_0[1], c0_1[0], c0_1[1]]
	r_a.append(r)
	a0.append(c1_0)
	a1.append(c0_0)
	a1.append(c0_1)
	step_2(a0, a1, r_a)

def step_4(a0, a1, r_a):
	c1_0 = a1.popleft()
	c1_1 = a1.popleft()
	c1_2 = a1.popleft()
	r = [c1_0[0], c1_0[1], c1_1[0], c1_1[1], c1_2[0], c1_2[1]]
	r_a.append(r)
	a0.append(c1_0)
	a0.append(c1_1)
	a0.append(c1_2)
	step_3(a0, a1, r_a)

def change_tbl(r, tbl):
	tbl[r[0] - 1][r[1] - 1] ^= 1
	tbl[r[2] - 1][r[3] - 1] ^= 1
	tbl[r[4] - 1][r[5] - 1] ^= 1
t = int(stdin.readline())
for _ in range(t):
	(n, m) = map(int, stdin.readline().split())
	tbl = []
	for _ in range(n):
		s = stdin.readline().strip()
		tbl.append([ord(c) - ord('0') for c in s])
	r_a = binary_table(n, m, tbl)
	stdout.write(str(len(r_a)) + '\n')
	for r in r_a:
		stdout.write(' '.join(map(str, r)) + '\n')


def printans(ans):
	print(len(ans))
	for i in ans:
		for (x, y) in i:
			print(x + 1, y + 1, end=' ')
		print()

def update(arr, lis):
	for (i, j) in lis:
		arr[i][j] = 1 - arr[i][j]

def considersquare(i, j, arr, ans, lastcol, last):
	a = arr[i][j]
	b = arr[i + 1][j]
	c = arr[i][j + 1]
	d = arr[i + 1][j + 1]
	if last and lastcol:
		while True:
			a = arr[i][j]
			b = arr[i + 1][j]
			c = arr[i][j + 1]
			d = arr[i + 1][j + 1]
			if a + b + c + d == 0:
				return
			elif a + b + c + d == 1:
				if a == 1 or b == 1 or d == 1:
					ans.append([(i, j), (i + 1, j), (i + 1, j + 1)])
					update(arr, [(i, j), (i + 1, j), (i + 1, j + 1)])
				elif c == 1:
					ans.append([(i, j), (i, j + 1), (i + 1, j + 1)])
					update(arr, [(i, j), (i, j + 1), (i + 1, j + 1)])
			elif a + b + c + d == 2:
				lis = []
				for p in (i, i + 1):
					for q in (j, j + 1):
						if arr[p][q] == 0:
							lis.append((p, q))
				for p in (i, i + 1):
					for q in (j, j + 1):
						if arr[p][q] == 1 and len(lis) < 3:
							lis.append((p, q))
				ans.append(lis)
				update(arr, lis)
			elif a + b + c + d == 3:
				lis = []
				for p in (i, i + 1):
					for q in (j, j + 1):
						if arr[p][q] == 1:
							lis.append((p, q))
				ans.append(lis)
				update(arr, lis)
			elif a + b + c + d == 4:
				ans.append([(i, j), (i + 1, j), (i + 1, j + 1)])
				update(arr, [(i, j), (i + 1, j), (i + 1, j + 1)])
	elif lastcol:
		if a == 0 and c == 0:
			return
		elif a == 1 and c == 0:
			ans.append([(i, j), (i + 1, j), (i + 1, j + 1)])
			update(arr, [(i, j), (i + 1, j), (i + 1, j + 1)])
		elif c == 1 and a == 0:
			ans.append([(i + 1, j), (i, j + 1), (i + 1, j + 1)])
			update(arr, [(i + 1, j), (i, j + 1), (i + 1, j + 1)])
		elif a == 1 and c == 1:
			ans.append([(i, j), (i, j + 1), (i + 1, j + 1)])
			update(arr, [(i, j), (i, j + 1), (i + 1, j + 1)])
	elif a == 0 and b == 0:
		return
	elif a == 1 and b == 0:
		ans.append([(i, j), (i, j + 1), (i + 1, j + 1)])
		update(arr, [(i, j), (i, j + 1), (i + 1, j + 1)])
	elif b == 1 and a == 0:
		ans.append([(i + 1, j), (i, j + 1), (i + 1, j + 1)])
		update(arr, [(i + 1, j), (i, j + 1), (i + 1, j + 1)])
	elif a == 1 and b == 1:
		ans.append([(i, j), (i + 1, j), (i + 1, j + 1)])
		update(arr, [(i, j), (i + 1, j), (i + 1, j + 1)])
for _ in range(int(input())):
	(n, m) = [int(c) for c in input().split()]
	arr = []
	for i in range(n):
		ar = [int(c) for c in input()]
		arr.append(ar)
	ans = []
	count = 0
	for i in range(n - 1):
		for j in range(m - 1):
			considersquare(i, j, arr, ans, j == m - 2, i == n - 2)
	if len(ans) == n * m + 1:
		raise ValueError()
	printans(ans)


import sys
readline = sys.stdin.readline
T = int(readline())
Ans = []
for qu in range(T):
	(N, M) = map(int, readline().split())
	ans = []
	G = [list(map(int, readline().strip())) for _ in range(N)]
	for i in range(N - 2):
		for j in range(M - 1):
			if G[i][j]:
				ans.append(f'{i + 1} {j + 1} {i + 1} {j + 2} {i + 2} {j + 1}')
				G[i][j] ^= 1
				G[i][j + 1] ^= 1
				G[i + 1][j] ^= 1
		j = M - 1
		if G[i][M - 1]:
			ans.append(f'{i + 1} {j + 1} {i + 2} {j} {i + 2} {j + 1}')
			G[i][j] ^= 1
			G[i + 1][j - 1] ^= 1
			G[i + 1][j] ^= 1
	i = N - 2
	for j in range(M - 2):
		if G[i][j]:
			ans.append(f'{i + 1} {j + 1} {i + 1} {j + 2} {i + 2} {j + 1}')
			G[i][j] ^= 1
			G[i][j + 1] ^= 1
			G[i + 1][j] ^= 1
	a = N - 2
	b = N - 1
	ai = a + 1
	bi = b + 1
	for j in range(M - 2):
		if G[a][j] and G[b][j]:
			ans.append(f'{ai} {j + 1} {bi} {j + 1} {ai} {j + 2}')
			G[a][j] ^= 1
			G[b][j] ^= 1
			G[a][j + 1] ^= 1
			continue
		if G[a][j] or G[b][j]:
			if G[a][j]:
				c = a
			else:
				c = b
			ans.append(f'{c + 1} {j + 1} {bi} {j + 2} {ai} {j + 2}')
			G[c][j] ^= 1
			G[b][j + 1] ^= 1
			G[a][j + 1] ^= 1
	H = [G[N - 2][M - 2], G[N - 1][M - 2], G[N - 2][M - 1], G[N - 1][M - 1]]
	(ax, ay) = (N - 2 + 1, M - 2 + 1)
	(bx, by) = (N - 1 + 1, M - 2 + 1)
	(cx, cy) = (N - 2 + 1, M - 1 + 1)
	(dx, dy) = (N - 1 + 1, M - 1 + 1)
	abcd = [(ax, ay), (bx, by), (cx, cy), (dx, dy)]
	if H.count(1) == 4:
		H[0] ^= 1
		H[1] ^= 1
		H[2] ^= 1
		ans.append(f'{ax} {ay} {bx} {by} {cx} {cy}')
	if H.count(1) == 1:
		res = [0, 1, 2, 3]
		for idx in range(4):
			if H[idx]:
				break
		res.remove(res[idx - 1])
		ans.append(f'{abcd[res[0]][0]} {abcd[res[0]][1]} {abcd[res[1]][0]} {abcd[res[1]][1]} {abcd[res[2]][0]} {abcd[res[2]][1]}')
		for r in res:
			H[r] ^= 1
	if H.count(1) == 2:
		res = []
		for idx in range(4):
			if not H[idx]:
				res.append(idx)
		for idx in range(4):
			if H[idx]:
				res.append(idx)
				break
		ans.append(f'{abcd[res[0]][0]} {abcd[res[0]][1]} {abcd[res[1]][0]} {abcd[res[1]][1]} {abcd[res[2]][0]} {abcd[res[2]][1]}')
		for r in res:
			H[r] ^= 1
	if H.count(1) == 3:
		res = []
		for idx in range(4):
			if H[idx]:
				res.append(idx)
		ans.append(f'{abcd[res[0]][0]} {abcd[res[0]][1]} {abcd[res[1]][0]} {abcd[res[1]][1]} {abcd[res[2]][0]} {abcd[res[2]][1]}')
		for r in res:
			H[r] ^= 1
	Ans.append(str(len(ans)))
	Ans.extend(ans)
print('\n'.join(Ans))


from collections import defaultdict, deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, itertools, math
sys.setrecursionlimit(10 ** 5)
input = sys.stdin.readline
sqrt = math.sqrt

def LI():
	return list(map(int, input().split()))

def LF():
	return list(map(float, input().split()))

def LI_():
	return list(map(lambda x: int(x) - 1, input().split()))

def II():
	return int(input())

def IF():
	return float(input())

def S():
	return input().rstrip()

def LS():
	return S().split()

def IR(n):
	res = [None] * n
	for i in range(n):
		res[i] = II()
	return res

def LIR(n):
	res = [None] * n
	for i in range(n):
		res[i] = LI()
	return res

def FR(n):
	res = [None] * n
	for i in range(n):
		res[i] = IF()
	return res

def LIR(n):
	res = [None] * n
	for i in range(n):
		res[i] = IF()
	return res

def LIR_(n):
	res = [None] * n
	for i in range(n):
		res[i] = LI_()
	return res

def SR(n):
	res = [None] * n
	for i in range(n):
		res[i] = S()
	return res

def LSR(n):
	res = [None] * n
	for i in range(n):
		res[i] = LS()
	return res
mod = 1000000007
inf = float('INF')

def solve():
	t = II()
	kuso = {'1': '0', '0': '1'}
	f = {1: 3, 2: 2, 3: 1, 4: 4}

	def fff(g, a):
		one = a.count('1')
		if one == 0:
			return
		tmp = []
		if one == 1 or one == 3:
			for i in range(4):
				if a[i] == '1':
					tmp.append(i)
			for i in range(4):
				if len(tmp) == 3:
					break
				if a[i] == '0':
					tmp.append(i)
			for i in range(3):
				a[tmp[i]] = kuso[a[tmp[i]]]
				tmp[i] = ' '.join(map(str, g[tmp[i]]))
			ans.append(' '.join(tmp))
			fff(g, a)
			return
		else:
			for i in range(4):
				if a[i] == '0':
					tmp.append(i)
			for i in range(4):
				if len(tmp) == 3:
					break
				if a[i] == '1':
					tmp.append(i)
			for i in range(3):
				a[tmp[i]] = kuso[a[tmp[i]]]
				tmp[i] = ' '.join(map(str, g[tmp[i]]))
			ans.append(' '.join(tmp))
			fff(g, a)
			return
	for i in range(t):
		(n, m) = LI()
		s = [list(input().rstrip()) for i in range(n)]
		ans = []
		if s[-1][-1] == s[-1][-2] == s[-2][-1] == '1':
			s[-1][-1] = '0'
			s[-1][-2] = '0'
			s[-2][-1] = '0'
			tmp = []
			tmp.append(n)
			tmp.append(m)
			tmp.append(n - 1)
			tmp.append(m)
			tmp.append(n)
			tmp.append(m - 1)
			ans.append(' '.join(map(str, tmp)))
		if m & 1:
			for y in range(n - 1):
				tmp = []
				if s[y][-1] == '1':
					tmp.append(y + 1)
					tmp.append(m)
					s[y][-1] = '0'
				if s[y + 1][-1] == '1':
					tmp.append(y + 2)
					tmp.append(m)
					s[y + 1][-1] = '0'
				if tmp:
					tmp.append(y + 1)
					tmp.append(m - 1)
					s[y][m - 2] = kuso[s[y][m - 2]]
					if len(tmp) == 4:
						tmp.append(y + 2)
						tmp.append(m - 1)
						s[y + 1][m - 2] = kuso[s[y + 1][m - 2]]
					ans.append(' '.join(map(str, tmp)))
		if n & 1:
			for x in range(m - 1):
				tmp = []
				if s[-1][x] == '1':
					tmp.append(n)
					tmp.append(x + 1)
					s[-1][x] = '0'
				if s[-1][x + 1] == '1':
					tmp.append(n)
					tmp.append(x + 2)
					s[-1][x + 1] = '0'
				if tmp:
					tmp.append(n - 1)
					tmp.append(x + 1)
					s[-2][x] = kuso[s[-2][x]]
					if len(tmp) == 4:
						tmp.append(n - 1)
						tmp.append(x + 2)
						s[-2][x + 1] = kuso[s[-2][x + 1]]
					ans.append(' '.join(map(str, tmp)))
		for y in range(0, n - 1, 2):
			for x in range(0, m - 1, 2):
				a0 = s[y][x]
				a1 = s[y][x + 1]
				a2 = s[y + 1][x]
				a3 = s[y + 1][x + 1]
				s[y][x] = '0'
				s[y + 1][x] = '0'
				s[y][x + 1] = '0'
				s[y + 1][x + 1] = '0'
				g = [[y + 1, x + 1], [y + 1, x + 2], [y + 2, x + 1], [y + 2, x + 2]]
				a = [a0, a1, a2, a3]
				c = a.count('1')
				if c == 0:
					continue
				fff(g, a)
		print(len(ans))
		for i in ans:
			print(i)
	return
solve()


t = int(input())
while t > 0:
	(n, m) = map(int, input().split())
	l = []
	for i in range(n):
		l.append(input())
	c = 0
	for i in range(n):
		for j in range(m):
			if l[i][j] == '1':
				c += 1
	print(3 * c)
	for i in range(n):
		for j in range(m):
			if l[i][j] == '1':
				if i < n - 1 and j < m - 1:
					print(i + 1, j + 1, i + 1, j + 2, i + 2, j + 2)
					print(i + 1, j + 1, i + 2, j + 2, i + 2, j + 1)
					print(i + 1, j + 1, i + 1, j + 2, i + 2, j + 1)
				elif i == n - 1 and j < m - 1:
					print(i + 1, j + 1, i + 1, j + 2, i, j + 2)
					print(i + 1, j + 1, i, j + 2, i, j + 1)
					print(i + 1, j + 1, i + 1, j + 2, i, j + 1)
				elif j == m - 1 and i < n - 1:
					print(i + 1, j + 1, i + 1, j, i + 2, j)
					print(i + 1, j + 1, i + 2, j, i + 2, j + 1)
					print(i + 1, j + 1, i + 1, j, i + 2, j + 1)
				else:
					print(i + 1, j + 1, i + 1, j, i, j)
					print(i + 1, j + 1, i, j, i, j + 1)
					print(i + 1, j + 1, i + 1, j, i, j + 1)
	t -= 1


import os
import sys
from io import BytesIO, IOBase
import threading
from bisect import bisect_right
from math import gcd, log
from collections import Counter, defaultdict
from pprint import pprint
import copy

def main(case_no):
	(n, m) = map(int, input().split())
	grid = []
	for i in range(n):
		grid.append([int(c) for c in input()])
	ans = []
	llt = copy.deepcopy(grid)
	for i in range(n - 2):
		for j in range(m):
			if grid[i][j] == 1:
				grid[i][j] = (grid[i][j] + 1) % 2
				grid[i + 1][j] = (grid[i + 1][j] + 1) % 2
				if j + 1 < m:
					grid[i][j + 1] = (grid[i][j + 1] + 1) % 2
					ans.append((i, j, i + 1, j, i, j + 1))
				else:
					grid[i + 1][j - 1] = (grid[i + 1][j - 1] + 1) % 2
					ans.append((i, j, i + 1, j, i + 1, j - 1))
	for i in range(m - 2):
		if grid[-2][i] == 1:
			grid[n - 2][i + 1] = (grid[n - 2][i + 1] + 1) % 2
			grid[n - 1][i + 1] = (grid[n - 1][i + 1] + 1) % 2
			grid[n - 2][i] = (grid[n - 2][i] + 1) % 2
			ans.append((n - 2, i + 1, n - 1, i + 1, n - 2, i))
		if grid[-1][i] == 1:
			grid[n - 2][i + 1] = (grid[n - 2][i + 1] + 1) % 2
			grid[n - 1][i + 1] = (grid[n - 1][i + 1] + 1) % 2
			grid[n - 1][i] = (grid[n - 1][i] + 1) % 2
			ans.append((n - 2, i + 1, n - 1, i + 1, n - 1, i))
	cc = [(n - 1, m - 1), (n - 1, m - 2), (n - 2, m - 1), (n - 2, m - 2)]
	ct = 0
	for (x, y) in cc:
		if grid[x][y] == 1:
			ct += 1
	if ct == 4:
		a = [n - 1, m - 1, n - 1, m - 2, n - 2, m - 1]
		ans.append(tuple(a))
		grid[a[0]][a[1]] = (grid[a[0]][a[1]] + 1) % 2
		grid[a[2]][a[3]] = (grid[a[2]][a[3]] + 1) % 2
		grid[a[4]][a[5]] = (grid[a[4]][a[5]] + 1) % 2
		ct = 1
	if ct == 1:
		a = []
		for (x, y) in cc:
			if grid[x][y] == 0:
				a.append(x)
				a.append(y)
				if len(a) == 4:
					break
		for (x, y) in cc:
			if grid[x][y] == 1:
				a.append(x)
				a.append(y)
				break
		ans.append(tuple(a))
		grid[a[0]][a[1]] = (grid[a[0]][a[1]] + 1) % 2
		grid[a[2]][a[3]] = (grid[a[2]][a[3]] + 1) % 2
		grid[a[4]][a[5]] = (grid[a[4]][a[5]] + 1) % 2
	if ct == 1 or ct == 2:
		a = []
		for (x, y) in cc:
			if grid[x][y] == 0:
				a.append(x)
				a.append(y)
		for (x, y) in cc:
			if grid[x][y] == 1:
				a.append(x)
				a.append(y)
				break
		grid[a[0]][a[1]] = (grid[a[0]][a[1]] + 1) % 2
		grid[a[2]][a[3]] = (grid[a[2]][a[3]] + 1) % 2
		grid[a[4]][a[5]] = (grid[a[4]][a[5]] + 1) % 2
		ans.append(a)
	if ct > 0:
		a = []
		for (x, y) in cc:
			if grid[x][y] == 1:
				a.append(x)
				a.append(y)
		ans.append(a)
		grid[a[0]][a[1]] = (grid[a[0]][a[1]] + 1) % 2
		grid[a[2]][a[3]] = (grid[a[2]][a[3]] + 1) % 2
		grid[a[4]][a[5]] = (grid[a[4]][a[5]] + 1) % 2
	for a in ans:
		llt[a[0]][a[1]] = (llt[a[0]][a[1]] + 1) % 2
		llt[a[2]][a[3]] = (llt[a[2]][a[3]] + 1) % 2
		llt[a[4]][a[5]] = (llt[a[4]][a[5]] + 1) % 2
	for i in range(n):
		for j in range(m):
			assert grid[i][j] == llt[i][j] == 0
	print(len(ans))
	assert len(ans) <= m * n
	for li in ans:
		print(*[i + 1 for i in li])
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
for _ in range(int(input())):
	main(_ + 1)


import sys, itertools

def one(x, y):
	if arr[x][y] == 0 and arr[x + 1][y + 1] == 0:
		if arr[x + 1][y] == 1:
			ans.append((x + 1, y + 1))
			ans.append((x + 2, y + 2))
			ans.append((x + 2, y + 1))
			arr[x][y] = 1 - arr[x][y]
			arr[x + 1][y + 1] = 1 - arr[x + 1][y + 1]
			arr[x + 1][y] = 1 - arr[x + 1][y]
		elif arr[x][y + 1]:
			ans.append((x + 1, y + 1))
			ans.append((x + 2, y + 2))
			ans.append((x + 1, y + 2))
			arr[x][y] = 1 - arr[x][y]
			arr[x + 1][y + 1] = 1 - arr[x + 1][y + 1]
			arr[x][y + 1] = 1 - arr[x][y + 1]
	elif arr[x + 1][y] == 0 and arr[x][y + 1] == 0:
		if arr[x][y] == 1:
			ans.append((x + 1, y + 1))
			ans.append((x + 2, y + 1))
			ans.append((x + 1, y + 2))
			arr[x][y] = 1 - arr[x][y]
			arr[x + 1][y] = 1 - arr[x + 1][y]
			arr[x][y + 1] = 1 - arr[x][y + 1]
		elif arr[x + 1][y + 1] == 1:
			ans.append((x + 2, y + 2))
			ans.append((x + 2, y + 1))
			ans.append((x + 1, y + 2))
			arr[x + 1][y + 1] = 1 - arr[x + 1][y + 1]
			arr[x + 1][y] = 1 - arr[x + 1][y]
			arr[x][y + 1] = 1 - arr[x][y + 1]
	two(x, y)

def two(x, y):
	res = []
	cnt = 0
	left = []
	for i in range(x, x + 2):
		for j in range(y, y + 2):
			if arr[i][j] == 0:
				res.append((i, j))
			elif cnt == 0:
				res.append((i, j))
				cnt += 1
			else:
				left.append((i, j))
	for i in res:
		ans.append((i[0] + 1, i[1] + 1))
		arr[i[0]][i[1]] = 1 - arr[i[0]][i[1]]
	three(x, y)

def three(x, y):
	global ans
	res = []
	for i in range(x, x + 2):
		for j in range(y, y + 2):
			if arr[i][j] == 1:
				if len(res) < 3:
					res.append((i, j))
	for i in res:
		ans.append((i[0] + 1, i[1] + 1))
		arr[i[0]][i[1]] = 1 - arr[i[0]][i[1]]

def four(x, y):
	ans.append((x + 1, y + 1))
	ans.append((x + 1, y + 2))
	ans.append((x + 2, y + 1))
	arr[x][y] = 1 - arr[x][y]
	arr[x + 1][y] = 1 - arr[x + 1][y]
	arr[x][y + 1] = 1 - arr[x][y + 1]
	one(x, y)
tc = int(sys.stdin.readline())
for _ in range(tc):
	(n, m) = map(int, sys.stdin.readline().split())
	arr = [list(map(int, sys.stdin.readline().rstrip())) for _ in range(n)]
	dx = [0, 1, 0, 1]
	dy = [0, 0, 1, 1]
	ans = []
	for i in range(n - 1):
		for j in range(m - 1):
			z_cnt = 0
			o_cnt = 0
			for k in range(4):
				if arr[i + dx[k]][j + dy[k]] == 0:
					z_cnt += 1
				else:
					o_cnt += 1
			if o_cnt == 1:
				one(i, j)
			elif o_cnt == 2:
				two(i, j)
			elif o_cnt == 3:
				three(i, j)
			elif o_cnt == 4:
				four(i, j)
	print(len(ans) // 3)
	for i in range(0, len(ans), 3):
		for j in range(3):
			print(ans[i + j][0], ans[i + j][1], end=' ')
		print()


import math
import random
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction
import sys
import threading
from collections import defaultdict
threading.stack_size(10 ** 8)
mod = 10 ** 9 + 7
mod1 = 998244353
import os
import sys
from io import BytesIO, IOBase
sys.setrecursionlimit(300000)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class TreeNode:

	def __init__(self, k, v):
		self.key = k
		self.value = v
		self.left = None
		self.right = None
		self.parent = None
		self.height = 1
		self.num_left = 1
		self.num_total = 1

class AvlTree:

	def __init__(self):
		self._tree = None

	def add(self, k, v):
		if not self._tree:
			self._tree = TreeNode(k, v)
			return
		node = self._add(k, v)
		if node:
			self._rebalance(node)

	def _add(self, k, v):
		node = self._tree
		while node:
			if k < node.key:
				if node.left:
					node = node.left
				else:
					node.left = TreeNode(k, v)
					node.left.parent = node
					return node.left
			elif node.key < k:
				if node.right:
					node = node.right
				else:
					node.right = TreeNode(k, v)
					node.right.parent = node
					return node.right
			else:
				node.value = v
				return

	@staticmethod
	def get_height(x):
		return x.height if x else 0

	@staticmethod
	def get_num_total(x):
		return x.num_total if x else 0

	def _rebalance(self, node):
		n = node
		while n:
			lh = self.get_height(n.left)
			rh = self.get_height(n.right)
			n.height = max(lh, rh) + 1
			balance_factor = lh - rh
			n.num_total = 1 + self.get_num_total(n.left) + self.get_num_total(n.right)
			n.num_left = 1 + self.get_num_total(n.left)
			if balance_factor > 1:
				if self.get_height(n.left.left) < self.get_height(n.left.right):
					self._rotate_left(n.left)
				self._rotate_right(n)
			elif balance_factor < -1:
				if self.get_height(n.right.right) < self.get_height(n.right.left):
					self._rotate_right(n.right)
				self._rotate_left(n)
			else:
				n = n.parent

	def _remove_one(self, node):
		replacement = node.left or node.right
		if node.parent:
			if AvlTree._is_left(node):
				node.parent.left = replacement
			else:
				node.parent.right = replacement
			replacement.parent = node.parent
			node.parent = None
		else:
			self._tree = replacement
			replacement.parent = None
		node.left = None
		node.right = None
		node.parent = None
		self._rebalance(replacement)

	def _remove_leaf(self, node):
		if node.parent:
			if AvlTree._is_left(node):
				node.parent.left = None
			else:
				node.parent.right = None
			self._rebalance(node.parent)
		else:
			self._tree = None
		node.parent = None
		node.left = None
		node.right = None

	def remove(self, k):
		node = self._get_node(k)
		if not node:
			return
		if AvlTree._is_leaf(node):
			self._remove_leaf(node)
			return
		if node.left and node.right:
			nxt = AvlTree._get_next(node)
			node.key = nxt.key
			node.value = nxt.value
			if self._is_leaf(nxt):
				self._remove_leaf(nxt)
			else:
				self._remove_one(nxt)
			self._rebalance(node)
		else:
			self._remove_one(node)

	def get(self, k):
		node = self._get_node(k)
		return node.value if node else -1

	def _get_node(self, k):
		if not self._tree:
			return None
		node = self._tree
		while node:
			if k < node.key:
				node = node.left
			elif node.key < k:
				node = node.right
			else:
				return node
		return None

	def get_at(self, pos):
		x = pos + 1
		node = self._tree
		while node:
			if x < node.num_left:
				node = node.left
			elif node.num_left < x:
				x -= node.num_left
				node = node.right
			else:
				return (node.key, node.value)
		raise IndexError('Out of ranges')

	@staticmethod
	def _is_left(node):
		return node.parent.left and node.parent.left == node

	@staticmethod
	def _is_leaf(node):
		return node.left is None and node.right is None

	def _rotate_right(self, node):
		if not node.parent:
			self._tree = node.left
			node.left.parent = None
		elif AvlTree._is_left(node):
			node.parent.left = node.left
			node.left.parent = node.parent
		else:
			node.parent.right = node.left
			node.left.parent = node.parent
		bk = node.left.right
		node.left.right = node
		node.parent = node.left
		node.left = bk
		if bk:
			bk.parent = node
		node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
		node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
		node.num_left = 1 + self.get_num_total(node.left)

	def _rotate_left(self, node):
		if not node.parent:
			self._tree = node.right
			node.right.parent = None
		elif AvlTree._is_left(node):
			node.parent.left = node.right
			node.right.parent = node.parent
		else:
			node.parent.right = node.right
			node.right.parent = node.parent
		bk = node.right.left
		node.right.left = node
		node.parent = node.right
		node.right = bk
		if bk:
			bk.parent = node
		node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
		node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
		node.num_left = 1 + self.get_num_total(node.left)

	@staticmethod
	def _get_next(node):
		if not node.right:
			return node.parent
		n = node.right
		while n.left:
			n = n.left
		return n

class SegmentTree1:

	def __init__(self, data, default=2 ** 51, func=lambda a, b: a & b):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class SegmentTree:

	def __init__(self, data, default=0, func=lambda a, b: a + b):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

def powm(a, n, m):
	if a == 1 or n == 0:
		return 1
	if n % 2 == 0:
		s = powm(a, n // 2, m)
		return s * s % m
	else:
		return a * powm(a, n - 1, m) % m

def sort_list(list1, list2):
	zipped_pairs = zip(list2, list1)
	z = [x for (_, x) in sorted(zipped_pairs)]
	return z

def product(l):
	por = 1
	for i in range(len(l)):
		por *= l[i]
	return por

def binarySearchCount(arr, n, key):
	left = 0
	right = n - 1
	count = 0
	while left <= right:
		mid = int((right + left) / 2)
		if arr[mid] < key:
			count = mid + 1
			left = mid + 1
		else:
			right = mid - 1
	return count

def countdig(n):
	c = 0
	while n > 0:
		n //= 10
		c += 1
	return c

def binary(x, length):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y

def countGreater(arr, n, k):
	l = 0
	r = n - 1
	leftGreater = n
	while l <= r:
		m = int(l + (r - l) / 2)
		if arr[m] >= k:
			leftGreater = m
			r = m - 1
		else:
			l = m + 1
	return n - leftGreater
for ik in range(int(input())):
	(n, m) = map(int, input().split())
	l = []
	ans = []
	for i in range(n):
		l.append(list(input()))
		for j in range(m):
			l[i][j] = int(l[i][j])
	for i in range(n - 2):
		for j in range(m):
			t = 1
			if j == m - 1:
				t = -1
			if l[i][j] == 1:
				ans.append([(i, j), (i + 1, j), (i + 1, j + t)])
				l[i + 1][j] = 1 - l[i + 1][j]
				l[i + 1][j + t] = 1 - l[i + 1][j + t]
	for j in range(m - 1, 1, -1):
		if l[-2][j] == 1:
			if l[-1][j] == 1:
				ans.append([(n - 2, j), (n - 1, j), (n - 2, j - 1)])
				l[-2][j - 1] = 1 - l[-2][j - 1]
			else:
				ans.append([(n - 2, j), (n - 1, j - 1), (n - 2, j - 1)])
				l[-2][j - 1] = 1 - l[-2][j - 1]
				l[-1][j - 1] = 1 - l[-1][j - 1]
		elif l[-1][j] == 1:
			ans.append([(n - 1, j), (n - 1, j - 1), (n - 2, j - 1)])
			l[-2][j - 1] = 1 - l[-2][j - 1]
			l[-1][j - 1] = 1 - l[-1][j - 1]
	one = []
	zero = []
	for i in range(n - 2, n):
		for j in range(2):
			if l[i][j] == 1:
				one.append((i, j))
			else:
				zero.append((i, j))
	if len(one) == 3:
		ans.append(one)
	elif len(one) == 2:
		we = [one[0], zero[0], zero[1]]
		we1 = [one[1], zero[0], zero[1]]
		ans.append(we)
		ans.append(we1)
	elif len(one) == 1:
		ans.append([one[0], zero[0], zero[1]])
		t = zero[0]
		t1 = zero[1]
		zero = [zero[2], one[0]]
		one = [t, t1]
		we = [one[0], zero[0], zero[1]]
		we1 = [one[1], zero[0], zero[1]]
		ans.append(we)
		ans.append(we1)
	elif len(one) == 4:
		ans.append([one[0], one[1], one[2]])
		zero = [one[0], one[1], one[2]]
		one = [one[3]]
		ans.append([one[0], zero[0], zero[1]])
		t = zero[0]
		t1 = zero[1]
		zero = [zero[2], one[0]]
		one = [t, t1]
		we = [one[0], zero[0], zero[1]]
		we1 = [one[1], zero[0], zero[1]]
		ans.append(we)
		ans.append(we1)
	print(len(ans))
	for i in range(len(ans)):
		for j in range(3):
			print(ans[i][j][0] + 1, ans[i][j][1] + 1, end=' ')
		print()


import sys
input = lambda : sys.stdin.readline().strip()
inp = lambda : list(map(int, sys.stdin.readline().strip().split()))
for _ in range(int(input())):
	(n, m) = inp()
	a = [[i for i in str(input())] for j in range(n)]
	ans = []

	def change(lol):
		(b, c, d, e, f, g) = lol
		a[b - 1][c - 1] = '0' if a[b - 1][c - 1] == '1' else '1'
		a[d - 1][e - 1] = '0' if a[d - 1][e - 1] == '1' else '1'
		a[f - 1][g - 1] = '0' if a[f - 1][g - 1] == '1' else '1'
	for i in range(1, n - 1):
		for j in range(1, m - 1):
			if a[i - 1][j - 1] == '1':
				ans.append([i, j, i + 1, j, i + 1, j + 1])
				change([i, j, i + 1, j, i + 1, j + 1])
	a1 = m - 1
	a2 = m
	for i in range(1, n - 1):
		if a[i - 1][a1 - 1] == '1' and a[i - 1][a2 - 1] == '1':
			ans.append([i, a1, i, a2, i + 1, a1])
		elif a[i - 1][a1 - 1] == '1' and a[i - 1][a2 - 1] == '0':
			ans.append([i, a1, i + 1, a1, i + 1, a2])
		elif a[i - 1][a1 - 1] == '0' and a[i - 1][a2 - 1] == '1':
			ans.append([i, a2, i + 1, a1, i + 1, a2])
		else:
			continue
		change(ans[-1])
	a1 = n - 1
	a2 = n
	for i in range(1, m - 1):
		if a[a1 - 1][i - 1] == '1' and a[a2 - 1][i - 1] == '1':
			ans.append([a1, i, a2, i, a1, i + 1])
		elif a[a1 - 1][i - 1] == '1' and a[a2 - 1][i - 1] == '0':
			ans.append([a1, i, a1, i + 1, a2, i + 1])
		elif a[a1 - 1][i - 1] == '0' and a[a2 - 1][i - 1] == '1':
			ans.append([a2, i, a1, i + 1, a2, i + 1])
		else:
			continue
		change(ans[-1])
	(a1, a2) = (n - 2, n - 1)
	(b1, b2) = (m - 2, m - 1)
	b = [a[a1][b1], a[a1][b2], a[a2][b1], a[a2][b2]]
	one = []
	zer = []
	if a[a1][b1] == '1':
		one.append([a1 + 1, b1 + 1])
	else:
		zer.append([a1 + 1, b1 + 1])
	if a[a1][b2] == '1':
		one.append([a1 + 1, b2 + 1])
	else:
		zer.append([a1 + 1, b2 + 1])
	if a[a2][b1] == '1':
		one.append([a2 + 1, b1 + 1])
	else:
		zer.append([a2 + 1, b1 + 1])
	if a[a2][b2] == '1':
		one.append([a2 + 1, b2 + 1])
	else:
		zer.append([a2 + 1, b2 + 1])
	if b.count('1') == 1:
		ans.append([one[0][0], one[0][1], zer[0][0], zer[0][1], zer[1][0], zer[1][1]])
		newzer = [[one[0][0], one[0][1]], [zer[2][0], zer[2][1]]]
		one = [[zer[0][0], zer[0][1]], [zer[1][0], zer[1][1]]]
		zer = newzer.copy()
	if b.count('1') == 0:
		pass
	elif b.count('1') == 3:
		ans.append([one[0][0], one[0][1], one[1][0], one[1][1], one[2][0], one[2][1]])
	elif b.count('1') == 4:
		ans.append([one[0][0], one[0][1], one[1][0], one[1][1], one[2][0], one[2][1]])
		ans.append([one[0][0], one[0][1], one[3][0], one[3][1], one[2][0], one[2][1]])
		ans.append([one[3][0], one[3][1], one[1][0], one[1][1], one[2][0], one[2][1]])
		ans.append([one[0][0], one[0][1], one[1][0], one[1][1], one[3][0], one[3][1]])
	else:
		ans.append([zer[0][0], zer[0][1], zer[1][0], zer[1][1], one[1][0], one[1][1]])
		ans.append([zer[0][0], zer[0][1], zer[1][0], zer[1][1], one[0][0], one[0][1]])
	print(len(ans))
	for i in ans:
		print(*i)


import io
import os

def solve():
	(n, m) = map(int, input().split())
	vals = []
	for _ in range(n):
		vals.append(list(map(int, input())))
	ops = []

	def flip(x1, y1, x2, y2, x3, y3):
		for (a, b) in ([x1, y1], [x2, y2], [x3, y3]):
			vals[b][a] = 1 - vals[b][a]
		ops.append((y1 + 1, x1 + 1, y2 + 1, x2 + 1, y3 + 1, x3 + 1))
	for y in range(n - 2):
		for x in range(m):
			if x == m - 1:
				if vals[y][x]:
					flip(x, y, x, y + 1, x - 1, y + 1)
			elif vals[y][x]:
				flip(x, y, x, y + 1, x + 1, y + 1)
	for x in range(m - 2):
		if vals[n - 2][x]:
			flip(x, n - 2, x + 1, n - 2, x + 1, n - 1)
		if vals[n - 1][x]:
			flip(x, n - 1, x + 1, n - 2, x + 1, n - 1)
	a = (m - 2, n - 2)
	b = (m - 1, n - 2)
	c = (m - 2, n - 1)
	d = (m - 1, n - 1)

	def last():
		return [vals[y][x] for (x, y) in [a, b, c, d]]
	if sum(last()) == 4:
		flip(*a, *b, *c)
	if sum(last()) == 1:
		i = last().index(1)
		if i == 0:
			flip(*a, *b, *c)
		elif i == 1:
			flip(*b, *d, *c)
		elif i == 2:
			flip(*a, *c, *d)
		else:
			flip(*b, *d, *c)
	if sum(last()) == 2:
		if last() == [1, 1, 0, 0]:
			flip(*a, *c, *d)
		elif last() == [1, 0, 1, 0]:
			flip(*a, *b, *d)
		elif last() == [1, 0, 0, 1]:
			flip(*a, *b, *c)
		elif last() == [0, 1, 1, 0]:
			flip(*a, *b, *d)
		elif last() == [0, 1, 0, 1]:
			flip(*a, *b, *c)
		else:
			flip(*a, *b, *c)
	if sum(last()) == 3:
		i = last().index(0)
		if i == 0:
			flip(*b, *c, *d)
		elif i == 1:
			flip(*a, *c, *d)
		elif i == 2:
			flip(*a, *b, *d)
		else:
			flip(*a, *b, *c)
	for row in vals:
		assert not any(row)
	print(len(ops))
	for op in ops:
		print(*op)
t = int(input())
for _ in range(t):
	solve()


from sys import stdin, stdout
input = stdin.readline

def f1(a, b, c, d):
	global ans
	ans.append((a[1], a[2], b[1], b[2], c[1], c[2]))
	ans.append((a[1], a[2], b[1], b[2], d[1], d[2]))
	ans.append((a[1], a[2], d[1], d[2], c[1], c[2]))

def f2(a, b, c, d):
	global ans
	ans.append((a[1], a[2], b[1], b[2], d[1], d[2]))
	ans.append((a[1], a[2], d[1], d[2], c[1], c[2]))

def f3(a, b, c, d):
	global ans
	ans.append((a[1], a[2], d[1], d[2], c[1], c[2]))
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	mat = [[0 for x in range(m)] for y in range(n)]
	for i in range(n):
		x = input()
		for j in range(m):
			mat[i][j] = int(x[j])
	ans = []
	for i in range(n - 1):
		for j in range(m - 1):
			if i == n - 2 and j == m - 2:
				arr = [(mat[i][j], i, j), (mat[i + 1][j], i + 1, j), (mat[i][j + 1], i, j + 1), (mat[i + 1][j + 1], i + 1, j + 1)]
				arr = sorted(arr, key=lambda x: x[0], reverse=True)
				c = 0
				for k in arr:
					if k[0]:
						c += 1
				if c == 0:
					continue
				elif c == 1:
					f1(arr[0], arr[1], arr[2], arr[3])
				elif c == 2:
					f2(arr[3], arr[0], arr[1], arr[2])
				elif c == 3:
					f3(arr[2], arr[3], arr[1], arr[0])
				else:
					ans.append((i + 1, j + 1, i, j + 1, i + 1, j))
					f1(arr[0], arr[1], arr[2], arr[3])
				continue
			if j == m - 2:
				if mat[i][j] and mat[i][j + 1]:
					ans.append((i, j, i, j + 1, i + 1, j))
				elif not mat[i][j] and mat[i][j + 1]:
					ans.append((i + 1, j + 1, i, j + 1, i + 1, j))
				elif mat[i][j] and (not mat[i][j + 1]):
					ans.append((i, j, i + 1, j, i + 1, j + 1))
				else:
					continue
				for k in range(0, 6, 2):
					mat[ans[-1][k]][ans[-1][k + 1]] ^= 1
				continue
			if i == n - 2:
				if mat[i][j] and mat[i + 1][j]:
					ans.append((i, j, i + 1, j, i, j + 1))
				elif not mat[i][j] and mat[i + 1][j]:
					ans.append((i + 1, j + 1, i, j + 1, i + 1, j))
				elif mat[i][j] and (not mat[i + 1][j]):
					ans.append((i, j, i, j + 1, i + 1, j + 1))
				else:
					continue
				for k in range(0, 6, 2):
					mat[ans[-1][k]][ans[-1][k + 1]] ^= 1
				continue
			if mat[i][j]:
				ans.append((i, j, i, j + 1, i + 1, j))
			else:
				continue
			for k in range(0, 6, 2):
				mat[ans[-1][k]][ans[-1][k + 1]] ^= 1
	stdout.write(str(len(ans)) + '\n')
	for i in ans:
		for j in i:
			stdout.write(str(j + 1) + ' ')
		stdout.write('\n')


import sys
input = sys.stdin.readline
t = int(input())
for you in range(t):
	l = input().split()
	n = int(l[0])
	m = int(l[1])
	l = []
	for i in range(n):
		s = input()
		l.append(s)
	ok = []
	for i in range(n - 1):
		for j in range(m - 1):
			if l[i][j] == '1':
				ok.append((i, j, i, j + 1, i + 1, j))
				ok.append((i, j, i + 1, j, i + 1, j + 1))
				ok.append((i, j, i, j + 1, i + 1, j + 1))
	for i in range(n - 1):
		if l[i][m - 1] == '1':
			ok.append((i, m - 1, i, m - 2, i + 1, m - 1))
			ok.append((i, m - 1, i, m - 2, i + 1, m - 2))
			ok.append((i, m - 1, i + 1, m - 1, i + 1, m - 2))
	for i in range(m - 1):
		if l[n - 1][i] == '1':
			ok.append((n - 1, i, n - 2, i, n - 1, i + 1))
			ok.append((n - 1, i, n - 1, i + 1, n - 2, i + 1))
			ok.append((n - 1, i, n - 2, i, n - 2, i + 1))
	if l[n - 1][m - 1] == '1':
		ok.append((n - 1, m - 1, n - 2, m - 1, n - 1, m - 2))
		ok.append((n - 1, m - 1, n - 1, m - 2, n - 2, m - 2))
		ok.append((n - 1, m - 1, n - 2, m - 1, n - 2, m - 2))
	print(len(ok))
	for i in ok:
		print(i[0] + 1, i[1] + 1, i[2] + 1, i[3] + 1, i[4] + 1, i[5] + 1)


import time, math as mt, bisect as bs, sys
from sys import stdin, stdout
from collections import deque
from fractions import Fraction
from collections import Counter
from collections import OrderedDict
pi = 3.141592653589793

def II():
	return int(stdin.readline())

def IP():
	return map(int, stdin.readline().split())

def L():
	return list(map(int, stdin.readline().split()))

def P(x):
	return stdout.write(str(x) + '\n')

def PI(x, y):
	return stdout.write(str(x) + ' ' + str(y) + '\n')

def lcm(a, b):
	return a * b // gcd(a, b)
mod = 1000000007

def solve():
	(n, m) = IP()
	li = []
	for i in range(n):
		s = input()
		temp = []
		for ele in s:
			if ele == '0':
				temp.append(0)
			else:
				temp.append(1)
		li.append(temp)
	ans = []
	for i in range(n - 1):
		for j in range(m):
			if j == m - 1:
				if li[i][j] == 1:
					ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j])
					li[i][j] = 0
					li[i + 1][j] = 1 - li[i + 1][j]
					li[i + 1][j - 1] = 1 - li[i + 1][j - 1]
			elif li[i][j] == 1:
				ans.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
				li[i][j] = 0
				li[i + 1][j] = 1 - li[i + 1][j]
				li[i + 1][j + 1] = 1 - li[i + 1][j + 1]
	for i in range(m):
		if i == m - 1:
			continue
		elif i == m - 2:
			continue
		elif li[n - 1][i] == 1:
			ans.append([n, i + 1, n, i + 2, n - 1, i + 2])
			li[n - 1][i] = 0
			li[n - 1][i + 1] = 1 - li[n - 1][i + 1]
			li[n - 2][i + 1] = 1 - li[n - 1][i + 2]
			ans.append([n - 2 + 1, i + 1 + 1, n - 1 + 1, i + 1 + 1, n - 1 + 1, i + 2 + 1])
			li[n - 2][i + 1] = 0
			li[n - 1][i + 1] = 1 - li[n - 1][i + 1]
			li[n - 1][i + 2] = 1 - li[n - 1][i + 2]
	if li[n - 1][m - 2] == 1 and li[n - 1][m - 1] == 1:
		ans.append([n - 2 + 1, m - 2 + 1, n - 2 + 1, m - 1 + 1, n - 1 + 1, m - 1 + 1])
		ans.append([n - 2 + 1, m - 2 + 1, n - 2 + 1, m - 1 + 1, n - 1 + 1, m - 2 + 1])
	elif li[n - 1][m - 2] == 1:
		ans.append([n - 2 + 1, m - 2 + 1, n - 1 + 1, m - 2 + 1, n - 1 + 1, m - 1 + 1])
		ans.append([n - 1 + 1, m - 2 + 1, n - 1 + 1, m - 1 + 1, n - 2 + 1, m - 1 + 1])
		ans.append([n - 2 + 1, m - 2 + 1, n - 2 + 1, m - 1 + 1, n - 1 + 1, m - 2 + 1])
	elif li[n - 1][m - 1] == 1:
		ans.append([n - 1 + 1, m - 2 + 1, n - 1 + 1, m - 1 + 1, n - 2 + 1, m - 1 + 1])
		ans.append([n - 2 + 1, m - 2 + 1, n - 1 + 1, m - 2 + 1, n - 1 + 1, m - 1 + 1])
		ans.append([n - 2 + 1, m - 2 + 1, n - 2 + 1, m - 1 + 1, n - 1 + 1, m - 1 + 1])
	print(len(ans))
	for ele in ans:
		print(*ele)
	return
t = II()
for i in range(t):
	solve()


for y in range(int(input())):
	(n, k) = map(int, input().split())
	lst = []
	ans = []
	for i in range(n):
		lst.append(list(input()))
	for i in range(n):
		for j in range(k):
			if i == n - 1:
				if j == k - 1:
					if lst[i][j] == '0':
						pass
					else:
						ans.append([i, j, i - 1, j, i - 1, j - 1])
						ans.append([i, j, i - 1, j, i, j - 1])
						ans.append([i, j, i - 1, j - 1, i, j - 1])
				elif lst[i][j] == '0':
					pass
				else:
					ans.append([i, j, i - 1, j, i - 1, j + 1])
					ans.append([i, j + 1, i - 1, j, i - 1, j + 1])
					lst[i][j] = '0'
					if lst[i][j + 1] == '1':
						lst[i][j + 1] = '0'
					else:
						lst[i][j + 1] = '1'
			elif j == k - 1:
				if lst[i][j] == '0':
					pass
				elif lst[i][j - 1] == '0':
					ans.append([i, j, i + 1, j, i + 1, j - 1])
					lst[i][j] = '0'
					if lst[i + 1][j] == '1':
						lst[i + 1][j] = '0'
					else:
						lst[i + 1][j] = '1'
					if lst[i + 1][j - 1] == '1':
						lst[i + 1][j - 1] = '0'
					else:
						lst[i + 1][j - 1] = '1'
			elif lst[i][j] == '0':
				pass
			elif lst[i][j + 1] == '0':
				ans.append([i, j, i + 1, j, i + 1, j + 1])
				lst[i][j] = '0'
				if lst[i + 1][j] == '1':
					lst[i + 1][j] = '0'
				else:
					lst[i + 1][j] = '1'
				if lst[i + 1][j + 1] == '1':
					lst[i + 1][j + 1] = '0'
				else:
					lst[i + 1][j + 1] = '1'
			else:
				ans.append([i, j, i, j + 1, i + 1, j + 1])
				lst[i][j] = '0'
				if lst[i][j + 1] == '1':
					lst[i][j + 1] = '0'
				else:
					lst[i][j + 1] = '1'
				if lst[i + 1][j + 1] == '1':
					lst[i + 1][j + 1] = '0'
				else:
					lst[i + 1][j + 1] = '1'
	print(len(ans))
	for i in ans:
		for j in i:
			print(j + 1, end=' ')
		print()


def solve(n, m, mat):
	ops = []
	for i in range(n):
		for j in range(m):
			if mat[i][j] == '1':
				mat[i][j] = 1
			else:
				mat[i][j] = 0
	for i in range(n - 1, 1, -1):
		for j in range(m - 1, -1, -1):
			if mat[i][j] == 1:
				ops.append([i, j, i - 1, j, i - 1, j - 1 if j else j + 1])
				mat[i][j] ^= 1
				mat[i - 1][j] ^= 1
				mat[i - 1][j - 1 if j else j + 1] ^= 1
	for j in range(m - 1, 1, -1):
		if mat[0][j] and mat[1][j]:
			ops.append([0, j, 1, j, 0, j - 1])
			mat[0][j] ^= 1
			mat[1][j] ^= 1
			mat[0][j - 1] ^= 1
		elif mat[0][j]:
			ops.append([0, j, 0, j - 1, 1, j - 1])
			mat[0][j] ^= 1
			mat[0][j - 1] ^= 1
			mat[1][j - 1] ^= 1
		elif mat[1][j]:
			ops.append([1, j, 0, j - 1, 1, j - 1])
			mat[1][j] ^= 1
			mat[0][j - 1] ^= 1
			mat[1][j - 1] ^= 1
	if mat[0][0] ^ mat[0][1] ^ mat[1][0]:
		ops.append([0, 0, 0, 1, 1, 0])
	if mat[0][0] ^ mat[0][1] ^ mat[1][1]:
		ops.append([0, 0, 0, 1, 1, 1])
	if mat[0][0] ^ mat[1][0] ^ mat[1][1]:
		ops.append([0, 0, 1, 1, 1, 0])
	if mat[0][1] ^ mat[1][0] ^ mat[1][1]:
		ops.append([0, 1, 1, 0, 1, 1])
	for op in ops:
		for z in range(6):
			op[z] += 1
	return ops
t = int(input())
while t:
	(n, m) = map(int, input().split())
	res = []
	for _ in range(n):
		res.append(list(input()))
	k = solve(n, m, res)
	print(len(k))
	for x in k:
		print(*x)
	t -= 1


def unique_pairs(n):
	for i in range(n):
		for j in range(n):
			yield (i, j)

def oper1(table, n, m, res):
	for i in range(n - 1, 1, -1):
		for j in range(m - 2):
			if table[i][j] == 1:
				res.append([i, j, i - 1, j, i - 1, j + 1])
				table[i - 1][j] ^= 1
				table[i - 1][j + 1] ^= 1
		if table[i][m - 1] == table[i][m - 2] == 1:
			res.append([i, m - 1, i, m - 2, i - 1, m - 1])
			table[i - 1][m - 1] ^= 1
		elif table[i][m - 1]:
			res.append([i, m - 1, i - 1, m - 1, i - 1, m - 2])
			table[i - 1][m - 1] ^= 1
			table[i - 1][m - 2] ^= 1
		elif table[i][m - 2]:
			res.append([i, m - 2, i - 1, m - 2, i - 1, m - 1])
			table[i - 1][m - 1] ^= 1
			table[i - 1][m - 2] ^= 1
		table = table[:-1]
	return (table, res)

def oper2(table, m, res):
	for j in range(m - 1, 1, -1):
		if table[0][j] == table[1][j] == 1:
			res.append([0, j, 1, j, 0, j - 1])
			table[0][j - 1] ^= 1
		elif table[0][j]:
			res.append([0, j, 0, j - 1, 1, j - 1])
			table[0][j - 1] ^= 1
			table[1][j - 1] ^= 1
		elif table[1][j]:
			res.append([1, j, 0, j - 1, 1, j - 1])
			table[0][j - 1] ^= 1
			table[1][j - 1] ^= 1
	return (table, res)

def solve(t, n, m):
	res = []
	if n > 2:
		(t, res) = oper1(t, n, m, res)
	if m > 2:
		(t, res) = oper2(t, m, res)
		t = [i[:2] for i in t]
	cnt1 = sum((x.count(1) for x in t))
	if cnt1:
		if cnt1 == 4:
			res.append([0, 1, 1, 1, 1, 0])
			t = [[1, 0], [0, 0]]
			cnt1 -= 3
		if cnt1 == 1:
			for (i, j) in unique_pairs(2):
				if t[i][j] == 1:
					res.append([i, j, i ^ 1, j, i ^ 1, j ^ 1])
					(t[i][j], t[i ^ 1][j], t[i ^ 1][j ^ 1]) = (0, 1, 1)
					break
			cnt1 += 1
		if cnt1 == 2:
			cnt = 0
			qwq = []
			for (i, j) in unique_pairs(2):
				if t[i][j] == 0:
					qwq.extend([i, j])
					t[i][j] = 1
				elif not cnt:
					qwq.extend([i, j])
					cnt += 1
					t[i][j] = 0
			res.append(qwq)
			cnt1 += 1
		if cnt1 == 3:
			for (i, j) in unique_pairs(2):
				if not t[i][j]:
					res.append([i, j ^ 1, i ^ 1, j ^ 1, i ^ 1, j])
					break
	print(len(res))
	res = [[j + 1 for j in i] for i in res]
	for _ in res:
		print(*_)
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	table = []
	for i in range(n):
		table.append([int(i) for i in list(input())])
	solve(table, n, m)


def f(x, y, l):
	p = [l[x][y], l[x][y + 1], l[x + 1][y], l[x + 1][y + 1]]
	ans = []
	tes = [[0, 0], [0, 1], [1, 0], [1, 1]]
	z = p.count(0)
	if z == 4:
		return ans
	if z == 1:
		l1 = []
		for (i, j) in tes:
			if l[x + i][y + j] == 0:
				for (g, h) in tes:
					if g != i or h != j:
						l[x + g][y + h] = 1 - l[x + g][y + h]
						l1.append(x + g + 1)
						l1.append(y + h + 1)
				return [l1] + f(x, y, l)
	if z == 2:
		l1 = []
		for (i, j) in tes:
			if l[x + i][y + j] == 1:
				for (g, h) in tes:
					if g != i or h != j:
						l[x + g][y + h] = 1 - l[x + g][y + h]
						l1.append(x + g + 1)
						l1.append(y + h + 1)
				return [l1] + f(x, y, l)
	if z == 3:
		l1 = []
		for (i, j) in tes:
			if l[x + i][y + j] == 0:
				for (g, h) in tes:
					if g != i or h != j:
						l[x + g][y + h] = 1 - l[x + g][y + h]
						l1.append(x + g + 1)
						l1.append(y + h + 1)
				return [l1] + f(x, y, l)
	if z == 0:
		l1 = []
		for (i, j) in tes:
			if l[x + i][y + j] == 1:
				for (g, h) in tes:
					if g != i or h != j:
						l[x + g][y + h] = 1 - l[x + g][y + h]
						l1.append(x + g + 1)
						l1.append(y + h + 1)
				return [l1] + f(x, y, l)
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	l = []
	for _ in range(n):
		l.append(list(map(int, input())))
	(i, j) = (0, 0)
	anl = []
	ans = 0
	while i < n:
		if i == n - 1:
			i -= 1
		while j < m:
			if j == m - 1:
				j -= 1
			p = f(i, j, l)
			for c in p:
				anl.append(c)
			ans += len(p)
			j += 2
		j = 0
		i += 2
	print(ans)
	for c in anl:
		print(*c)


a = []

def solve(i, j):
	if a[i][j] == 0 and a[i + 1][j + 1] == 0 and (a[i + 1][j] == 0) and (a[i][j + 1] == 0):
		return []
	if a[i][j] == 1 and a[i + 1][j + 1] == 0 and (a[i + 1][j] == 0) and (a[i][j + 1] == 0):
		return [(0, 0, 0, 1, 1, 0), (0, 0, 0, 1, 1, 1), (0, 0, 1, 0, 1, 1)]
	if a[i][j] == 0 and a[i + 1][j + 1] == 0 and (a[i + 1][j] == 0) and (a[i][j + 1] == 1):
		return [(0, 0, 0, 1, 1, 1), (1, 0, 0, 0, 0, 1), (1, 1, 1, 0, 0, 1)]
	if a[i][j] == 0 and a[i + 1][j + 1] == 0 and (a[i + 1][j] == 1) and (a[i][j + 1] == 0):
		return [(0, 0, 1, 0, 1, 1), (0, 0, 0, 1, 1, 0), (0, 1, 1, 0, 1, 1)]
	if a[i][j] == 0 and a[i + 1][j + 1] == 1 and (a[i + 1][j] == 0) and (a[i][j + 1] == 0):
		return [(0, 1, 1, 0, 1, 1), (0, 0, 0, 1, 1, 1), (0, 0, 1, 0, 1, 1)]
	if a[i][j] == 1 and a[i + 1][j + 1] == 0 and (a[i + 1][j] == 0) and (a[i][j + 1] == 1):
		return [(0, 1, 1, 0, 1, 1), (0, 0, 1, 0, 1, 1)]
	if a[i][j] == 0 and a[i + 1][j + 1] == 1 and (a[i + 1][j] == 1) and (a[i][j + 1] == 0):
		return [(0, 0, 0, 1, 1, 0), (0, 0, 0, 1, 1, 1)]
	if a[i][j] == 1 and a[i + 1][j + 1] == 0 and (a[i + 1][j] == 1) and (a[i][j + 1] == 0):
		return [(0, 0, 0, 1, 1, 1), (0, 1, 1, 0, 1, 1)]
	if a[i][j] == 0 and a[i + 1][j + 1] == 1 and (a[i + 1][j] == 0) and (a[i][j + 1] == 1):
		return [(0, 0, 1, 0, 1, 1), (0, 0, 0, 1, 1, 0)]
	if a[i][j] == 1 and a[i + 1][j + 1] == 1 and (a[i + 1][j] == 0) and (a[i][j + 1] == 0):
		return [(0, 1, 1, 0, 1, 1), (0, 0, 0, 1, 1, 0)]
	if a[i][j] == 0 and a[i + 1][j + 1] == 0 and (a[i + 1][j] == 1) and (a[i][j + 1] == 1):
		return [(0, 0, 1, 0, 1, 1), (0, 0, 0, 1, 1, 1)]
	if a[i][j] == 1 and a[i + 1][j + 1] == 1 and (a[i + 1][j] == 1) and (a[i][j + 1] == 0):
		return [(0, 0, 1, 0, 1, 1)]
	if a[i][j] == 1 and a[i + 1][j + 1] == 1 and (a[i + 1][j] == 0) and (a[i][j + 1] == 1):
		return [(0, 0, 1, 1, 0, 1)]
	if a[i][j] == 1 and a[i + 1][j + 1] == 0 and (a[i + 1][j] == 1) and (a[i][j + 1] == 1):
		return [(0, 0, 1, 0, 0, 1)]
	if a[i][j] == 0 and a[i + 1][j + 1] == 1 and (a[i + 1][j] == 1) and (a[i][j + 1] == 1):
		return [(0, 1, 1, 0, 1, 1)]
	if a[i][j] == 1 and a[i + 1][j + 1] == 1 and (a[i + 1][j] == 1) and (a[i][j + 1] == 1):
		return [(0, 0, 0, 1, 1, 1), (0, 0, 1, 0, 1, 1), (0, 0, 0, 1, 1, 0), (0, 1, 1, 0, 1, 1)]
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = []
	for i in range(n):
		b = input().strip()
		b = [int(j) for j in b]
		a.append(b)
	res = []
	for i in range(n - 1):
		for j in range(m - 1):
			val = solve(i, j)
			for tp in val:
				res.append([tp[0] + i + 1, tp[1] + j + 1, tp[2] + i + 1, tp[3] + j + 1, tp[4] + i + 1, tp[5] + j + 1])
				a[tp[0] + i][tp[1] + j] ^= 1
				a[tp[2] + i][tp[3] + j] ^= 1
				a[tp[4] + i][tp[5] + j] ^= 1
	print(len(res))
	for i in res:
		print(*i)


import sys
from math import gcd, sqrt, ceil, log2
from collections import defaultdict, Counter, deque
from bisect import bisect_left, bisect_right
import math
sys.setrecursionlimit(2 * 10 ** 5 + 10)
import heapq
from itertools import permutations
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192
aa = 'abcdefghijklmnopqrstuvwxyz'

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def get_sum(bit, i):
	s = 0
	i += 1
	while i > 0:
		s += bit[i]
		i -= i & -i
	return s

def update(bit, n, i, v):
	i += 1
	while i <= n:
		bit[i] += v
		i += i & -i

def modInverse(b, m):
	g = math.gcd(b, m)
	if g != 1:
		return -1
	else:
		return pow(b, m - 2, m)

def primeFactors(n):
	sa = []
	while n % 2 == 0:
		sa.append(2)
		n = n // 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			sa.append(i)
			n = n // i
	if n > 2:
		sa.append(n)
	return sa

def seive(n):
	pri = [True] * (n + 1)
	p = 2
	while p * p <= n:
		if pri[p] == True:
			for i in range(p * p, n + 1, p):
				pri[i] = False
		p += 1
	return pri

def check_prim(n):
	if n < 0:
		return False
	for i in range(2, int(sqrt(n)) + 1):
		if n % i == 0:
			return False
	return True

def getZarr(string, z):
	n = len(string)
	(l, r, k) = (0, 0, 0)
	for i in range(1, n):
		if i > r:
			(l, r) = (i, i)
			while r < n and string[r - l] == string[r]:
				r += 1
			z[i] = r - l
			r -= 1
		else:
			k = i - l
			if z[k] < r - i + 1:
				z[i] = z[k]
			else:
				l = i
				while r < n and string[r - l] == string[r]:
					r += 1
				z[i] = r - l
				r -= 1

def search(text, pattern):
	concat = pattern + '$' + text
	l = len(concat)
	z = [0] * l
	getZarr(concat, z)
	ha = []
	for i in range(l):
		if z[i] == len(pattern):
			ha.append(i - len(pattern) - 1)
	return ha

def mergeIntervals(arr):
	arr.sort(key=lambda x: x[0])
	m = []
	s = -10000
	max = -100000
	for i in range(len(arr)):
		a = arr[i]
		if a[0] > max:
			if i != 0:
				m.append([s, max])
			max = a[1]
			s = a[0]
		elif a[1] >= max:
			max = a[1]
	if max != -100000 and [s, max] not in m:
		m.append([s, max])
	return m

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

def ncr(n, r, p):
	num = den = 1
	for i in range(r):
		num = num * (n - i) % p
		den = den * (i + 1) % p
	return num * pow(den, p - 2, p) % p

def sol(n):
	seti = set()
	for i in range(1, int(sqrt(n)) + 1):
		if n % i == 0:
			seti.add(n // i)
			seti.add(i)
	return seti

def lcm(a, b):
	return a * b // gcd(a, b)

def moore_voting(l):
	count1 = 0
	count2 = 0
	first = 10 ** 18
	second = 10 ** 18
	n = len(l)
	for i in range(n):
		if l[i] == first:
			count1 += 1
		elif l[i] == second:
			count2 += 1
		elif count1 == 0:
			count1 += 1
			first = l[i]
		elif count2 == 0:
			count2 += 1
			second = l[i]
		else:
			count1 -= 1
			count2 -= 1
	for i in range(n):
		if l[i] == first:
			count1 += 1
		elif l[i] == second:
			count2 += 1
	if count1 > n // 3:
		return first
	if count2 > n // 3:
		return second
	return -1

def find_parent(u, parent):
	if u != parent[u]:
		parent[u] = find_parent(parent[u], parent)
	return parent[u]

def dis_union(n):
	par = [i for i in range(n + 1)]
	rank = [1] * (n + 1)
	k = int(input())
	for i in range(k):
		(a, b) = map(int, input().split())
		(z1, z2) = (find_parent(a, par), find_parent(b, par))
		if z1 != z2:
			par[z1] = z2
			rank[z2] += rank[z1]

def dijkstra(n, tot, hash):
	hea = [[0, n]]
	dis = [10 ** 18] * (tot + 1)
	dis[n] = 0
	boo = defaultdict(bool)
	check = defaultdict(int)
	while hea:
		(a, b) = heapq.heappop(hea)
		if boo[b]:
			continue
		boo[b] = True
		for (i, w) in hash[b]:
			if b == 1:
				c = 0
				if (1, i, w) in nodes:
					c = nodes[1, i, w]
					del nodes[1, i, w]
				if dis[b] + w < dis[i]:
					dis[i] = dis[b] + w
					check[i] = c
				elif dis[b] + w == dis[i] and c == 0:
					dis[i] = dis[b] + w
					check[i] = c
			elif dis[b] + w <= dis[i]:
				dis[i] = dis[b] + w
				check[i] = check[b]
			heapq.heappush(hea, [dis[i], i])
	return check

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res *= x
		x = x * x
		y = y >> 1
	return res
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	l = []
	for i in range(n):
		s = list(input())
		l.append(s)
	ans = []
	for x in range(n):
		for y in range(m):
			if x + 1 < n and y + 1 < m:
				cnt = 0
				(i, j) = (x, y)
				(a, b, c, d) = (l[i][j], l[i + 1][j], l[i][j + 1], l[i + 1][j + 1])
				k = [a, b, c, d]
				co = [(i, j), (i + 1, j), (i, j + 1), (i + 1, j + 1)]
				if k.count('1') == 3:
					for i in co:
						(a, b) = i
						if l[a][b] == '1':
							l[a][b] = '0'
							ans.append((a + 1, b + 1))
				elif k.count('1') == 2:
					flag = 0
					flag1 = 0
					for i in co:
						(a, b) = i
						if l[a][b] == '1' and flag == 0:
							l[a][b] = '0'
							ans.append((a + 1, b + 1))
							flag = 1
						elif l[a][b] == '0' and flag1 < 2:
							l[a][b] = '1'
							ans.append((a + 1, b + 1))
							flag1 += 1
					for i in co:
						(a, b) = i
						if l[a][b] == '1':
							l[a][b] = '0'
							ans.append((a + 1, b + 1))
				elif k.count('1') == 1:
					flag = 0
					for i in co:
						(a, b) = i
						if l[a][b] == '1':
							l[a][b] = '0'
							ans.append((a + 1, b + 1))
						elif l[a][b] == '0' and flag < 2:
							l[a][b] = '1'
							ans.append((a + 1, b + 1))
							flag += 1
					flag = 0
					flag1 = 0
					for i in co:
						(a, b) = i
						if l[a][b] == '1' and flag == 0:
							l[a][b] = '0'
							ans.append((a + 1, b + 1))
							flag = 1
						elif l[a][b] == '0' and flag1 < 2:
							l[a][b] = '1'
							ans.append((a + 1, b + 1))
							flag1 += 1
					for i in co:
						(a, b) = i
						if l[a][b] == '1':
							l[a][b] = '0'
							ans.append((a + 1, b + 1))
				elif k.count('1') == 4:
					flag = 0
					for i in co:
						(a, b) = i
						if l[a][b] == '1' and flag <= 2:
							l[a][b] = '0'
							flag += 1
							ans.append((a + 1, b + 1))
					flag = 0
					for i in co:
						(a, b) = i
						if l[a][b] == '1':
							l[a][b] = '0'
							ans.append((a + 1, b + 1))
						elif l[a][b] == '0' and flag < 2:
							l[a][b] = '1'
							ans.append((a + 1, b + 1))
							flag += 1
					flag = 0
					flag1 = 0
					for i in co:
						(a, b) = i
						if l[a][b] == '1' and flag == 0:
							l[a][b] = '0'
							ans.append((a + 1, b + 1))
							flag = 1
						elif l[a][b] == '0' and flag1 < 2:
							l[a][b] = '1'
							ans.append((a + 1, b + 1))
							flag1 += 1
					for i in co:
						(a, b) = i
						if l[a][b] == '1':
							l[a][b] = '0'
							ans.append((a + 1, b + 1))
	print(len(ans) // 3)
	for i in range(0, len(ans), 3):
		(a, b, c) = (ans[i], ans[i + 1], ans[i + 2])
		print(*a, *b, *c)


def main():
	(n, m) = map(int, input().split())
	s = [input() for _ in range(n)]
	ans = []
	for i in range(m - 1):
		for j in range(n - 1):
			if s[j][i:i + 2].count('1') + s[j + 1][i:i + 2].count('1') == 4:
				s[j] = s[j][:i] + '10' + s[j][i + 2:]
				s[j + 1] = s[j + 1][:i] + '00' + s[j + 1][i + 2:]
				ans.append([j + 1, i + 2, j + 2, i + 1, j + 2, i + 2])
			if s[j][i:i + 2].count('1') + s[j + 1][i:i + 2].count('1') == 1:
				index = 1 * ('1' in s[j][i:i + 2])
				index2 = s[j + 1 - index][i:i + 2].index('1')
				s[j + 1 - index] = s[j + 1 - index][:i] + '00' + s[j + 1 - index][i + 2:]
				s[j + index] = s[j + index][:i] + '11' + s[j + index][i + 2:]
				ans.append([j + 2 - index, i + index2 + 1, j + index + 1, i + 1, j + index + 1, i + 2])
			if s[j][i:i + 2].count('1') + s[j + 1][i:i + 2].count('1') == 2:
				if s[j][i:i + 2].count('1') == 2:
					s[j] = s[j][:i] + '10' + s[j][i + 2:]
					s[j + 1] = s[j + 1][:i] + '11' + s[j + 1][i + 2:]
					ans.append([j + 1, i + 2, j + 2, i + 1, j + 2, i + 2])
				elif s[j][i:i + 2].count('1') == 1:
					index2 = s[j + 1][i:i + 2].index('1')
					index3 = s[j][i:i + 2].index('0')
					index4 = s[j + 1][i:i + 2].index('0')
					mid0 = '11'
					mid = '10'
					if s[j + 1][i:i + 2] == '10':
						mid = '01'
					s[j] = s[j][:i] + mid0 + s[j][i + 2:]
					s[j + 1] = s[j + 1][:i] + mid + s[j + 1][i + 2:]
					ans.append([j + 2, i + index2 + 1, j + 1, i + index3 + 1, j + 2, i + index4 + 1])
				else:
					s[j] = s[j][:i] + '11' + s[j][i + 2:]
					s[j + 1] = s[j + 1][:i] + '10' + s[j + 1][i + 2:]
					ans.append([j + 2, i + 2, j + 1, i + 1, j + 1, i + 2])
			if s[j][i:i + 2].count('1') + s[j + 1][i:i + 2].count('1') == 3:
				if s[j][i:i + 2].count('1') == 2:
					ans.append([j + 1, i + 1, j + 1, i + 2, j + 2, i + s[j + 1][i:i + 2].index('1') + 1])
				else:
					ans.append([j + 2, i + 1, j + 2, i + 2, j + 1, i + s[j][i:i + 2].index('1') + 1])
				s[j] = s[j][:i] + '00' + s[j][i + 2:]
				s[j + 1] = s[j + 1][:i] + '00' + s[j + 1][i + 2:]
	print(len(ans))
	for (a, b, c, d, e, f) in ans:
		print(a, b, c, d, e, f)
t = int(input())
for _ in range(t):
	main()


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	l = []
	for i in range(n):
		k = input()
		x = list(k)
		l.append(x)
	c = 0
	ans = []
	if m % 2 == 1:
		for i in range(0, n - 2):
			for j in range(0, m - 1, 2):
				if l[i][j] == '0' and l[i][j + 1] == '1':
					c += 1
					l[i][j] = '0'
					l[i][j + 1] = '0'
					ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
					if l[i + 1][j + 1] == '1':
						l[i + 1][j + 1] = '0'
					else:
						l[i + 1][j + 1] = '1'
					if l[i + 1][j] == '1':
						l[i + 1][j] = '0'
					else:
						l[i + 1][j] = '1'
				elif l[i][j] == '1' and l[i][j + 1] == '0':
					c += 1
					l[i][j] = '0'
					l[i][j + 1] = '0'
					ans.append([i, j, i + 1, j, i + 1, j + 1])
					if l[i + 1][j + 1] == '1':
						l[i + 1][j + 1] = '0'
					else:
						l[i + 1][j + 1] = '1'
					if l[i + 1][j] == '1':
						l[i + 1][j] = '0'
					else:
						l[i + 1][j] = '1'
				elif l[i][j] == '1' and l[i][j + 1] == '1':
					c += 1
					l[i][j] = '0'
					l[i][j + 1] = '0'
					ans.append([i, j, i, j + 1, i + 1, j + 1])
					if l[i + 1][j + 1] == '1':
						l[i + 1][j + 1] = '0'
					else:
						l[i + 1][j + 1] = '1'
			j = m - 2
			if l[i][j] == '0' and l[i][j + 1] == '1':
				c += 1
				l[i][j] = '0'
				l[i][j + 1] = '0'
				ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
				if l[i + 1][j + 1] == '1':
					l[i + 1][j + 1] = '0'
				else:
					l[i + 1][j + 1] = '1'
				if l[i + 1][j] == '1':
					l[i + 1][j] = '0'
				else:
					l[i + 1][j] = '1'
			elif l[i][j] == '1' and l[i][j + 1] == '0':
				c += 1
				l[i][j] = '0'
				l[i][j + 1] = '0'
				ans.append([i, j, i + 1, j, i + 1, j + 1])
				if l[i + 1][j + 1] == '1':
					l[i + 1][j + 1] = '0'
				else:
					l[i + 1][j + 1] = '1'
				if l[i + 1][j] == '1':
					l[i + 1][j] = '0'
				else:
					l[i + 1][j] = '1'
			elif l[i][j] == '1' and l[i][j + 1] == '1':
				c += 1
				l[i][j] = '0'
				l[i][j + 1] = '0'
				ans.append([i, j, i, j + 1, i + 1, j + 1])
				if l[i + 1][j + 1] == '1':
					l[i + 1][j + 1] = '0'
				else:
					l[i + 1][j + 1] = '1'
		i = n - 2
		for j in range(0, m - 1, 2):
			c0 = []
			c1 = []
			if l[i][j] == '1':
				c1.append([i, j])
			else:
				c0.append([i, j])
			if l[i][j + 1] == '1':
				c1.append([i, j + 1])
			else:
				c0.append([i, j + 1])
			if l[i + 1][j] == '1':
				c1.append([i + 1, j])
			else:
				c0.append([i + 1, j])
			if l[i + 1][j + 1] == '1':
				c1.append([i + 1, j + 1])
			else:
				c0.append([i + 1, j + 1])
			l0 = len(c0)
			l1 = len(c1)
			if l1 == 1:
				c += 1
				z = []
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				ans.append(z)
				z = []
				c += 1
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[2][0])
				z.append(c0[2][1])
				ans.append(z)
				c += 1
				z = []
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[2][0])
				z.append(c0[2][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				ans.append(z)
			elif l1 == 2:
				z = []
				c += 1
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				ans.append(z)
				z = []
				c += 1
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				z.append(c1[1][0])
				z.append(c1[1][1])
				ans.append(z)
			elif l1 == 3:
				z = []
				c += 1
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c1[1][0])
				z.append(c1[1][1])
				z.append(c1[2][0])
				z.append(c1[2][1])
				ans.append(z)
			elif l1 == 4:
				c += 1
				c0 = []
				z = []
				for b in range(l1 - 1):
					c0.append(c1[b])
					z.append(c1[b][0])
					z.append(c1[b][1])
				c1 = c1[-1:]
				ans.append(z)
				c += 1
				z = []
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				ans.append(z)
				z = []
				c += 1
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[2][0])
				z.append(c0[2][1])
				ans.append(z)
				c += 1
				z = []
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[2][0])
				z.append(c0[2][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				ans.append(z)
		i = n - 2
		j = m - 2
		c0 = []
		c1 = []
		l[n - 2][m - 2] = '0'
		l[n - 1][m - 2] = '0'
		if l[i][j] == '1':
			c1.append([i, j])
		else:
			c0.append([i, j])
		if l[i][j + 1] == '1':
			c1.append([i, j + 1])
		else:
			c0.append([i, j + 1])
		if l[i + 1][j] == '1':
			c1.append([i + 1, j])
		else:
			c0.append([i + 1, j])
		if l[i + 1][j + 1] == '1':
			c1.append([i + 1, j + 1])
		else:
			c0.append([i + 1, j + 1])
		l0 = len(c0)
		l1 = len(c1)
		if l1 == 1:
			c += 1
			z = []
			z.append(c1[0][0])
			z.append(c1[0][1])
			z.append(c0[0][0])
			z.append(c0[0][1])
			z.append(c0[1][0])
			z.append(c0[1][1])
			ans.append(z)
			z = []
			c += 1
			z.append(c1[0][0])
			z.append(c1[0][1])
			z.append(c0[0][0])
			z.append(c0[0][1])
			z.append(c0[2][0])
			z.append(c0[2][1])
			ans.append(z)
			c += 1
			z = []
			z.append(c1[0][0])
			z.append(c1[0][1])
			z.append(c0[2][0])
			z.append(c0[2][1])
			z.append(c0[1][0])
			z.append(c0[1][1])
			ans.append(z)
		elif l1 == 2:
			z = []
			c += 1
			z.append(c1[0][0])
			z.append(c1[0][1])
			z.append(c0[0][0])
			z.append(c0[0][1])
			z.append(c0[1][0])
			z.append(c0[1][1])
			ans.append(z)
			z = []
			c += 1
			z.append(c0[0][0])
			z.append(c0[0][1])
			z.append(c0[1][0])
			z.append(c0[1][1])
			z.append(c1[1][0])
			z.append(c1[1][1])
			ans.append(z)
		elif l1 == 3:
			z = []
			c += 1
			z.append(c1[0][0])
			z.append(c1[0][1])
			z.append(c1[1][0])
			z.append(c1[1][1])
			z.append(c1[2][0])
			z.append(c1[2][1])
			ans.append(z)
		elif l1 == 4:
			c0 = []
			z = []
			c += 1
			for b in range(0, l1 - 1):
				c0.append(c1[b])
				z.append(c1[b][0])
				z.append(c1[b][1])
			c1 = c1[:-1]
			c += 1
			ans.append(z)
			z = []
			z.append(c1[0][0])
			z.append(c1[0][1])
			z.append(c0[0][0])
			z.append(c0[0][1])
			z.append(c0[1][0])
			z.append(c0[1][1])
			ans.append(z)
			z = []
			c += 1
			z.append(c1[0][0])
			z.append(c1[0][1])
			z.append(c0[0][0])
			z.append(c0[0][1])
			z.append(c0[2][0])
			z.append(c0[2][1])
			ans.append(z)
			c += 1
			z = []
			z.append(c1[0][0])
			z.append(c1[0][1])
			z.append(c0[2][0])
			z.append(c0[2][1])
			z.append(c0[1][0])
			z.append(c0[1][1])
			ans.append(z)
	else:
		for i in range(0, n - 2):
			for j in range(0, m, 2):
				if l[i][j] == '0' and l[i][j + 1] == '1':
					c += 1
					l[i][j] = '0'
					l[i][j + 1] = '0'
					ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
					if l[i + 1][j + 1] == '1':
						l[i + 1][j + 1] = '0'
					else:
						l[i + 1][j + 1] = '1'
					if l[i + 1][j] == '1':
						l[i + 1][j] = '0'
					else:
						l[i + 1][j] = '1'
				elif l[i][j] == '1' and l[i][j + 1] == '0':
					c += 1
					l[i][j] = '0'
					l[i][j + 1] = '0'
					ans.append([i, j, i + 1, j, i + 1, j + 1])
					if l[i + 1][j + 1] == '1':
						l[i + 1][j + 1] = '0'
					else:
						l[i + 1][j + 1] = '1'
					if l[i + 1][j] == '1':
						l[i + 1][j] = '0'
					else:
						l[i + 1][j] = '1'
				elif l[i][j] == '1' and l[i][j + 1] == '1':
					c += 1
					l[i][j] = '0'
					l[i][j + 1] = '0'
					ans.append([i, j, i, j + 1, i + 1, j + 1])
					if l[i + 1][j + 1] == '1':
						l[i + 1][j + 1] = '0'
					else:
						l[i + 1][j + 1] = '1'
		i = n - 2
		for j in range(0, m, 2):
			c0 = []
			c1 = []
			if l[i][j] == '1':
				c1.append([i, j])
			else:
				c0.append([i, j])
			if l[i][j + 1] == '1':
				c1.append([i, j + 1])
			else:
				c0.append([i, j + 1])
			if l[i + 1][j] == '1':
				c1.append([i + 1, j])
			else:
				c0.append([i + 1, j])
			if l[i + 1][j + 1] == '1':
				c1.append([i + 1, j + 1])
			else:
				c0.append([i + 1, j + 1])
			l0 = len(c0)
			l1 = len(c1)
			if l1 == 1:
				c += 1
				z = []
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				ans.append(z)
				z = []
				c += 1
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[2][0])
				z.append(c0[2][1])
				ans.append(z)
				c += 1
				z = []
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[2][0])
				z.append(c0[2][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				ans.append(z)
			elif l1 == 2:
				z = []
				c += 1
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				ans.append(z)
				z = []
				c += 1
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				z.append(c1[1][0])
				z.append(c1[1][1])
				ans.append(z)
			elif l1 == 3:
				z = []
				c += 1
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c1[1][0])
				z.append(c1[1][1])
				z.append(c1[2][0])
				z.append(c1[2][1])
				ans.append(z)
			elif l1 == 4:
				c0 = []
				z = []
				c += 1
				for b in range(l1 - 1):
					c0.append(c1[b])
					z.append(c1[b][0])
					z.append(c1[b][1])
				c1 = c1[-1:]
				ans.append(z)
				c += 1
				z = []
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				ans.append(z)
				z = []
				c += 1
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[0][0])
				z.append(c0[0][1])
				z.append(c0[2][0])
				z.append(c0[2][1])
				ans.append(z)
				c += 1
				z = []
				z.append(c1[0][0])
				z.append(c1[0][1])
				z.append(c0[2][0])
				z.append(c0[2][1])
				z.append(c0[1][0])
				z.append(c0[1][1])
				ans.append(z)
	if c == 0:
		ans.append([0, 0, 1, 0, 1, 1])
		ans.append([0, 0, 1, 0, 1, 1])
		c = 2
	print(c)
	for i in ans:
		k = []
		for j in i:
			k.append(j + 1)
		print(*k)


for _ in range(int(input())):
	(r, c) = map(int, input().split())
	a = []
	b = []
	[a.append(list(input())) for i in range(r)]
	for i in range(r - 2):
		for j in range(c):
			if j == 0 and int(a[i][j]):
				a[i][j] = (int(a[i][j]) + 1) % 2
				a[i + 1][j] = (int(a[i + 1][j]) + 1) % 2
				a[i + 1][j + 1] = (int(a[i + 1][j + 1]) + 1) % 2
				b.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
			elif int(a[i][j]):
				a[i][j] = (int(a[i][j]) + 1) % 2
				a[i + 1][j] = (int(a[i + 1][j]) + 1) % 2
				a[i + 1][j - 1] = (int(a[i + 1][j - 1]) + 1) % 2
				b.append([i + 1, j + 1, i + 2, j + 1, i + 2, j])
	count = 0
	for i in range(r - 2, r):
		for j in range(c):
			count += int(a[i][j])
	for j in range(c - 1):
		if int(a[r - 2][j]) or int(a[r - 1][j]):
			if int(a[r - 2][j]) and int(a[r - 1][j]):
				count -= 2
				if int(a[r - 2][j + 1]):
					b.append([r, j + 1, r - 1, j + 1, r - 1, j + 2])
					a[r - 2][j + 1] = (int(a[r - 2][j + 1]) + 1) % 2
					count -= 1
				else:
					b.append([r - 1, j + 1, r, j + 1, r, j + 2])
					a[r - 1][j + 1] = (int(a[r - 1][j + 1]) + 1) % 2
					if int(a[r - 1][j + 1]):
						count += a[r - 1][j + 1]
					else:
						count -= 1
			elif int(a[r - 2][j]):
				if count == 1:
					i = r - 2
					b.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					b.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					b.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					break
				else:
					count -= 1
					b.append([r - 1, j + 1, r - 1, j + 2, r, j + 2])
					a[r - 2][j + 1] = (int(a[r - 2][j + 1]) + 1) % 2
					a[r - 1][j + 1] = (int(a[r - 1][j + 1]) + 1) % 2
					count += a[r - 1][j + 1] + a[r - 2][j + 1]
			elif count == 1:
				n = r
				b.append([n, j + 1, n, j + 2, n - 1, j + 1])
				b.append([n, j + 1, n, j + 2, n - 1, j + 2])
				b.append([n, j + 1, n - 1, j + 1, n - 1, j + 2])
				break
			else:
				count -= 1
				b.append([r, j + 1, r, j + 2, r - 1, j + 2])
				a[r - 2][j + 1] = (int(a[r - 2][j + 1]) + 1) % 2
				a[r - 1][j + 1] = (int(a[r - 1][j + 1]) + 1) % 2
				count += a[r - 1][j + 1] + a[r - 2][j + 1]
	if int(a[-1][-1]) and int(a[-2][-1]):
		b.append([r, c - 1, r - 1, c, r, c])
		b.append([r - 1, c - 1, r, c - 1, r, c])
		b.append([r - 1, c - 1, r - 1, c, r, c - 1])
		b.append([r, c, r, c - 1, r - 1, c])
	elif int(a[-1][-1]):
		i = r - 1
		j = c - 1
		b.append([i + 1, j + 1, i, j + 1, i + 1, j])
		b.append([i, j + 1, i + 1, j + 1, i, j])
		b.append([i + 1, j, i + 1, j + 1, i, j])
	elif int(a[-2][-1]):
		b.append([r - 1, c - 1, r - 1, c, r, c])
		b.append([r - 1, c, r - 1, c - 1, r, c - 1])
		b.append([r - 1, c, r, c, r, c - 1])
	print(len(b))
	for i in b:
		print(*i)


import sys
input = sys.stdin.readline
t = int(input())
for tests in range(t):
	(n, m) = map(int, input().split())
	A = [input().strip() for i in range(n)]
	ANS = []
	for i in range(n):
		for j in range(m):
			if A[i][j] == '1':
				if 0 <= i + 1 < n and 0 <= j + 1 < m:
					ANS.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 1))
					ANS.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 2))
					ANS.append((i + 1, j + 1, i + 2, j + 2, i + 2, j + 1))
				elif 0 <= i - 1 < n and 0 <= j - 1 < m:
					ANS.append((i + 1, j + 1, i + 1, j, i, j + 1))
					ANS.append((i + 1, j + 1, i + 1, j, i, j))
					ANS.append((i + 1, j + 1, i, j, i, j + 1))
				elif 0 <= i - 1 < n and 0 <= j + 1 < m:
					ANS.append((i + 1, j + 1, i + 1, j + 2, i, j + 1))
					ANS.append((i + 1, j + 1, i + 1, j + 2, i, j + 2))
					ANS.append((i + 1, j + 1, i, j + 2, i, j + 1))
				elif 0 <= i + 1 < n and 0 <= j - 1 < m:
					ANS.append((i + 1, j + 1, i + 1, j, i + 2, j + 1))
					ANS.append((i + 1, j + 1, i + 1, j, i + 2, j))
					ANS.append((i + 1, j + 1, i + 2, j, i + 2, j + 1))
	print(len(ANS))
	for (a, b, c, d, e, f) in ANS:
		print(a, b, c, d, e, f)


from os import path
import sys
from heapq import heappush, heappop
from functools import cmp_to_key as ctk
from collections import deque, Counter, defaultdict as dd
from bisect import bisect, bisect_left, bisect_right, insort, insort_left, insort_right
from itertools import permutations
from datetime import datetime
from math import ceil, sqrt, log, gcd

def ii():
	return int(input())

def si():
	return input().rstrip()

def mi():
	return map(int, input().split())

def li():
	return list(mi())
abc = 'abcdefghijklmnopqrstuvwxyz'
mod = 998244353
inf = float('inf')
vow = ['a', 'e', 'i', 'o', 'u']
(dx, dy) = ([-1, 1, 0, 0], [0, 0, 1, -1])

def bo(i):
	return ord(i) - ord('0')
file = 1

def solve():
	for _ in range(ii()):
		(n, m) = mi()
		a = []
		for i in range(n):
			s = si()
			p = []
			for j in s:
				p.append(int(j))
			a.append(p)

		def change(p):
			for i in range(0, 5, 2):
				a[p[i]][p[i + 1]] ^= 1
		ans = []
		for i in range(n - 2):
			for j in range(m):
				if a[i][j] == 0:
					if j == 0 or a[i][j - 1] == 0:
						continue
					else:
						ans.append([i, j - 1, i + 1, j - 1, i + 1, j])
						change(ans[-1])
				else:
					if j > 0 and a[i][j - 1] == 1:
						if a[i + 1][j - 1] == 1:
							ans.append([i, j, i + 1, j - 1, i, j - 1])
						else:
							ans.append([i, j, i, j - 1, i + 1, j])
					elif j < m - 1 and (a[i][j + 1] or a[i + 1][j + 1]):
						if a[i][j + 1] == 1:
							if a[i + 1][j] == 1:
								ans.append([i, j, i + 1, j, i, j + 1])
							else:
								ans.append([i, j, i + 1, j + 1, i, j + 1])
						else:
							ans.append([i, j, i + 1, j, i + 1, j + 1])
					elif j > 0:
						ans.append([i, j, i + 1, j - 1, i + 1, j])
					else:
						ans.append([i, j, i + 1, j + 1, i + 1, j])
					change(ans[-1])

		def count2(x1, y1, x2, y2):
			(o, z) = ([], [])
			for i in range(x1, x2 + 1):
				for j in range(y1, y2 + 1):
					if a[i][j]:
						o.append(i)
						o.append(j)
					else:
						z.append(i)
						z.append(j)
			p = []
			ans.append(z + o[:2])
			change(ans[-1])
			ans.append(z + o[2:])
			change(ans[-1])

		def count1(x1, y1, x2, y2):
			p = []
			cnt = 0
			for i in range(x1, x2 + 1):
				for j in range(y1, y2 + 1):
					if a[i][j]:
						p.append(i)
						p.append(j)
					elif cnt < 2:
						cnt += 1
						p.append(i)
						p.append(j)
			ans.append(p)
			change(ans[-1])
			count2(x1, y1, x2, y2)

		def func(x1, y1, x2, y2):
			cnt = 0
			for i in range(x1, x2 + 1):
				for j in range(y1, y2 + 1):
					cnt += a[i][j]
			if cnt == 0:
				return
			if cnt == 3:
				p = []
				for i in range(x1, x2 + 1):
					for j in range(y1, y2 + 1):
						if a[i][j]:
							p.append(i)
							p.append(j)
				ans.append(p)
				change(ans[-1])
			elif cnt == 2:
				count2(x1, y1, x2, y2)
			elif cnt == 1:
				count1(x1, y1, x2, y2)
			else:
				p = []
				for i in range(x1, x2 + 1):
					for j in range(y1, y2 + 1):
						if a[i][j]:
							p.append(i)
							p.append(j)
						if len(p) == 6:
							break
				ans.append(p)
				change(ans[-1])
				count1(x1, y1, x2, y2)
		if m & 1:
			if a[n - 2][m - 1] and a[n - 1][m - 1]:
				ans.append([n - 2, m - 1, n - 1, m - 1, n - 2, m - 2])
				change(ans[-1])
			elif a[n - 2][m - 1]:
				ans.append([n - 2, m - 1, n - 1, m - 2, n - 2, m - 2])
				change(ans[-1])
			elif a[n - 1][m - 1]:
				ans.append([n - 2, m - 2, n - 1, m - 1, n - 1, m - 2])
				change(ans[-1])
		for i in range(0, m - 1, 2):
			func(n - 2, i, n - 1, i + 1)
		print(len(ans))
		for i in ans:
			for j in i:
				print(j + 1, end=' ')
			print()
if file:
	if path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	else:
		input = sys.stdin.readline
solve()


t = int(input())
for a in range(t):
	operations = []
	(n, m) = map(int, input().split())
	grid = [list(map(int, list(input()))) for _ in range(n)]
	for y in range(n):
		for x in range(m):
			if grid[y][x]:
				if y == n - 1 and x == 0:
					operations.append((x, y, x + 1, y, x, y - 1))
					operations.append((x, y, x + 1, y, x + 1, y - 1))
					operations.append((x, y, x + 1, y - 1, x, y - 1))
				elif y == 0 and x == m - 1:
					operations.append((x, y, x - 1, y, x, y + 1))
					operations.append((x, y, x - 1, y, x - 1, y + 1))
					operations.append((x, y, x - 1, y + 1, x, y + 1))
				elif y < n - 1 and x < m - 1:
					operations.append((x, y, x + 1, y, x, y + 1))
					operations.append((x, y, x + 1, y, x + 1, y + 1))
					operations.append((x, y, x + 1, y + 1, x, y + 1))
				else:
					operations.append((x, y, x - 1, y, x, y - 1))
					operations.append((x, y, x - 1, y, x - 1, y - 1))
					operations.append((x, y, x - 1, y - 1, x, y - 1))
	print(len(operations))
	for t in operations:
		print(*[u + 1 for u in t[::-1]])


for _ in range(int(input())):
	(m, n) = map(int, input().split())
	A = [[0] * (n + 1)] + [[0] + list(map(int, list(input()))) for _ in range(m)]
	ans = []
	for i in range(1, m - 1):
		for j in range(1, n + 1):
			if A[i][j]:
				ans.append([i, j, i + 1, j, i + 1, j + 1 if j < n else j - 1])
				A[i][j] ^= 1
				A[i + 1][j] ^= 1
				A[i + 1][j + 1 if j < n else j - 1] ^= 1
	for j in range(1, n - 1):
		if A[m - 1][j] and A[m][j]:
			ans.append([m - 1, j, m, j, m - 1, j + 1])
			A[m - 1][j] ^= 1
			A[m][j] ^= 1
			A[m - 1][j + 1] ^= 1
		elif A[m - 1][j]:
			ans.append([m - 1, j, m - 1, j + 1, m, j + 1])
			A[m - 1][j] ^= 1
			A[m - 1][j + 1] ^= 1
			A[m][j + 1] ^= 1
		elif A[m][j]:
			ans.append([m, j, m, j + 1, m - 1, j + 1])
			A[m][j] ^= 1
			A[m][j + 1] ^= 1
			A[m - 1][j + 1] ^= 1
	if A[m - 1][n - 1] ^ A[m - 1][n] ^ A[m][n - 1]:
		ans.append([m - 1, n - 1, m - 1, n, m, n - 1])
	if A[m - 1][n - 1] ^ A[m][n - 1] ^ A[m][n]:
		ans.append([m - 1, n - 1, m, n - 1, m, n])
	if A[m][n - 1] ^ A[m][n] ^ A[m - 1][n]:
		ans.append([m, n - 1, m, n, m - 1, n])
	if A[m][n] ^ A[m - 1][n] ^ A[m - 1][n - 1]:
		ans.append([m, n, m - 1, n, m - 1, n - 1])
	print(len(ans))
	for a in ans:
		print(*a)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def solve(area, ans, n, m):
	if n % 2 == 1:
		n -= 1
	if m % 2 == 1:
		m -= 1
	for q in range(0, n, 2):
		for r in range(0, m, 2):
			g1 = [area[q][r], q + 1, r + 1]
			g2 = [area[q + 1][r], q + 2, r + 1]
			g3 = [area[q][r + 1], q + 1, r + 2]
			g4 = [area[q + 1][r + 1], q + 2, r + 2]
			ass = [g1, g2, g3, g4]
			ass.sort()
			cnt = 0
			for i in range(len(ass)):
				if ass[i][0] == 1:
					cnt += 1
			if cnt == 4:
				t1 = []
				t1.extend([ass[0][1], ass[0][2]])
				t1.extend([ass[1][1], ass[1][2]])
				t1.extend([ass[2][1], ass[2][2]])
				for i in range(3):
					ass[i][0] = 0
				ans.append(t1)
				t1 = []
				cnt = 1
			if cnt == 3:
				t1 = []
				for i in range(len(ass)):
					if ass[i][0] == 1:
						t1.extend([ass[i][1], ass[i][2]])
				ans.append(t1)
				continue
				cnt = 1
			if cnt == 2:
				t1 = []
				for i in range(len(ass)):
					if ass[i][0] == 0:
						t1.extend([ass[i][1], ass[i][2]])
						ass[i][0] = -1
				for i in range(len(ass)):
					if ass[i][0] == 1:
						t1.extend([ass[i][1], ass[i][2]])
						ass[i][0] = 0
						break
				ans.append(t1)
				t1 = []
				for i in range(len(ass)):
					if abs(ass[i][0]) == 1:
						t1.extend([ass[i][1], ass[i][2]])
				ans.append(t1)
				continue
			if cnt == 1:
				t1 = []
				for i in range(len(ass)):
					if ass[i][0] == 0:
						t1.extend([ass[i][1], ass[i][2]])
						ass[i][0] = -1
					if len(t1) == 4:
						break
				for i in range(len(ass)):
					if ass[i][0] == 1:
						t1.extend([ass[i][1], ass[i][2]])
						ass[i][0] = 0
						break
				for i in range(len(ass)):
					ass[i][0] = abs(ass[i][0])
				ans.append(t1)
				cnt = 2
			if cnt == 2:
				t1 = []
				for i in range(len(ass)):
					if ass[i][0] == 0:
						t1.extend([ass[i][1], ass[i][2]])
						ass[i][0] = -1
				for i in range(len(ass)):
					if ass[i][0] == 1:
						t1.extend([ass[i][1], ass[i][2]])
						ass[i][0] = 0
						break
				ans.append(t1)
				t1 = []
				for i in range(len(ass)):
					if abs(ass[i][0]) == 1:
						t1.extend([ass[i][1], ass[i][2]])
				ans.append(t1)
				continue
a = int(input())
for i in range(a):
	(n, m) = map(int, input().split())
	ans = []
	area = []
	for i in range(n):
		s = input()
		g1 = []
		for j in range(len(s)):
			g1.append(int(s[j]))
		area.append(g1)
	if n % 2 == 0 and m % 2 == 0:
		solve(area, ans, n, m)
		print(len(ans))
		for j in range(len(ans)):
			print(*ans[j])
		continue
	if m % 2 == 1:
		ans = []
		for j in range(n):
			if area[j][m - 1] == 1:
				area[j][m - 1] = 0
				t1 = []
				t1.extend([j + 1, m])
				t1.extend([j + 1, m - 1])
				area[j][m - 2] = 1 - area[j][m - 2]
				if j - 1 >= 0:
					area[j - 1][m - 2] = 1 - area[j - 1][m - 2]
					t1.extend([j, m - 1])
				else:
					area[j + 1][m - 2] = 1 - area[j + 1][m - 2]
					t1.extend([j + 2, m - 1])
				ans.append(t1)
		if n % 2 == 0:
			solve(area, ans, n, m)
			print(len(ans))
			for j in range(len(ans)):
				print(*ans[j])
	if n % 2 == 1:
		for j in range(m):
			if area[n - 1][j] == 1:
				t1 = []
				area[n - 1][j] = 0
				t1.extend([n, j + 1])
				t1.extend([n - 1, j + 1])
				area[n - 2][j] = 1 - area[n - 2][j]
				if j - 1 >= 0:
					area[n - 2][j - 1] = 1 - area[n - 2][j - 1]
					t1.extend([n - 1, j])
				else:
					area[n - 2][j + 1] = 1 - area[n - 2][j + 1]
					t1.extend([n - 1, j + 2])
				ans.append(t1)
		solve(area, ans, n, m)
		print(len(ans))
		for j in range(len(ans)):
			print(*ans[j])


for _ in range(int(input())):
	(rows, cols) = map(int, input().split())
	ss = [list(map(int, input())) for _ in range(rows)]
	count = 0
	res = []
	for y in range(rows - 1):
		if y % 2 and y < rows - 2:
			continue
		fixed = False
		for x in range(cols - 1):
			if not ss[y][x] and (not ss[y + 1][x]) and (x < cols - 2):
				fixed = False
				continue
			elif fixed and x < cols - 2:
				fixed = False
				continue
			var = sum(ss[y][x:x + 2]) + sum(ss[y + 1][x:x + 2])
			if var == 0:
				fixed = True
				continue
			if var == 4:
				count += 1
				ss[y + 1][x + 1] = 0
				ss[y][x + 1] = 0
				ss[y + 1][x] = 0
				res.append([y + 2, x + 2, y + 1, x + 2, y + 2, x + 1])
				var = 1
			if var == 1:
				if ss[y][x] == 1:
					cx = x
					cy = y
				elif ss[y][x + 1] == 1:
					cx = x + 1
					cy = y
				elif ss[y + 1][x] == 1:
					cx = x
					cy = y + 1
				else:
					cx = x + 1
					cy = y + 1
				ss[cy][cx] = 0
				ss[y + (1 - (cy - y))][cx] = 1
				ss[y + (1 - (cy - y))][x + (1 - (cx - x))] = 1
				count += 1
				res.append([cy + 1, cx + 1, y + (1 - (cy - y)) + 1, cx + 1, y + (1 - (cy - y)) + 1, x + (1 - (cx - x)) + 1])
				var = 2
			if var == 2:
				if ss[y][x] == 1:
					cx = x
					cy = y
				elif ss[y][x + 1] == 1:
					cx = x + 1
					cy = y
				elif ss[y + 1][x] == 1:
					cx = x
					cy = y + 1
				else:
					cx = x + 1
					cy = y + 1
				cres = []
				for cy2 in range(y, y + 2):
					for cx2 in range(x, x + 2):
						if ss[cy2][cx2] == 0:
							cres += [cy2 + 1, cx2 + 1]
							ss[cy2][cx2] = 1
				count += 1
				ss[cy][cx] = 0
				cres += [cy + 1, cx + 1]
				res.append(cres)
			count += 1
			cres = []
			for cy in range(y, y + 2):
				for cx in range(x, x + 2):
					if ss[cy][cx] == 1:
						cres += [cy + 1, cx + 1]
						ss[cy][cx] = 0
			res.append(cres)
			fixed = True
	print(count)
	for r in res:
		print(*r)


from math import *
from bisect import *
from collections import *
from random import *
from decimal import *
import sys
input = sys.stdin.readline

def inp():
	return int(input())

def st():
	return input().rstrip('\n')

def lis():
	return list(map(int, input().split()))

def ma():
	return map(int, input().split())
t = inp()
while t:
	t -= 1
	(n, m) = ma()
	r = []
	for i in range(n):
		a = st()
		a = list(a)
		r.append(a)
	res = []
	for i in range(n - 1):
		for j in range(m - 1):
			ll = 0
			one = []
			zer = []
			if r[i][j] == '1':
				ll += 1
				one.append([i + 1, j + 1])
				r[i][j] = '0'
			else:
				zer.append([i + 1, j + 1])
			if r[i + 1][j] == '1':
				ll += 1
				one.append([i + 2, j + 1])
				r[i + 1][j] = '0'
			else:
				zer.append([i + 2, j + 1])
			if r[i][j + 1] == '1':
				ll += 1
				one.append([i + 1, j + 2])
				r[i][j + 1] = '0'
			else:
				zer.append([i + 1, j + 2])
			if r[i + 1][j + 1] == '1':
				ll += 1
				one.append([i + 2, j + 2])
				r[i + 1][j + 1] = '0'
			else:
				zer.append([i + 2, j + 2])
			if ll == 0:
				continue
			if ll == 3:
				res.append(one[0])
				res.append(one[1])
				res.append(one[2])
				continue
			if ll == 2:
				res.append(zer[0])
				res.append(zer[1])
				res.append(one[0])
				res.append(zer[0])
				res.append(zer[1])
				res.append(one[1])
				continue
			if ll == 1:
				res.append(zer[0])
				res.append(zer[1])
				res.append(one[0])
				res.append(zer[2])
				res.append(zer[0])
				res.append(one[0])
				res.append(zer[2])
				res.append(zer[1])
				res.append(one[0])
				continue
			if ll == 4:
				res.append(one[0])
				res.append(one[1])
				res.append(one[2])
				res.append(one[0])
				res.append(one[1])
				res.append(one[3])
				res.append(one[2])
				res.append(one[3])
				res.append(one[1])
				res.append(one[0])
				res.append(one[2])
				res.append(one[3])
				continue
	print(len(res) // 3)
	i = 0
	while i < len(res):
		print(*res[i], *res[i + 1], *res[i + 2])
		i += 3


for _ in range(int(input())):
	(a, b) = map(int, input().split())
	li = [list(map(int, list(input()))) for __ in range(a)]
	ope = []
	for i in range(a - 1):
		for j in range(b):
			if li[i][j] == 1:
				if j == 0:
					ope.append([i, j, i + 1, j, i + 1, j + 1])
					li[i][j] = 1 - li[i][j]
					li[i + 1][j] = 1 - li[i + 1][j]
					li[i + 1][j + 1] = 1 - li[i + 1][j + 1]
				else:
					ope.append([i, j, i + 1, j, i + 1, j - 1])
					li[i][j] = 1 - li[i][j]
					li[i + 1][j] = 1 - li[i + 1][j]
					li[i + 1][j - 1] = 1 - li[i + 1][j - 1]
	t = a - 1
	for cl in range(b):
		if li[t][cl] == 1:
			if cl == 0:
				ope.append([t, cl, t - 1, cl, t - 1, cl + 1])
				li[t][cl] = 1 - li[t][cl]
				ope.append([t, cl, t, cl + 1, t - 1, cl + 1])
				ope.append([t - 1, cl, t, cl, t, cl + 1])
			else:
				ope.append([t, cl, t, cl - 1, t - 1, cl - 1])
				li[t][cl] = 1 - li[t][cl]
				ope.append([t, cl, t - 1, cl, t - 1, cl - 1])
				ope.append([t, cl - 1, t, cl, t - 1, cl])
	print(len(ope))
	for ele in ope:
		print(*list(map(lambda i: i + 1, ele)))


t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = list((list(map(int, input())) for _ in range(n)))
	all_ans = list()
	for i in range(n - 1):
		for j in range(m - 1):
			ans = list()
			if a[i][j] == 0 and 0 == a[i][j + 1]:
				continue
			if a[i][j] == 1:
				ans.append(i + 1)
				ans.append(j + 1)
				a[i][j] = 0
			if a[i][j + 1] == 1:
				ans.append(i + 1)
				ans.append(j + 2)
				a[i][j + 1] = 0
			ans.append(i + 2)
			ans.append(j + 1)
			a[i + 1][j] = (a[i + 1][j] + 1) % 2
			if len(ans) == 4:
				ans.append(i + 2)
				ans.append(j + 2)
				a[i + 1][j + 1] = (a[i + 1][j + 1] + 1) % 2
			all_ans.append(ans)
	for j in range(m - 1):
		ans = list()
		if a[-2][j] == 0 and 0 == a[-1][j]:
			continue
		if a[-2][j] == 1:
			ans.append(n - 1)
			ans.append(j + 1)
			a[-2][j] = 0
		if a[-1][j] == 1:
			ans.append(n)
			ans.append(j + 1)
			a[-1][j] = 0
		ans.append(n - 1)
		ans.append(j + 2)
		a[-2][j + 1] = (a[-2][j + 1] + 1) % 2
		if len(ans) == 4:
			ans.append(n)
			ans.append(j + 2)
			a[-1][j + 1] = (a[-1][j + 1] + 1) % 2
		all_ans.append(ans)
	if a[-2][-1] == a[-1][-1] == 0:
		pass
	elif a[-2][-1] == 0 and a[-1][-1] == 1:
		ans = list()
		ans.append(n - 1)
		ans.append(m - 1)
		a[-2][-2] = 1
		ans.append(n)
		ans.append(m - 1)
		a[-1][-2] = 1
		ans.append(n)
		ans.append(m)
		a[-1][-1] = 0
		all_ans.append(ans)
	elif a[-2][-1] == 1 and a[-1][-1] == 0:
		ans = list()
		ans.append(n - 1)
		ans.append(m - 1)
		a[-2][-2] = 1
		ans.append(n)
		ans.append(m - 1)
		a[-1][-2] = 1
		ans.append(n - 1)
		ans.append(m)
		a[-2][-1] = 0
		all_ans.append(ans)
	if a[-1][-2] == 1:
		ans = list()
		ans.append(n)
		ans.append(m - 1)
		a[-1][-2] = 0
		ans.append(n)
		ans.append(m)
		a[-1][-1] = 1
		ans.append(n - 1)
		ans.append(m)
		a[-2][-1] = 1
		all_ans.append(ans)
		ans = list()
		ans.append(n - 1)
		ans.append(m - 1)
		a[-2][-2] = 0
		ans.append(n)
		ans.append(m)
		a[-1][-1] = 0
		ans.append(n - 1)
		ans.append(m)
		a[-2][-1] = 0
		all_ans.append(ans)
	elif a[-1][-1] == 1:
		ans = list()
		ans.append(n)
		ans.append(m)
		a[-1][-1] = 0
		ans.append(n)
		ans.append(m - 1)
		a[-1][-2] = 1
		ans.append(n - 1)
		ans.append(m - 1)
		a[-2][-2] = 1
		all_ans.append(ans)
		ans = list()
		ans.append(n - 1)
		ans.append(m - 1)
		a[-2][-2] = 0
		ans.append(n)
		ans.append(m - 1)
		a[-1][-1] = 0
		ans.append(n - 1)
		ans.append(m)
		a[-2][-1] = 0
		all_ans.append(ans)
	print(len(all_ans))
	for ans in all_ans:
		print(*ans)


import sys
Z = sys.stdin.readline
O = []

def S(q, x, y):
	s = sum((sum(i) for i in q))
	v = [(x, y, x + 1, y, x, y + 1), (x, y, x + 1, y + 1, x, y + 1), (x, y, x + 1, y, x + 1, y + 1), (x + 1, y + 1, x + 1, y, x, y + 1)]
	if s > 3:
		return v
	if s > 2:
		if q[0][0] < 1:
			return [v[3]]
		if q[0][1] < 1:
			return [v[2]]
		if q[1][0] < 1:
			return [v[1]]
		return [v[0]]
	if s > 1:
		if q[0][0] < 1 and q[0][1] < 1:
			return v[:2]
		if q[0][0] < 1 and q[1][1] < 1:
			return v[1:3]
		if q[0][0] < 1 and q[1][0] < 1:
			return [v[0], v[2]]
		if q[0][1] < 1 and q[1][1] < 1:
			return [v[1], v[3]]
		if q[0][1] < 1 and q[1][0] < 1:
			return [v[0], v[3]]
		if q[1][0] < 1 and q[1][1] < 1:
			return v[2:]
	if s:
		if q[0][0]:
			k = 3
		elif q[0][1]:
			k = 2
		elif q[1][0]:
			k = 1
		else:
			k = 0
		return v[:k] + v[k + 1:]
	return []
for _ in range(int(Z())):
	(n, m) = map(int, Z().split())
	a = []
	o = []
	for i in range(n):
		a.append(list(map(int, Z().strip())))
	if n % 2:
		for i in range(0, m - m % 2, 2):
			if a[-1][i]:
				if a[-1][i + 1]:
					o += [(n, i + 1, n, i + 2, n - 1, i + 1)]
					a[-2][i] = 1 - a[-2][i]
				else:
					o += [(n, i + 1, n - 1, i + 2, n - 1, i + 1)]
					a[-2][i] = 1 - a[-2][i]
					a[-2][i + 1] = 1 - a[-2][i + 1]
			elif a[-1][i + 1]:
				o += [(n, i + 2, n - 1, i + 2, n - 1, i + 1)]
				a[-2][i] = 1 - a[-2][i]
				a[-2][i + 1] = 1 - a[-2][i + 1]
		if m % 2 and a[-1][-1]:
			o += [(n, m, n - 1, m, n - 1, m - 1)]
			a[-2][-1] = 1 - a[-2][-1]
			a[-2][-2] = 1 - a[-2][-2]
	if m % 2:
		for i in range(0, n - n % 2, 2):
			if a[i][-1]:
				if a[i + 1][-1]:
					o += [(i + 1, m, i + 2, m, i + 1, m - 1)]
					a[i][-2] = 1 - a[i][-2]
				else:
					o += [(i + 1, m, i + 2, m - 1, i + 1, m - 1)]
					a[i][-2] = 1 - a[i][-2]
					a[i + 1][-2] = 1 - a[i + 1][-2]
			elif a[i + 1][-1]:
				o += [(i + 2, m - 1, i + 2, m, i + 1, m - 1)]
				a[i][-2] = 1 - a[i][-2]
				a[i + 1][-2] = 1 - a[i + 1][-2]
	for i in range(n // 2):
		for j in range(m // 2):
			(x, y) = (2 * i, 2 * j)
			o += S(((a[x][y], a[x][y + 1]), (a[x + 1][y], a[x + 1][y + 1])), x + 1, y + 1)
	O.append(str(len(o)))
	O.append('\n'.join((' '.join(map(str, i)) for i in o)))
print('\n'.join(O))


import sys
input = sys.stdin.readline
a = None
ops = None

def update(loc):
	global a
	for i in range(len(loc) // 2):
		if a[loc[2 * i] - 1][loc[2 * i + 1] - 1] == '1':
			a[loc[2 * i] - 1][loc[2 * i + 1] - 1] = '0'
		else:
			a[loc[2 * i] - 1][loc[2 * i + 1] - 1] = '1'

def solve(i, j):
	global a
	global ops
	ones = []
	zeros = []
	for k in range(2):
		for l in range(2):
			if a[i + k][j + l] == '1':
				ones.append([i + k + 1, j + l + 1])
			else:
				zeros.append([i + k + 1, j + l + 1])
	if len(ones) == 4:
		op = []
		for k in range(3):
			update(ones[-1])
			op.extend(ones[-1])
			zeros.append(ones.pop())
		ops.append(op)
	if len(ones) > 0:
		while len(ones) != 3:
			op = []
			for k in range(2):
				update(zeros[-1])
				op.extend(zeros[-1])
				ones.append(zeros.pop())
			update(ones[-3])
			op.extend(ones[-3])
			zeros.append(ones[-3])
			del ones[-3]
			ops.append(op)
		op = []
		for k in range(3):
			update(ones[k])
			op.extend(ones[k])
		ops.append(op)

def prog():
	global a, ops
	for _ in range(int(input())):
		(n, m) = map(int, input().split())
		a = [list(input().strip()) for i in range(n)]
		ops = []
		if n % 2 == 1 and m % 2 == 0:
			for j in range(m - 1):
				if a[n - 1][j] == '1':
					ops.append([n - 1 + 1, j + 1, n - 2 + 1, j + 1, n - 2 + 1, j + 1 + 1])
					update([n - 1 + 1, j + 1, n - 2 + 1, j + 1, n - 2 + 1, j + 1 + 1])
			if a[n - 1][m - 1] == '1':
				ops.append([n - 1 + 1, m - 1 + 1, n - 2 + 1, m - 1 + 1, n - 2 + 1, m - 2 + 1])
				update([n - 1 + 1, m - 1 + 1, n - 2 + 1, m - 1 + 1, n - 2 + 1, m - 2 + 1])
		elif n % 2 == 0 and m % 2 == 1:
			for i in range(n - 1):
				if a[i][m - 1] == '1':
					ops.append([i + 1, m - 1 + 1, i + 1, m - 2 + 1, i + 1 + 1, m - 2 + 1])
					update([i + 1, m - 1 + 1, i + 1, m - 2 + 1, i + 1 + 1, m - 2 + 1])
			if a[n - 1][m - 1] == '1':
				ops.append([n - 1 + 1, m - 1 + 1, n - 1 + 1, m - 2 + 1, n - 2 + 1, m - 2 + 1])
				update([n - 1 + 1, m - 1 + 1, n - 1 + 1, m - 2 + 1, n - 2 + 1, m - 2 + 1])
		elif n % 2 == 1 and m % 2 == 1:
			if a[n - 1][m - 1] == '1':
				ops.append([n - 1 + 1, m - 1 + 1, n - 1 + 1, m - 2 + 1, n - 2 + 1, m - 2 + 1])
				update([n - 1 + 1, m - 1 + 1, n - 1 + 1, m - 2 + 1, n - 2 + 1, m - 2 + 1])
			for i in range(n - 2):
				if a[i][m - 1] == '1':
					ops.append([i + 1, m - 1 + 1, i + 1, m - 2 + 1, i + 1 + 1, m - 2 + 1])
					update([i + 1, m - 1 + 1, i + 1, m - 2 + 1, i + 1 + 1, m - 2 + 1])
			if a[n - 2][m - 1] == '1':
				ops.append([n - 2 + 1, m - 1 + 1, n - 2 + 1, m - 2 + 1, n - 3 + 1, m - 2 + 1])
				update([n - 2 + 1, m - 1 + 1, n - 2 + 1, m - 2 + 1, n - 3 + 1, m - 2 + 1])
			for j in range(m - 2):
				if a[n - 1][j] == '1':
					ops.append([n - 1 + 1, j + 1, n - 2 + 1, j + 1, n - 2 + 1, j + 1 + 1])
					update([n - 1 + 1, j + 1, n - 2 + 1, j + 1, n - 2 + 1, j + 1 + 1])
			if a[n - 1][m - 2] == '1':
				ops.append([n - 1 + 1, m - 2 + 1, n - 2 + 1, m - 2 + 1, n - 2 + 1, m - 3 + 1])
				update([n - 1 + 1, m - 2 + 1, n - 2 + 1, m - 2 + 1, n - 2 + 1, m - 3 + 1])
		for i in range(0, n - 1, 2):
			for j in range(0, m - 1, 2):
				solve(i, j)
		print(len(ops))
		for op in ops:
			print(*op)
prog()


t = int(input())

def countone(i, j):
	count = 0
	ans = []
	if arr[i][j] == '1':
		count += 1
		ans.append(i + 1)
		ans.append(j + 1)
	if arr[i + 1][j] == '1':
		count += 1
		ans.append(i + 2)
		ans.append(j + 1)
	if arr[i][j + 1] == '1':
		count += 1
		ans.append(i + 1)
		ans.append(j + 2)
	if arr[i + 1][j + 1] == '1':
		count += 1
		(ans.append(i + 2), ans.append(j + 2))
	return (ans, count)

def switch(i, j):
	if arr[i][j] == '1':
		arr[i][j] = '0'
	else:
		arr[i][j] = '1'

def change1(i, j, a):
	a1 = a.copy()
	(x1, y1) = a
	c1 = [x1 - 1, y1 - 1]
	ans1 = []
	matrix = [[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]]
	m = []
	for item in matrix:
		if item != c1:
			m.append(item)
	for i in range(3):
		for j in range(i + 1, 3):
			k = [x1, y1, m[i][0] + 1, m[i][1] + 1, m[j][0] + 1, m[j][1] + 1]
			switch(x1 - 1, y1 - 1)
			switch(m[i][0], m[i][1])
			switch(m[j][0], m[j][1])
			ans1.append(k)
	return ans1

def change2(i, j, a1):
	a = a1.copy()
	(x1, y1, x2, y2) = a
	c1 = [x1 - 1, y1 - 1]
	c2 = [x2 - 1, y2 - 1]
	matrix = [[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]]
	for item in matrix:
		if item != c1 and item != c2:
			a.append(item[0] + 1)
			a.append(item[1] + 1)
			switch(item[0], item[1])
			break
	switch(x1 - 1, y1 - 1)
	switch(x2 - 1, y2 - 1)
	return a
while t > 0:
	t -= 1
	(n, m) = [int(x) for x in input().split()]
	arr = []
	for i in range(n):
		s = input()
		a = []
		for j in range(m):
			a.append(s[j])
		arr.append(a)
	ans = []
	result = 0
	if n % 2 != 0:
		for i in range(m - 1):
			if arr[n - 1][i] == '1':
				switch(n - 1, i)
				switch(n - 2, i)
				switch(n - 2, i + 1)
				ans.append([n, i + 1, n - 1, i + 1, n - 1, i + 2])
				result += 1
		if arr[n - 1][m - 1] == '1':
			switch(n - 1, m - 1)
			switch(n - 2, m - 1)
			switch(n - 2, m - 2)
			ans.append([n, m, n - 1, m, n - 1, m - 1])
			result += 1
	if m % 2 != 0:
		if arr[0][m - 1] == '1':
			switch(0, m - 1)
			switch(0, m - 2)
			switch(1, m - 2)
			ans.append([1, m, 1, m - 1, 2, m - 1])
			result += 1
		end = n - n % 2
		for i in range(1, end):
			if arr[i][m - 1] == '1':
				switch(i, m - 1)
				switch(i, m - 2)
				switch(i - 1, m - 2)
				ans.append([i + 1, m, i + 1, m - 1, i, m - 1])
				result += 1
	i = 0
	j = 0
	while i < n - 1:
		while j < m - 1:
			(a, count) = countone(i, j)
			if count == 4:
				result += 4
				ans.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
				switch(i, j + 1)
				switch(i + 1, j)
				switch(i + 1, j + 1)
				ans += change1(i, j, [i + 1, j + 1])
			elif count == 3:
				result += 1
				switch(a[0] - 1, a[1] - 1)
				switch(a[2] - 1, a[3] - 1)
				switch(a[4] - 1, a[5] - 1)
				ans.append(a)
			elif count == 2:
				ans.append(change2(i, j, a))
				col = ans[-1][-1]
				row = ans[-1][-2]
				ans += change1(i, j, [row, col])
				result += 4
			elif count == 1:
				ans += change1(i, j, a)
				result += 3
			j += 2
		j = 0
		i += 2
	while i < n - 1:
		while j < m - 1:
			(a, count) = countone(i, j)
			j += 1
		i += 1
	print(result)
	for i in range(result):
		print(*ans[i])


import sys, os
import heapq, functools, collections
import math, random
from collections import Counter, defaultdict

def solve_(g, n, m):
	og = [[x for x in row] for row in grid]
	(x, y) = (0, 0)
	res = []
	for y in range(n - 2):
		for x in range(m - 1):
			if g[y][x] == 0:
				continue
			if g[y][x] == 1 and g[y][x + 1] == 1:
				if g[y + 1][x] == 1:
					r = [(y, x), (y, x + 1), (y + 1, x)]
				else:
					r = [(y, x), (y, x + 1), (y + 1, x + 1)]
			if g[y][x] == 1 and g[y][x + 1] == 0:
				r = [(y, x), (y + 1, x), (y + 1, x + 1)]
			assert len(r) == 3
			assert len(set(r)) == 3
			res.append(r)
			for (yy, xx) in r:
				g[yy][xx] = 1 - g[yy][xx]
		assert x + 1 == m - 1
		if g[y][x] == 0 and g[y][x + 1] == 0:
			continue
		elif g[y][x] == 1 and g[y][x + 1] == 0:
			r = [(y, x), (y + 1, x), (y + 1, x + 1)]
		elif g[y][x] == 0 and g[y][x + 1] == 1:
			r = [(y, x + 1), (y + 1, x), (y + 1, x + 1)]
		elif g[y][x] == 1 and g[y][x + 1] == 1:
			r = [(y, x), (y, x + 1), (y + 1, x)]
		assert len(r) == 3
		assert len(set(r)) == 3
		res.append(r)
		for (yy, xx) in r:
			g[yy][xx] = 1 - g[yy][xx]
	for x in range(m - 2):
		if g[-2][x] == 0 and g[-1][x] == 0:
			continue
		if g[-2][x] == 1 and g[-1][x] == 0:
			r = [(-2, x), (-2, x + 1), (-1, x + 1)]
		if g[-2][x] == 0 and g[-1][x] == 1:
			r = [(-1, x), (-2, x + 1), (-1, x + 1)]
		if g[-2][x] == 1 and g[-1][x] == 1:
			if g[-2][x + 1] == 1:
				r = [(-2, x), (-1, x), (-2, x + 1)]
			else:
				r = [(-2, x), (-1, x), (-1, x + 1)]
		assert len(r) == 3
		assert len(set(r)) == 3
		res.append(r)
		for (yy, xx) in r:
			g[yy][xx] = 1 - g[yy][xx]
	l4 = [(-2, -2), (-2, -1), (-1, -2), (-1, -1)]
	if g[-2][-2] + g[-2][-1] + g[-1][-2] + g[-1][-1] == 4:
		console('resolve 4')
		r = l4[:3]
		assert len(r) == 3
		assert len(set(r)) == 3
		res.append(r)
		for (yy, xx) in r:
			g[yy][xx] = 1 - g[yy][xx]
	if g[-2][-2] + g[-2][-1] + g[-1][-2] + g[-1][-1] == 1:
		console('resolve 1')
		for (i, (y, x)) in enumerate(l4 + l4):
			if g[y][x] == 1:
				r = (l4 + l4)[i:i + 3]
				break
		assert len(r) == 3
		assert len(set(r)) == 3
		res.append(r)
		for (yy, xx) in r:
			g[yy][xx] = 1 - g[yy][xx]
	if g[-2][-2] + g[-2][-1] + g[-1][-2] + g[-1][-1] == 2:
		console('resolve 2')
		sett = set()
		for (i, (y, x)) in enumerate(l4 + l4 + l4):
			if g[y][x] == 0:
				sett.add((y, x))
			if len(sett) == 2:
				sett.add((y, x))
			if len(sett) == 3:
				break
		r = list(sett)
		assert len(r) == 3
		assert len(set(r)) == 3
		res.append(r)
		for (yy, xx) in r:
			g[yy][xx] = 1 - g[yy][xx]
	if g[-2][-2] + g[-2][-1] + g[-1][-2] + g[-1][-1] == 3:
		console('resolve 3')
		r = []
		for (i, (y, x)) in enumerate(l4):
			if g[y][x] == 1:
				r.append((y, x))
		assert len(r) == 3
		assert len(set(r)) == 3
		res.append(r)
		for (yy, xx) in r:
			g[yy][xx] = 1 - g[yy][xx]
	res2 = []
	for re in res:
		re2 = []
		for (a, b) in re:
			if a < 0:
				a = n + a
			if b < 0:
				b = m + b
			re2.extend((a + 1, b + 1))
		res2.append(re2)
	assert sum((sum(row) for row in grid)) == 0
	for (x1, y1, x2, y2, x3, y3) in res2:
		(x1, y1, x2, y2, x3, y3) = (x1 - 1, y1 - 1, x2 - 1, y2 - 1, x3 - 1, y3 - 1)
		og[x1][y1] = 1 - og[x1][y1]
		og[x2][y2] = 1 - og[x2][y2]
		og[x3][y3] = 1 - og[x3][y3]
	assert sum((sum(row) for row in og)) == 0
	assert len(res2) <= n * m
	return res2

def console(*args):
	print('\x1b[36m', *args, '\x1b[0m', file=sys.stderr)
	pass
ONLINE_JUDGE = False
if os.path.exists('input.txt'):
	ONLINE_JUDGE = True
if ONLINE_JUDGE:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')

	def console(*args):
		pass

def solve(*args):
	if not ONLINE_JUDGE:
		console('----- solving ------')
		console(*args)
		console('----- ------- ------')
	return solve_(*args)
if True:
	inp = iter(sys.stdin.readlines())
	input = lambda : next(inp)
else:
	input = sys.stdin.readline
for case_num in range(int(input())):
	(n, m) = list(map(int, input().split()))
	grid = []
	for _ in range(n):
		grid.append(list(map(int, list(input().strip()))))
	res = solve(grid, n, m)
	print(len(res))
	for r in res:
		print(*r)


from collections import Counter
from collections import OrderedDict
from collections import defaultdict
import bisect
import math
from sys import setrecursionlimit

def gcd(a, b):
	if a == 0:
		return b
	return gcd(b % a, a)

def fre_count(mylist):
	return Counter(mylist)
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	grid = [[int(x) for x in input()] for x in range(n)]
	ans = []
	for i in range(n):
		for j in range(m):
			count = 0
			if i + 1 < n and j + 1 < m:
				p1 = []
				p0 = []
				if grid[i][j] == 1:
					p1.append([i + 1, j + 1])
					grid[i][j] = 0
				else:
					p0.append([i + 1, j + 1])
				if grid[i + 1][j] == 1:
					p1.append([i + 2, j + 1])
					grid[i + 1][j] = 0
				else:
					p0.append([i + 1 + 1, j + 1])
				if grid[i][j + 1] == 1:
					p1.append([i + 1, j + 2])
					grid[i][j + 1] = 0
				else:
					p0.append([i + 1, j + 2])
				if grid[i + 1][j + 1] == 1:
					p1.append([i + 2, j + 2])
					grid[i + 1][j + 1] = 0
				else:
					p0.append([i + 2, j + 2])
				if len(p1) == 4:
					for k in range(3):
						ans.append(p1[k])
					for k in range(3, 0, -1):
						ans.append(p1[k])
					ans.append(p1[3])
					ans.append(p1[2])
					ans.append(p1[0])
					ans.append(p1[1])
					ans.append(p1[0])
					ans.append(p1[3])
				elif len(p1) == 3:
					for k in range(3):
						ans.append(p1[k])
				elif len(p1) == 2:
					ans.append(p1[0])
					ans.append(p0[0])
					ans.append(p0[1])
					ans.append(p1[1])
					ans.append(p0[0])
					ans.append(p0[1])
				elif len(p1) == 1:
					ans.append(p1[0])
					ans.append(p0[0])
					ans.append(p0[1])
					ans.append(p0[0])
					ans.append(p1[0])
					ans.append(p0[2])
					ans.append(p1[0])
					ans.append(p0[1])
					ans.append(p0[2])
	print(len(ans) // 3)
	for i in range(len(ans)):
		print(*ans[i], end=' ')
		if (i + 1) % 3 == 0 and i != 0:
			print()


def fu1(A, i, j, kkk):
	o = 0
	z = 0
	ans = []
	for k in range(i, i + 2):
		for m in range(j, j + 2):
			if A[k][m] == '0' and z < 2:
				z += 1
				A[k][m] = '1'
				ans.append([k + 1, m + 1])
			elif A[k][m] == '1':
				A[k][m] = '0'
				ans.append([k + 1, m + 1])
	kkk.append(ans[:])
	fu2(A, i, j, kkk)

def fu2(A, i, j, kkk):
	o = 0
	ans = []
	for k in range(i, i + 2):
		for m in range(j, j + 2):
			if A[k][m] == '0':
				A[k][m] = '1'
				ans.append([k + 1, m + 1])
			elif A[k][m] == '1' and o == 0:
				o = 1
				A[k][m] = '0'
				ans.append([k + 1, m + 1])
	kkk.append(ans[:])
	fu3(A, i, j, kkk)

def fu3(A, i, j, kkk):
	ans = []
	if A[i][j] == '1':
		ans.append([i + 1, j + 1])
		A[i][j] = '0'
	if A[i + 1][j] == '1':
		ans.append([i + 2, j + 1])
		A[i + 1][j] = '0'
	if A[i][j + 1] == '1':
		ans.append([i + 1, j + 2])
		A[i][j + 1] = '0'
	if A[i + 1][j + 1] == '1':
		ans.append([i + 2, j + 2])
		A[i + 1][j + 1] = '0'
	kkk.append(ans[:])
	return

def fu4(A, i, j, kkk):
	ans = []
	ans.append([i + 1, j + 1])
	ans.append([i + 1, j + 2])
	ans.append([i + 2, j + 1])
	A[i][j] = '0'
	A[i + 1][j] = '0'
	A[i][j + 1] = '0'
	kkk.append(ans[:])
	fu1(A, i, j, kkk)

def fu(A, i, j, ans):
	t = int(A[i][j]) + int(A[i + 1][j]) + int(A[i][j + 1]) + int(A[i + 1][j + 1])
	if t == 4:
		fu4(A, i, j, ans)
	elif t == 3:
		fu3(A, i, j, ans)
	elif t == 2:
		fu2(A, i, j, ans)
	elif t == 1:
		fu1(A, i, j, ans)
for i in range(int(input())):
	(n, m) = map(int, input().split())
	l = []
	for i in range(n):
		t = list(input())
		l.append(t[:])
	ans = []
	for i in range(0, n - 1):
		for j in range(0, m - 1):
			fu(l, i, j, ans)
	print(len(ans))
	for i in ans:
		for j in i:
			print(j[0], j[1], end=' ')
		print()


import sys
input = sys.stdin.readline
from collections import *

def tran():
	pos = []
	epos = []
	for i in range(n - 2, n):
		for j in range(m - 2, m):
			if s[i][j] == 1:
				pos.append((i, j))
			else:
				epos.append((i, j))
	if len(pos) in [1, 2]:
		row = (pos[0][0], pos[0][1], epos[0][0], epos[0][1], epos[1][0], epos[1][1])
		ans.append(row)
		for j in range(3):
			x = row[2 * j]
			y = row[2 * j + 1]
			s[x][y] ^= 1
	else:
		row = (pos[0][0], pos[0][1], pos[1][0], pos[1][1], pos[2][0], pos[2][1])
		ans.append(row)
		for j in range(3):
			x = row[2 * j]
			y = row[2 * j + 1]
			s[x][y] ^= 1
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	s = [list(map(int, input()[:-1])) for _ in range(n)]
	ans = []
	for i in range(n - 1):
		for j in range(m - 1):
			if i == n - 2 and j == m - 2:
				continue
			if s[i][j] == 1:
				ans.append((i, j, i + 1, j, i, j + 1))
				s[i][j] ^= 1
				s[i + 1][j] ^= 1
				s[i][j + 1] ^= 1
	for i in range(m - 2):
		if s[n - 2][i] == 1 and s[n - 1][i] == 1:
			row = (n - 2, i, n - 1, i, n - 2, i + 1)
		elif s[n - 2][i] == 1 and s[n - 1][i] == 0:
			row = (n - 2, i, n - 2, i + 1, n - 1, i + 1)
		elif s[n - 2][i] == 0 and s[n - 1][i] == 1:
			row = (n - 1, i, n - 2, i + 1, n - 1, i + 1)
		else:
			continue
		for j in range(3):
			x = row[2 * j]
			y = row[2 * j + 1]
			s[x][y] ^= 1
		ans.append(row)
	for i in range(n - 2):
		if s[i][m - 2] == 1 and s[i][m - 1] == 1:
			row = (i, m - 2, i, m - 1, i + 1, m - 2)
		elif s[i][m - 2] == 1 and s[i][m - 1] == 0:
			row = (i, m - 2, i + 1, m - 2, i + 1, m - 1)
		elif s[i][m - 2] == 0 and s[i][m - 1] == 1:
			row = (i, m - 1, i + 1, m - 2, i + 1, m - 1)
		else:
			continue
		for j in range(3):
			x = row[2 * j]
			y = row[2 * j + 1]
			s[x][y] ^= 1
		ans.append(row)
	while s[n - 2][m - 2] == 1 or s[n - 2][m - 1] == 1 or s[n - 1][m - 2] == 1 or (s[n - 1][m - 1] == 1):
		tran()
	for i in range(n):
		for j in range(m):
			if s[i][j] == 1:
				1 / 0
	print(len(ans))
	for (a, b, c, d, e, f) in ans:
		print(a + 1, b + 1, c + 1, d + 1, e + 1, f + 1)


import sys
from collections import deque
from copy import *
from bisect import *
from math import gcd, ceil, sqrt
from itertools import permutations as prm, product

def eprint(*args):
	print(*args, file=sys.stderr)
zz = 1
if zz:
	input = sys.stdin.readline
else:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('all.txt', 'w')
di = [[-1, 0], [1, 0], [0, 1], [0, -1]]

def string(s):
	return ''.join(s)

def fori(n):
	return [fi() for i in range(n)]

def inc(d, c, x=1):
	d[c] = d[c] + x if c in d else x

def bo(i):
	return ord(i) - ord('A')

def li():
	return [int(xx) for xx in input().split()]

def fli():
	return [float(x) for x in input().split()]

def comp(a, b):
	if a > b:
		return 2
	return 2 if a == b else 0

def gi():
	return [xx for xx in input().split()]

def gtc(tc, ans):
	print('Case #' + str(tc) + ':', ans)

def cil(n, m):
	return n // m + int(n % m > 0)

def fi():
	return int(input())

def pro(a):
	return reduce(lambda a, b: a * b, a)

def swap(a, i, j):
	(a[i], a[j]) = (a[j], a[i])

def si():
	return list(input().rstrip())

def mi():
	return map(int, input().split())

def gh():
	sys.stdout.flush()

def isvalid(i, j, n, m):
	return 0 <= i < n and 0 <= j < m

def bo(i):
	return ord(i) - ord('a')

def graph(n, m):
	for i in range(m):
		(x, y) = mi()
		a[x].append(y)
		a[y].append(x)
t = fi()

def foh(b, p):
	v = []
	u = []
	for (i, j) in b:
		u.append(a[i][j])
	if p == 1:
		for j in range(4):
			if u[j] == '1':
				a[b[j][0]][b[j][1]] = '0'
				v.append(b[j][0] + 1)
				v.append(b[j][1] + 1)
		ans.append(v)
	elif p == 2:
		f = 0
		for j in range(4):
			if u[j] == '0':
				a[b[j][0]][b[j][1]] = '1'
				v.append(b[j][0] + 1)
				v.append(b[j][1] + 1)
			elif f == 0:
				a[b[j][0]][b[j][1]] = '0'
				v.append(b[j][0] + 1)
				v.append(b[j][1] + 1)
				f += 1
		ans.append(v)
		foh(b, 1)
	elif p == 3:
		f = 0
		for j in range(4):
			if u[j] == '0':
				if f < 2:
					a[b[j][0]][b[j][1]] = '1'
					v.append(b[j][0] + 1)
					v.append(b[j][1] + 1)
					f += 1
			else:
				a[b[j][0]][b[j][1]] = '0'
				v.append(b[j][0] + 1)
				v.append(b[j][1] + 1)
		ans.append(v)
		foh(b, 2)
	elif p == 0:
		for j in range(3):
			if u[j] == '1':
				a[b[j][0]][b[j][1]] = '0'
				v.append(b[j][0] + 1)
				v.append(b[j][1] + 1)
		ans.append(v)
		foh(b, 3)
while t > 0:
	t -= 1
	(n, m) = mi()
	a = []
	ans = []
	for i in range(n):
		a.append(si())
	for i in range(n - 1):
		for j in range(m - 1):
			(p, q, r, s) = (a[i][j], a[i + 1][j], a[i + 1][j + 1], a[i][j + 1])
			u = [p, q, r, s]
			b = [(i, j), (i + 1, j), (i + 1, j + 1), (i, j + 1)]
			y = u.count('0')
			foh(b, y)
	print(len(ans))
	for i in ans:
		print(*i)


t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = []
	for i in range(n):
		a.append([int(i) for i in input().strip()])
	ops = [[] for i in range(3 * n * m)]
	ct = 0
	for i in range(0, n - 1):
		for j in range(0, m - 1):
			while a[i][j] or a[i + 1][j] or a[i][j + 1] or a[i + 1][j + 1]:
				cur = a[i][j] + a[i + 1][j] + a[i][j + 1] + a[i + 1][j + 1]
				if cur == 4:
					ops[ct] += [i + 1, j + 1, i + 2, j + 1, i + 1, j + 2]
					a[i][j] = 0
					a[i + 1][j] = 0
					a[i][j + 1] = 0
				elif cur == 3:
					for k in range(2):
						for l in range(2):
							if a[i + k][j + l]:
								a[i + k][j + l] = 0
								ops[ct] += [i + k + 1, j + l + 1]
				elif cur == 2:
					found_white = False
					for k in range(2):
						for l in range(2):
							if not a[i + k][j + l]:
								ops[ct] += [i + k + 1, j + l + 1]
								a[i + k][j + l] = 1
							elif a[i + k][j + l] and (not found_white):
								found_white = True
								ops[ct] += [i + k + 1, j + l + 1]
								a[i + k][j + l] = 0
				elif cur == 1:
					found = 0
					for k in range(2):
						for l in range(2):
							if a[i + k][j + l]:
								a[i + k][j + l] = 0
								ops[ct] += [i + k + 1, j + l + 1]
							elif found < 2 and (not a[i + k][j + l]):
								found += 1
								a[i + k][j + l] = 1
								ops[ct] += [i + k + 1, j + l + 1]
				ct += 1
	print(ct)
	for i in range(ct):
		print(*ops[i])


d = {'0': 0, '1': 1}
cases = int(input())
for t in range(cases):
	(n, m) = list(map(int, input().split()))
	matrix = []
	for i in range(n):
		matrix.append([d[i] for i in input()])
	k = 0
	out = []
	for i in range(n - 2):
		for j in range(m):
			if matrix[i][j]:
				k += 1
				if j < m - 1:
					matrix[i][j] = 0
					matrix[i + 1][j] = matrix[i + 1][j] ^ 1
					matrix[i + 1][j + 1] = matrix[i + 1][j + 1] ^ 1
					out.append([i, j, i + 1, j, i + 1, j + 1])
				elif j == m - 1:
					matrix[i][j] = 0
					matrix[i + 1][j] = matrix[i + 1][j] ^ 1
					matrix[i + 1][j - 1] = matrix[i + 1][j - 1] ^ 1
					out.append([i, j, i + 1, j, i + 1, j - 1])
	for i in range(m - 1):
		(x1, x2) = (matrix[n - 2][i], matrix[n - 1][i])
		if x1 == 0 and x2 == 0:
			continue
		elif x1 == 1 and x2 == 1:
			out.append([n - 2, i, n - 1, i, n - 1, i + 1])
			matrix[n - 2][i] ^= 1
			matrix[n - 1][i] ^= 1
			matrix[n - 1][i + 1] ^= 1
		elif x1 == 0 and x2 == 1:
			out.append([n - 2, i + 1, n - 1, i, n - 1, i + 1])
			matrix[n - 2][i + 1] ^= 1
			matrix[n - 1][i] ^= 1
			matrix[n - 1][i + 1] ^= 1
		elif x1 == 1 and x2 == 0:
			out.append([n - 2, i, n - 2, i + 1, n - 1, i + 1])
			matrix[n - 2][i] ^= 1
			matrix[n - 2][i + 1] ^= 1
			matrix[n - 1][i + 1] ^= 1
		k += 1
	if matrix[-1][-1] or matrix[-2][-1]:
		(x1, x2, x3, x4) = (matrix[n - 2][m - 2], matrix[n - 2][m - 1], matrix[n - 1][m - 2], matrix[n - 1][m - 1])
		if x2 == 1 and x4 == 1:
			out.append([n - 2, m - 2, n - 2, m - 1, n - 1, m - 2])
			out.append([n - 2, m - 2, n - 1, m - 2, n - 1, m - 1])
			(matrix[n - 2][m - 1], matrix[n - 1][m - 1]) = (0, 0)
			k += 2
		elif x2 == 0 and x4 == 1:
			out.append([n - 2, m - 2, n - 1, m - 2, n - 1, m - 1])
			out.append([n - 2, m - 2, n - 2, m - 1, n - 1, m - 1])
			out.append([n - 2, m - 1, n - 1, m - 2, n - 1, m - 1])
			matrix[n - 1][m - 1] = 0
			k += 3
		elif x2 == 1 and x4 == 0:
			out.append([n - 2, m - 2, n - 2, m - 1, n - 1, m - 2])
			out.append([n - 2, m - 2, n - 2, m - 1, n - 1, m - 1])
			out.append([n - 2, m - 1, n - 1, m - 2, n - 1, m - 1])
			matrix[n - 2][m - 1] = 0
			k += 3
	print(k)
	for (x1, y1, x2, y2, x3, y3) in out:
		print(x1 + 1, y1 + 1, x2 + 1, y2 + 1, x3 + 1, y3 + 1)


MOD = 1000000007
from collections import defaultdict as dd, Counter, deque

def si():
	return input()

def ii():
	return int(input())

def li():
	return list(map(int, input().split()))

def mi():
	return map(int, input().split())

def out(v):
	print(v)

def spout():
	print(v, end=' ')

def d2b(n):
	return bin(n).replace('0b', '')

def twod(n, m, num):
	return [[num for x in range(m)] for y in range(n)]

def vow():
	return ['a', 'e', 'i', 'o', 'u']

def let():
	return [chr(i) for i in range(97, 123)]

def gcd(x, y):
	while y:
		(x, y) = (y, x % y)
	return x

def ispow2(x):
	return x and (not x & x - 1)

def prime_factors(n):
	i = 2
	factors = []
	while i * i <= n:
		if n % i:
			i += 1
		else:
			n //= i
			factors.append(i)
	if n > 1:
		factors.append(n)
	return list(factors)

def solve(ans, arr, c1, i0, i1):
	if c1 == 1:
		ans += 3
		arr.append([i1[0][0], i1[0][1], i0[0][0], i0[0][1], i0[1][0], i0[1][1]])
		arr.append([i1[0][0], i1[0][1], i0[2][0], i0[2][1], i0[1][0], i0[1][1]])
		arr.append([i1[0][0], i1[0][1], i0[0][0], i0[0][1], i0[2][0], i0[2][1]])
	elif c1 == 2:
		ans += 2
		arr.append([i0[0][0], i0[0][1], i0[1][0], i0[1][1], i1[0][0], i1[0][1]])
		arr.append([i0[0][0], i0[0][1], i0[1][0], i0[1][1], i1[1][0], i1[1][1]])
	elif c1 == 3:
		ans += 1
		arr.append([i1[0][0], i1[0][1], i1[1][0], i1[1][1], i1[2][0], i1[2][1]])
	else:
		ans += 4
		arr.append([i1[0][0], i1[0][1], i1[1][0], i1[1][1], i1[2][0], i1[2][1]])
		arr.append([i1[1][0], i1[1][1], i1[2][0], i1[2][1], i1[3][0], i1[3][1]])
		arr.append([i1[0][0], i1[0][1], i1[2][0], i1[2][1], i1[3][0], i1[3][1]])
		arr.append([i1[0][0], i1[0][1], i1[1][0], i1[1][1], i1[3][0], i1[3][1]])
	return (ans, arr)
t = ii()
while t:
	t -= 1
	(n, m) = mi()
	a = []
	arr = []
	ans = 0
	for _ in range(n):
		s = si()
		b = []
		for i in range(m):
			b.append(int(s[i]))
		a.append(b)
	i = 0
	while i < n:
		j = 0
		while j < m:
			c0 = c1 = 0
			idx0 = []
			idx1 = []
			for k in range(i, i + 2):
				for l in range(j, j + 2):
					if a[k][l] == 0:
						c0 += 1
						idx0.append((k + 1, l + 1))
					else:
						c1 += 1
						idx1.append((k + 1, l + 1))
						a[k][l] = 0
			if c0 != 4:
				(ans, arr) = solve(ans, arr, c1, idx0, idx1)
			j += 2
			if j == m - 1:
				j -= 1
		i += 2
		if i == n - 1:
			i -= 1
	print(ans)
	for i in range(ans):
		print(' '.join((str(j) for j in arr[i])))


import os
import sys
from io import BytesIO, IOBase
import heapq as h
from bisect import bisect_left, bisect_right
import time
from types import GeneratorType
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		import os
		self.os = os
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			self.os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from collections import defaultdict as dd, deque as dq, Counter as dc
import math, string

def getInts():
	return [int(s) for s in input().split()]

def getInt():
	return int(input())

def getStrs():
	return [s for s in input().split()]

def getStr():
	return input()

def listStr():
	return list(input())

def getMat(n):
	return [getInts() for _ in range(n)]
MOD = 10 ** 9 + 7

def solve():
	(N, M) = getInts()
	grid = []
	for n in range(N):
		grid.append([int(s) for s in input()])
	ans = 0
	ops = []

	def solve2(inds, flag=False, flag2=False):
		ret = []
		if not inds:
			return ret
		if len(inds) == 3:
			ret.append((inds[0][0], inds[0][1], inds[1][0], inds[1][1], inds[2][0], inds[2][1]))
			return ret
		if len(inds) == 1:
			neigh1 = (inds[0][0] + (1 if inds[0][0] % 2 == 1 and inds[0][0] < N and (not flag) or (flag and inds[0][0] < N) else -1), inds[0][1] + (1 if inds[0][1] % 2 == 1 and inds[0][1] < M and (not flag2) or (flag2 and inds[0][1] < M) else -1))
			neigh2 = (inds[0][0] + (1 if inds[0][0] % 2 == 1 and inds[0][0] < N and (not flag) or (flag and inds[0][0] < N) else -1), inds[0][1])
			ret.append((inds[0][0], inds[0][1], neigh1[0], neigh1[1], neigh2[0], neigh2[1]))
			new_inds = [neigh1, neigh2]
			x = solve2(new_inds, flag, flag2)
			for el in x:
				ret.append(el)
			return ret
		if len(inds) == 4:
			ret.append((inds[0][0], inds[0][1], inds[1][0], inds[1][1], inds[2][0], inds[2][1]))
			new_inds = [(inds[3][0], inds[3][1])]
			x = solve2(new_inds, flag, flag2)
			for el in x:
				ret.append(el)
			return ret
		if len(inds) == 2:
			if (inds[0][0] + inds[0][1]) % 2 == (inds[1][0] + inds[1][1]) % 2:
				neigh1 = (inds[0][0], inds[0][1] + (1 if inds[0][1] % 2 == 1 and inds[0][1] < M and (not flag2) or (flag2 and inds[0][1] < M) else -1))
				neigh2 = (inds[0][0] + (1 if inds[0][0] % 2 == 1 and inds[0][0] < N and (not flag) or (flag and inds[0][0] < N) else -1), inds[0][1])
			else:
				neigh1 = (inds[0][0], inds[0][1] + (1 if inds[0][1] % 2 == 1 and inds[0][1] < M and (not flag2) or (flag2 and inds[0][1] < M) else -1))
				neigh2 = (inds[0][0] + (1 if inds[0][0] % 2 == 1 and inds[0][0] < N and (not flag) or (flag and inds[0][0] < N) else -1), inds[0][1])
				if neigh1 == inds[1]:
					neigh1 = (inds[0][0] + (1 if inds[0][0] % 2 == 1 and inds[0][0] < N and (not flag) or (flag and inds[0][0] < N) else -1), inds[0][1] + (1 if inds[0][1] % 2 == 1 and inds[0][1] < M and (not flag2) or (flag2 and inds[0][1] < M) else -1))
				else:
					neigh2 = (inds[0][0] + (1 if inds[0][0] % 2 == 1 and inds[0][0] < N and (not flag) or (flag and inds[0][0] < N) else -1), inds[0][1] + (1 if inds[0][1] % 2 == 1 and inds[0][1] < M and (not flag2) or (flag2 and inds[0][1] < M) else -1))
			ret.append((inds[0][0], inds[0][1], neigh1[0], neigh1[1], neigh2[0], neigh2[1]))
			new_inds = [inds[1], neigh1, neigh2]
			x = solve2(new_inds, flag, flag2)
			for el in x:
				ret.append(el)
			return ret
	for n in range(N - 1, 1, -1):
		for m in range(M - 1, 1, -1):
			if grid[n][m] == 1:
				inds = (n + 1, m + 1, n, m + 1, n, m)
				ops.append(inds)
				grid[n][m] ^= 1
				grid[n - 1][m] ^= 1
				grid[n - 1][m - 1] ^= 1
		if grid[n][0] * grid[n][1] == 1:
			inds = (n + 1, 1, n + 1, 2, n, 2)
			ops.append(inds)
			grid[n][0] = 0
			grid[n][1] = 0
			grid[n - 1][1] ^= 1
		elif grid[n][0] == 1:
			inds = (n + 1, 1, n, 1, n, 2)
			ops.append(inds)
			grid[n][0] = 0
			grid[n - 1][0] ^= 1
			grid[n - 1][1] ^= 1
		elif grid[n][1] == 1:
			inds = (n + 1, 2, n, 2, n, 1)
			ops.append(inds)
			grid[n][1] = 0
			grid[n - 1][1] ^= 1
			grid[n - 1][0] ^= 1
	for m in range(M - 1, 1, -1):
		if grid[0][m] * grid[1][m] == 1:
			inds = (1, m + 1, 2, m + 1, 2, m)
			ops.append(inds)
			grid[0][m] = 0
			grid[1][m] = 0
			grid[1][m - 1] ^= 1
		elif grid[0][m] == 1:
			inds = (1, m + 1, 1, m, 2, m)
			ops.append(inds)
			grid[0][m] = 0
			grid[0][m - 1] ^= 1
			grid[1][m - 1] ^= 1
		elif grid[1][m] == 1:
			inds = (2, m + 1, 2, m, 1, m)
			ops.append(inds)
			grid[1][m] = 0
			grid[1][m - 1] ^= 1
			grid[0][m - 1] ^= 1
	inds = []
	for i in range(2):
		for j in range(2):
			if grid[i][j] == 1:
				inds.append((i + 1, j + 1))
				grid[i][j] = 0
	tmp = solve2(inds)
	ans += len(tmp)
	for t in tmp:
		ops.append(t)
	print(len(ops))
	for op in ops:
		print(*op)
	return
for _ in range(getInt()):
	solve()


import os
import sys
from io import BytesIO, IOBase

def main():
	for _ in range(int(input())):
		(n, m) = map(int, input().split())
		grid = []
		for _ in range(n):
			grid.append(input())
		ans = []
		for i in range(n):
			for j in range(m):
				if grid[i][j] == '1':
					if i == n - 1:
						iP2 = i
					else:
						iP2 = i + 2
					if j == m - 1:
						jP2 = j
					else:
						jP2 = j + 2
					ans.append([i + 1, j + 1, iP2, jP2, iP2, j + 1])
					ans.append([i + 1, j + 1, i + 1, jP2, iP2, jP2])
					ans.append([i + 1, j + 1, iP2, j + 1, i + 1, jP2])
		print(len(ans))
		for lineAns in ans:
			print(' '.join(map(str, lineAns)))
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


def solve(r, c):
	nr = r + 1 if r + 1 <= n else r - 1
	nc = c + 1 if c + 1 <= m else c - 1
	print(r, c, r, nc, nr, c)
	print(r, c, r, nc, nr, nc)
	print(r, c, nr, c, nr, nc)
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = [list(map(int, list(input()))) for _ in range(n)]
	print(sum((sum(u) for u in a)) * 3)
	for i in range(n):
		for j in range(m):
			if a[i][j] == 1:
				solve(i + 1, j + 1)


t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	a = [list(map(int, input())) for i in range(n)]

	def add(x, y, z):
		a[x[0]][x[1]] ^= 1
		a[y[0]][y[1]] ^= 1
		a[z[0]][z[1]] ^= 1
		ans.append(' '.join(map(lambda x: str(x + 1), (*x, *y, *z))))
	ans = []
	for i in range(n - 1, 1, -1):
		for j in range(m):
			if a[i][j]:
				add((i, j), (i - 1, j), (i - 1, j + (1 if j < m - 1 else -1)))
	for j in range(m - 1, 1, -1):
		for i in (0, 1):
			if a[i][j]:
				add((i, j), (0, j - 1), (1, j - 1))
	for i in (0, 1):
		for j in (0, 1):
			if (a[0][0] + a[0][1] + a[1][0] + a[1][1] + a[i][j]) % 2:
				add((i ^ 1, j), (i, j ^ 1), (i ^ 1, j ^ 1))
	print(len(ans))
	print('\n'.join(ans))


import os
from heapq import heapify, heappop, heappush
import sys
import sys, threading
import math
import operator
import bisect
from collections import defaultdict
from io import BytesIO, IOBase
sys.setrecursionlimit(10 ** 5)

def inpt():
	return [int(k) for k in input().split()]

def main():
	for _ in range(int(input())):
		(n, m) = inpt()
		ar = []
		for i in range(n):
			br = list(input())
			ar.append(br)
		ans = []
		d = [(0, 0), (1, 0), (0, 1), (1, 1)]
		for i in range(n - 1):
			for j in range(m - 1):
				temp = []
				count = 0
				for (a, b) in d:
					if ar[i + a][j + b] == '1':
						count += 1
				if count == 3:
					for (a, b) in d:
						if ar[i + a][j + b] == '1':
							ar[i + a][j + b] = '0'
							temp.append((i + a, j + b))
				elif count == 2:
					ok = False
					for (a, b) in d:
						if ar[i + a][j + b] == '0':
							temp.append((i + a, j + b))
						if ar[i + a][j + b] == '1' and (not ok):
							temp.append((i + a, j + b))
							ok = True
					for (p, q) in temp:
						if ar[p][q] == '0':
							ar[p][q] = '1'
						else:
							ar[p][q] = '0'
					ans.append(temp)
					temp = []
					for (a, b) in d:
						if ar[i + a][j + b] == '1':
							ar[i + a][j + b] = '0'
							temp.append((i + a, j + b))
				elif count == 1:
					ct = 0
					for (a, b) in d:
						if ar[i + a][j + b] == '0' and ct < 2:
							ct += 1
							temp.append((i + a, j + b))
						if ar[i + a][j + b] == '1':
							temp.append((i + a, j + b))
					for (p, q) in temp:
						if ar[p][q] == '0':
							ar[p][q] = '1'
						else:
							ar[p][q] = '0'
					ans.append(temp)
					temp = []
					ok = False
					for (a, b) in d:
						if ar[i + a][j + b] == '0':
							temp.append((i + a, j + b))
						if ar[i + a][j + b] == '1' and (not ok):
							temp.append((i + a, j + b))
							ok = True
					for (p, q) in temp:
						if ar[p][q] == '0':
							ar[p][q] = '1'
						else:
							ar[p][q] = '0'
					ans.append(temp)
					temp = []
					for (a, b) in d:
						if ar[i + a][j + b] == '1':
							ar[i + a][j + b] = '0'
							temp.append((i + a, j + b))
				elif count == 4:
					ct = 0
					for (a, b) in d:
						if ar[i + a][j + b] == '1' and ct < 3:
							temp.append((i + a, j + b))
							ct += 1
					for (p, q) in temp:
						if ar[p][q] == '0':
							ar[p][q] = '1'
						else:
							ar[p][q] = '0'
					ans.append(temp)
					temp = []
					ct = 0
					for (a, b) in d:
						if ar[i + a][j + b] == '0' and ct < 2:
							ct += 1
							temp.append((i + a, j + b))
						if ar[i + a][j + b] == '1':
							temp.append((i + a, j + b))
					for (p, q) in temp:
						if ar[p][q] == '0':
							ar[p][q] = '1'
						else:
							ar[p][q] = '0'
					ans.append(temp)
					temp = []
					ok = False
					for (a, b) in d:
						if ar[i + a][j + b] == '0':
							temp.append((i + a, j + b))
						if ar[i + a][j + b] == '1' and (not ok):
							temp.append((i + a, j + b))
							ok = True
					for (p, q) in temp:
						if ar[p][q] == '0':
							ar[p][q] = '1'
						else:
							ar[p][q] = '0'
					ans.append(temp)
					temp = []
					for (a, b) in d:
						if ar[i + a][j + b] == '1':
							ar[i + a][j + b] = '0'
							temp.append((i + a, j + b))
				if temp:
					ans.append(temp)
					temp = []
		print(len(ans))
		for i in ans:
			for (a, b) in i:
				print(a + 1, b + 1, end=' ')
			print()
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


mod = 10 ** 9 + 7
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = []
	for i in range(n):
		b = input()
		a.append([])
		for j in range(m):
			a[i].append(int(b[j]))
	res = []
	for i in range(n - 2):
		for j in range(m - 2):
			if a[i][j] == 1:
				if a[i][j + 1] == 1:
					res.append((i + 1, j + 1, i + 2, j + 1, i + 1, j + 2))
					a[i][j] = 1 - a[i][j]
					a[i + 1][j] = 1 - a[i + 1][j]
					a[i][j + 1] = 1 - a[i][j + 1]
				else:
					res.append((i + 1, j + 1, i + 2, j + 1, i + 2, j + 2))
					a[i][j] = 1 - a[i][j]
					a[i + 1][j] = 1 - a[i + 1][j]
					a[i + 1][j + 1] = 1 - a[i + 1][j + 1]
		if a[i][m - 2] == 1 and a[i][m - 1] == 1:
			res.append((i + 1, m - 1, i + 1, m, i + 2, m - 1))
			a[i][m - 2] = 1 - a[i][m - 2]
			a[i][m - 1] = 1 - a[i][m - 1]
			a[i + 1][m - 2] = 1 - a[i + 1][m - 2]
		elif a[i][m - 2] == 1:
			res.append((i + 1, m - 1, i + 2, m - 1, i + 2, m))
			a[i][m - 2] = 1 - a[i][m - 2]
			a[i + 1][m - 1] = 1 - a[i + 1][m - 1]
			a[i + 1][m - 2] = 1 - a[i + 1][m - 2]
		elif a[i][m - 1] == 1:
			res.append((i + 1, m, i + 2, m - 1, i + 2, m))
			a[i + 1][m - 1] = 1 - a[i + 1][m - 1]
			a[i][m - 1] = 1 - a[i][m - 1]
			a[i + 1][m - 2] = 1 - a[i + 1][m - 2]
	for i in range(m - 2):
		if a[n - 2][i] == 1 and a[n - 1][i] == 1:
			res.append((n - 1, i + 1, n, i + 1, n, i + 2))
			a[n - 1][i] = 1 - a[n - 1][i]
			a[n - 2][i] = 1 - a[n - 2][i]
			a[n - 1][i + 1] = 1 - a[n - 1][i + 1]
		elif a[n - 2][i] == 1:
			res.append((n - 1, i + 1, n - 1, i + 2, n, i + 2))
			a[n - 1][i + 1] = 1 - a[n - 1][i + 1]
			a[n - 2][i] = 1 - a[n - 2][i]
			a[n - 2][i + 1] = 1 - a[n - 2][i + 1]
		elif a[n - 1][i] == 1:
			res.append((n - 1, i + 2, n, i + 1, n, i + 2))
			a[n - 1][i] = 1 - a[n - 1][i]
			a[n - 1][i + 1] = 1 - a[n - 1][i + 1]
			a[n - 2][i + 1] = 1 - a[n - 2][i + 1]
	p = [(n - 1, m - 1, n - 1, m, n, m), (n - 1, m - 1, n, m - 1, n, m), (n - 1, m, n, m - 1, n, m), (n - 1, m - 1, n - 1, m, n, m - 1)]
	ct = 0
	ap = []
	az = []
	if a[n - 2][m - 2] == 1:
		ct += 1
		ap += [n - 1, m - 1]
	else:
		az += [n - 1, m - 1]
	if a[n - 2][m - 1] == 1:
		ct += 1
		ap += [n - 1, m]
	else:
		az += [n - 1, m]
	if a[n - 1][m - 2] == 1:
		ct += 1
		ap += [n, m - 1]
	else:
		az += [n, m - 1]
	if a[n - 1][m - 1] == 1:
		ct += 1
		ap += [n, m]
	else:
		az += [n, m]
	if ct == 4:
		for i in p:
			res.append(i)
	elif ct == 3:
		res.append(ap)
	elif ct == 2:
		if a[n - 2][m - 2] == 1 and a[n - 2][m - 1] == 1:
			res.append((n, m - 1, n, m, n - 1, m - 1))
			res.append((n, m - 1, n, m, n - 1, m))
		elif a[n - 1][m - 2] == 1 and a[n - 1][m - 1] == 1:
			res.append((n - 1, m - 1, n - 1, m, n, m - 1))
			res.append((n - 1, m - 1, n - 1, m, n, m))
		elif a[n - 2][m - 2] == 1 and a[n - 1][m - 2] == 1:
			res.append((n - 1, m, n, m, n - 1, m - 1))
			res.append((n - 1, m, n, m, n, m - 1))
		elif a[n - 2][m - 1] == 1 and a[n - 1][m - 1] == 1:
			res.append((n - 1, m - 1, n, m - 1, n - 1, m))
			res.append((n - 1, m - 1, n, m - 1, n, m))
		elif a[n - 2][m - 2] == 1 and a[n - 1][m - 1] == 1:
			res.append((n - 1, m, n, m - 1, n - 1, m - 1))
			res.append((n - 1, m, n, m - 1, n, m))
		elif a[n - 2][m - 1] == 1 and a[n - 1][m - 2] == 1:
			res.append((n - 1, m - 1, n, m, n - 1, m))
			res.append((n - 1, m - 1, n, m, n, m - 1))
	elif ct == 1:
		if a[n - 2][m - 2] == 1:
			res.append((n - 1, m, n, m, n - 1, m - 1))
			a[n - 2][m - 1] = 1 - a[n - 2][m - 1]
			a[n - 1][m - 1] = 1 - a[n - 1][m - 1]
			a[n - 2][m - 2] = 1 - a[n - 2][m - 2]
		elif a[n - 2][m - 1] == 1:
			res.append((n - 1, m - 1, n - 1, m, n, m))
			a[n - 2][m - 2] = 1 - a[n - 2][m - 2]
			a[n - 2][m - 1] = 1 - a[n - 2][m - 1]
			a[n - 1][m - 1] = 1 - a[n - 1][m - 1]
		elif a[n - 1][m - 2] == 1:
			res.append((n - 1, m - 1, n, m, n, m - 1))
			a[n - 2][m - 2] = 1 - a[n - 2][m - 2]
			a[n - 1][m - 1] = 1 - a[n - 1][m - 1]
			a[n - 1][m - 2] = 1 - a[n - 1][m - 2]
		elif a[n - 1][m - 1] == 1:
			res.append((n, m - 1, n, m, n - 1, m - 1))
			a[n - 1][m - 2] = 1 - a[n - 1][m - 2]
			a[n - 1][m - 1] = 1 - a[n - 1][m - 1]
			a[n - 2][m - 2] = 1 - a[n - 2][m - 2]
		if a[n - 2][m - 2] == 1 and a[n - 2][m - 1] == 1:
			res.append((n, m - 1, n, m, n - 1, m - 1))
			res.append((n, m - 1, n, m, n - 1, m))
		elif a[n - 1][m - 2] == 1 and a[n - 1][m - 1] == 1:
			res.append((n - 1, m - 1, n - 1, m, n, m - 1))
			res.append((n - 1, m - 1, n - 1, m, n, m))
		elif a[n - 2][m - 2] == 1 and a[n - 1][m - 2] == 1:
			res.append((n - 1, m, n, m, n - 1, m - 1))
			res.append((n - 1, m, n, m, n, m - 1))
		elif a[n - 2][m - 1] == 1 and a[n - 1][m - 1] == 1:
			res.append((n - 1, m - 1, n, m - 1, n - 1, m))
			res.append((n - 1, m - 1, n, m - 1, n, m))
		elif a[n - 2][m - 2] == 1 and a[n - 1][m - 1] == 1:
			res.append((n - 1, m, n, m - 1, n - 1, m - 1))
			res.append((n - 1, m, n, m - 1, n, m))
		elif a[n - 2][m - 1] == 1 and a[n - 1][m - 2] == 1:
			res.append((n - 1, m - 1, n, m, n - 1, m))
			res.append((n - 1, m - 1, n, m, n, m - 1))
	print(len(res))
	for i in res:
		print(*i)


rn = lambda : int(input())
rns = lambda : map(int, input().split())
rl = lambda : list(map(int, input().split()))
rs = lambda : input()
yn = lambda x: print('Yes') if x else print('No')
YN = lambda x: print('YES') if x else print('NO')
pl = lambda l: print(' '.join(list(map(str, l))))
for _ in range(rn()):
	(n, m) = rns()
	l = []
	for i in range(n):
		l.append(rs())
	ans = 0
	for i in l:
		ans += i.count('1')
	ans *= 3
	print(ans)
	for i in range(n):
		for j in range(m):
			if l[i][j] == '1':
				a = [i + 1, j + 1]
				if i == n - 1:
					a.append(i)
				else:
					a.append(i + 2)
				if j == m - 1:
					a.append(j)
				else:
					a.append(j + 2)
				a += [a[0], a[3], a[2], a[1]]
				print(*[a[0], a[1], a[2], a[3], a[4], a[5]])
				print(*[a[0], a[1], a[2], a[3], a[6], a[7]])
				print(*[a[0], a[1], a[4], a[5], a[6], a[7]])


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
for j in range(int(input())):
	(n, m) = map(int, input().split())
	matr = []
	for s in range(n):
		string = [k for k in input()]
		matr.append(string)
	ans = []
	for s in range(n):
		for i in range(m):
			if matr[s][i] == '1':
				if s < n - 1 and i < m - 1:
					o1 = [(s + 1, i + 1), (s + 1, i + 2), (s + 2, i + 2)]
					o2 = [(s + 1, i + 2), (s + 2, i + 1), (s + 1, i + 1)]
					o3 = [(s + 2, i + 2), (s + 2, i + 1), (s + 1, i + 1)]
					ans += [o1, o2, o3]
				elif s == n - 1 and i == m - 1:
					p1 = [(s + 1, i + 1), (s + 1, i), (s, i)]
					p2 = [(s, i), (s, i + 1), (s + 1, i + 1)]
					p3 = [(s + 1, i), (s, i + 1), (s + 1, i + 1)]
					ans += [p1, p2, p3]
				elif s == n - 1:
					q1 = [(s + 1, i + 1), (s + 1, i + 2), (s, i + 2)]
					q2 = [(s + 1, i + 1), (s + 1, i + 2), (s, i + 1)]
					q3 = [(s + 1, i + 1), (s, i + 1), (s, i + 2)]
					ans += [q1, q2, q3]
				else:
					w1 = [(s + 1, i + 1), (s + 1, i), (s + 2, i)]
					w2 = [(s + 1, i + 1), (s + 1, i), (s + 2, i + 1)]
					w3 = [(s + 1, i + 1), (s + 2, i + 1), (s + 2, i)]
					ans += [w1, w2, w3]
	print(len(ans))
	for s in range(len(ans)):
		ops = ans[s]
		print(*ops[0], *ops[1], *ops[2])


import sys
import atexit
import io
import sys
_INPUT_LINES = sys.stdin.read().splitlines()
data = iter(_INPUT_LINES)

def input():
	return next(data)

def tprint(matrix):
	for row in matrix:
		print(*row)

def task_apply(matrix, op):
	for i in range(3):
		(y, x) = (op[2 * i], op[2 * i + 1])
		matrix[y][x] = 1 - matrix[y][x]
cache = [None] * 16

def sum_sq(matrix, i, j):
	return matrix[i][j] + matrix[i][j + 1] + matrix[i + 1][j] + matrix[i + 1][j + 1]

def get_k(matrix, i, j, k):
	indices = [(i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1)]
	indices.sort(key=lambda o: matrix[o[0]][o[1]])
	indices = indices[-k:] + indices[:3 - k]
	return indices[0] + indices[1] + indices[2]
solver = {4: 3, 3: 3, 2: 1, 1: 1}

def solve_square(matrix, i, j):
	s = sum_sq(matrix, i, j)
	ans = []
	while s != 0:
		op = get_k(matrix, i, j, solver[s])
		task_apply(matrix, op)
		ans.append(op)
		s = sum_sq(matrix, i, j)
	return ans

def solve(matrix):
	ans = []
	n = len(matrix)
	m = len(matrix[0])
	if n % 2 == 1:
		for j in range(m):
			if matrix[-1][j] == 1:
				if j != 0:
					op = (n - 1, j, n - 2, j - 1, n - 2, j)
				else:
					op = (n - 1, j, n - 2, j, n - 2, j + 1)
				task_apply(matrix, op)
				ans.append(op)
	if m % 2 == 1:
		for i in range(n):
			if matrix[i][-1] == 1:
				if i != 0:
					op = (i, m - 1, i - 1, m - 2, i, m - 2)
				else:
					op = (i, m - 1, i, m - 2, i + 1, m - 2)
				task_apply(matrix, op)
				ans.append(op)
	for i in range(0, n, 2):
		for j in range(0, m, 2):
			if i + 1 < n and j + 1 < m:
				ops = solve_square(matrix, i, j)
				ans.extend(ops)
	return ans
ans = []
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	matrix = []
	tprint(matrix)
	for _ in range(n):
		(*row,) = map(int, input())
		matrix.append(row)
	ans.append(solve(matrix))
output = []
for solution in ans:
	output.append(len(solution))
	output.append('\n'.join(('%s %s %s %s %s %s' % tuple((v + 1 for v in row)) for row in solution)))
print('\n'.join(map(str, output)))


for _ in range(int(input())):
	(r, c) = map(int, input().split())
	a = []
	b = []
	[a.append(list(input())) for i in range(r)]
	for i in range(r - 1):
		for j in range(c):
			if j == 0 and int(a[i][j]):
				a[i][j] = (int(a[i][j]) + 1) % 2
				a[i + 1][j] = (int(a[i + 1][j]) + 1) % 2
				a[i + 1][j + 1] = (int(a[i + 1][j + 1]) + 1) % 2
				b.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
			elif int(a[i][j]):
				a[i][j] = (int(a[i][j]) + 1) % 2
				a[i + 1][j] = (int(a[i + 1][j]) + 1) % 2
				a[i + 1][j - 1] = (int(a[i + 1][j - 1]) + 1) % 2
				b.append([i + 1, j + 1, i + 2, j + 1, i + 2, j])
	for j in range(c - 1):
		i = r - 1
		if int(a[-1][j]):
			b.append([i, j + 1, i + 1, j + 1, i + 1, j + 2])
			b.append([i, j + 1, i, j + 2, i + 1, j + 1])
			b.append([i + 1, j + 2, i + 1, j + 1, i, j + 2])
	if int(a[-1][-1]):
		i = r - 1
		j = c - 1
		b.append([i + 1, j + 1, i, j + 1, i + 1, j])
		b.append([i, j + 1, i + 1, j + 1, i, j])
		b.append([i + 1, j, i + 1, j + 1, i, j])
	print(len(b))
	for i in b:
		print(*i)


def read_ints():
	return list(map(int, input().split()))
d = {'0': '1', '1': '0'}

def change(rest, a, b, c):
	v = list(rest)
	for i in (a, b, c):
		v[i] = d[v[i]]
	return ''.join(v)

def get_moves(*args):
	result = []
	for i in args:
		result.extend([i % 2, i // 2])
	return [result]
d_rest = {'0000': []}
while len(d_rest) < 16:
	known = list(d_rest)
	for rest in known:
		new = change(rest, 0, 1, 2)
		if new not in d_rest:
			d_rest[new] = d_rest[rest] + get_moves(0, 1, 2)
		new = change(rest, 0, 1, 3)
		if new not in d_rest:
			d_rest[new] = d_rest[rest] + get_moves(0, 1, 3)
		new = change(rest, 0, 2, 3)
		if new not in d_rest:
			d_rest[new] = d_rest[rest] + get_moves(0, 2, 3)
		new = change(rest, 1, 2, 3)
		if new not in d_rest:
			d_rest[new] = d_rest[rest] + get_moves(1, 2, 3)

def remove_row(v):
	y = len(v) - 1
	row = v[-1]
	row1 = v[-2]
	result = []
	x = len(row) - 1
	while x > 0:
		if row[x] == '0':
			x -= 1
			continue
		if row[x - 1] == '1':
			result.append([x, y, x - 1, y, x, y - 1])
			row1[x] = d[row1[x]]
			x -= 2
			continue
		result.append([x, y, x, y - 1, x - 1, y - 1])
		row1[x] = d[row1[x]]
		row1[x - 1] = d[row1[x - 1]]
		x -= 2
	if x == 0 and row[0] == '1':
		result.append([0, y, 0, y - 1, 1, y - 1])
		row1[0] = d[row1[0]]
		row1[1] = d[row1[1]]
	del v[-1]
	return result

def remove_col(v):
	x = len(v[0]) - 1
	col = v[0][-1] + v[1][-1]
	del v[0][-1]
	del v[1][-1]
	if col == '00':
		return []
	if col == '01':
		v[0][-1] = d[v[0][-1]]
		v[1][-1] = d[v[1][-1]]
		return [[x, 1, x - 1, 0, x - 1, 1]]
	if col == '10':
		v[0][-1] = d[v[0][-1]]
		v[1][-1] = d[v[1][-1]]
		return [[x, 0, x - 1, 0, x - 1, 1]]
	v[0][-1] = d[v[0][-1]]
	return [[x, 0, x - 1, 0, x, 1]]
(t,) = read_ints()
for i in range(t):
	(n, m) = read_ints()
	values = [list(input()) for j in range(n)]
	moves = []
	while len(values) > 2:
		moves.extend(remove_row(values))
	while len(values[0]) > 2:
		moves.extend(remove_col(values))
	rest = ''.join(values[0] + values[1])
	moves.extend(d_rest[rest])
	print(len(moves))
	for (a, b, c, d0, e, f) in moves:
		print(*(b + 1, a + 1, d0 + 1, c + 1, f + 1, e + 1))


from os import path
import sys, time
from math import ceil, floor, gcd, log, log2, factorial, sqrt
from collections import defaultdict, Counter, OrderedDict, deque
from itertools import combinations, permutations
from bisect import *
from functools import reduce
from operator import mul
maxx = float('inf')
I = lambda : int(sys.stdin.buffer.readline())
lint = lambda : [int(x) for x in sys.stdin.buffer.readline().split()]
S = lambda : sys.stdin.readline().strip('\n')
grid = lambda r: [lint() for i in range(r)]
localsys = 0
start_time = time.time()
nCr = lambda n, r: reduce(mul, range(n - r + 1, n + 1), 1) // factorial(r)

def ceill(n, x):
	return (n + x - 1) // x
T = 1

def solve():
	ans = []
	(n, m) = map(int, input().split())
	arr = [S() for _ in range(n)]
	for i in range(n - 1):
		for j in range(m - 1):
			if arr[i][j] == '1':
				ans.append((i, j, i, j + 1, i + 1, j))
				ans.append((i, j, i + 1, j, i + 1, j + 1))
				ans.append((i, j, i, j + 1, i + 1, j + 1))
	for i in range(n - 1):
		if arr[i][m - 1] == '1':
			ans.append((i, m - 1, i, m - 2, i + 1, m - 1))
			ans.append((i, m - 1, i, m - 2, i + 1, m - 2))
			ans.append((i, m - 1, i + 1, m - 1, i + 1, m - 2))
	for i in range(m - 1):
		if arr[n - 1][i] == '1':
			ans.append((n - 1, i, n - 2, i, n - 1, i + 1))
			ans.append((n - 1, i, n - 1, i + 1, n - 2, i + 1))
			ans.append((n - 1, i, n - 2, i, n - 2, i + 1))
	if arr[n - 1][m - 1] == '1':
		ans.append((n - 1, m - 1, n - 2, m - 1, n - 1, m - 2))
		ans.append((n - 1, m - 1, n - 1, m - 2, n - 2, m - 2))
		ans.append((n - 1, m - 1, n - 2, m - 1, n - 2, m - 2))
	print(len(ans))
	s = [' '.join(map(lambda x: str(x + 1), i)) for i in ans]
	print(*s, sep='\n')

def run():
	if path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
run()
T = I() if T else 1
for _ in range(T):
	solve()
if localsys:
	print('\n\nTime Elased :', time.time() - start_time, 'seconds')


import sys
import bisect, string, math, time, functools, random, fractions
from heapq import heappush, heappop, heapify
from collections import deque, defaultdict, Counter
from itertools import permutations, combinations, groupby
rep = range
R = range

def Golf():
	(n, *t) = map(int, open(0).read().split())

def I():
	return int(input())

def S_():
	return input()

def IS():
	return input().split()

def LS():
	return [i for i in input().split()]

def MI():
	return map(int, input().split())

def LI():
	return [int(i) for i in input().split()]

def LI_():
	return [int(i) - 1 for i in input().split()]

def NI(n):
	return [int(input()) for i in range(n)]

def NI_(n):
	return [int(input()) - 1 for i in range(n)]

def NLI(n):
	return [[int(i) for i in input().split()] for i in range(n)]

def NLI_(n):
	return [[int(i) - 1 for i in input().split()] for i in range(n)]

def StoLI():
	return [ord(i) - 97 for i in input()]

def ItoS(n):
	return chr(n + 97)

def LtoS(ls):
	return ''.join([chr(i + 97) for i in ls])

def RA():
	return map(int, open(0).read().split())

def RLI(n=8, a=1, b=10):
	return [random.randint(a, b) for i in range(n)]

def RI(a=1, b=10):
	return random.randint(a, b)

def INP():
	N = 9
	n = random.randint(1, N)
	m = random.randint(1, n * n)
	A = [random.randint(1, n) for i in range(m)]
	B = [random.randint(1, n) for i in range(m)]
	G = [[] for i in range(n)]
	RG = [[] for i in range(n)]
	for i in range(m):
		(a, b) = (A[i] - 1, B[i] - 1)
		if a == b:
			continue
		G[a] += ((b, 1),)
		RG[b] += ((a, 1),)
	return (n, m, G, RG)

def Rtest(T):
	(case, err) = (0, 0)
	for i in range(T):
		inp = INP()
		a1 = naive(*inp)
		a2 = solve(*inp)
		if a1 == a2:
			print(inp)
			print('naive', a1)
			print('solve', a2)
			err += 1
		case += 1
	print('Tested', case, 'case with', err, 'errors')

def GI(V, E, ls=None, Directed=False, index=1):
	org_inp = []
	g = [[] for i in range(V)]
	FromStdin = True if ls == None else False
	for i in range(E):
		if FromStdin:
			inp = LI()
			org_inp.append(inp)
		else:
			inp = ls[i]
		if len(inp) == 2:
			(a, b) = inp
			c = 1
		else:
			(a, b, c) = inp
		if index == 1:
			a -= 1
			b -= 1
		aa = (a, c)
		bb = (b, c)
		g[a].append(bb)
		if not Directed:
			g[b].append(aa)
	return (g, org_inp)

def GGI(h, w, search=None, replacement_of_found='.', mp_def={'#': 1, '.': 0}, boundary=1):
	mp = [boundary] * (w + 2)
	found = {}
	for i in R(h):
		s = input()
		for char in search:
			if char in s:
				found[char] = (i + 1) * (w + 2) + s.index(char) + 1
				mp_def[char] = mp_def[replacement_of_found]
		mp += [boundary] + [mp_def[j] for j in s] + [boundary]
	mp += [boundary] * (w + 2)
	return (h + 2, w + 2, mp, found)

def TI(n):
	return GI(n, n - 1)

def accum(ls):
	rt = [0]
	for i in ls:
		rt += [rt[-1] + i]
	return rt

def bit_combination(n, base=2):
	rt = []
	for tb in R(base ** n):
		s = [tb // base ** bt % base for bt in R(n)]
		rt += [s]
	return rt

def gcd(x, y):
	if y == 0:
		return x
	if x % y == 0:
		return y
	while x % y != 0:
		(x, y) = (y, x % y)
	return y

def YN(x):
	print(['NO', 'YES'][x])

def Yn(x):
	print(['No', 'Yes'][x])

def show(*inp, end='\n'):
	if show_flg:
		print(*inp, end=end)
mo = 10 ** 9 + 7
inf = float('inf')
FourNb = [(-1, 0), (1, 0), (0, 1), (0, -1)]
EightNb = [(-1, 0), (1, 0), (0, 1), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)]
compas = dict(zip('WENS', FourNb))
cursol = dict(zip('LRUD', FourNb))
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
input = lambda : sys.stdin.readline().rstrip()

class Comb:

	def __init__(self, n, mo=10 ** 9 + 7):
		self.fac = [0] * (n + 1)
		self.inv = [1] * (n + 1)
		self.fac[0] = 1
		self.fact(n)
		for i in range(1, n + 1):
			self.fac[i] = i * self.fac[i - 1] % mo
			self.inv[n] *= i
			self.inv[n] %= mo
		self.inv[n] = pow(self.inv[n], mo - 2, mo)
		for i in range(1, n):
			self.inv[n - i] = self.inv[n - i + 1] * (n - i + 1) % mo
		return

	def fact(self, n):
		return self.fac[n]

	def invf(self, n):
		return self.inv[n]

	def comb(self, x, y):
		if y < 0 or y > x:
			return 0
		return self.fac[x] * self.inv[x - y] * self.inv[y] % mo
show_flg = False
show_flg = True
ans = 0

def solve(n, m, mp):
	cnt = 0
	rt = []
	for i in range(n - 2):
		for j in range(m):
			if mp[i][j] == 1:
				ans = [i, j, i + 1, j, i + 1, j + (-1 if j == m - 1 else 1)]
				rt += ans
				cnt += 1
				while ans:
					w = ans.pop()
					h = ans.pop()
					mp[h][w] = 1 - mp[h][w]
	for j in range(m - 2):
		if mp[n - 2][j] == 1 and mp[n - 1][j] == 1:
			ans = [n - 2, j, n - 1, j, n - 1, j + 1]
			rt += ans
			while ans:
				w = ans.pop()
				h = ans.pop()
				mp[h][w] = 1 - mp[h][w]
			cnt += 1
		elif mp[n - 2][j] == 1 and mp[n - 1][j] == 0:
			ans = [n - 2, j, n - 1, j + 1, n - 2, j + 1]
			rt += ans
			while ans:
				w = ans.pop()
				h = ans.pop()
				mp[h][w] = 1 - mp[h][w]
			cnt += 1
		elif mp[n - 2][j] == 0 and mp[n - 1][j] == 1:
			ans = [n - 2, j + 1, n - 1, j, n - 1, j + 1]
			rt += ans
			while ans:
				w = ans.pop()
				h = ans.pop()
				mp[h][w] = 1 - mp[h][w]
			cnt += 1
	lst = [[mp[i][j] for j in range(m - 2, m)] for i in range(n - 2, n)]
	lst2 = lst[0] + lst[1]
	ans = []
	if sum(lst2) == 4:
		ans = [n - 1, m - 1, n - 1, m - 2, n - 2, m - 1]
		rt += ans
		while ans:
			w = ans.pop()
			h = ans.pop()
			mp[h][w] = 1 - mp[h][w]
		lst = [[mp[i][j] for j in range(m - 2, m)] for i in range(n - 2, n)]
		lst2 = lst[0] + lst[1]
	if sum(lst2) == 0:
		pass
	elif sum(lst2) == 3:
		for i in range(n - 2, n):
			for j in range(m - 2, m):
				if mp[i][j] == 1:
					ans += [i, j]
		rt += ans
		while ans:
			w = ans.pop()
			h = ans.pop()
			mp[h][w] = 1 - mp[h][w]
		cnt += 1
	elif sum(lst2) <= 2:
		zero = []
		one = []
		for i in range(n - 2, n):
			for j in range(m - 2, m):
				if mp[i][j] == 0:
					zero += [i, j]
				else:
					one += [i, j]
		ans = zero[:4] + one[:2]
		rt += ans
		cnt += 1
		while ans:
			w = ans.pop()
			h = ans.pop()
			mp[h][w] = 1 - mp[h][w]
		if len(one) == 4:
			ans = zero[:4] + one[2:]
			rt += ans
			cnt += 1
			while ans:
				w = ans.pop()
				h = ans.pop()
				mp[h][w] = 1 - mp[h][w]
		else:
			zero = []
			one = []
			for i in range(n - 2, n):
				for j in range(m - 2, m):
					if mp[i][j] == 0:
						zero += [i, j]
					else:
						one += [i, j]
			ans = zero[:4] + one[:2]
			rt += ans
			cnt += 1
			while ans:
				w = ans.pop()
				h = ans.pop()
				mp[h][w] = 1 - mp[h][w]
			ans = zero[:4] + one[2:]
			rt += ans
			cnt += 1
			while ans:
				w = ans.pop()
				h = ans.pop()
				mp[h][w] = 1 - mp[h][w]
	return [rr + 1 for rr in rt]

def check(n, m, mp, rt):
	nn = len(rt) // 6
	ch = [i[:] for i in mp]
	for i in range(nn):
		(x, y, s, t, u, v) = [w - 1 for w in rt[i * 6:(i + 1) * 6]]
		if 0 <= x < n and 0 <= s < n and (0 <= u < n) and (0 <= y < m) and (0 <= t < m) and (0 <= v < m):
			pass
		else:
			return (False, 'not in area')
		if max(x, s, u) - min(x, s, u) > 1:
			return (False, 'not in square')
		if max(y, t, v) - min(y, t, v) > 1:
			return (False, 'not in square')
		if len(set([(x, y), (s, t), (u, v)])) < 3:
			return (False, 'same points')
		ch[x][y] = 1 - ch[x][y]
		ch[s][t] = 1 - ch[s][t]
		ch[u][v] = 1 - ch[u][v]
	tmp = 0
	for i in ch:
		tmp += sum(i)
	if tmp != 0:
		return (False, 'not 0', ch)
	return (True, 'ok', ch)

def sm(mp):
	show('-----------')
	for i in mp:
		show(*i)
T = I()
for _ in range(T):
	(n, m) = LI()
	mp = []
	for i in range(n):
		mp += ([int(i) for i in input()],)
	rt = solve(n, m, mp)
	nn = len(rt) // 6
	print(nn)
	for i in range(nn):
		print(*rt[i * 6:(i + 1) * 6])


import io, os
from math import *

def move(i, j, n, m):
	if i < n - 1 and j < m - 1:
		return [(i + 1, j + 1, i + 2, j + 1, i + 1, j + 2), (i + 1, j + 1, i + 2, j + 1, i + 2, j + 2), (i + 1, j + 1, i + 2, j + 2, i + 1, j + 2)]
	elif i > 0 and j > 0:
		return [(i + 1, j + 1, i + 1, j, i, j + 1), (i, j, i + 1, j, i + 1, j + 1), (i, j, i + 1, j + 1, i, j + 1)]
	elif i == 0 and j == m - 1:
		return [(i + 1, j + 1, i + 2, j + 1, i + 2, j), (i + 1, j + 1, i + 1, j, i + 2, j), (i + 1, j + 1, i + 2, j + 1, i + 1, j)]
	else:
		return [(i + 1, j + 1, i, j + 1, i + 1, j + 2), (i + 1, j + 1, i + 1, j + 2, i, j + 2), (i + 1, j + 1, i, j + 1, i, j + 2)]

def main():
	t = int(input())
	for _ in range(t):
		(n, m) = list(map(int, input().split()))
		a = [input() for _ in range(n)]
		moves = []
		for i in range(n):
			for j in range(m):
				if a[i][j] == '1':
					moves.append(move(i, j, n, m))
		print(len(moves) * 3)
		for i in range(len(moves)):
			for m in moves[i]:
				print(str(m).replace(',', '').replace('(', '').replace(')', ''))
main()


def f(c):
	if c == '1':
		return '0'
	return '1'
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	arr = [list(input()) for i in range(n)]

	def do(x):
		res.append(x)
		arr[x[0] - 1][x[1] - 1] = f(arr[x[0] - 1][x[1] - 1])
		arr[x[2] - 1][x[3] - 1] = f(arr[x[2] - 1][x[3] - 1])
		arr[x[4] - 1][x[5] - 1] = f(arr[x[4] - 1][x[5] - 1])
	res = []
	if n % 2 == 1:
		for j in range(m - 1):
			if arr[n - 1][j] == '0':
				continue
			do((n, j + 1, n - 1, j + 1, n - 1, j + 2))
		if arr[n - 1][m - 1] == '1':
			do((n, m, n - 1, m, n - 1, m - 1))
		n -= 1
	if m % 2 == 1:
		for i in range(n - 1):
			if arr[i][m - 1] == '0':
				continue
			do((i + 1, m, i + 1, m - 1, i + 2, m - 1))
		if arr[n - 1][m - 1] == '1':
			do((n, m, n, m - 1, n - 1, m - 1))
		m -= 1
	for i in range(0, n, 2):
		for j in range(0, m, 2):
			a = [arr[i][j], arr[i + 1][j], arr[i][j + 1], arr[i + 1][j + 1]]
			if a.count('0') == 4:
				continue
			if a.count('1') == 4:
				do((i + 1, j + 1, i + 2, j + 1, i + 1, j + 2))
				do((i + 2, j + 2, i + 2, j + 1, i + 1, j + 2))
				do((i + 1, j + 1, i + 2, j + 2, i + 1, j + 2))
				do((i + 1, j + 1, i + 2, j + 1, i + 2, j + 2))
				continue
			if a.count('1') == 2:
				do((i + 1, j + 1, i + 2, j + 1, i + 1, j + 2))
				a = [arr[i][j], arr[i + 1][j], arr[i][j + 1], arr[i + 1][j + 1]]
			if a.count('1') == 3:
				if arr[i][j] == '0':
					do((i + 1, j + 2, i + 2, j + 1, i + 2, j + 2))
				elif arr[i + 1][j] == '0':
					do((i + 1, j + 2, i + 1, j + 1, i + 2, j + 2))
				elif arr[i][j + 1] == '0':
					do((i + 1, j + 1, i + 2, j + 1, i + 2, j + 2))
				elif arr[i + 1][j + 1] == '0':
					do((i + 1, j + 2, i + 2, j + 1, i + 1, j + 1))
			if a.count('1') == 1:
				if arr[i][j] == '1':
					do((i + 1, j + 2, i + 2, j + 1, i + 1, j + 1))
					do((i + 1, j + 2, i + 1, j + 1, i + 2, j + 2))
					do((i + 1, j + 1, i + 2, j + 1, i + 2, j + 2))
				elif arr[i + 1][j + 1] == '1':
					do((i + 1, j + 2, i + 2, j + 1, i + 2, j + 2))
					do((i + 1, j + 2, i + 1, j + 1, i + 2, j + 2))
					do((i + 1, j + 1, i + 2, j + 1, i + 2, j + 2))
				elif arr[i + 1][j] == '1':
					do((i + 1, j + 1, i + 2, j + 1, i + 2, j + 2))
					do((i + 1, j + 2, i + 2, j + 1, i + 2, j + 2))
					do((i + 1, j + 2, i + 2, j + 1, i + 1, j + 1))
				elif arr[i][j + 1] == '1':
					do((i + 1, j + 2, i + 1, j + 1, i + 2, j + 2))
					do((i + 1, j + 2, i + 2, j + 1, i + 2, j + 2))
					do((i + 1, j + 2, i + 2, j + 1, i + 1, j + 1))
	print(len(res))
	for e in res:
		print(*e)


import sys
input = sys.stdin.readline
t = int(input())
for case in range(t):
	(n, m) = [int(x) for x in input().split(' ')]
	grid = [input() for i in range(n)]
	ans = []
	for i in range(n):
		for j in range(m):
			if grid[i][j] != '0':
				x = (i + 1, j + 1)
				if i == n - 1 and j == m - 1:
					options = [(n - 1, m - 1), (n, m - 1), (n - 1, m)]
				elif i == n - 1:
					options = [(n - 1, j + 2), (n - 1, j + 1), (n, j + 2)]
				elif j == m - 1:
					options = [(i + 2, m), (i + 1, m - 1), (i + 2, m - 1)]
				else:
					options = [(i + 2, j + 1), (i + 2, j + 2), (i + 1, j + 2)]
				for z in options:
					u = [y for y in options if y != z]
					ans.append([x[0], x[1], u[0][0], u[0][1], u[1][0], u[1][1]])
	print(len(ans))
	for row in ans:
		print(*row)


import sys
from itertools import permutations
from itertools import combinations
from itertools import combinations_with_replacement

def makeThree(mat, i, j, liAns):
	liToAdd = []
	if mat[i][j] == 1:
		liToAdd.append(i)
		liToAdd.append(j)
		mat[i][j] = 0
	if mat[i + 1][j] == 1:
		liToAdd.append(i + 1)
		liToAdd.append(j)
		mat[i + 1][j] = 0
	if mat[i][j + 1] == 1:
		liToAdd.append(i)
		liToAdd.append(j + 1)
		mat[i][j + 1] = 0
	if mat[i + 1][j + 1] == 1:
		liToAdd.append(i + 1)
		liToAdd.append(j + 1)
		mat[i + 1][j + 1] = 0
	liAns.append(liToAdd)

def makeTwo(mat, i, j, liAns):
	liToAdd = []
	liAllCoord = [(i, j), (i + 1, j), (i, j + 1), (i + 1, j + 1)]
	flag = 0
	for coord in liAllCoord:
		if mat[coord[0]][coord[1]] == 1 and flag == 0:
			flag = 1
			liToAdd.append(coord[0])
			liToAdd.append(coord[1])
		if mat[coord[0]][coord[1]] == 0:
			liToAdd.append(coord[0])
			liToAdd.append(coord[1])
	a = 0
	while a < 6:
		initial = mat[liToAdd[a]][liToAdd[a + 1]]
		if initial == 1:
			mat[liToAdd[a]][liToAdd[a + 1]] = 0
		else:
			mat[liToAdd[a]][liToAdd[a + 1]] = 1
		a += 2
	liAns.append(liToAdd)
	makeThree(mat, i, j, liAns)

def makeOne(mat, i, j, liAns):
	liToAdd = []
	liAllCoord = [(i, j), (i + 1, j), (i, j + 1), (i + 1, j + 1)]
	ctr = 0
	for coord in liAllCoord:
		if mat[coord[0]][coord[1]] == 1:
			liToAdd.append(coord[0])
			liToAdd.append(coord[1])
		if mat[coord[0]][coord[1]] == 0 and ctr < 2:
			ctr += 1
			liToAdd.append(coord[0])
			liToAdd.append(coord[1])
	a = 0
	while a < 6:
		initial = mat[liToAdd[a]][liToAdd[a + 1]]
		if initial == 1:
			mat[liToAdd[a]][liToAdd[a + 1]] = 0
		else:
			mat[liToAdd[a]][liToAdd[a + 1]] = 1
		a += 2
	liAns.append(liToAdd)
	makeTwo(mat, i, j, liAns)

def makeFour(mat, i, j, liAns):
	liAllCoord = [(i, j), (i + 1, j), (i, j + 1), (i + 1, j + 1)]
	ctr = 0
	liToAdd = []
	for coord in liAllCoord:
		if ctr >= 3:
			break
		ctr += 1
		liToAdd.append(coord[0])
		liToAdd.append(coord[1])
		mat[coord[0]][coord[1]] = 0
	liAns.append(liToAdd)
	makeOne(mat, i, j, liAns)
for _ in range(int(input())):
	liStr = input().split()
	p = int(liStr[0])
	q = int(liStr[1])
	mat = []
	for _ in range(0, p):
		liStr = list(input())
		li = []
		for i in liStr:
			li.append(int(i))
		mat.append(li)
	liAns = []
	i = 0
	while i < p:
		j = 0
		while j < q:
			if i == p - 1:
				i = i - 1
			if j == q - 1:
				j = j - 1
			ctr = 0
			if mat[i][j] == 1:
				ctr += 1
			if mat[i + 1][j] == 1:
				ctr += 1
			if mat[i][j + 1] == 1:
				ctr += 1
			if mat[i + 1][j + 1] == 1:
				ctr += 1
			if ctr == 1:
				makeOne(mat, i, j, liAns)
			if ctr == 2:
				makeTwo(mat, i, j, liAns)
			if ctr == 3:
				makeThree(mat, i, j, liAns)
			if ctr == 4:
				makeFour(mat, i, j, liAns)
			j += 2
		i += 2
	print(len(liAns))
	for sixNum in liAns:
		for a in sixNum:
			print(a + 1, end=' ')
		print()


import sys
try:
	(sys.stdin, sys.stdout) = (open('in.txt', 'r'), open('out.txt', 'w'))
except:
	pass
ii1 = lambda : int(sys.stdin.readline().strip())
is1 = lambda : sys.stdin.readline().strip()
iia = lambda : list(map(int, sys.stdin.readline().strip().split()))
isa = lambda : sys.stdin.readline().strip().split()
from collections import Counter
from math import *
from random import sample, shuffle

def fun(p, n, m):
	Res = []
	for i in range(1, n - 1):
		for j in range(1, m):
			if p[i][j] == '0' and p[i][j + 1] == '0':
				continue
			V = []
			if p[i][j] == '1':
				V.append([i, j])
			if p[i][j + 1] == '1':
				V.append([i, j + 1])
			for k in range(j, j + 2):
				if len(V) < 3:
					V.append([i + 1, k])
			Res.append(V)
			for (x, y) in V:
				if p[x][y] == '1':
					p[x][y] = '0'
				else:
					p[x][y] = '1'
	for j in range(1, m):
		if p[n][j] == '0' and p[n - 1][j] == '0':
			continue
		V = []
		if p[n][j] == '1':
			V.append([n, j])
		if p[n - 1][j] == '1':
			V.append([n - 1, j])
		for k in range(n - 1, n + 1):
			if len(V) < 3:
				V.append([k, j + 1])
		Res.append(V)
		for (x, y) in V:
			if p[x][y] == '1':
				p[x][y] = '0'
			else:
				p[x][y] = '1'
	if p[n - 1][m] == '1' and p[n][m] == '0':
		V = []
		V.append([n - 1, m])
		V.append([n, m])
		V.append([n - 1, m - 1])
		Res.append(V)
		V = []
		V.append([n - 1, m - 1])
		V.append([n - 1, m])
		V.append([n, m - 1])
		Res.append(V)
		V = []
		V.append([n - 1, m])
		V.append([n, m - 1])
		V.append([n, m])
		Res.append(V)
	elif p[n - 1][m] == '0' and p[n][m] == '1':
		V = []
		V.append([n - 1, m])
		V.append([n, m])
		V.append([n - 1, m - 1])
		Res.append(V)
		V = []
		V.append([n - 1, m - 1])
		V.append([n, m])
		V.append([n, m - 1])
		Res.append(V)
		V = []
		V.append([n, m])
		V.append([n, m - 1])
		V.append([n - 1, m])
		Res.append(V)
	elif p[n - 1][m] == '1' and p[n][m] == '1':
		V = []
		V.append([n - 1, m - 1])
		V.append([n - 1, m])
		V.append([n, m - 1])
		Res.append(V)
		V = []
		V.append([n - 1, m - 1])
		V.append([n, m - 1])
		V.append([n, m])
		Res.append(V)
	print(len(Res))
	for i in range(len(Res)):
		for (x, y) in Res[i]:
			print(x, y, end=' ')
		print()
for _ in range(ii1()):
	(n, m) = iia()
	s = [[]]
	for i in range(n):
		a = [' '] + list(is1())
		s.append(a)
	fun(s, n, m)


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	l = list()
	for i in range(n):
		l.append(input())
	ans = list()
	for i in range(n):
		for j in range(m):
			if l[i][j] == '1':
				if i != n - 1 and j != m - 1:
					ans.append((i, j, i + 1, j, i + 1, j + 1))
					ans.append((i, j, i, j + 1, i + 1, j + 1))
					ans.append((i, j, i + 1, j, i, j + 1))
				elif i == n - 1 and j != m - 1:
					ans.append((i, j, i, j + 1, i - 1, j + 1))
					ans.append((i, j, i - 1, j, i - 1, j + 1))
					ans.append((i, j, i - 1, j, i, j + 1))
				elif i != n - 1 and j == m - 1:
					ans.append((i, j, i, j - 1, i + 1, j - 1))
					ans.append((i, j, i + 1, j, i + 1, j - 1))
					ans.append((i, j, i, j - 1, i + 1, j))
				else:
					ans.append((i, j, i, j - 1, i - 1, j - 1))
					ans.append((i, j, i - 1, j, i - 1, j - 1))
					ans.append((i, j, i, j - 1, i - 1, j))
	print(len(ans))
	for i in range(len(ans)):
		for j in range(6):
			print(ans[i][j] + 1, end=' ')
		print()


import sys
sys.setrecursionlimit(10 ** 5)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.buffer.readline())

def MI():
	return map(int, sys.stdin.buffer.readline().split())

def LI():
	return list(map(int, sys.stdin.buffer.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def BI():
	return sys.stdin.buffer.readline().rstrip()

def SI():
	return sys.stdin.buffer.readline().rstrip().decode()

def flip(i, j):
	res = []
	if j == w - 1:
		j -= 1
	cnt = 3
	if aa[i][j]:
		aa[i][j] ^= 1
		cnt -= 1
		res += [i + 1, j + 1]
	if aa[i][j + 1]:
		aa[i][j + 1] ^= 1
		cnt -= 1
		res += [i + 1, j + 2]
	if cnt == 2 or aa[i + 1][j]:
		aa[i + 1][j] ^= 1
		cnt -= 1
		res += [i + 2, j + 1]
	if cnt:
		aa[i + 1][j + 1] ^= 1
		cnt -= 1
		res += [i + 2, j + 2]
	return res

def right(i, j):
	res = []
	cnt = 3
	if aa[i][j]:
		aa[i][j] ^= 1
		cnt -= 1
		res += [i + 1, j + 1]
	if aa[i + 1][j]:
		aa[i + 1][j] ^= 1
		cnt -= 1
		res += [i + 2, j + 1]
	if cnt == 2 or aa[i][j + 1]:
		aa[i][j + 1] ^= 1
		cnt -= 1
		res += [i + 1, j + 2]
	if cnt:
		aa[i + 1][j + 1] ^= 1
		res += [i + 2, j + 2]
	return res

def zero(sj):
	ij1 = []
	ij0 = []
	res = []
	for i in range(h - 2, h):
		for j in range(sj, sj + 2):
			if aa[i][j]:
				ij1.append((i, j))
			else:
				ij0.append((i, j))
	if len(ij1) == 3:
		for (i, j) in ij1:
			aa[i][j] ^= 1
			res += [i + 1, j + 1]
	elif len(ij1) == 2:
		(i, j) = ij1[0]
		aa[i][j] ^= 1
		res += [i + 1, j + 1]
		for (i, j) in ij0:
			aa[i][j] ^= 1
			res += [i + 1, j + 1]
	else:
		(i, j) = ij1[0]
		aa[i][j] ^= 1
		res += [i + 1, j + 1]
		for (i, j) in ij0[:2]:
			aa[i][j] ^= 1
			res += [i + 1, j + 1]
	return res
for _ in range(II()):
	(h, w) = MI()
	aa = [[int(c) for c in SI()] for _ in range(h)]
	ans = []
	for i in range(h - 2):
		for j in range(w):
			if aa[i][j]:
				ans.append(flip(i, j))
	for j in range(w - 1):
		if aa[h - 2][j] + aa[h - 1][j]:
			ans.append(right(h - 2, j))
	while aa[h - 2][w - 2] + aa[h - 2][w - 1] + aa[h - 1][w - 2] + aa[h - 1][w - 1]:
		ans.append(zero(w - 2))
	print(len(ans))
	for row in ans:
		print(*row)


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = []
	for i in range(n):
		a.append(list(map(int, input().rstrip())))
	b = []
	for i in range(n - 1):
		for j in range(m):
			if j != m - 1:
				if a[i][j] == 1:
					b.extend([[i, j], [i + 1, j], [i + 1, j + 1]])
					a[i][j] = int(not a[i][j])
					a[i + 1][j] = int(not a[i + 1][j])
					a[i + 1][j + 1] = int(not a[i + 1][j + 1])
			elif a[i][j] == 1:
				b.extend([[i, j], [i + 1, j], [i + 1, j - 1]])
				a[i][j] = int(not a[i][j])
				a[i + 1][j] = int(not a[i + 1][j])
				a[i + 1][j - 1] = int(not a[i + 1][j - 1])
	i = n - 1
	x = 0
	for j in range(m - 2):
		if a[i][j] == 1 or a[i - 1][j] == 1:
			if a[i][j] == 1 and a[i - 1][j] == 1:
				b.extend([[i, j], [i - 1, j]])
				a[i][j] = int(not a[i][j])
				a[i - 1][j] = int(not a[i - 1][j])
			elif a[i][j] == 1:
				b.extend([[i, j], [i - 1, j + 1]])
				a[i][j] = int(not a[i][j])
				a[i - 1][j + 1] = int(not a[i - 1][j + 1])
			else:
				b.extend([[i - 1, j], [i - 1, j + 1]])
				a[i - 1][j] = int(not a[i - 1][j])
				a[i - 1][j + 1] = int(not a[i - 1][j + 1])
			b.append([i, j + 1])
			a[i][j + 1] = int(not a[i][j + 1])
			x += 1
	z = (a[-1][-1] == 0) + (a[-1][-2] == 0) + (a[-2][-1] == 0) + (a[-2][-2] == 0)
	f = 0
	if z == 3 and len(b) // 3 == n * m - 2:
		f = 1
		b[-3 * (x + 2)] = [-1, -1]
		a[-2][-2] = int(not a[-2][-2])
		a[-1][-2] = int(not a[-1][-2])
		a[-1][-1] = int(not a[-1][-1])
	z = (a[-1][-1] == 0) + (a[-1][-2] == 0) + (a[-2][-1] == 0) + (a[-2][-2] == 0)
	if z == 1:
		b.extend([[n - 1, m - 1], [n - 1, m - 2], [n - 2, m - 2]])
	elif z == 2 or z == 3:
		if z == 3:
			a[n - 1][m - 2] = int(not a[n - 1][m - 2])
			a[n - 1][m - 1] = int(not a[n - 1][m - 1])
			a[n - 2][m - 2] = int(not a[n - 2][m - 2])
			b.extend([[n - 2, m - 2], [n - 1, m - 2], [n - 1, m - 1]])
		if a[-2][-2] == 0:
			b.extend([[n - 2, m - 2], [n - 2, m - 1], [n - 1, m - 2], [n - 1, m - 1], [n - 2, m - 2], [n - 2, m - 1]])
		elif a[-1][-2] == 0:
			b.extend([[n - 2, m - 2], [n - 1, m - 2], [n - 2, m - 1], [n - 1, m - 1], [n - 1, m - 2], [n - 2, m - 1]])
		elif a[-1][-1] == 0:
			b.extend([[n - 2, m - 1], [n - 1, m - 1], [n - 2, m - 2], [n - 1, m - 1], [n - 2, m - 1], [n - 1, m - 2]])
	print(len(b) // 3 - f)
	for i in range(0, len(b), 3):
		if b[i][0] != -1:
			print(b[i][0] + 1, b[i][1] + 1, b[i + 1][0] + 1, b[i + 1][1] + 1, b[i + 2][0] + 1, b[i + 2][1] + 1)


t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	s = []
	for _ in range(n):
		s.append(list(input()))
	o = []

	def R(x):
		global s
		for z in x:
			if s[z[0]][z[1]] == '1':
				s[z[0]][z[1]] = '0'
			else:
				s[z[0]][z[1]] = '1'
	for x in range(n - 2):
		for y in range(m - 1):
			a = []
			if s[x][y] == '1':
				a.append((x, y))
			if s[x][y + 1] == '1':
				a.append((x, y + 1))
			if not a:
				continue
			if (x + 1, y + 1) not in a and len(a) < 3:
				a.append((x + 1, y + 1))
			if (x + 1, y) not in a and len(a) < 3:
				a.append((x + 1, y))
			o.append(a)
			R(a)
	for y in range(m - 2):
		x = n - 2
		a = []
		if s[x][y] == '1':
			a.append((x, y))
		if s[x + 1][y] == '1':
			a.append((x + 1, y))
		if not a:
			continue
		if (x + 1, y + 1) not in a and len(a) < 3:
			a.append((x + 1, y + 1))
		if (x, y + 1) not in a and len(a) < 3:
			a.append((x, y + 1))
		o.append(a)
		R(a)
	A = ((n - 2, m - 2), (n - 1, m - 2), (n - 2, m - 1), (n - 1, m - 1))
	while True:
		z = []
		for x in A:
			if s[x[0]][x[1]] == '1':
				z.append(x)
		if len(z) > 0:
			z1 = z[:]
			if len(z) == 4:
				z1 = z1[:3]
			elif len(z) == 2:
				z1 = [z1[0]]
			for r in A:
				if len(z1) < 3 and r not in z:
					z1.append(r)
			o.append(z1)
			R(z1)
		else:
			break
	print(len(o))
	for b in o:
		print(b[0][0] + 1, b[0][1] + 1, b[1][0] + 1, b[1][1] + 1, b[2][0] + 1, b[2][1] + 1)


import math

def I():
	return input()

def II():
	return int(I())

def M():
	return map(int, I().split())

def L():
	return list(M())

def P(a):
	print(a)
for _ in range(II()):
	(n, m) = M()
	a = []
	for i in range(n):
		a.append(I())
	k = 0
	s = [0, 3, 2, 1, 4]

	def ans(a, i, j, n, m, step):
		one = []
		zero = []

		def val(i, j):
			ans = int(a[i][j])
			if ans == 1:
				one.append((i, j))
			else:
				zero.append((i, j))
			return ans
		c = val(i, j)
		if i != n - 1:
			c += val(i + 1, j)
			if j != m - 1:
				c += val(i + 1, j + 1) + val(i, j + 1)
			else:
				zero.append((i, j - 1))
				zero.append((i + 1, j - 1))
		else:
			zero.append((i - 1, j))
			if j != m - 1:
				c += val(i, j + 1)
				zero.append((i - 1, j + 1))
			else:
				zero.append((i - 1, j - 1))
				zero.append((i, j - 1))

		def steps():
			if len(one) == 0:
				return
			elif len(one) == 3:
				for i in one:
					step.append(i)
			elif len(one) == 2 or len(one) == 1:
				for i in range(2):
					step.append(zero[0])
					one.append(zero.pop(0))
				step.append(one[0])
				zero.append(one.pop(0))
				steps()
			else:
				for i in range(3):
					step.append(one[0])
					zero.append(one.pop(0))
				steps()
		steps()
		return c
	step = []
	for i in range(0, n, 2):
		for j in range(0, m, 2):
			c = ans(a, i, j, n, m, step)
			k += s[c]
	print(k)
	for i in range(0, len(step), 3):
		for k in range(3):
			print(step[i + k][0] + 1, step[i + k][1] + 1, end=' ')
		print('')


import sys
input = sys.stdin.readline
t = int(input())
for tests in range(t):
	(n, m) = map(int, input().split())
	A = [list(map(int, list(input().strip()))) for i in range(n)]
	ANS = []
	for i in range(n - 2):
		for j in range(m - 1):
			if A[i][j] == 1 and A[i][j + 1] == 1:
				ANS.append((i + 1, j + 1, i + 1, j + 2, i + 2, j + 2))
				A[i][j] ^= 1
				A[i][j + 1] ^= 1
				A[i + 1][j + 1] ^= 1
			elif A[i][j] == 1 and A[i][j + 1] == 0:
				ANS.append((i + 1, j + 1, i + 2, j + 1, i + 2, j + 2))
				A[i][j] ^= 1
				A[i + 1][j] ^= 1
				A[i + 1][j + 1] ^= 1
			elif j == m - 2 and A[i][j] == 0 and (A[i][j + 1] == 1):
				ANS.append((i + 1, j + 2, i + 2, j + 1, i + 2, j + 2))
				A[i][j + 1] ^= 1
				A[i + 1][j] ^= 1
				A[i + 1][j + 1] ^= 1
	for j in range(m - 2):
		if A[n - 2][j] == 1 and A[n - 1][j] == 1:
			ANS.append((n - 1, j + 1, n, j + 1, n - 1, j + 2))
			A[n - 2][j] ^= 1
			A[n - 1][j] ^= 1
			A[n - 2][j + 1] ^= 1
		elif A[n - 2][j] == 1 and A[n - 1][j] == 0:
			ANS.append((n - 1, j + 1, n - 1, j + 2, n, j + 2))
			A[n - 2][j] ^= 1
			A[n - 2][j + 1] ^= 1
			A[n - 1][j + 1] ^= 1
		elif A[n - 2][j] == 0 and A[n - 1][j] == 1:
			ANS.append((n, j + 1, n - 1, j + 2, n, j + 2))
			A[n - 1][j] ^= 1
			A[n - 2][j + 1] ^= 1
			A[n - 1][j + 1] ^= 1
	count = 0
	C = []
	if A[n - 2][m - 2] == 1:
		count += 1
		C.append(n - 1)
		C.append(m - 1)
	if A[n - 2][m - 1] == 1:
		count += 1
		C.append(n - 1)
		C.append(m)
	if A[n - 1][m - 2] == 1:
		count += 1
		C.append(n)
		C.append(m - 1)
	if A[n - 1][m - 1] == 1:
		count += 1
		C.append(n)
		C.append(m)
	if count == 3:
		ANS.append(tuple(C))
	elif count == 0:
		True
	else:
		ANSX = []
		if count == 2:
			for (x, y) in [(n - 2, m - 2), (n - 2, m - 1), (n - 1, m - 2), (n - 1, m - 1)]:
				if A[x][y] == 0:
					C.append(x + 1)
					C.append(y + 1)
					ANSX = tuple(C)
					break
		elif count == 4:
			ANSX = (n - 1, m - 1, n - 1, m, n, m)
		if ANSX != []:
			ANS.append(ANSX)
			(a, b, c, d, e, f) = ANSX
			A[a - 1][b - 1] ^= 1
			A[c - 1][d - 1] ^= 1
			A[e - 1][f - 1] ^= 1
		if A[n - 2][m - 2] == 1:
			ANS.append((n - 1, m - 1, n - 1, m, n, m - 1))
			ANS.append((n - 1, m - 1, n - 1, m, n, m))
			ANS.append((n - 1, m - 1, n, m - 1, n, m))
		elif A[n - 1][m - 1] == 1:
			ANS.append((n, m, n - 1, m, n, m - 1))
			ANS.append((n, m, n - 1, m, n - 1, m - 1))
			ANS.append((n, m, n, m - 1, n - 1, m - 1))
		elif A[n - 2][m - 1] == 1:
			ANS.append((n - 1, m, n, m, n - 1, m - 1))
			ANS.append((n - 1, m, n, m, n, m - 1))
			ANS.append((n - 1, m, n - 1, m - 1, n, m - 1))
		elif A[n - 1][m - 2] == 1:
			ANS.append((n, m - 1, n - 1, m - 1, n, m))
			ANS.append((n, m - 1, n - 1, m - 1, n - 1, m))
			ANS.append((n, m - 1, n, m, n - 1, m))
	print(len(ANS))
	for (a, b, c, d, e, f) in ANS:
		print(a, b, c, d, e, f)


import math

def main():
	(n, m) = map(int, input().split())
	table = []
	for i in range(n):
		line = input()
		table.append(list(line))
	moves = ''
	moves_n = 0
	for i in range(0, n - 2):
		for k in range(0, m - 1, 2):
			swap_down = 0
			if table[i][k] == '1':
				table[i][k] = '0'
				moves += str(i + 1) + ' ' + str(k + 1) + ' '
				swap_down += 1
			if table[i][k + 1] == '1':
				table[i][k + 1] = '0'
				moves += str(i + 1) + ' ' + str(k + 2) + ' '
				swap_down += 1
			if swap_down > 0:
				moves += str(i + 2) + ' ' + str(k + 1) + ' '
				if table[i + 1][k] == '1':
					table[i + 1][k] = '0'
				else:
					table[i + 1][k] = '1'
				if swap_down == 1:
					moves += str(i + 2) + ' ' + str(k + 2) + ' '
					if table[i + 1][k + 1] == '1':
						table[i + 1][k + 1] = '0'
					else:
						table[i + 1][k + 1] = '1'
				moves += '\n'
				moves_n += 1
		if m % 2 != 0:
			if table[i][m - 1] == '1':
				table[i][m - 1] = '0'
				moves += str(i + 1) + ' ' + str(m) + ' '
				moves += str(i + 2) + ' ' + str(m - 1) + ' '
				moves += str(i + 2) + ' ' + str(m) + ' '
				if table[i + 1][m - 1] == '0':
					table[i + 1][m - 1] = '1'
				else:
					table[i + 1][m - 1] = '0'
				if table[i + 1][m - 2] == '0':
					table[i + 1][m - 2] = '1'
				else:
					table[i + 1][m - 2] = '0'
				moves += '\n'
				moves_n += 1
	for i in range(0, m - 2):
		swap_right = 0
		if table[n - 1][i] == '1':
			table[n - 1][i] = '0'
			moves += str(n) + ' ' + str(i + 1) + ' '
			swap_right += 1
		if table[n - 2][i] == '1':
			table[n - 2][i] = '0'
			moves += str(n - 1) + ' ' + str(i + 1) + ' '
			swap_right += 1
		if swap_right > 0:
			moves += str(n) + ' ' + str(i + 2) + ' '
			if table[n - 1][i + 1] == '1':
				table[n - 1][i + 1] = '0'
			else:
				table[n - 1][i + 1] = '1'
			if swap_right == 1:
				moves += str(n - 1) + ' ' + str(i + 2) + ' '
				if table[n - 2][i + 1] == '1':
					table[n - 2][i + 1] = '0'
				else:
					table[n - 2][i + 1] = '1'
			moves += '\n'
			moves_n += 1
	last_sqr = [[table[-2][-2], table[-2][-1]], [table[-1][-2], table[-1][-1]]]
	ones = []
	zeros = []
	for i in range(2):
		for k in range(2):
			if last_sqr[i][k] == '1':
				ones.append([i, k])
			else:
				zeros.append([i, k])
	if len(ones) == 4:
		moves += str(n - 1 + ones[0][0]) + ' ' + str(m - 1 + ones[0][1]) + ' '
		moves += str(n - 1 + ones[1][0]) + ' ' + str(m - 1 + ones[1][1]) + ' '
		moves += str(n - 1 + ones[2][0]) + ' ' + str(m - 1 + ones[2][1]) + ' '
		moves += '\n'
		moves_n += 1
		last_sqr[ones[0][0]][ones[0][1]] = '0'
		last_sqr[ones[1][0]][ones[1][1]] = '0'
		last_sqr[ones[2][0]][ones[2][1]] = '0'
	ones = []
	zeros = []
	for i in range(2):
		for k in range(2):
			if last_sqr[i][k] == '1':
				ones.append([i, k])
			else:
				zeros.append([i, k])
	if len(ones) == 1:
		moves += str(n - 1 + ones[0][0]) + ' ' + str(m - 1 + ones[0][1]) + ' '
		moves += str(n - 1 + zeros[0][0]) + ' ' + str(m - 1 + zeros[0][1]) + ' '
		moves += str(n - 1 + zeros[1][0]) + ' ' + str(m - 1 + zeros[1][1]) + ' '
		last_sqr[ones[0][0]][ones[0][1]] = '0'
		last_sqr[zeros[0][0]][zeros[0][1]] = '1'
		last_sqr[zeros[1][0]][zeros[1][1]] = '1'
		moves += '\n'
		moves_n += 1
	ones = []
	zeros = []
	for i in range(2):
		for k in range(2):
			if last_sqr[i][k] == '1':
				ones.append([i, k])
			else:
				zeros.append([i, k])
	if len(ones) == 2:
		moves += str(n - 1 + ones[0][0]) + ' ' + str(m - 1 + ones[0][1]) + ' '
		moves += str(n - 1 + zeros[0][0]) + ' ' + str(m - 1 + zeros[0][1]) + ' '
		moves += str(n - 1 + zeros[1][0]) + ' ' + str(m - 1 + zeros[1][1]) + ' '
		last_sqr[ones[0][0]][ones[0][1]] = '0'
		last_sqr[zeros[0][0]][zeros[0][1]] = '1'
		last_sqr[zeros[1][0]][zeros[1][1]] = '1'
		moves += '\n'
		moves_n += 1
	ones = []
	zeros = []
	for i in range(2):
		for k in range(2):
			if last_sqr[i][k] == '1':
				ones.append([i, k])
			else:
				zeros.append([i, k])
	if len(ones) == 3:
		moves += str(n - 1 + ones[0][0]) + ' ' + str(m - 1 + ones[0][1]) + ' '
		moves += str(n - 1 + ones[1][0]) + ' ' + str(m - 1 + ones[1][1]) + ' '
		moves += str(n - 1 + ones[2][0]) + ' ' + str(m - 1 + ones[2][1]) + ' '
		moves += '\n'
		moves_n += 1
		last_sqr[ones[0][0]][ones[0][1]] = '0'
		last_sqr[ones[1][0]][ones[1][1]] = '0'
		last_sqr[ones[2][0]][ones[2][1]] = '0'
	print(moves_n)
	print(moves, end='')
t = int(input())
for i in range(t):
	main()


def f(c):
	if c == '1':
		return '0'
	else:
		return '1'
t = int(input())
for _ in range(t):
	(h, w) = map(int, input().split())
	s = [list(input()) for _ in range(h)]
	ans = []
	for i in range(h - 1):
		for j in range(0, w, 2):
			if j == w - 1:
				j -= 1
			if s[i][j] == s[i][j + 1] == '0':
				continue
			elif s[i][j] == s[i][j + 1] == '1':
				s[i][j] = '0'
				s[i][j + 1] = '0'
				s[i + 1][j] = f(s[i + 1][j])
				ans.append((i, j, i, j + 1, i + 1, j))
			elif s[i][j] == '1':
				s[i][j] = '0'
				s[i + 1][j] = f(s[i + 1][j])
				s[i + 1][j + 1] = f(s[i + 1][j + 1])
				ans.append((i, j, i + 1, j, i + 1, j + 1))
			else:
				s[i][j + 1] = '0'
				s[i + 1][j] = f(s[i + 1][j])
				s[i + 1][j + 1] = f(s[i + 1][j + 1])
				ans.append((i, j + 1, i + 1, j, i + 1, j + 1))
	for j in range(0, w, 2):
		if j == w - 1:
			j -= 1
		if s[-1][j] == s[-1][j + 1] == '0':
			continue
		elif s[-1][j] == s[-1][j + 1] == '1':
			s[-1][j] = '0'
			s[-1][j + 1] = '0'
			ans.append((h - 1, j, h - 2, j, h - 2, j + 1))
			ans.append((h - 1, j + 1, h - 2, j, h - 2, j + 1))
		elif s[-1][j] == '1':
			s[-1][j] = '0'
			ans.append((h - 1, j, h - 2, j, h - 2, j + 1))
			ans.append((h - 2, j, h - 1, j, h - 1, j + 1))
			ans.append((h - 2, j + 1, h - 1, j, h - 1, j + 1))
		else:
			s[-1][j + 1] = '0'
			ans.append((h - 1, j + 1, h - 2, j, h - 2, j + 1))
			ans.append((h - 2, j, h - 1, j, h - 1, j + 1))
			ans.append((h - 2, j + 1, h - 1, j, h - 1, j + 1))
	print(len(ans))
	for row in ans:
		print(*map(lambda x: x + 1, row))


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = []
	for i in range(n):
		a.append(list(input()))
	op = 0
	ops = []
	for i in range(n):
		for j in range(m):
			if i == n - 1:
				if j == 0:
					if a[i][j] == '1':
						op += 3
						ops.append([i, j, i - 1, j, i - 1, j + 1])
						ops.append([i, j, i, j + 1, i - 1, j + 1])
						ops.append([i, j, i - 1, j, i, j + 1])
				elif j == m - 1:
					if a[i][j] == '1':
						op += 3
						ops.append([i, j, i - 1, j, i - 1, j - 1])
						ops.append([i, j, i, j - 1, i - 1, j - 1])
						ops.append([i, j, i - 1, j, i, j - 1])
				elif a[i][j] == '1':
					op += 3
					ops.append([i, j, i - 1, j, i - 1, j + 1])
					ops.append([i, j, i, j + 1, i - 1, j + 1])
					ops.append([i, j, i - 1, j, i, j + 1])
			elif j == 0:
				if a[i][j] == '1':
					op += 3
					ops.append([i, j, i + 1, j, i + 1, j + 1])
					ops.append([i, j, i, j + 1, i + 1, j + 1])
					ops.append([i, j, i + 1, j, i, j + 1])
			elif j == m - 1:
				if a[i][j] == '1':
					op += 3
					ops.append([i, j, i + 1, j, i + 1, j - 1])
					ops.append([i, j, i, j - 1, i + 1, j - 1])
					ops.append([i, j, i + 1, j, i, j - 1])
			elif a[i][j] == '1':
				op += 3
				ops.append([i, j, i + 1, j, i + 1, j + 1])
				ops.append([i, j, i, j + 1, i + 1, j + 1])
				ops.append([i, j, i, j + 1, i + 1, j])
	print(op)
	for i in ops:
		l = [int(j) + 1 for j in i]
		print(*l)


import sys
input = sys.stdin.readline
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	table = [list(map(int, list(input().strip()))) for _ in range(n)]

	def add(a, b, c):
		table[a[0]][a[1]] = 1 - table[a[0]][a[1]]
		table[b[0]][b[1]] = 1 - table[b[0]][b[1]]
		table[c[0]][c[1]] = 1 - table[c[0]][c[1]]
		out.append(' '.join(map(lambda x: str(x + 1), (a[0], a[1], b[0], b[1], c[0], c[1]))))
	out = []
	for i in range(n - 1, 1, -1):
		for j in range(m):
			if table[i][j]:
				if j + 1 < m:
					add((i, j), (i - 1, j), (i - 1, j + 1))
				else:
					add((i, j), (i - 1, j), (i - 1, j - 1))
	for j in range(m - 1, 1, -1):
		for i in range(2):
			if table[i][j]:
				if table[i][j]:
					add((i, j), (0, j - 1), (1, j - 1))
	for i in range(2):
		for j in range(2):
			tot = table[0][0] + table[0][1] + table[1][0] + table[1][1]
			if (tot + table[i][j]) % 2:
				add((1 - i, j), (1 - i, 1 - j), (i, 1 - j))
	print(len(out))
	print('\n'.join(out))


import sys

def minp():
	return sys.stdin.readline().strip()

def mint():
	return int(minp())

def mints():
	return map(int, minp().split())

def solve():
	(n, m) = mints()
	a = [list(map(int, minp())) for i in range(n)]
	ans = []
	for i in range(n - 2):
		l = a[i]
		ll = a[i + 1]
		for j in range(m - 1):
			if l[j] == 1:
				if l[j + 1] == 1:
					ans.append((i, j, i, j + 1, i + 1, j))
					l[j + 1] ^= 1
					ll[j] ^= 1
				else:
					ans.append((i, j, i + 1, j, i + 1, j + 1))
					ll[j] ^= 1
					ll[j + 1] ^= 1
			elif l[j + 1] == 1:
				ans.append((i, j + 1, i + 1, j, i + 1, j + 1))
				l[j + 1] ^= 1
				ll[j] ^= 1
				ll[j + 1] ^= 1
	aa = a[n - 2]
	bb = a[n - 1]
	for j in range(m - 2):
		if aa[j] == 1:
			if bb[j] == 1:
				ans.append((n - 2, j, n - 1, j, n - 2, j + 1))
				aa[j + 1] ^= 1
			else:
				ans.append((n - 2, j, n - 2, j + 1, n - 1, j + 1))
				aa[j + 1] ^= 1
				bb[j + 1] ^= 1
		elif bb[j] == 1:
			ans.append((n - 1, j, n - 2, j + 1, n - 1, j + 1))
			aa[j + 1] ^= 1
			bb[j + 1] ^= 1
	c = [(n - 2, m - 2), (n - 2, m - 1), (n - 1, m - 2), (n - 1, m - 1)]
	while True:
		ss = 0
		for (x, y) in c:
			ss += a[x][y]
		if ss == 0:
			break
		if ss == 1 or ss == 3:
			for i in range(4):
				(x, y) = c[i]
				if a[x][y] == 0:
					break
		if ss == 2:
			for i in range(4):
				(x, y) = c[i]
				if a[x][y] == 1:
					break
		if ss == 4:
			i = 0
		d = c.copy()
		d.pop(i)
		tmp = []
		for (x, y) in d:
			a[x][y] ^= 1
			tmp.append(x)
			tmp.append(y)
		ans.append(tmp)
	print(len(ans))
	for l in ans:
		print(' '.join([str(i + 1) for i in l]))
for i in range(mint()):
	solve()


def special(xx):
	global ans, ar, mai
	left = 3
	(x1, y1) = (xx[0][0], xx[0][1])
	(x2, y2) = (xx[1][0], xx[1][1])
	(x3, y3) = (xx[2][0], xx[2][1])
	(x4, y4) = (xx[3][0], xx[3][1])
	if ar[x1][y1] != 0 or ar[x3][y3] != 0:
		ans += 1
		mai.append([])
		if ar[x1][y1] != 0:
			left -= 1
			mai[-1].append(x1 + 1)
			mai[-1].append(y1 + 1)
			ar[x1][y1] = 0
		if ar[x3][y3] != 0:
			mai[-1].append(x3 + 1)
			mai[-1].append(y3 + 1)
			left -= 1
			ar[x3][y3] = 0
		if left != 0:
			ar[x2][y2] = abs(ar[x2][y2] - 1)
			mai[-1].append(x2 + 1)
			mai[-1].append(y2 + 1)
			left -= 1
		if left != 0:
			ar[x4][y4] = abs(ar[x4][y4] - 1)
			mai[-1].append(x4 + 1)
			mai[-1].append(y4 + 1)

def special2(xx):
	global ans, ar, mai
	left = 3
	(x1, y1) = (xx[0][0], xx[0][1])
	(x3, y3) = (xx[1][0], xx[1][1])
	(x2, y2) = (xx[2][0], xx[2][1])
	(x4, y4) = (xx[3][0], xx[3][1])
	if ar[x1][y1] != 0 or ar[x3][y3] != 0:
		ans += 1
		mai.append([])
		if ar[x1][y1] != 0:
			left -= 1
			mai[-1].append(x1 + 1)
			mai[-1].append(y1 + 1)
			ar[x1][y1] = 0
		if ar[x3][y3] != 0:
			mai[-1].append(x3 + 1)
			mai[-1].append(y3 + 1)
			left -= 1
			ar[x3][y3] = 0
		if left != 0:
			ar[x2][y2] = abs(ar[x2][y2] - 1)
			mai[-1].append(x2 + 1)
			mai[-1].append(y2 + 1)
			left -= 1
		if left != 0:
			ar[x4][y4] = abs(ar[x4][y4] - 1)
			mai[-1].append(x4 + 1)
			mai[-1].append(y4 + 1)

def fun1(xx):
	global ar, ans, mai
	zer = []
	one = []
	for i in xx:
		if ar[i[0]][i[1]] == 0:
			zer.append([i[0], i[1]])
		else:
			one.append([i[0], i[1]])
	ans += 2
	mai.append([])
	for i in zer:
		mai[-1].append(i[0] + 1)
		mai[-1].append(i[1] + 1)
		ar[i[0]][i[1]] = 1
	for i in one:
		mai[-1].append(i[0] + 1)
		mai[-1].append(i[1] + 1)
		ar[i[0]][i[1]] = 0
		break
	del one[0]
	mai.append([])
	for i in zer:
		mai[-1].append(i[0] + 1)
		mai[-1].append(i[1] + 1)
		ar[i[0]][i[1]] = 0
	for i in one:
		mai[-1].append(i[0] + 1)
		mai[-1].append(i[1] + 1)
		ar[i[0]][i[1]] = 0

def fun2(xx):
	global ar, ans, mai
	zer = []
	one = []
	for i in xx:
		if ar[i[0]][i[1]] == 0:
			zer.append([i[0], i[1]])
		else:
			one.append([i[0], i[1]])
	ans += 1
	mai.append([])
	zer.pop()
	for i in zer:
		mai[-1].append(i[0] + 1)
		mai[-1].append(i[1] + 1)
		ar[i[0]][i[1]] = 1
	for i in one:
		mai[-1].append(i[0] + 1)
		mai[-1].append(i[1] + 1)
		ar[i[0]][i[1]] = 0
	fun1(xx)

def fun3(xx):
	global ar, ans, mai
	zer = []
	one = []
	for i in xx:
		if ar[i[0]][i[1]] == 0:
			zer.append([i[0], i[1]])
		else:
			one.append([i[0], i[1]])
	ans += 1
	mai.append([])
	for i in one:
		mai[-1].append(i[0] + 1)
		mai[-1].append(i[1] + 1)
		ar[i[0]][i[1]] = 0
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	ans = 0
	mai = []
	ar = []
	if m != 2:
		for i in range(n):
			ar.append(list(map(int, list(input()))))
		for i in range(n - 1):
			for j in range(m - 1):
				special([[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]])
		for i in range(n - 1):
			j = m - 2
			special2([[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]])
		i = n - 2
		j = m - 2
		zero = 0
		one = 0
		if ar[i][j] == 0:
			zero += 1
		else:
			one += 1
		if ar[i + 1][j] == 0:
			zero += 1
		else:
			one += 1
		if ar[i][j + 1] == 0:
			zero += 1
		else:
			one += 1
		if ar[i + 1][j + 1] == 0:
			zero += 1
		else:
			one += 1
		if one == 2 and zero == 2:
			fun1([[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]])
		elif zero == 3 and one == 1:
			fun2([[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]])
		print(ans)
		for i in mai:
			print(*i)
	else:
		for i in range(n):
			ar.append(list(map(int, list(input()))))
		for i in range(n - 1):
			for j in range(m - 1):
				zero = 0
				one = 0
				if ar[i][j] == 0:
					zero += 1
				else:
					one += 1
				if ar[i + 1][j] == 0:
					zero += 1
				else:
					one += 1
				if ar[i][j + 1] == 0:
					zero += 1
				else:
					one += 1
				if ar[i + 1][j + 1] == 0:
					zero += 1
				else:
					one += 1
				if one == 4:
					ans += 1
					mai.append([])
					mai[-1].append(i + 1)
					mai[-1].append(j + 1)
					mai[-1].append(i + 2)
					mai[-1].append(j + 1)
					mai[-1].append(i + 1)
					mai[-1].append(j + 2)
					ar[i][j] = 0
					ar[i][j + 1] = 0
					ar[i + 1][j] = 0
				elif one == 2 and zero == 2:
					fun1([[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]])
				elif zero == 3 and one == 1:
					fun2([[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]])
				elif one == 3:
					fun3([[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]])
		zero = 0
		one = 0
		if ar[i][j] == 0:
			zero += 1
		else:
			one += 1
		if ar[i + 1][j] == 0:
			zero += 1
		else:
			one += 1
		if ar[i][j + 1] == 0:
			zero += 1
		else:
			one += 1
		if ar[i + 1][j + 1] == 0:
			zero += 1
		else:
			one += 1
		if one == 4:
			ans += 1
			mai.append([])
			mai[-1].append(i + 1)
			mai[-1].append(j + 1)
			mai[-1].append(i + 2)
			mai[-1].append(j + 1)
			mai[-1].append(i + 1)
			mai[-1].append(j + 2)
			ar[i][j] = 0
			ar[i][j + 1] = 0
			ar[i + 1][j] = 0
		elif one == 2 and zero == 2:
			fun1([[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]])
		elif zero == 3 and one == 1:
			fun2([[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]])
		elif one == 3:
			fun3([[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]])
		print(ans)
		for i in mai:
			print(*i)


t = int(input())
for test in range(t):
	[n, m] = list(map(int, input().rstrip().split()))
	g = [[0 for _ in range(m)] for _ in range(n)]
	for i in range(n):
		s = input()
		for j in range(m):
			g[i][j] = int(s[j])
	o = 0
	op = list()
	for i in range(n - 2):
		for j in range(m - 2):
			if g[i][j] == 1:
				o += 1
				op.append([i, j, i + 1, j, i, j + 1])
				g[i + 1][j] = 1 - g[i + 1][j]
				g[i][j + 1] = 1 - g[i][j + 1]
	for i in range(n - 2):
		if g[i][m - 2] == 1:
			o += 1
			if g[i][m - 1] == 1:
				op.append([i, m - 2, i, m - 1, i + 1, m - 2])
				g[i + 1][m - 2] = 1 - g[i + 1][m - 2]
			else:
				op.append([i, m - 2, i + 1, m - 1, i + 1, m - 2])
				g[i + 1][m - 2] = 1 - g[i + 1][m - 2]
				g[i + 1][m - 1] = 1 - g[i + 1][m - 1]
		elif g[i][m - 1] == 1:
			o += 1
			op.append([i, m - 1, i + 1, m - 2, i + 1, m - 1])
			g[i + 1][m - 2] = 1 - g[i + 1][m - 2]
			g[i + 1][m - 1] = 1 - g[i + 1][m - 1]
	for j in range(m - 2):
		if g[n - 2][j] == 1:
			o += 1
			if g[n - 1][j] == 1:
				op.append([n - 2, j, n - 1, j, n - 2, j + 1])
				g[n - 2][j + 1] = 1 - g[n - 2][j + 1]
			else:
				op.append([n - 2, j, n - 1, j + 1, n - 2, j + 1])
				g[n - 2][j + 1] = 1 - g[n - 2][j + 1]
				g[n - 1][j + 1] = 1 - g[n - 1][j + 1]
		elif g[n - 1][j] == 1:
			o += 1
			op.append([n - 1, j, n - 2, j + 1, n - 1, j + 1])
			g[n - 2][j + 1] = 1 - g[n - 2][j + 1]
			g[n - 1][j + 1] = 1 - g[n - 1][j + 1]
	d = {0: [], 1: []}
	for i in range(n - 2, n):
		for j in range(m - 2, m):
			d[g[i][j]].append([i, j])
	if len(d[1]) == 4:
		o += 4
		op.append([n - 2, m - 2, n - 1, m - 2, n - 2, m - 1])
		op.append([n - 1, m - 1, n - 2, m - 2, n - 1, m - 2])
		op.append([n - 2, m - 1, n - 1, m - 1, n - 2, m - 2])
		op.append([n - 1, m - 2, n - 2, m - 1, n - 1, m - 1])
	elif len(d[1]) == 3:
		o += 1
		oper = []
		l = d[1]
		for (x, y) in l:
			oper.append(x)
			oper.append(y)
		op.append(oper)
	elif len(d[1]) == 2:
		o += 2
		oper = []
		l = d[0]
		for (x, y) in l:
			oper.append(x)
			oper.append(y)
		oper.append(d[1][0][0])
		oper.append(d[1][0][1])
		op.append(oper)
		oper = []
		for (x, y) in l:
			oper.append(x)
			oper.append(y)
		oper.append(d[1][1][0])
		oper.append(d[1][1][1])
		op.append(oper)
	elif len(d[1]) == 1:
		o += 3
		oper = []
		oper.append(d[1][0][0])
		oper.append(d[1][0][1])
		oper.append(d[0][0][0])
		oper.append(d[0][0][1])
		oper.append(d[0][1][0])
		oper.append(d[0][1][1])
		op.append(oper)
		newd = {0: [d[1][0], d[0][2]], 1: [d[0][0], d[0][1]]}
		d = newd
		oper = []
		l = d[0]
		for (x, y) in l:
			oper.append(x)
			oper.append(y)
		oper.append(d[1][0][0])
		oper.append(d[1][0][1])
		op.append(oper)
		oper = []
		for (x, y) in l:
			oper.append(x)
			oper.append(y)
		oper.append(d[1][1][0])
		oper.append(d[1][1][1])
		op.append(oper)
	print(o)
	for i in range(o):
		k = [x + 1 for x in op[i]]
		print(' '.join(map(str, k)))


def count1(x1, y1, x2, y2, x3, y3, x4, y4, arr):
	count = 0
	if arr[x1][y1] == 1:
		count += 1
	if arr[x2][y2] == 1:
		count += 1
	if arr[x3][y3] == 1:
		count += 1
	if arr[x4][y4] == 1:
		count += 1
	return count

def moves4(x1, y1, x2, y2, x3, y3, x4, y4, arr, li):
	li.append([x1, y1, x2, y2, x3, y3])
	li.append([x1, y1, x2, y2, x4, y4])
	li.append([x2, y2, x3, y3, x4, y4])
	li.append([x1, y1, x3, y3, x4, y4])
	arr[x1][y1] = 0
	arr[x2][y2] = 0
	arr[x3][y3] = 0
	arr[x4][y4] = 0

def moves3(x1, y1, x2, y2, x3, y3, x4, y4, arr, li):
	if arr[x1][y1] == 0:
		li.append([x2, y2, x3, y3, x4, y4])
		arr[x2][y2] = 0
		arr[x3][y3] = 0
		arr[x4][y4] = 0
	elif arr[x2][y2] == 0:
		li.append([x1, y1, x3, y3, x4, y4])
		arr[x1][y1] = 0
		arr[x3][y3] = 0
		arr[x4][y4] = 0
	elif arr[x3][y3] == 0:
		li.append([x1, y1, x2, y2, x4, y4])
		arr[x1][y1] = 0
		arr[x2][y2] = 0
		arr[x4][y4] = 0
	else:
		li.append([x1, y1, x2, y2, x3, y3])
		arr[x1][y1] = 0
		arr[x2][y2] = 0
		arr[x3][y3] = 0

def moves2(x1, y1, x2, y2, x3, y3, x4, y4, arr, li):
	if arr[x1][y1] == 1:
		if arr[x2][y2] == 1:
			li.append([x2, y2, x3, y3, x4, y4])
			arr[x2][y2] = 0
			arr[x3][y3] = 1
			arr[x4][y4] = 1
		elif arr[x3][y3] == 1:
			li.append([x1, y1, x2, y2, x4, y4])
			arr[x1][y1] = 0
			arr[x2][y2] = 1
			arr[x4][y4] = 1
		elif arr[x4][y4] == 1:
			li.append([x1, y1, x2, y2, x3, y3])
			arr[x1][y1] = 0
			arr[x2][y2] = 1
			arr[x3][y3] = 1
	elif arr[x4][y4] == 1:
		if arr[x2][y2] == 1:
			li.append([x1, y1, x2, y2, x3, y3])
			arr[x1][y1] = 1
			arr[x2][y2] = 0
			arr[x3][y3] = 1
		elif arr[x3][y3] == 1:
			li.append([x1, y1, x2, y2, x3, y3])
			arr[x1][y1] = 1
			arr[x2][y2] = 1
			arr[x3][y3] = 0
	elif arr[x2][y2] == 1 and arr[x3][y3] == 1:
		li.append([x1, y1, x2, y2, x4, y4])
		arr[x1][y1] = 1
		arr[x2][y2] = 0
		arr[x4][y4] = 1
	moves3(x1, y1, x2, y2, x3, y3, x4, y4, arr, li)

def moves1(x1, y1, x2, y2, x3, y3, x4, y4, arr, li):
	if arr[x1][y1] == 1:
		li.append([x1, y1, x2, y2, x4, y4])
		arr[x1][y1] = 0
		arr[x2][y2] = 1
		arr[x4][y4] = 1
	elif arr[x2][y2] == 1:
		li.append([x1, y1, x2, y2, x3, y3])
		arr[x1][y1] = 1
		arr[x2][y2] = 0
		arr[x3][y3] = 1
	elif arr[x3][y3] == 1:
		li.append([x1, y1, x2, y2, x3, y3])
		arr[x1][y1] = 1
		arr[x2][y2] = 1
		arr[x3][y3] = 0
	else:
		li.append([x1, y1, x2, y2, x4, y4])
		arr[x1][y1] = 1
		arr[x2][y2] = 1
		arr[x4][y4] = 0
	moves2(x1, y1, x2, y2, x3, y3, x4, y4, arr, li)
for tetscase in range(int(input())):
	arr = [int(x) for x in input().split()]
	(n, m) = (arr[0], arr[1])
	arr = []
	li = []
	for i in range(n):
		s = list(input())
		for j in range(m):
			s[j] = int(s[j])
		arr.append(s)
	for i in range(0, n - 1):
		for j in range(0, m - 1):
			(x1, y1) = (i, j)
			(x2, y2) = (i, j + 1)
			(x3, y3) = (i + 1, j)
			(x4, y4) = (i + 1, j + 1)
			c1 = count1(x1, y1, x2, y2, x3, y3, x4, y4, arr)
			if c1 == 4:
				moves4(x1, y1, x2, y2, x3, y3, x4, y4, arr, li)
			elif c1 == 3:
				moves3(x1, y1, x2, y2, x3, y3, x4, y4, arr, li)
			elif c1 == 2:
				moves2(x1, y1, x2, y2, x3, y3, x4, y4, arr, li)
			elif c1 == 1:
				moves1(x1, y1, x2, y2, x3, y3, x4, y4, arr, li)
	print(len(li))
	for ele in li:
		for element in ele:
			print(element + 1, end=' ')
		print()


from itertools import permutations
import sys
input = lambda : sys.stdin.readline().rstrip('\r\n')

def countSet(arr):
	n = len(arr)
	m = len(arr[0])
	cnt = 0
	for i in range(n):
		for j in range(m):
			if arr[i][j] == 1:
				cnt += 1
	return cnt

def applyInPlace(grid, igrid, jgrid, sq2x2):
	if sq2x2[0][0] == 1:
		grid[igrid][jgrid] = 1 - grid[igrid][jgrid]
	if sq2x2[0][1] == 1:
		grid[igrid][jgrid + 1] = 1 - grid[igrid][jgrid + 1]
	if sq2x2[1][0] == 1:
		grid[igrid + 1][jgrid] = 1 - grid[igrid + 1][jgrid]
	if sq2x2[1][1] == 1:
		grid[igrid + 1][jgrid + 1] = 1 - grid[igrid + 1][jgrid + 1]

def solveAllExceptLast2Rows(grid):
	n = len(grid)
	m = len(grid[0])
	ans = []
	for igrid in range(n - 2):
		for jgrid in range(m):
			if grid[igrid][jgrid] == 1:
				if jgrid < m - 1:
					apply = 2
				else:
					jgrid -= 1
					apply = 3
				sq2x2 = all2x2with3set[apply]
				applyInPlace(grid, igrid, jgrid, sq2x2)
				ans.append(convertToSixIntegers(igrid, jgrid, sq2x2))
	return ans

def solveLast2Rows(grid):
	n = len(grid)
	m = len(grid[0])
	igrid = n - 2
	ans = []
	for jgrid in range(m - 2):
		if grid[igrid][jgrid] == 1 and grid[igrid + 1][jgrid] == 1:
			apply = 0
		elif grid[igrid][jgrid] == 1:
			apply = 1
		elif grid[igrid + 1][jgrid] == 1:
			apply = 3
		else:
			continue
		sq2x2 = all2x2with3set[apply]
		applyInPlace(grid, igrid, jgrid, sq2x2)
		ans.append(convertToSixIntegers(igrid, jgrid, sq2x2))
	for x in solveLastCorner(grid):
		ans.append(x)
	return ans

def solveLastCorner(grid):
	n = len(grid)
	m = len(grid[0])
	arr = [[grid[n - 2][m - 2], grid[n - 2][m - 1]], [grid[n - 1][m - 2], grid[n - 1][m - 1]]]
	if countSet(arr) == 0:
		return []
	ans = [-1, -1, -1, -1, -1]
	for p in permutations((0, 1, 2, 3)):
		arr = [[grid[n - 2][m - 2], grid[n - 2][m - 1]], [grid[n - 1][m - 2], grid[n - 1][m - 1]]]
		for i in range(4):
			applyInPlace(arr, 0, 0, all2x2with3set[p[i]])
			if countSet(arr) == 0:
				if i + 1 < len(ans):
					ans = p[:i + 1]
				break
	igrid = n - 2
	jgrid = m - 2
	ans2 = []
	for i in ans:
		sq2x2 = all2x2with3set[i]
		ans2.append(convertToSixIntegers(igrid, jgrid, sq2x2))
	return ans2

def convertToSixIntegers(igrid, jgrid, sq2x2):
	ans = []
	if sq2x2[0][0] == 1:
		ans.append(igrid + 1)
		ans.append(jgrid + 1)
	if sq2x2[0][1] == 1:
		ans.append(igrid + 1)
		ans.append(jgrid + 2)
	if sq2x2[1][0] == 1:
		ans.append(igrid + 2)
		ans.append(jgrid + 1)
	if sq2x2[1][1] == 1:
		ans.append(igrid + 2)
		ans.append(jgrid + 2)
	return ans

def multiLineArrayOfArraysPrint(arr):
	print('\n'.join([' '.join([str(x) for x in y]) for y in arr]))
all2x2sqs = []
for b in range(16):
	temp = [[0, 0], [0, 0]]
	if b & 1 << 0 > 0:
		temp[0][0] = 1
	if b & 1 << 1 > 0:
		temp[0][1] = 1
	if b & 1 << 2 > 0:
		temp[1][0] = 1
	if b & 1 << 3 > 0:
		temp[1][1] = 1
	all2x2sqs.append(temp)
all2x2with3set = []
for arr in all2x2sqs:
	if countSet(arr) == 3:
		all2x2with3set.append(arr)
t = int(input())
for _ in range(t):
	(n, m) = [int(x) for x in input().split()]
	grid = []
	for __ in range(n):
		grid.append([int(x) for x in input()])
	ans = []
	ans = ans + solveAllExceptLast2Rows(grid) + solveLast2Rows(grid)
	print(len(ans))
	multiLineArrayOfArraysPrint(ans)


def ans(i, j):
	x = i + 1 if i < n else i - 1
	y = j + 1 if j < m else j - 1
	print(i, j, i, y, x, y)
	print(i, j, x, j, x, y)
	print(i, j, i, y, x, j)
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	l = [list(map(int, list(input()))) for i in range(n)]
	print(sum((sum(z) for z in l)) * 3)
	for i in range(n):
		for j in range(m):
			if l[i][j] == 1:
				ans(i + 1, j + 1)


dic = {'1000': [1, 1, 1, 2, 2, 2], '0100': [1, 1, 1, 2, 2, 2], '0010': [1, 1, 1, 2, 2, 1], '0001': [1, 1, 1, 2, 2, 2], '0011': [1, 1, 1, 2, 2, 1], '0110': [1, 1, 1, 2, 2, 2], '0101': [1, 1, 1, 2, 2, 1], '1001': [1, 1, 1, 2, 2, 1], '1010': [1, 1, 1, 2, 2, 2], '1100': [1, 1, 2, 1, 2, 2], '0111': [1, 2, 2, 1, 2, 2], '1011': [1, 1, 2, 1, 2, 2], '1101': [1, 1, 1, 2, 2, 2], '1110': [1, 1, 1, 2, 2, 1], '1111': [1, 1, 1, 2, 2, 1]}
dic1 = {'1000': '0101', '0100': '1001', '0010': '1100', '0001': '1100', '0011': '1101', '0110': '1011', '0101': '1011', '1001': '0111', '1010': '0111', '1100': '0111', '0111': '0000', '1011': '0000', '1101': '0000', '1110': '0000', '1111': '0001'}
T = int(input())
while T > 0:
	(n, m) = map(int, input().split())
	matrix = []
	res = []
	for i in range(n):
		matrix.append(input())
	count = 0
	for i in range(n // 2):
		row = i * 2
		for j in range(m // 2):
			col = j * 2
			temp = matrix[row][col] + matrix[row][col + 1] + matrix[row + 1][col] + matrix[row + 1][col + 1]
			while temp != '0000':
				xx = dic[temp].copy()
				(xx[0], xx[2], xx[4]) = (xx[0] + row, xx[2] + row, xx[4] + row)
				(xx[1], xx[3], xx[5]) = (xx[1] + col, xx[3] + col, xx[5] + col)
				res.append(xx)
				temp = dic1[temp]
				count += 1
		if m % 2 == 1:
			temp = '0' + matrix[row][m - 1] + '0' + matrix[row + 1][m - 1]
			while temp != '0000':
				xx = dic[temp].copy()
				(xx[0], xx[2], xx[4]) = (xx[0] + row, xx[2] + row, xx[4] + row)
				(xx[1], xx[3], xx[5]) = (xx[1] + m - 2, xx[3] + m - 2, xx[5] + m - 2)
				res.append(xx)
				temp = dic1[temp]
				count += 1
	if n % 2 == 1:
		for i in range(m // 2):
			col = i * 2
			temp = '0' + '0' + matrix[n - 1][col] + matrix[n - 1][col + 1]
			while temp != '0000':
				xx = dic[temp].copy()
				(xx[0], xx[2], xx[4]) = (xx[0] + n - 2, xx[2] + n - 2, xx[4] + n - 2)
				(xx[1], xx[3], xx[5]) = (xx[1] + col, xx[3] + col, xx[5] + col)
				res.append(xx)
				temp = dic1[temp]
				count += 1
		if m % 2 == 1 and matrix[n - 1][m - 1] == '1':
			temp = '0001'
			while temp != '0000':
				xx = dic[temp].copy()
				(xx[0], xx[2], xx[4]) = (xx[0] + n - 2, xx[2] + n - 2, xx[4] + n - 2)
				(xx[1], xx[3], xx[5]) = (xx[1] + m - 2, xx[3] + m - 2, xx[5] + m - 2)
				res.append(xx)
				temp = dic1[temp]
				count += 1
	print(count)
	for r in res:
		print(*r)
	T -= 1


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush
from math import *
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
import copy
import time
starttime = time.time()
mod = int(pow(10, 9) + 7)
mod2 = 998244353

def data():
	return sys.stdin.readline().strip()

def out(*var, end='\n'):
	sys.stdout.write(' '.join(map(str, var)) + end)

def L():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]
try:
	sys.stdin = open('input.txt', 'r')
except:
	pass

def pmat(A):
	for ele in A:
		print(*ele, end='\n')

def seive():
	prime = [1 for i in range(10 ** 6 + 1)]
	prime[0] = 0
	prime[1] = 0
	for i in range(10 ** 6 + 1):
		if prime[i]:
			for j in range(2 * i, 10 ** 6 + 1, i):
				prime[j] = 0
	return prime
for _ in range(int(input())):
	(m, n) = map(int, input().split())
	A = [[0] * (n + 1)] + [[0] + list(map(int, list(input()))) for _ in range(m)]
	ans = []
	for i in range(1, m - 1):
		for j in range(1, n + 1):
			if A[i][j]:
				ans.append([i, j, i + 1, j, i + 1, j + 1 if j < n else j - 1])
				A[i][j] ^= 1
				A[i + 1][j] ^= 1
				A[i + 1][j + 1 if j < n else j - 1] ^= 1
	for j in range(1, n - 1):
		if A[m - 1][j] and A[m][j]:
			ans.append([m - 1, j, m, j, m - 1, j + 1])
			A[m - 1][j] ^= 1
			A[m][j] ^= 1
			A[m - 1][j + 1] ^= 1
		elif A[m - 1][j]:
			ans.append([m - 1, j, m - 1, j + 1, m, j + 1])
			A[m - 1][j] ^= 1
			A[m - 1][j + 1] ^= 1
			A[m][j + 1] ^= 1
		elif A[m][j]:
			ans.append([m, j, m, j + 1, m - 1, j + 1])
			A[m][j] ^= 1
			A[m][j + 1] ^= 1
			A[m - 1][j + 1] ^= 1
	if A[m - 1][n - 1] ^ A[m - 1][n] ^ A[m][n - 1]:
		ans.append([m - 1, n - 1, m - 1, n, m, n - 1])
	if A[m - 1][n - 1] ^ A[m][n - 1] ^ A[m][n]:
		ans.append([m - 1, n - 1, m, n - 1, m, n])
	if A[m][n - 1] ^ A[m][n] ^ A[m - 1][n]:
		ans.append([m, n - 1, m, n, m - 1, n])
	if A[m][n] ^ A[m - 1][n] ^ A[m - 1][n - 1]:
		ans.append([m, n, m - 1, n, m - 1, n - 1])
	print(len(ans))
	for a in ans:
		print(*a)
endtime = time.time()


def f(x1, y1, x2, y2, x3, y3, x4, y4):
	arr = [x1, y1, x2, y2, x3, y3, x4, y4]
	s = [a[x1][y1], a[x2][y2], a[x3][y3], a[x4][y4]]
	if s.count(1) == 1:
		l = s.index(1)
		if l >= 2:
			ans.append([arr[2 * l] + 1, arr[2 * l + 1] + 1, arr[0] + 1, arr[1] + 1, arr[2] + 1, arr[3] + 1])
			ans.append([arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1, arr[0] + 1, arr[1] + 1])
			ans.append([arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1, arr[2] + 1, arr[3] + 1])
		else:
			ans.append([arr[2 * l] + 1, arr[2 * l + 1] + 1, arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1])
			ans.append([arr[0] + 1, arr[1] + 1, arr[2] + 1, arr[3] + 1, arr[4] + 1, arr[5] + 1])
			ans.append([arr[0] + 1, arr[1] + 1, arr[2] + 1, arr[3] + 1, arr[6] + 1, arr[7] + 1])
	elif s.count(1) == 2:
		(l1, l2) = (0, 0)
		for i in range(4):
			if s[i] == 1:
				l1 = i
				break
		for i in range(3, -1, -1):
			if s[i] == 1:
				l2 = i
				break
		if min(l1, l2) == 0 and max(l1, l2) == 3:
			ans.append([arr[0] + 1, arr[1] + 1, arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1])
			ans.append([arr[4] + 1, arr[5] + 1, arr[0] + 1, arr[1] + 1, arr[2] + 1, arr[3] + 1])
			ans.append([arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1, arr[0] + 1, arr[1] + 1])
			ans.append([arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1, arr[2] + 1, arr[3] + 1])
		elif min(l1, l2) == 1 and max(l1, l2) == 2:
			ans.append([arr[2] + 1, arr[3] + 1, arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1])
			ans.append([arr[6] + 1, arr[7] + 1, arr[0] + 1, arr[1] + 1, arr[2] + 1, arr[3] + 1])
			ans.append([arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1, arr[0] + 1, arr[1] + 1])
			ans.append([arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1, arr[2] + 1, arr[3] + 1])
		elif min(l1, l2) == 0 and max(l1, l2) == 1 or (min(l1, l2) == 0 and max(l1, l2) == 2):
			ans.append([arr[0] + 1, arr[1] + 1, arr[max(l1, l2) * 2] + 1, arr[max(l1, l2) * 2 + 1] + 1, arr[6] + 1, arr[7] + 1])
			ans.append([arr[6] + 1, arr[7] + 1, arr[0] + 1, arr[1] + 1, arr[2] + 1, arr[3] + 1])
			ans.append([arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1, arr[0] + 1, arr[1] + 1])
			ans.append([arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1, arr[2] + 1, arr[3] + 1])
		else:
			ans.append([arr[6] + 1, arr[7] + 1, arr[min(l1, l2) * 2] + 1, arr[min(l1, l2) * 2 + 1] + 1, arr[0] + 1, arr[1] + 1])
			ans.append([arr[0] + 1, arr[1] + 1, arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1])
			ans.append([arr[0] + 1, arr[1] + 1, arr[2] + 1, arr[3] + 1, arr[4] + 1, arr[5] + 1])
			ans.append([arr[0] + 1, arr[1] + 1, arr[2] + 1, arr[3] + 1, arr[6] + 1, arr[7] + 1])
	elif s.count(1) == 3:
		q = []
		for i in range(4):
			if s[i] == 1:
				q.extend([arr[i * 2] + 1, arr[i * 2 + 1] + 1])
		ans.append(q)
	elif s.count(1) == 4:
		ans.append([arr[0] + 1, arr[1] + 1, arr[2] + 1, arr[3] + 1, arr[4] + 1, arr[5] + 1])
		ans.append([arr[6] + 1, arr[7] + 1, arr[0] + 1, arr[1] + 1, arr[2] + 1, arr[3] + 1])
		ans.append([arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1, arr[0] + 1, arr[1] + 1])
		ans.append([arr[4] + 1, arr[5] + 1, arr[6] + 1, arr[7] + 1, arr[2] + 1, arr[3] + 1])
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = []
	ans = []
	for i in range(n):
		a.append([int(i) for i in list(input())])
	if n % 2 == 0 and m % 2 == 0:
		for i in range(0, n, 2):
			for j in range(0, m, 2):
				f(i, j, i, j + 1, i + 1, j, i + 1, j + 1)
				a[i][j] = 0
				a[i][j + 1] = 0
				a[i + 1][j] = 0
				a[i + 1][j + 1] = 0
	elif n % 2 == 1 and m % 2 == 0:
		for i in range(0, n - 1, 2):
			for j in range(0, m, 2):
				f(i, j, i, j + 1, i + 1, j, i + 1, j + 1)
				a[i][j] = 0
				a[i][j + 1] = 0
				a[i + 1][j] = 0
				a[i + 1][j + 1] = 0
		for j in range(m - 1):
			f(n - 2, j, n - 2, j + 1, n - 1, j, n - 1, j + 1)
			a[n - 2][j] = 0
			a[n - 2][j + 1] = 0
			a[n - 1][j] = 0
			a[n - 1][j + 1] = 0
	elif n % 2 == 0 and m % 2 == 1:
		for i in range(0, n, 2):
			for j in range(0, m - 1, 2):
				f(i, j, i, j + 1, i + 1, j, i + 1, j + 1)
				a[i][j] = 0
				a[i][j + 1] = 0
				a[i + 1][j] = 0
				a[i + 1][j + 1] = 0
		for j in range(n - 1):
			f(j, m - 2, j, m - 1, j + 1, m - 1, j + 1, m - 2)
			a[j][m - 2] = 0
			a[j][m - 1] = 0
			a[j + 1][m - 2] = 0
			a[j + 1][m - 1] = 0
	else:
		for i in range(0, n - 1, 2):
			for j in range(0, m - 1, 2):
				f(i, j, i, j + 1, i + 1, j, i + 1, j + 1)
				a[i][j] = 0
				a[i][j + 1] = 0
				a[i + 1][j] = 0
				a[i + 1][j + 1] = 0
		for j in range(n - 1):
			f(j, m - 2, j, m - 1, j + 1, m - 1, j + 1, m - 2)
			a[j][m - 2] = 0
			a[j][m - 1] = 0
			a[j + 1][m - 2] = 0
			a[j + 1][m - 1] = 0
		for j in range(m - 1):
			f(n - 2, j, n - 2, j + 1, n - 1, j, n - 1, j + 1)
			a[n - 2][j] = 0
			a[n - 2][j + 1] = 0
			a[n - 1][j] = 0
			a[n - 1][j + 1] = 0
	print(len(ans))
	for row in ans:
		print(*row)


import math
import sys
from collections import defaultdict
from functools import lru_cache
t = int(input())
for _ in range(t):
	(n, m) = [int(i) for i in input().split()]
	matrix = []
	for i in range(n):
		matrix.append([int(i) for i in input()])
	ans = []
	for i in range(n - 1):
		for j in range(m):
			if j != m - 1:
				if matrix[i][j] == 1:
					ans.append([i, j, i + 1, j, i + 1, j + 1])
					ans.append([i + 1, j, i + 1, j + 1, i, j + 1])
					matrix[i][j] = 0
					matrix[i][j + 1] = (matrix[i][j + 1] + 1) % 2
			elif matrix[i][j] == 1:
				ans.append([i, j, i, j - 1, i + 1, j])
				ans.append([i, j - 1, i + 1, j, i + 1, j - 1])
				matrix[i][j] = 0
				matrix[i + 1][j - 1] = (matrix[i + 1][j - 1] + 1) % 2
	for i in range(m - 1):
		if matrix[n - 1][i] == 1:
			ans.append([n - 1, i, n - 2, i, n - 2, i + 1])
			ans.append([n - 2, i, n - 2, i + 1, n - 1, i + 1])
			matrix[n - 1][i] = 0
			matrix[n - 1][i + 1] = (matrix[n - 1][i + 1] + 1) % 2
	if matrix[n - 1][m - 1] == 1:
		ans.append([n - 2, m - 2, n - 1, m - 2, n - 1, m - 1])
		ans.append([n - 1, m - 2, n - 1, m - 1, n - 2, m - 1])
		matrix[n - 2][m - 2] = (matrix[n - 2][m - 2] + 1) % 2
		matrix[n - 2][m - 1] = (matrix[n - 2][m - 1] + 1) % 2
		ans.append([n - 1, m - 1, n - 2, m - 1, n - 2, m - 2])
	a1 = []
	for i in range(len(ans)):
		a2 = [i + 1 for i in ans[i]]
		a1.append(a2)
	print(len(ans))
	for i in range(len(a1)):
		print(*a1[i])


from sys import stdin
input = stdin.readline

def make_zero_2x2(y, x):
	zeros = []
	ones = []
	for i in range(2):
		for j in range(2):
			if a[y + i][x + j] == '0':
				zeros.append((y + i, x + j))
			else:
				ones.append((y + i, x + j))
				a[y + i][x + j] = '0'
	flip = []
	if len(zeros) == 0:
		flip.append([])
		for i in range(3):
			o = ones.pop()
			zeros.append(o)
			flip[-1].extend(o)
	for _ in range(2):
		if len(zeros) == 2 or len(zeros) == 3:
			flip.append([])
			o = ones.pop()
			flip[-1].extend(o)
			for i in range(2):
				z = zeros.pop()
				ones.append(z)
				flip[-1].extend(z)
			zeros.append(o)
	if len(zeros) == 1:
		flip.append([])
		for i in range(3):
			o = ones.pop()
			flip[-1].extend(o)
	return flip
t = int(input())
for _ in range(t):
	(n, m) = [int(x) for x in input().split()]
	a = [list(input().rstrip()) for _ in range(n)]
	ans = []
	for r in range(0, n, 2):
		for c in range(0, m, 2):
			if r + 1 < n:
				y = r
			else:
				y = r - 1
			if c + 1 < m:
				x = c
			else:
				x = c - 1
			flip = make_zero_2x2(y, x)
			if flip == []:
				continue
			for i in flip:
				ans.append([x + 1 for x in i])
	print(len(ans))
	for i in ans:
		print(*i)


from __future__ import division, print_function
from fractions import Fraction
import sys
import os
from io import BytesIO, IOBase
from functools import cmp_to_key
from heapq import *
from math import gcd, factorial, floor, ceil, sqrt
from copy import deepcopy
from collections import deque
from bisect import bisect_left as bl
from bisect import bisect_right as br
from bisect import bisect
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
from types import GeneratorType

def iterative(f, stack=[]):

	def wrapped_func(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		to = f(*args, **kwargs)
		while True:
			if type(to) is GeneratorType:
				stack.append(to)
				to = next(to)
				continue
			stack.pop()
			if not stack:
				break
			to = stack[-1].send(to)
		return to
	return wrapped_func

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def testcase(t):
	for pp in range(t):
		solve(pp)

def google(p):
	print('Case #' + str(p) + ': ', end='')

def lcm(a, b):
	return a * b // gcd(a, b)

def power(x, y, p):
	y %= p - 1
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(max(n - r, 1)))

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True
inf = pow(10, 20)
mod = 10 ** 9 + 7
from random import randint

def solve(case):
	(n, m) = sep()
	g = []
	for i in range(n):
		temp = list(inp())
		for j in range(len(temp)):
			temp[j] = int(temp[j])
		g.append(temp)
	ans = []
	for i in range(n - 1):
		for j in range(m):
			if i == n - 2 and j == m - 1 or (i == n - 2 and j == m - 2):
				continue
			if g[i][j] == 1:
				if j != m - 1:
					ans.append((i, i + 1, i + 1, j, j, j + 1))
					g[i + 1][j] = 1 - g[i + 1][j]
					g[i + 1][j + 1] = 1 - g[i + 1][j + 1]
				else:
					ans.append((i, i + 1, i + 1, j, j, j - 1))
					g[i + 1][j] = 1 - g[i + 1][j]
					g[i + 1][j - 1] = 1 - g[i + 1][j - 1]
	i = n - 1
	for j in range(m - 2):
		if g[i][j] == 1:
			if g[i][j + 1] == 0:
				ans.append((i, i, i - 1, j, j + 1, j + 1))
				ans.append((i - 1, i, i, j + 1, j + 1, j + 2))
				g[i][j + 2] = 1 - g[i][j + 2]
			else:
				ans.append((i, i - 1, i - 1, j, j, j + 1))
				ans.append((i - 1, i - 1, i, j, j + 1, j + 1))
				g[i][j + 1] = 0
	if g[i - 1][m - 2] == 0:
		if g[i][m - 2] == 1 and g[i][m - 1] == 1:
			if g[i - 1][m - 1] == 1:
				ans.append((i - 1, i, i, m - 1, m - 1, m - 2))
			else:
				ans.append((i, i - 1, i - 1, m - 2, m - 2, m - 1))
				ans.append((i - 1, i - 1, i, m - 2, m - 1, m - 1))
		if g[i][m - 2] == 0 and g[i][m - 1] == 1:
			if g[i - 1][m - 1] == 1:
				ans.append((i - 1, i, i, m - 2, m - 2, m - 1))
				ans.append((i, i - 1, i - 1, m - 2, m - 2, m - 1))
			else:
				ans.append((i - 1, i, i, m - 2, m - 2, m - 1))
				ans.append((i - 1, i - 1, i, m - 2, m - 1, m - 1))
				ans.append((i - 1, i, i, m - 1, m - 1, m - 2))
		if g[i][m - 2] == 1 and g[i][m - 1] == 0:
			if g[i - 1][m - 1] == 1:
				ans.append((i - 1, i - 1, i, m - 2, m - 1, m - 1))
				ans.append((i - 1, i, i, m - 2, m - 2, m - 1))
			else:
				ans.append((i - 1, i, i, m - 2, m - 2, m - 1))
				ans.append((i - 1, i, i, m - 1, m - 1, m - 2))
				ans.append((i - 1, i - 1, i, m - 2, m - 1, m - 2))
		if g[i][m - 2] == 0 and g[i][m - 1] == 0 and (g[i - 1][m - 1] == 1):
			ans.append((i - 1, i - 1, i, m - 1, m - 2, m - 2))
			ans.append((i - 1, i - 1, i, m - 2, m - 1, m - 1))
			ans.append((i - 1, i, i, m - 1, m - 1, m - 2))
	else:
		if g[i][m - 2] == 1 and g[i][m - 1] == 1:
			if g[i - 1][m - 1] == 0:
				ans.append((i - 1, i, i, m - 2, m - 2, m - 1))
			else:
				ans.append((i - 1, i - 1, i, m - 2, m - 1, m - 1))
				ans.append((i, i - 1, i - 1, m - 2, m - 2, m - 1))
				ans.append((i - 1, i, i, m - 2, m - 2, m - 1))
				ans.append((i - 1, i, i, m - 1, m - 1, m - 2))
		if g[i][m - 2] == 0 and g[i][m - 1] == 0:
			if g[i - 1][m - 1] == 1:
				ans.append((i - 1, i, i, m - 2, m - 2, m - 1))
				ans.append((i - 1, i, i, m - 1, m - 1, m - 2))
			else:
				ans.append((i - 1, i, i, m - 2, m - 2, m - 1))
				ans.append((i, i - 1, i - 1, m - 2, m - 2, m - 1))
				ans.append((i - 1, i - 1, i, m - 2, m - 1, m - 1))
		if g[i][m - 2] == 1 and g[i][m - 1] == 0:
			if g[i - 1][m - 1] == 1:
				ans.append((i, i - 1, i - 1, m - 2, m - 2, m - 1))
			else:
				ans.append((i - 1, i - 1, i, m - 2, m - 1, m - 1))
				ans.append((i, i, i - 1, m - 2, m - 1, m - 1))
		if g[i][m - 2] == 0 and g[i][m - 1] == 1:
			if g[i - 1][m - 1] == 1:
				ans.append((i - 1, i - 1, i, m - 2, m - 1, m - 1))
			else:
				ans.append((i, i, i - 1, m - 2, m - 1, m - 1))
				ans.append((i, i - 1, i - 1, m - 2, m - 2, m - 1))
	print(len(ans))
	for i in range(len(ans)):
		print(ans[i][0] + 1, ans[i][3] + 1, ans[i][1] + 1, ans[i][4] + 1, ans[i][2] + 1, ans[i][5] + 1)
testcase(int(inp()))


n = int(input())
for i in range(0, n):
	L = []
	Q = []
	W = []
	S = []
	D = []
	ans = []
	o = input().rstrip().split(' ')
	for j in range(0, int(o[0])):
		p = input().rstrip()
		p = list(p)
		L.append(p)
	r = int(o[0])
	c = int(o[1])
	for j in range(0, r - 1):
		for k in range(0, c - 1):
			A = L[j][k:k + 2]
			B = L[j + 1][k:k + 2]
			C = A.count('0') + B.count('0')
			E = []
			R = []
			for O in range(0, len(A)):
				if A[O] == '0':
					E.append(j)
					E.append(k + O)
				else:
					R.append(j)
					R.append(k + O)
			for O in range(0, len(B)):
				if B[O] == '0':
					E.append(j + 1)
					E.append(k + O)
				else:
					R.append(j + 1)
					R.append(k + O)
			if C == 4:
				continue
			elif C == 0:
				ans.append(R[0])
				ans.append(R[1])
				ans.append(R[2])
				ans.append(R[3])
				ans.append(R[4])
				ans.append(R[5])
				ans.append(R[0])
				ans.append(R[1])
				ans.append(R[2])
				ans.append(R[3])
				ans.append(R[6])
				ans.append(R[7])
				ans.append(R[0])
				ans.append(R[1])
				ans.append(R[4])
				ans.append(R[5])
				ans.append(R[6])
				ans.append(R[7])
				ans.append(R[4])
				ans.append(R[5])
				ans.append(R[6])
				ans.append(R[7])
				ans.append(R[2])
				ans.append(R[3])
				for O in range(k, k + 2):
					L[j][O] = str(0)
					L[j + 1][O] = str(0)
			elif C == 1:
				for O in range(0, len(R)):
					ans.append(R[O])
				for O in range(k, k + 2):
					L[j][O] = str(0)
					L[j + 1][O] = str(0)
			elif C == 2:
				for O in range(0, len(E)):
					ans.append(E[O])
				ans.append(R[0])
				ans.append(R[1])
				for O in range(0, len(E)):
					ans.append(E[O])
				ans.append(R[2])
				ans.append(R[3])
				for O in range(k, k + 2):
					L[j][O] = str(0)
					L[j + 1][O] = str(0)
			else:
				ans.append(E[0])
				ans.append(E[1])
				ans.append(E[2])
				ans.append(E[3])
				ans.append(R[0])
				ans.append(R[1])
				ans.append(R[0])
				ans.append(R[1])
				ans.append(E[4])
				ans.append(E[5])
				ans.append(E[0])
				ans.append(E[1])
				ans.append(E[2])
				ans.append(E[3])
				ans.append(E[4])
				ans.append(E[5])
				ans.append(R[0])
				ans.append(R[1])
				for O in range(k, k + 2):
					L[j][O] = str(0)
					L[j + 1][O] = str(0)
	print(len(ans) // 6)
	for i in range(0, len(ans), 6):
		print(ans[i] + 1, end=' ')
		print(ans[i + 1] + 1, end=' ')
		print(ans[i + 2] + 1, end=' ')
		print(ans[i + 3] + 1, end=' ')
		print(ans[i + 4] + 1, end=' ')
		print(ans[i + 5] + 1)


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	l = []
	for i in range(n):
		s = str(input())
		t = []
		for i in range(len(s)):
			t.append(int(s[i]))
		l.append(t)
	(lr, lc) = ([], [])
	for i in range(n - 2):
		for j in range(m):
			if j == m - 1:
				if l[i][j] == 1:
					lr.append(i)
					lc.append(j)
					l[i][j] = 0
					lr.append(i + 1)
					lc.append(j - 1)
					l[i + 1][j - 1] = 1 - l[i + 1][j - 1]
					lr.append(i + 1)
					lc.append(j)
					l[i + 1][j] = 1 - l[i + 1][j]
			elif l[i][j] == 1:
				lr.append(i)
				lc.append(j)
				l[i][j] = 0
				lr.append(i + 1)
				lc.append(j + 1)
				l[i + 1][j + 1] = 1 - l[i + 1][j + 1]
				lr.append(i + 1)
				lc.append(j)
				l[i + 1][j] = 1 - l[i + 1][j]
	if m % 2 != 0:
		if l[n - 2][m - 1] == 1:
			lr.append(n - 2)
			lc.append(m - 1)
			l[n - 2][m - 1] = 0
			lr.append(n - 2)
			lc.append(m - 2)
			l[n - 2][m - 2] = 1 - l[n - 2][m - 2]
			lr.append(n - 1)
			lc.append(m - 2)
			l[n - 1][m - 2] = 1 - l[n - 1][m - 2]
		if l[n - 1][m - 1] == 1:
			lr.append(n - 1)
			lc.append(m - 1)
			l[n - 1][m - 1] = 0
			lr.append(n - 2)
			lc.append(m - 2)
			l[n - 2][m - 2] = 1 - l[n - 2][m - 2]
			lr.append(n - 1)
			lc.append(m - 2)
			l[n - 1][m - 2] = 1 - l[n - 1][m - 2]
	i = n - 2
	for j in range(0, m - 1, 2):
		if l[i][j] == 1 and l[i + 1][j] == 1 and (l[i][j + 1] == 1) and (l[i + 1][j + 1] == 1):
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
		elif l[i][j] == 1 and l[i + 1][j] == 1 and (l[i + 1][j + 1] == 1):
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
		elif l[i][j] == 1 and l[i][j + 1] == 1 and (l[i + 1][j] == 1):
			lr.append(i)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
		elif l[i][j] == 1 and l[i][j + 1] == 1 and (l[i + 1][j + 1] == 1):
			lr.append(i)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j + 1)
		elif l[i][j + 1] == 1 and l[i + 1][j] == 1 and (l[i + 1][j + 1] == 1):
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
		elif l[i][j] == 1 and l[i + 1][j] == 1:
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j + 1)
		elif l[i][j] == 1 and l[i][j + 1] == 1:
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
		elif l[i][j + 1] == 1 and l[i + 1][j + 1] == 1:
			lr.append(i)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
		elif l[i + 1][j] == 1 and l[i + 1][j + 1] == 1:
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j + 1)
		elif l[i][j] == 1 and l[i + 1][j + 1] == 1:
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
		elif l[i][j + 1] == 1 and l[i + 1][j] == 1:
			lr.append(i)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
		elif l[i][j] == 1:
			lr.append(i)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
		elif l[i][j + 1] == 1:
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j + 1)
		elif l[i + 1][j] == 1:
			lr.append(i)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
		elif l[i + 1][j + 1] == 1:
			lr.append(i)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j)
			lr.append(i)
			lc.append(j + 1)
			lr.append(i + 1)
			lc.append(j + 1)
	print(len(lr) // 3)
	for i in range(0, len(lr), 3):
		print(lr[i] + 1, lc[i] + 1, lr[i + 1] + 1, lc[i + 1] + 1, lr[i + 2] + 1, lc[i + 2] + 1)


moves = 0

def check_sum(i, j):
	x = 0
	for c in range(2):
		for d in range(2):
			x += a[i + c][j + d]
	return x

def fix3(i, j):
	global moves
	moves += 1
	temp = ''
	for c in range(2):
		for d in range(2):
			if a[i + c][j + d]:
				a[i + c][j + d] = int(not a[i + c][j + d])
				temp += str(i + c + 1) + ' ' + str(j + d + 1) + ' '
	global text
	text.append(temp)

def fix2(i, j):
	global moves
	moves += 1
	temp = ''
	enough = False
	for c in range(2):
		for d in range(2):
			if not a[i + c][j + d]:
				a[i + c][j + d] = int(not a[i + c][j + d])
				temp += str(i + c + 1) + ' ' + str(j + d + 1) + ' '
			elif a[i + c][j + d] and (not enough):
				a[i + c][j + d] = int(not a[i + c][j + d])
				temp += str(i + c + 1) + ' ' + str(j + d + 1) + ' '
				enough = not enough
	global text
	text.append(temp)
	fix3(i, j)

def fix1(i, j):
	global moves
	moves += 1
	temp = ''
	enough = 0
	for c in range(2):
		for d in range(2):
			if a[i + c][j + d]:
				a[i + c][j + d] = int(not a[i + c][j + d])
				temp += str(i + c + 1) + ' ' + str(j + d + 1) + ' '
			elif not a[i + c][j + d] and enough < 2:
				a[i + c][j + d] = int(not a[i + c][j + d])
				temp += str(i + c + 1) + ' ' + str(j + d + 1) + ' '
				enough += 1
	global text
	text.append(temp)
	fix2(i, j)

def fix4(i, j):
	global moves
	moves += 1
	temp = ''
	enough = 0
	for c in range(2):
		for d in range(2):
			if a[i + c][j + d] and enough < 3:
				a[i + c][j + d] = int(not a[i + c][j + d])
				temp += str(i + c + 1) + ' ' + str(j + d + 1) + ' '
				enough += 1
	global text
	text.append(temp)
	fix1(i, j)

def fix0(i, j):
	pass
for test in range(int(input())):
	(n, m) = map(int, input().split())
	a = []
	for z in range(n):
		a.append(list(map(int, input())))
	moves = 0
	text = []
	for i in range(n - 1):
		for j in range(m - 1):
			eval(f'fix{check_sum(i, j)}(i,j)')
			j += 2
	print(moves)
	for zz in text:
		print(zz)


def chgg(sttt):
	if sttt == '0':
		return '1'
	return '0'
T = int(input())
for _ in range(0, T):
	(n, m) = map(int, input().split())
	L = []
	for i in range(0, n):
		s = input()
		st = []
		for j in range(0, len(s)):
			st.append(s[j])
		L.append(st)
	ans = []
	for i in range(n - 1):
		for j in range(m - 1):
			if i == n - 2 and j == m - 2:
				for gg in range(4):
					ch = 0
					for e1 in range(2):
						for e2 in range(2):
							ch += int(L[i + e1][j + e2])
					if ch == 0:
						eee = 1
					elif ch == 1:
						h = []
						ct = 0
						for e1 in range(2):
							for e2 in range(2):
								if L[i + e1][j + e2] == '1':
									h.append(i + e1)
									h.append(j + e2)
									L[i + e1][j + e2] = '0'
								elif L[i + e1][j + e2] == '0' and ct < 2:
									ct += 1
									h.append(i + e1)
									h.append(j + e2)
									L[i + e1][j + e2] = '1'
						ans.append(h)
					elif ch == 2:
						h = []
						ct = 0
						for e1 in range(2):
							for e2 in range(2):
								if L[i + e1][j + e2] == '0':
									h.append(i + e1)
									h.append(j + e2)
									L[i + e1][j + e2] = '1'
								elif L[i + e1][j + e2] == '1' and ct < 1:
									ct += 1
									h.append(i + e1)
									h.append(j + e2)
									L[i + e1][j + e2] = '0'
						ans.append(h)
					elif ch == 3:
						h = []
						ct = 0
						for e1 in range(2):
							for e2 in range(2):
								if L[i + e1][j + e2] == '1':
									h.append(i + e1)
									h.append(j + e2)
									L[i + e1][j + e2] = '0'
						ans.append(h)
					elif ch == 4:
						h = []
						ct = 0
						for e1 in range(2):
							for e2 in range(2):
								if L[i + e1][j + e2] == '1' and ct < 3:
									ct += 1
									h.append(i + e1)
									h.append(j + e2)
									L[i + e1][j + e2] = '0'
						ans.append(h)
			elif i == n - 2:
				if L[i][j] == '1' and L[i + 1][j] == '1':
					ans.append([i, j, i + 1, j, i + 1, j + 1])
					L[i][j] = chgg(L[i][j])
					L[i + 1][j] = chgg(L[i + 1][j])
					L[i + 1][j + 1] = chgg(L[i + 1][j + 1])
				elif L[i][j] == '1' and L[i + 1][j] == '0':
					ans.append([i, j, i + 1, j + 1, i, j + 1])
					L[i][j] = chgg(L[i][j])
					L[i][j + 1] = chgg(L[i][j + 1])
					L[i + 1][j + 1] = chgg(L[i + 1][j + 1])
				elif L[i][j] == '0' and L[i + 1][j] == '1':
					ans.append([i + 1, j + 1, i, j + 1, i + 1, j])
					L[i][j + 1] = chgg(L[i][j + 1])
					L[i + 1][j] = chgg(L[i + 1][j])
					L[i + 1][j + 1] = chgg(L[i + 1][j + 1])
			elif L[i][j] == '1' and L[i][j + 1] == '1':
				ans.append([i, j, i, j + 1, i + 1, j])
				L[i][j + 1] = chgg(L[i][j + 1])
				L[i + 1][j] = chgg(L[i + 1][j])
				L[i][j] = chgg(L[i][j])
			elif L[i][j] == '1' and L[i][j + 1] == '0':
				ans.append([i, j, i + 1, j + 1, i + 1, j])
				L[i][j] = chgg(L[i][j])
				L[i + 1][j] = chgg(L[i + 1][j])
				L[i + 1][j + 1] = chgg(L[i + 1][j + 1])
			elif L[i][j] == '0' and L[i][j + 1] == '1':
				ans.append([i + 1, j + 1, i, j + 1, i + 1, j])
				L[i][j + 1] = chgg(L[i][j + 1])
				L[i + 1][j] = chgg(L[i + 1][j])
				L[i + 1][j + 1] = chgg(L[i + 1][j + 1])
	print(len(ans))
	for i in range(0, len(ans)):
		for j in range(0, len(ans[i])):
			ans[i][j] += 1
	for i in ans:
		print(*i)


import os
import sys
from io import BytesIO, IOBase
import heapq as h
import bisect
from types import GeneratorType
BUFSIZE = 8192

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		import os
		self.os = os
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			self.os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
import collections as col
import math, string

def getInts():
	return [int(s) for s in input().split()]

def getInt():
	return int(input())

def getStrs():
	return [s for s in input().split()]

def getStr():
	return input()

def listStr():
	return list(input())
MOD = 10 ** 9 + 7
mod = 10 ** 9 + 7
t = int(input())
p = 10 ** 9 + 7

def ncr_util():
	inv[0] = inv[1] = 1
	fact[0] = fact[1] = 1
	for i in range(2, 300001):
		inv[i] = inv[i % p] * (p - p // i) % p
	for i in range(1, 300001):
		inv[i] = inv[i - 1] * inv[i] % p
		fact[i] = fact[i - 1] * i % p

def z_array(s1):
	n = len(s1)
	z = [0] * n
	(l, r, k) = (0, 0, 0)
	for i in range(1, n):
		if i > r:
			(l, r) = (i, i)
			while r < n and s1[r - l] == s1[r]:
				r += 1
			z[i] = r - l
			r -= 1
		else:
			k = i - l
			if z[k] < r - i + 1:
				z[i] = z[k]
			else:
				l = i
				while r < n and s1[r - l] == s1[r]:
					r += 1
				z[i] = r - l
				r -= 1
	return z

def solve3(ans, d, i, j):
	ans1 = []
	for i1 in range(i, i + 2):
		for j1 in range(j, j + 2):
			if d[i1][j1] == 1:
				d[i1][j1] ^= 1
				ans1.append(i1)
				ans1.append(j1)
	ans.append(ans1)

def solve2(ans, d, i, j):
	cnt = 0
	ans1 = []
	for i1 in range(i, i + 2):
		for j1 in range(j, j + 2):
			if d[i1][j1] == 0:
				ans1.append(i1)
				ans1.append(j1)
				d[i1][j1] ^= 1
			elif cnt == 0 and d[i1][j1] == 1:
				cnt = 1
				ans1.append(i1)
				ans1.append(j1)
				d[i1][j1] ^= 1
	ans.append(ans1)
	solve3(ans, d, i, j)

def solve1(ans, d, i, j):
	cnt = 0
	ans1 = []
	for i1 in range(i, i + 2):
		for j1 in range(j, j + 2):
			if d[i1][j1] == 1:
				ans1.append(i1)
				ans1.append(j1)
				d[i1][j1] ^= 1
			elif d[i1][j1] == 0 and cnt < 2:
				cnt += 1
				ans1.append(i1)
				ans1.append(j1)
				d[i1][j1] ^= 1
	ans.append(ans1)
	solve2(ans, d, i, j)

def solve4(ans, d, i, j):
	d[i][j] ^= 1
	d[i][j + 1] ^= 1
	d[i + 1][j] ^= 1
	ans.append([i, j, i, j + 1, i + 1, j])
	solve1(ans, d, i, j)

def solve_util(ans, d, i, j):
	(x1, y) = (0, 0)
	for i1 in range(i, i + 2):
		for j1 in range(j, j + 2):
			if d[i1][j1] == 1:
				x1 += 1
	if x1 == 4:
		solve4(ans, d, i, j)
	elif x1 == 3:
		solve3(ans, d, i, j)
	elif x1 == 2:
		solve2(ans, d, i, j)
	elif x1 == 1:
		solve1(ans, d, i, j)

def solve():
	ans = []
	d = {}
	for i in range(n):
		d[i] = []
		for j in range(m):
			if l[i][j] == '0':
				d[i].append(0)
			else:
				d[i].append(1)
	(i1, j1) = (0, 0)
	for i1 in range(n - 2):
		for j1 in range(m):
			if d[i1][j1] == 1:
				if j1 == m - 1:
					ans.append([i1, j1, i1 + 1, j1, i1 + 1, j1 - 1])
					d[i1][j1] ^= 1
					d[i1 + 1][j1] ^= 1
					d[i1 + 1][j1 - 1] ^= 1
				else:
					ans.append([i1, j1, i1 + 1, j1, i1, j1 + 1])
					d[i1][j1] ^= 1
					d[i1 + 1][j1] ^= 1
					d[i1][j1 + 1] ^= 1
	if m % 2 != 0:
		if d[n - 2][m - 1] == 1 and d[n - 1][m - 1] == 1:
			ans.append([n - 2, m - 1, n - 1, m - 1, n - 2, m - 2])
			d[n - 2][m - 1] ^= 1
			d[n - 1][m - 1] ^= 1
			d[n - 2][m - 2] ^= 1
		elif d[n - 2][m - 1] == 1:
			ans.append([n - 2, m - 1, n - 2, m - 2, n - 1, m - 2])
			d[n - 2][m - 1] ^= 1
			d[n - 2][m - 2] ^= 1
			d[n - 1][m - 2] ^= 1
		elif d[n - 1][m - 1] == 1:
			ans.append([n - 1, m - 1, n - 1, m - 2, n - 2, m - 2])
			d[n - 1][m - 1] ^= 1
			d[n - 1][m - 2] ^= 1
			d[n - 2][m - 2] ^= 1
	j1 = 0
	cnt1 = m // 2
	while cnt1:
		solve_util(ans, d, n - 2, j1)
		j1 += 2
		cnt1 -= 1
	print(len(ans))
	for i in range(len(ans)):
		for j in range(6):
			print(ans[i][j] + 1, end=' ')
		print()
for _ in range(t):
	(n, m) = map(int, input().split())
	l = []
	for i in range(n):
		l.append(input())
	solve()


def main():
	(n, m) = map(int, input().split())
	ig = [input() for _ in range(n)]
	g = [[False] * (m + 1) for _ in range(n + 1)]
	ans = []

	def swap(a, b):
		g[a][b] = not g[a][b]

	def out(a, b, c, d, e, f):
		ans.append(' '.join(map(str, [a, b, c, d, e, f])))
		swap(a, b)
		swap(c, d)
		swap(e, f)
	for i in range(n):
		for j in range(m):
			if ig[i][j] == '1':
				g[i + 1][j + 1] = True
	for i in range(1, n - 1):
		for j in range(1, m):
			if g[i][j]:
				if g[i][j + 1]:
					out(i, j, i, j + 1, i + 1, j + 1)
				else:
					out(i, j, i + 1, j, i + 1, j + 1)
			if g[i][j + 1]:
				out(i, j + 1, i + 1, j, i + 1, j + 1)
	for i in range(1, m - 1):
		if g[n - 1][i]:
			if g[n][i]:
				out(n - 1, i, n, i, n - 1, i + 1)
			else:
				out(n - 1, i, n, i + 1, n - 1, i + 1)
		elif g[n][i]:
			out(n, i, n - 1, i + 1, n, i + 1)
	rest = [[n - 1, m - 1], [n - 1, m], [n, m - 1], [n, m]]

	def three():
		cur = []
		for (cx, cy) in rest:
			if g[cx][cy]:
				cur.append(cx)
				cur.append(cy)
		out(*cur)

	def two():
		flag = 1
		cur = []
		for (cx, cy) in rest:
			if g[cx][cy]:
				if flag:
					flag -= 1
					cur.append(cx)
					cur.append(cy)
			else:
				cur.append(cx)
				cur.append(cy)
		out(*cur)
		three()

	def one():
		flag = 2
		cur = []
		for (cx, cy) in rest:
			if not g[cx][cy]:
				if flag:
					flag -= 1
					cur.append(cx)
					cur.append(cy)
			else:
				cur.append(cx)
				cur.append(cy)
		out(*cur)
		two()

	def four():
		flag = 3
		cur = []
		for (cx, cy) in rest:
			if flag:
				flag -= 1
				cur.append(cx)
				cur.append(cy)
		out(*cur)
		one()
	mx = 0
	for i in rest:
		if g[i[0]][i[1]]:
			mx += 1
	if mx == 1:
		one()
	elif mx == 2:
		two()
	elif mx == 3:
		three()
	elif mx == 4:
		four()
	print(len(ans))
	for i in ans:
		print(i)
t = int(input())
for _ in range(t):
	main()


num_test = int(input())

def solve():
	(n, m) = map(int, input().split())
	bList = [[0] * (m + 1)]
	for i in range(n):
		bList.append([0] + list(input()))
	ansNum = 0
	ansList = []
	for i in range(1, n + 1):
		for j in range(1, m + 1):
			if bList[i][j] == '0':
				continue
			ansNum += 3
			dx = 1
			dy = 1
			if i == n:
				dx = -1
			if j == m:
				dy = -1
			ansList.append(sorted([[i, j], [i + dx, j], [i + dx, j + dy]]))
			ansList.append(sorted([[i, j], [i, j + dy], [i + dx, j + dy]]))
			ansList.append(sorted([[i, j], [i, j + dy], [i + dx, j]]))
	print(ansNum)
	for ans in ansList:
		for (i, j) in ans:
			print(i, j, end=' ')
		print()
for i in range(num_test):
	solve()


import copy

def two_two_solver(mat, i, j, ans):
	oneind = []
	zeroind = []
	for x in range(i, i + 2):
		for y in range(j, j + 2):
			if mat[x][y] == '1':
				oneind += [[x, y]]
			else:
				zeroind += [[x, y]]
	if len(oneind) == 0:
		return
	if len(oneind) == 4:
		newoneind = [oneind[0][:]]
		newzeroind = [oneind[1][:], oneind[2][:], oneind[3][:]]
		ans += [[oneind[1][:], oneind[2][:], oneind[3][:]]]
		oneind = copy.deepcopy(newoneind)
		zeroind = copy.deepcopy(newzeroind)
	if len(oneind) == 1:
		newoneind = [zeroind[0][:], zeroind[1][:]]
		newzeroind = [zeroind[2][:], oneind[0][:]]
		ans += [[zeroind[0][:], zeroind[1][:], oneind[0][:]]]
		oneind = copy.deepcopy(newoneind)
		zeroind = copy.deepcopy(newzeroind)
	if len(oneind) == 2:
		newoneind = [zeroind[0][:], zeroind[1][:], oneind[0][:]]
		newzeroind = [oneind[1][:]]
		ans += [[zeroind[0][:], zeroind[1][:], oneind[1][:]]]
		oneind = copy.deepcopy(newoneind)
		zeroind = copy.deepcopy(newzeroind)
	if len(oneind) == 3:
		ans += [[oneind[0][:], oneind[1][:], oneind[2][:]]]
	for x in range(i, i + 2):
		for y in range(j, j + 2):
			mat[x][y] = '0'

def three_two_solver(mat, i, j, ans):
	oneind = []
	zeroind = []
	for x in range(i, i + 2):
		for y in range(j, j + 2):
			if mat[x][y] == '1':
				oneind += [[x, y]]
			else:
				zeroind += [[x, y]]
	oneind2 = []
	zeroind2 = []
	for x in range(i, i + 2):
		for y in range(j + 1, j + 3):
			if mat[x][y] == '1':
				oneind2 += [[x, y]]
			else:
				zeroind2 += [[x, y]]
	if len(oneind2) < len(oneind):
		two_two_solver(mat, i, j + 1, ans)
		two_two_solver(mat, i, j, ans)
	else:
		two_two_solver(mat, i, j, ans)
		two_two_solver(mat, i, j + 1, ans)

def two_three_solver(mat, i, j, ans):
	oneind = []
	zeroind = []
	for x in range(i, i + 2):
		for y in range(j, j + 2):
			if mat[x][y] == '1':
				oneind += [[x, y]]
			else:
				zeroind += [[x, y]]
	oneind2 = []
	zeroind2 = []
	for x in range(i + 1, i + 3):
		for y in range(j, j + 2):
			if mat[x][y] == '1':
				oneind2 += [[x, y]]
			else:
				zeroind2 += [[x, y]]
	if len(oneind2) < len(oneind):
		two_two_solver(mat, i + 1, j, ans)
		two_two_solver(mat, i, j, ans)
	else:
		two_two_solver(mat, i, j, ans)
		two_two_solver(mat, i + 1, j, ans)
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	mat = []
	for i in range(n):
		s = input()
		mat += [[x for x in s]]
	ans = []
	if n % 2 == 0 and m % 2 == 0:
		for i in range(0, n - 1, 2):
			for j in range(0, m - 1, 2):
				two_two_solver(mat, i, j, ans)
	elif n % 2 == 0 and m % 2 == 1:
		for i in range(0, n - 1, 2):
			for j in range(0, m - 3, 2):
				two_two_solver(mat, i, j, ans)
			three_two_solver(mat, i, m - 3, ans)
	elif n % 2 == 1 and m % 2 == 0:
		for i in range(0, n - 3, 2):
			for j in range(0, m - 1, 2):
				two_two_solver(mat, i, j, ans)
		for j in range(0, m - 1, 2):
			two_three_solver(mat, n - 3, j, ans)
	else:
		if mat[n - 1][m - 1] == '1':
			ans += [[[n - 1, m - 1], [n - 2, m - 1], [n - 1, m - 2]]]
			mat[n - 1][m - 1] = '0'
			if mat[n - 2][m - 1] == '1':
				mat[n - 2][m - 1] = '0'
			else:
				mat[n - 2][m - 1] = '1'
			if mat[n - 1][m - 2] == '1':
				mat[n - 1][m - 2] = '0'
			else:
				mat[n - 1][m - 2] = '1'
		if mat[n - 1][m - 2] == '1':
			ans += [[[n - 1, m - 2], [n - 2, m - 2], [n - 1, m - 3]]]
			mat[n - 1][m - 2] = '0'
			if mat[n - 2][m - 2] == '1':
				mat[n - 2][m - 2] = '0'
			else:
				mat[n - 2][m - 2] = '1'
			if mat[n - 1][m - 3] == '1':
				mat[n - 1][m - 3] = '0'
			else:
				mat[n - 1][m - 3] = '1'
		if mat[n - 1][m - 3] == '1':
			ans += [[[n - 1, m - 3], [n - 2, m - 3], [n - 2, m - 2]]]
			mat[n - 1][m - 3] = '0'
			if mat[n - 2][m - 3] == '1':
				mat[n - 2][m - 3] = '0'
			else:
				mat[n - 2][m - 3] = '1'
			if mat[n - 2][m - 2] == '1':
				mat[n - 2][m - 2] = '0'
			else:
				mat[n - 2][m - 2] = '1'
		for i in range(0, n - 3, 2):
			for j in range(0, m - 3, 2):
				two_two_solver(mat, i, j, ans)
		for i in range(0, n - 1, 2):
			three_two_solver(mat, i, m - 3, ans)
		for j in range(0, m - 1, 2):
			two_three_solver(mat, n - 3, j, ans)
	print(len(ans))
	for x in ans:
		for y in x:
			print(y[0] + 1, y[1] + 1, end=' ')
		print('')


from sys import stdin
input = stdin.readline
mp = lambda : map(int, input().split())
it = lambda : int(input())
for _ in range(it()):
	(a, b) = mp()
	t = [list(map(int, list(input().strip()))) for i in range(a)]
	saare = []
	for i in range(a - 2):
		for j in range(b):
			if t[i][j] == 1:
				if j != b - 1:
					t[i][j] = 1 - t[i][j]
					t[i + 1][j] = 1 - t[i + 1][j]
					t[i + 1][j + 1] = 1 - t[i + 1][j + 1]
					saare.append([i, j, i + 1, j, i + 1, j + 1])
				else:
					t[i][j] = 1 - t[i][j]
					t[i + 1][j] = 1 - t[i + 1][j]
					t[i + 1][j - 1] = 1 - t[i + 1][j - 1]
					saare.append([i, j, i + 1, j, i + 1, j - 1])
	ls2 = a - 2
	ls = a - 1
	for k in range(b - 2):
		if t[ls2][k] == t[ls][k] == 0:
			continue
		elif t[ls2][k] == t[ls][k] == 1:
			if t[ls2][k + 1]:
				saare.append([ls, k, ls2, k, ls2, k + 1])
				t[ls2][k] = 1 - t[ls2][k]
				t[ls][k] = 1 - t[ls][k]
				t[ls2][k + 1] = 1 - t[ls2][k + 1]
			else:
				saare.append([ls2, k, ls, k, ls, k + 1])
				t[ls2][k] = 1 - t[ls2][k]
				t[ls][k] = 1 - t[ls][k]
				t[ls][k + 1] = 1 - t[ls][k + 1]
		elif t[ls2][k] == 1:
			saare.append([ls2, k, ls2, k + 1, ls, k + 1])
			t[ls2][k] = 1 - t[ls2][k]
			t[ls2][k + 1] = 1 - t[ls2][k + 1]
			t[ls][k + 1] = 1 - t[ls][k + 1]
		else:
			saare.append([ls, k, ls, k + 1, ls2, k + 1])
			t[ls][k] = 1 - t[ls][k]
			t[ls][k + 1] = 1 - t[ls][k + 1]
			t[ls2][k + 1] = 1 - t[ls2][k + 1]
	st = str(t[ls2][b - 2]) + str(t[ls2][b - 1]) + str(t[ls][b - 2]) + str(t[ls][b - 1])
	if st == '0000':
		pass
	elif st == '0001':
		saare.append([ls, b - 2, ls, b - 1, ls2, b - 1])
		saare.append([ls, b - 1, ls2, b - 1, ls2, b - 2])
		saare.append([ls, b - 1, ls, b - 2, ls2, b - 2])
	elif st == '0010':
		saare.append([ls2, b - 2, ls, b - 2, ls, b - 1])
		saare.append([ls, b - 2, ls, b - 1, ls2, b - 1])
		saare.append([ls, b - 2, ls2, b - 2, ls2, b - 1])
	elif st == '0100':
		saare.append([ls2, b - 2, ls2, b - 1, ls, b - 1])
		saare.append([ls2, b - 1, ls, b - 1, ls, b - 2])
		saare.append([ls2, b - 1, ls2, b - 2, ls, b - 2])
	elif st == '1000':
		saare.append([ls2, b - 1, ls2, b - 2, ls, b - 2])
		saare.append([ls2, b - 2, ls, b - 2, ls, b - 1])
		saare.append([ls2, b - 2, ls2, b - 1, ls, b - 1])
	elif st == '0011':
		saare.append([ls, b - 2, ls, b - 1, ls2, b - 1])
		saare.append([ls2, b - 2, ls2, b - 1, ls, b - 1])
		saare.append([ls2, b - 1, ls, b - 1, ls, b - 2])
		saare.append([ls2, b - 1, ls2, b - 2, ls, b - 2])
	elif st == '0101':
		saare.append([ls2, b - 1, ls, b - 1, ls, b - 2])
		saare.append([ls2, b - 2, ls, b - 2, ls, b - 1])
		saare.append([ls, b - 2, ls, b - 1, ls2, b - 1])
		saare.append([ls, b - 2, ls2, b - 2, ls2, b - 1])
	elif st == '0110':
		saare.append([ls2, b - 1, ls, b - 1, ls, b - 2])
		saare.append([ls, b - 2, ls, b - 1, ls2, b - 1])
		saare.append([ls, b - 1, ls2, b - 1, ls2, b - 2])
		saare.append([ls, b - 1, ls, b - 2, ls2, b - 2])
	elif st == '0111':
		saare.append([ls2, b - 1, ls, b - 1, ls, b - 2])
	elif st == '1001':
		saare.append([ls2, b - 2, ls, b - 2, ls, b - 1])
		saare.append([ls2, b - 2, ls, b - 2, ls, b - 1])
		saare.append([ls, b - 2, ls, b - 1, ls2, b - 1])
		saare.append([ls, b - 2, ls2, b - 2, ls2, b - 1])
	elif st == '1010':
		saare.append([ls2, b - 2, ls, b - 2, ls, b - 1])
		saare.append([ls, b - 2, ls, b - 1, ls2, b - 1])
		saare.append([ls, b - 1, ls2, b - 1, ls2, b - 2])
		saare.append([ls, b - 1, ls, b - 2, ls2, b - 2])
	elif st == '1011':
		saare.append([ls2, b - 2, ls, b - 2, ls, b - 1])
	elif st == '1100':
		saare.append([ls2, b - 2, ls2, b - 1, ls, b - 1])
		saare.append([ls, b - 2, ls, b - 1, ls2, b - 1])
		saare.append([ls, b - 1, ls2, b - 1, ls2, b - 2])
		saare.append([ls, b - 1, ls, b - 2, ls2, b - 2])
	elif st == '1101':
		saare.append([ls2, b - 2, ls2, b - 1, ls, b - 1])
	elif st == '1110':
		saare.append([ls, b - 2, ls2, b - 2, ls2, b - 1])
	elif st == '1111':
		saare.append([ls, b - 2, ls2, b - 2, ls2, b - 1])
		saare.append([ls, b - 2, ls, b - 1, ls2, b - 1])
		saare.append([ls, b - 1, ls2, b - 1, ls2, b - 2])
		saare.append([ls, b - 1, ls, b - 2, ls2, b - 2])
	print(len(saare))
	for i in saare:
		print(*list(map(lambda x: x + 1, i)))


import math
t = int(input())
for case in range(t):
	(n, m) = input().split()
	(n, m) = (int(n), int(m))
	mat = []
	for i in range(n):
		l = [int(i) for i in input()]
		mat.append(l)
	l = []
	count = 0
	for i in range(0, n):
		for j in range(0, m):
			if 0 <= j <= m - 2 and 0 <= i <= n - 2:
				if mat[i][j] == 1:
					mat[i][j] ^= 1
					mat[i][j + 1] ^= 1
					mat[i + 1][j] ^= 1
					l.append(tuple([i + 1, j + 1, i + 1, j + 1 + 1, i + 1 + 1, j + 1]))
					mat[i][j] ^= 1
					mat[i + 1][j] ^= 1
					mat[i + 1][j + 1] ^= 1
					l.append(tuple([i + 1, j + 1, i + 1 + 1, j + 1, i + 1 + 1, j + 1 + 1]))
					mat[i][j] ^= 1
					mat[i][j + 1] ^= 1
					mat[i + 1][j + 1] ^= 1
					l.append(tuple([i + 1, j + 1, i + 1, j + 1 + 1, i + 1 + 1, j + 1 + 1]))
					count += 3
			elif i == n - 1 and j == m - 1:
				if mat[i][j] == 1:
					mat[i][j] ^= 1
					mat[i - 1][j] ^= 1
					mat[i][j - 1] ^= 1
					l.append(tuple([i + 1, j + 1, i - 1 + 1, j + 1, i + 1, j - 1 + 1]))
					mat[i][j] ^= 1
					mat[i - 1][j] ^= 1
					mat[i - 1][j - 1] ^= 1
					l.append(tuple([i + 1, j + 1, i - 1 + 1, j + 1, i - 1 + 1, j - 1 + 1]))
					mat[i][j] ^= 1
					mat[i][j - 1] ^= 1
					mat[i - 1][j - 1] ^= 1
					l.append(tuple([i + 1, j + 1, i + 1, j - 1 + 1, i - 1 + 1, j - 1 + 1]))
					count += 3
			elif i == n - 1 and j < m - 1:
				if mat[i][j] == 1:
					mat[i][j] ^= 1
					mat[i - 1][j] ^= 1
					mat[i][j + 1] ^= 1
					l.append(tuple([i + 1, j + 1, i - 1 + 1, j + 1, i + 1, j + 1 + 1]))
					mat[i][j] ^= 1
					mat[i - 1][j] ^= 1
					mat[i - 1][j + 1] ^= 1
					l.append(tuple([i + 1, j + 1, i - 1 + 1, j + 1, i - 1 + 1, j + 1 + 1]))
					mat[i][j] ^= 1
					mat[i][j + 1] ^= 1
					mat[i - 1][j + 1] ^= 1
					l.append(tuple([i + 1, j + 1, i + 1, j + 1 + 1, i - 1 + 1, j + 1 + 1]))
					count += 3
			elif j == m - 1 and i < n - 1:
				if mat[i][j] == 1:
					mat[i][j] ^= 1
					mat[i + 1][j] ^= 1
					mat[i][j - 1] ^= 1
					l.append(tuple([i + 1, j + 1, i + 1 + 1, j + 1, i + 1, j - 1 + 1]))
					mat[i][j] ^= 1
					mat[i][j - 1] ^= 1
					mat[i + 1][j - 1] ^= 1
					l.append(tuple([i + 1, j + 1, i + 1, j - 1 + 1, i + 1 + 1, j - 1 + 1]))
					mat[i][j] ^= 1
					mat[i + 1][j] ^= 1
					mat[i + 1][j - 1] ^= 1
					l.append(tuple([i + 1, j + 1, i + 1 + 1, j + 1, i + 1 + 1, j - 1 + 1]))
					count += 3
	print(count)
	for i in range(len(l)):
		print(' '.join([str(j) for j in l[i]]))


import sys
input = lambda : sys.stdin.readline().rstrip()
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	field = [list(map(int, input())) for _ in range(n)]
	ans = []
	for i in range(n - 1):
		j = 0
		while j < m:
			while j < m and field[i][j] == 0:
				j += 1
			if j < m:
				if j + 1 < m:
					if field[i][j + 1] == 1:
						ans.append((i, j, i, j + 1, i + 1, j))
						field[i][j] ^= 1
						field[i][j + 1] ^= 1
						field[i + 1][j] ^= 1
					else:
						ans.append((i, j, i + 1, j + 1, i + 1, j))
						field[i][j] ^= 1
						field[i + 1][j + 1] ^= 1
						field[i + 1][j] ^= 1
				else:
					ans.append((i, j, i + 1, j - 1, i + 1, j))
					field[i][j] ^= 1
					field[i + 1][j - 1] ^= 1
					field[i + 1][j] ^= 1
			j += 2
	i = n - 1
	j = 0
	while j < m:
		while j < m and field[i][j] == 0:
			j += 1
		if j < m:
			if j + 1 < m:
				if field[i][j + 1] == 1:
					t = (i - 1, j, i - 1, j + 1, i, j)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans.append(t)
					t = (i - 1, j, i - 1, j + 1, i, j + 1)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans.append(t)
				else:
					t = (i - 1, j, i - 1, j + 1, i, j)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans.append(t)
					t = (i - 1, j, i, j, i, j + 1)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans.append(t)
					t = (i, j, i, j + 1, i - 1, j + 1)
					it = iter(t)
					for (ni, nj) in zip(it, it):
						field[ni][nj] ^= 1
					ans.append(t)
			else:
				t = (i - 1, j, i - 1, j - 1, i, j)
				it = iter(t)
				for (ni, nj) in zip(it, it):
					field[ni][nj] ^= 1
				ans.append(t)
				t = (i - 1, j, i, j, i, j - 1)
				it = iter(t)
				for (ni, nj) in zip(it, it):
					field[ni][nj] ^= 1
				ans.append(t)
				t = (i, j, i, j - 1, i - 1, j - 1)
				it = iter(t)
				for (ni, nj) in zip(it, it):
					field[ni][nj] ^= 1
				ans.append(t)
			j += 2
	print(len(ans))
	for line in ans:
		print(*[l + 1 for l in line])


import sys
input = sys.stdin.readline
I = lambda : list(map(int, input().split()))
(A, B, C, D) = ([0, 0], [0, 1], [1, 0], [1, 1])

def func(a, b, c, d):
	(a, b, c, d) = (int(a), int(b), int(c), int(d))
	x = a + b + c + d
	zz = A * (not a) + B * (not b) + C * (not c) + D * (not d)
	oo = A * a + B * b + C * c + D * d
	pr = []
	if x == 1:
		pr.append(oo + zz[2:])
		pr.append(oo + zz[:2] + zz[4:])
		pr.append(oo + zz[:4])
	elif x == 2:
		pr.append(zz + oo[:2])
		pr.append(zz + oo[2:])
	elif x == 3:
		pr.append(A * a + B * b + C * c + D * d)
	elif x == 4:
		pr.append(oo[2:])
		zz = oo[2:]
		oo = oo[:2]
		pr.append(oo + zz[2:])
		pr.append(oo + zz[:2] + zz[4:])
		pr.append(oo + zz[:4])
	return pr
(t,) = I()
for _ in range(t):
	(n, m) = I()
	l = []
	for i in range(n):
		l.append(list(input().strip()))
	an = []
	for i in range(0, n - 1):
		for j in range(0, m - 1):
			x = func(l[i][j], l[i][j + 1], l[i + 1][j], l[i + 1][j + 1])
			for pp in x:
				for k in range(6):
					pp[k] += 1 + i * (k % 2 == 0) + j * (k % 2)
			an += x
			(l[i][j], l[i][j + 1], l[i + 1][j], l[i + 1][j + 1]) = list('0000')
	print(len(an))
	for i in an:
		print(*i)


def d(n=4):

	def c(n):
		if n == 0:
			return [[]]
		r = []
		for x in c(n - 1):
			r += [[0] + x]
			r += [[1] + x]
		return r
	return {tuple(x): sum(x) for x in c(4)}

def xor(a, b):
	return [x[0] ^ x[1] for x in zip(a, b)]
p3 = [x for x in d() if sum(x) == 3]
route = {4: 1, 1: 2, 2: 3, 3: 0}

def seek(cur):
	s = sum(cur)
	for p in p3:
		if sum(xor(p, cur)) == route[s]:
			return p
	print('error')

def printa(a):
	for x in a:
		print(''.join(map(str, x)))

def f(a):
	result = []
	for x in range(0, n, 2):
		for y in range(0, m, 2):
			i = x - 1 if x == n - 1 else x
			j = y - 1 if y == m - 1 else y
			q = ((i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1))
			cur = [a[x[0]][x[1]] for x in q]
			while True:
				if sum(cur) == 0:
					break
				r = seek(cur)
				cur = xor(cur, r)
				for (Q, R, C) in zip(q, r, cur):
					if R == 1:
						a[Q[0]][Q[1]] = C
				result += [[(x[0][0] + 1, x[0][1] + 1) for x in zip(q, r) if x[1] == 1]]
	print(len(result))
	for x in result:
		line = []
		for (i, j) in x:
			line += [i, j]
		print(' '.join(map(str, line)))
	return
for _ in range(int(input())):
	a = []
	(n, m) = map(int, input().split())
	for x in range(n):
		a += [list(map(int, input()))]
	f(a)


t = int(input())
for _ in range(t):
	(n, m) = [int(x) for x in input().split()]
	l_tmp = []
	for x in range(n):
		l_tmp.append(input())
	l = []
	for x in range(n):
		tmp = []
		for y in range(m):
			if l_tmp[x][y] == '0':
				tmp.append(0)
			else:
				tmp.append(1)
		l.append(tmp)
	i = 0
	ans = []
	j = 0
	while i < n - 1:
		j = 0
		while j < m - 1:
			ones = []
			zeros = []
			if l[i][j] == 0:
				zeros.append([i, j])
			else:
				ones.append([i, j])
			if l[i + 1][j] == 0:
				zeros.append([i + 1, j])
			else:
				ones.append([i + 1, j])
			if l[i][j + 1] == 0:
				zeros.append([i, j + 1])
			else:
				ones.append([i, j + 1])
			if l[i + 1][j + 1] == 0:
				zeros.append([i + 1, j + 1])
			else:
				ones.append([i + 1, j + 1])
			c = len(ones)
			if c == 4:
				ans.append([ones[0], ones[1], ones[2]])
				ans.append([ones[1], ones[2], ones[3]])
				ans.append([ones[0], ones[1], ones[3]])
				ans.append([ones[0], ones[2], ones[3]])
			elif c == 3:
				ans.append(ones)
			elif c == 2:
				ans.append([zeros[0], zeros[1], ones[0]])
				ans.append([zeros[0], zeros[1], ones[1]])
			elif c == 1:
				if zeros[0][0] + 1 == zeros[1][0] and zeros[0][1] + 1 == zeros[1][1] or (zeros[1][0] + 1 == zeros[0][0] and zeros[1][1] + 1 == zeros[0][1]):
					ans.append([zeros[0], zeros[1], ones[0]])
					zeros.append(ones[0])
					ones.pop()
					ones.append(zeros[0])
					ones.append(zeros[1])
					zeros.pop(0)
					zeros.pop(0)
					ans.append([zeros[0], zeros[1], ones[0]])
					ans.append([zeros[0], zeros[1], ones[1]])
				elif zeros[0][0] + 1 == zeros[2][0] and zeros[0][1] + 1 == zeros[2][1] or (zeros[2][0] + 1 == zeros[0][0] and zeros[2][1] + 1 == zeros[0][1]):
					ans.append([zeros[0], zeros[2], ones[0]])
					zeros.append(ones[0])
					ones.pop()
					ones.append(zeros[0])
					ones.append(zeros[2])
					zeros.pop(0)
					zeros.pop(1)
					ans.append([zeros[0], zeros[1], ones[0]])
					ans.append([zeros[0], zeros[1], ones[1]])
				elif zeros[1][0] + 1 == zeros[2][0] and zeros[1][1] + 1 == zeros[2][1] or (zeros[2][0] + 1 == zeros[1][0] and zeros[2][1] + 1 == zeros[1][1]):
					ans.append([zeros[1], zeros[2], ones[0]])
					zeros.append(ones[0])
					ones.pop()
					ones.append(zeros[1])
					ones.append(zeros[2])
					zeros.pop(1)
					zeros.pop(1)
					ans.append([zeros[0], zeros[1], ones[0]])
					ans.append([zeros[0], zeros[1], ones[1]])
				elif zeros[0][0] - 1 == zeros[1][0] and zeros[0][1] + 1 == zeros[1][1] or (zeros[1][0] - 1 == zeros[0][0] and zeros[1][1] + 1 == zeros[0][1]):
					ans.append([zeros[0], zeros[1], ones[0]])
					zeros.append(ones[0])
					ones.pop()
					ones.append(zeros[0])
					ones.append(zeros[1])
					zeros.pop(0)
					zeros.pop(0)
					ans.append([zeros[0], zeros[1], ones[0]])
					ans.append([zeros[0], zeros[1], ones[1]])
				elif zeros[0][0] - 1 == zeros[2][0] and zeros[0][1] + 1 == zeros[2][1] or (zeros[2][0] - 1 == zeros[0][0] and zeros[2][1] + 1 == zeros[0][1]):
					ans.append([zeros[0], zeros[2], ones[0]])
					zeros.append(ones[0])
					ones.pop()
					ones.append(zeros[0])
					ones.append(zeros[2])
					zeros.pop(0)
					zeros.pop(1)
					ans.append([zeros[0], zeros[1], ones[0]])
					ans.append([zeros[0], zeros[1], ones[1]])
				elif zeros[1][0] - 1 == zeros[2][0] and zeros[1][1] + 1 == zeros[2][1] or (zeros[2][0] - 1 == zeros[1][0] and zeros[2][1] + 1 == zeros[1][1]):
					ans.append([zeros[1], zeros[2], ones[0]])
					zeros.append(ones[0])
					ones.pop()
					ones.append(zeros[1])
					ones.append(zeros[2])
					zeros.pop(1)
					zeros.pop(1)
					ans.append([zeros[0], zeros[1], ones[0]])
					ans.append([zeros[0], zeros[1], ones[1]])
			l[i][j] = 0
			l[i + 1][j] = 0
			l[i + 1][j + 1] = 0
			l[i][j + 1] = 0
			if j + 1 == m - 1 or j == m - 1:
				break
			if j + 2 < m - 1:
				j += 2
			elif j + 2 == m - 1:
				j += 1
		if i + 1 == n - 1 or i == n - 1:
			break
		if i + 2 < n - 1:
			i += 2
		elif i + 2 == n - 1:
			i += 1
	print(len(ans))
	for c in range(len(ans)):
		print(ans[c][0][0] + 1, ans[c][0][1] + 1, ans[c][1][0] + 1, ans[c][1][1] + 1, ans[c][2][0] + 1, ans[c][2][1] + 1)


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	arr = [[*map(int, input())] for _ in range(n)]
	ans = []

	def invert(i, j, k, a, b, c):
		arr[i][j] = 1 if arr[i][j] == 0 else 0
		arr[k][a] = 1 if arr[k][a] == 0 else 0
		arr[b][c] = 1 if arr[b][c] == 0 else 0
	for i in range(n - 2):
		for j in range(m):
			if arr[i][j] == 1:
				ans.append([i, j, i + 1, j, i + 1, j + 1 if j == 0 else j - 1])
				invert(i, j, i + 1, j, i + 1, j + 1 if j == 0 else j - 1)
	i = n - 2
	for j in range(0, m, 2):
		if j == m - 1:
			j -= 1
		if arr[i][j] + arr[i + 1][j] + arr[i][j + 1] + arr[i + 1][j + 1] == 4:
			ans.append([i, j, i + 1, j, i, j + 1])
			invert(i, j, i + 1, j, i, j + 1)
			if j + 2 < m:
				ans.append([i + 1, j + 1, i + 1, j + 2, i, j + 2])
				invert(i + 1, j + 1, i + 1, j + 2, i, j + 2)
			else:
				ans.append([i, j, i, j + 1, i + 1, j + 1])
				invert(i, j, i, j + 1, i + 1, j + 1)
				ans.append([i, j, i + 1, j, i + 1, j + 1])
				invert(i, j, i + 1, j, i + 1, j + 1)
				ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
				invert(i, j + 1, i + 1, j, i + 1, j + 1)
		elif arr[i][j] + arr[i + 1][j] + arr[i][j + 1] + arr[i + 1][j + 1] == 3:
			if arr[i][j] == 0:
				ans.append([i + 1, j, i, j + 1, i + 1, j + 1])
				invert(i + 1, j, i, j + 1, i + 1, j + 1)
			elif arr[i + 1][j] == 0:
				ans.append([i, j, i, j + 1, i + 1, j + 1])
				invert(i, j, i, j + 1, i + 1, j + 1)
			elif arr[i][j + 1] == 0:
				ans.append([i, j, i + 1, j, i + 1, j + 1])
				invert(i, j, i + 1, j, i + 1, j + 1)
			elif arr[i + 1][j + 1] == 0:
				ans.append([i, j, i + 1, j, i, j + 1])
				invert(i, j, i + 1, j, i, j + 1)
		elif arr[i][j] + arr[i + 1][j] + arr[i][j + 1] + arr[i + 1][j + 1] == 2:
			if arr[i][j] == arr[i + 1][j] == 0:
				ans.append([i, j, i + 1, j, i, j + 1])
				invert(i, j, i + 1, j, i, j + 1)
				ans.append([i, j, i + 1, j, i + 1, j + 1])
				invert(i, j, i + 1, j, i + 1, j + 1)
			elif arr[i][j] == arr[i][j + 1] == 0:
				ans.append([i, j, i, j + 1, i + 1, j + 1])
				ans.append([i, j, i, j + 1, i + 1, j])
				invert(i, j, i, j + 1, i + 1, j + 1)
				invert(i, j, i, j + 1, i + 1, j)
			elif arr[i][j] == arr[i + 1][j + 1] == 0:
				ans.append([i, j, i + 1, j + 1, i, j + 1])
				ans.append([i, j, i + 1, j + 1, i + 1, j])
				invert(i, j, i + 1, j + 1, i, j + 1)
				invert(i, j, i + 1, j + 1, i + 1, j)
			elif arr[i + 1][j] == arr[i + 1][j + 1] == 0:
				ans.append([i + 1, j, i + 1, j + 1, i, j])
				ans.append([i + 1, j, i + 1, j + 1, i, j + 1])
				invert(i + 1, j, i + 1, j + 1, i, j)
				invert(i + 1, j, i + 1, j + 1, i, j + 1)
			elif arr[i][j + 1] == arr[i + 1][j + 1] == 0:
				ans.append([i, j + 1, i + 1, j + 1, i, j])
				ans.append([i, j + 1, i + 1, j + 1, i + 1, j])
				invert(i, j + 1, i + 1, j + 1, i, j)
				invert(i, j + 1, i + 1, j + 1, i + 1, j)
			elif arr[i][j + 1] == arr[i + 1][j] == 0:
				ans.append([i, j + 1, i + 1, j, i, j])
				ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
				invert(i, j + 1, i + 1, j, i, j)
				invert(i, j + 1, i + 1, j, i + 1, j + 1)
		elif arr[i][j] + arr[i + 1][j] + arr[i][j + 1] + arr[i + 1][j + 1] == 1:
			if arr[i][j] == 1:
				ans.append([i, j, i, j + 1, i + 1, j + 1])
				ans.append([i, j, i + 1, j, i, j + 1])
				ans.append([i, j, i + 1, j, i + 1, j + 1])
				invert(i, j, i, j + 1, i + 1, j + 1)
				invert(i, j, i + 1, j, i, j + 1)
				invert(i, j, i + 1, j, i + 1, j + 1)
			elif arr[i + 1][j] == 1:
				ans.append([i, j, i, j + 1, i + 1, j])
				ans.append([i, j, i + 1, j, i + 1, j + 1])
				ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
				invert(i, j, i, j + 1, i + 1, j)
				invert(i, j, i + 1, j, i + 1, j + 1)
				invert(i, j + 1, i + 1, j, i + 1, j + 1)
			elif arr[i][j + 1] == 1:
				ans.append([i, j, i, j + 1, i + 1, j])
				ans.append([i, j, i, j + 1, i + 1, j + 1])
				ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
				invert(i, j, i, j + 1, i + 1, j)
				invert(i, j, i, j + 1, i + 1, j + 1)
				invert(i, j + 1, i + 1, j, i + 1, j + 1)
			elif arr[i + 1][j + 1] == 1:
				ans.append([i, j, i + 1, j, i + 1, j + 1])
				ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
				ans.append([i, j, i, j + 1, i + 1, j + 1])
				invert(i, j, i + 1, j, i + 1, j + 1)
				invert(i, j + 1, i + 1, j, i + 1, j + 1)
				invert(i, j, i, j + 1, i + 1, j + 1)
	print(len(ans))
	for i in ans:
		i = [j + 1 for j in i]
		print(*i)


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	k = 0
	mat = []
	for _ in range(n):
		row = list(input())
		mat.append(row)
	ans = []
	for i in range(n):
		for j in range(m):
			temp = []
			if mat[i][j] == '1':
				if i != n - 1 and j != m - 1:
					temp.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
					temp.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					temp.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
				elif i == n - 1 and j != m - 1:
					temp.append([i + 1, j + 1, i, j + 1, i + 1, j + 2])
					temp.append([i + 1, j + 1, i, j + 1, i, j + 2])
					temp.append([i + 1, j + 1, i + 1, j + 2, i, j + 2])
				elif j == m - 1 and i != n - 1:
					temp.append([i + 1, j + 1, i + 2, j + 1, i + 1, j])
					temp.append([i + 1, j + 1, i + 1, j, i + 2, j])
					temp.append([i + 1, j + 1, i + 2, j + 1, i + 2, j])
				else:
					temp.append([i + 1, j + 1, i, j + 1, i + 1, j])
					temp.append([i + 1, j + 1, i, j + 1, i, j])
					temp.append([i + 1, j + 1, i, j, i + 1, j])
				k += 3
			if len(temp):
				ans.append(temp)
	print(k)
	for w in ans:
		for l in w:
			print(*l)


import sys
import math
import bisect
from sys import stdin, stdout
from math import gcd, floor, sqrt, log
from collections import defaultdict as dd
from bisect import bisect_left as bl, bisect_right as br
from collections import Counter
from collections import defaultdict as dd
inp = lambda : int(input())
strng = lambda : input().strip()
jn = lambda x, l: x.join(map(str, l))
strl = lambda : list(input().strip())
mul = lambda : map(int, input().strip().split())
mulf = lambda : map(float, input().strip().split())
seq = lambda : list(map(int, input().strip().split()))
ceil = lambda x: int(x) if x == int(x) else int(x) + 1
ceildiv = lambda x, d: x // d if x % d == 0 else x // d + 1
flush = lambda : stdout.flush()
stdstr = lambda : stdin.readline()
stdint = lambda : int(stdin.readline())
stdpr = lambda x: stdout.write(str(x))
stdmap = lambda : map(int, stdstr().split())
stdarr = lambda : list(map(int, stdstr().split()))
mod = 1000000007
d = {4: 1, 1: 2, 2: 3, 3: 0}

def printm(lol):
	for i in lol:
		print(*i)
	print('----')
for _ in range(stdint()):
	(n, m) = stdmap()
	x = []
	for i in range(n):
		row = list(input())
		rx = []
		for i in row:
			rx.append(int(i))
		x.append(rx)
	x1 = []
	for i in x:
		x1.append(i.copy())
	res = []
	for i in range(n - 1):
		for j in range(m - 1):
			xx = [x[i][j], x[i][j + 1], x[i + 1][j], x[i + 1][j + 1]]
			o = xx.count(1)
			while o != 0:
				if o == 4:
					res.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					(xx[0], xx[1], xx[2]) = (0, 0, 0)
				elif o == 1:
					r = xx.index(1)
					if r == 0:
						res.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
						(xx[0], xx[1], xx[2]) = (0, 1, 1)
					elif r == 1:
						res.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
						(xx[1], xx[2], xx[3]) = (0, 1, 1)
					elif r == 2:
						res.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
						(xx[2], xx[1], xx[0]) = (0, 1, 1)
					else:
						res.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
						(xx[3], xx[2], xx[1]) = (0, 1, 1)
				elif o == 2:
					if xx[0] == 1:
						if xx[1] == 1:
							res.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
							(xx[0], xx[2], xx[3]) = (0, 1, 1)
						elif xx[2] == 1:
							res.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
							(xx[0], xx[1], xx[3]) = (0, 1, 1)
						else:
							res.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
							(xx[0], xx[1], xx[2]) = (0, 1, 1)
					elif xx[1] == 1:
						if xx[2] == 1:
							res.append([i + 1, j + 2, i + 1, j + 1, i + 2, j + 2])
							(xx[1], xx[0], xx[3]) = (0, 1, 1)
						elif xx[3] == 1:
							res.append([i + 1, j + 2, i + 2, j + 1, i + 1, j + 1])
							(xx[1], xx[0], xx[2]) = (0, 1, 1)
					else:
						res.append([i + 2, j + 1, i + 1, j + 1, i + 1, j + 2])
						(xx[2], xx[0], xx[1]) = (0, 1, 1)
				elif o == 3:
					r = xx.index(0)
					if r == 0:
						res.append([i + 1, j + 2, i + 2, j + 1, i + 2, j + 2])
					elif r == 1:
						res.append([i + 1, j + 1, i + 2, j + 1, i + 2, j + 2])
					elif r == 2:
						res.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					else:
						res.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
					xx = [0, 0, 0, 0]
				else:
					break
				o = d[o]
				x[i][j] = xx[0]
				x[i][j + 1] = xx[1]
				x[i + 1][j] = xx[2]
				x[i + 1][j + 1] = xx[3]
	print(len(res))
	for i in res:
		x1[i[0] - 1][i[1] - 1] ^= 1
		x1[i[2] - 1][i[3] - 1] ^= 1
		x1[i[4] - 1][i[5] - 1] ^= 1
		print(*i)


import math
inf = float('inf')
mod = 10 ** 9 + 7
for _ in range(int(input())):
	(m, n) = map(int, input().split())
	A = [[0] * (n + 1)] + [[0] + list(map(int, list(input()))) for _ in range(m)]
	ans = []
	for i in range(1, m - 1):
		for j in range(1, n + 1):
			if A[i][j]:
				ans.append([i, j, i + 1, j, i + 1, j + 1 if j < n else j - 1])
				A[i][j] ^= 1
				A[i + 1][j] ^= 1
				A[i + 1][j + 1 if j < n else j - 1] ^= 1
	for j in range(1, n - 1):
		if A[m - 1][j] and A[m][j]:
			ans.append([m - 1, j, m, j, m - 1, j + 1])
			A[m - 1][j] ^= 1
			A[m][j] ^= 1
			A[m - 1][j + 1] ^= 1
		elif A[m - 1][j]:
			ans.append([m - 1, j, m - 1, j + 1, m, j + 1])
			A[m - 1][j] ^= 1
			A[m - 1][j + 1] ^= 1
			A[m][j + 1] ^= 1
		elif A[m][j]:
			ans.append([m, j, m, j + 1, m - 1, j + 1])
			A[m][j] ^= 1
			A[m][j + 1] ^= 1
			A[m - 1][j + 1] ^= 1
	if A[m - 1][n - 1] ^ A[m - 1][n] ^ A[m][n - 1]:
		ans.append([m - 1, n - 1, m - 1, n, m, n - 1])
	if A[m - 1][n - 1] ^ A[m][n - 1] ^ A[m][n]:
		ans.append([m - 1, n - 1, m, n - 1, m, n])
	if A[m][n - 1] ^ A[m][n] ^ A[m - 1][n]:
		ans.append([m, n - 1, m, n, m - 1, n])
	if A[m][n] ^ A[m - 1][n] ^ A[m - 1][n - 1]:
		ans.append([m, n, m - 1, n, m - 1, n - 1])
	print(len(ans))
	for a in ans:
		print(*a)


import sys

def z4(o):
	p = []
	return p

def z0(o):
	p = []
	cnt = 0
	for i in o:
		if cnt == 3:
			break
		if l[i[0]][i[1]] == 1:
			l[i[0]][i[1]] = 0
			p.append(i[0] + 1)
			p.append(i[1] + 1)
			cnt += 1
	return p

def z3(o):
	p = []
	cnt0 = 0
	cnt1 = 0
	for i in o:
		if l[i[0]][i[1]] == 0 and cnt0 < 2:
			l[i[0]][i[1]] = 1
			p.append(i[0] + 1)
			p.append(i[1] + 1)
			cnt0 += 1
			continue
		if l[i[0]][i[1]] == 1 and cnt1 < 1:
			l[i[0]][i[1]] = 0
			p.append(i[0] + 1)
			p.append(i[1] + 1)
			cnt1 += 1
	return p

def z2(o):
	p = []
	cnt0 = 0
	cnt1 = 0
	for i in o:
		if l[i[0]][i[1]] == 0 and cnt0 < 2:
			l[i[0]][i[1]] = 1
			p.append(i[0] + 1)
			p.append(i[1] + 1)
			cnt0 += 1
			continue
		if l[i[0]][i[1]] == 1 and cnt1 < 1:
			l[i[0]][i[1]] = 0
			p.append(i[0] + 1)
			p.append(i[1] + 1)
			cnt1 += 1
	return p

def z1(o):
	p = []
	cnt1 = 0
	for i in o:
		if l[i[0]][i[1]] == 1 and cnt1 < 3:
			l[i[0]][i[1]] = 0
			p.append(i[0] + 1)
			p.append(i[1] + 1)
			cnt1 += 1
	return p
for _ in range(int(input())):
	(n, m) = map(int, input().split())
	l = []
	for i in range(n):
		x = input()
		o = []
		cnt = 0
		for j in x:
			o.append(int(j))
		l.append(o)
	i = 0
	ans = 0
	b = []
	while i < n - 1:
		j = 0
		while j < m - 1:
			o = []
			e1 = (i, j)
			e2 = (i, j + 1)
			e3 = (i + 1, j)
			e4 = (i + 1, j + 1)
			z = 0
			o.append(e1)
			o.append(e2)
			o.append(e3)
			o.append(e4)
			if l[i][j] == 0:
				z += 1
			if l[i][j + 1] == 0:
				z += 1
			if l[i + 1][j] == 0:
				z += 1
			if l[i + 1][j + 1] == 0:
				z += 1
			if z == 3:
				ans += 3
			if z == 2:
				ans += 2
			if z == 1:
				ans += 1
			if z == 0:
				ans += 4
			if z == 0:
				b.append(z0(o))
				b.append(z3(o))
				b.append(z2(o))
				b.append(z1(o))
			if z == 1:
				b.append(z1(o))
			if z == 2:
				b.append(z2(o))
				b.append(z1(o))
			if z == 3:
				b.append(z3(o))
				b.append(z2(o))
				b.append(z1(o))
			j = j + 1
		i = i + 1
	print(ans)
	for i in b:
		print(*i)


import math
a = int(input())
arr = []
(n, m) = (0, 0)

def flip(i):
	if i == 0:
		return 1
	return 0

def p(ans):
	print(len(ans))
	for i in range(0, len(ans)):
		for j in range(0, len(ans[0])):
			ans[i][j] = ans[i][j] + 1
	for i in ans:
		print(' '.join(map(str, i)))

def o1(temp):
	temp.append([n - 2, m - 2, n - 2, m - 1, n - 1, m - 1])
	arr[n - 2][m - 2] = flip(arr[n - 2][m - 2])
	arr[n - 2][m - 1] = flip(arr[n - 2][m - 1])
	arr[n - 1][m - 1] = flip(arr[n - 1][m - 1])

def o2(temp):
	temp.append([n - 1, m - 1, n - 2, m - 1, n - 1, m - 2])
	arr[n - 1][m - 1] = flip(arr[n - 1][m - 1])
	arr[n - 2][m - 1] = flip(arr[n - 2][m - 1])
	arr[n - 1][m - 2] = flip(arr[n - 1][m - 2])

def o3(temp):
	temp.append([n - 1, m - 1, n - 1, m - 2, n - 2, m - 2])
	arr[n - 1][m - 1] = flip(arr[n - 1][m - 1])
	arr[n - 1][m - 2] = flip(arr[n - 1][m - 2])
	arr[n - 2][m - 2] = flip(arr[n - 2][m - 2])

def o4(temp):
	temp.append([n - 2, m - 2, n - 1, m - 2, n - 2, m - 1])
	arr[n - 2][m - 2] = flip(arr[n - 2][m - 2])
	arr[n - 1][m - 2] = flip(arr[n - 1][m - 2])
	arr[n - 2][m - 1] = flip(arr[n - 2][m - 1])
for i in range(a):
	(n, m) = map(int, input().split())
	arr = []
	for i in range(n):
		s = input()
		arr.append([int(i) for i in s])
	ans = []
	for i in range(0, n - 2):
		for j in range(0, m):
			if arr[i][j] == 1 and j < m - 1:
				ans.append([i, j, i, j + 1, i + 1, j])
				arr[i][j] = flip(arr[i][j])
				arr[i][j + 1] = flip(arr[i][j + 1])
				arr[i + 1][j] = flip(arr[i + 1][j])
			elif arr[i][j] == 1:
				ans.append([i, j, i + 1, j, i + 1, j - 1])
				arr[i][j] = flip(arr[i][j])
				arr[i + 1][j] = flip(arr[i + 1][j])
				arr[i + 1][j - 1] = flip(arr[i + 1][j - 1])
	for j in range(0, m - 2):
		for i in range(n - 2, n):
			if arr[i][j] == 1:
				if i == n - 2:
					ans.append([i, j, i, j + 1, i + 1, j + 1])
					arr[i][j] = flip(arr[i][j])
					arr[i][j + 1] = flip(arr[i][j + 1])
					arr[i + 1][j + 1] = flip(arr[i + 1][j + 1])
				else:
					ans.append([i, j, i, j + 1, i - 1, j + 1])
					arr[i][j] = flip(arr[i][j])
					arr[i][j + 1] = flip(arr[i][j + 1])
					arr[i - 1][j + 1] = flip(arr[i - 1][j + 1])
	su = 0
	for i in range(n - 2, n):
		for j in range(m - 2, m):
			su = su + arr[i][j]
	if su == 0:
		p(ans)
	if su == 1:
		if arr[n - 2][m - 2] == 1:
			o1(ans)
			o3(ans)
			o4(ans)
			p(ans)
		if arr[n - 1][m - 1] == 1:
			o1(ans)
			o2(ans)
			o3(ans)
			p(ans)
		if arr[n - 2][m - 1] == 1:
			o2(ans)
			o1(ans)
			o4(ans)
			p(ans)
		if arr[n - 1][m - 2] == 1:
			o4(ans)
			o2(ans)
			o3(ans)
			p(ans)
	if su == 2:
		if arr[n - 2][m - 2] == 1 and arr[n - 2][m - 1] == 1:
			o2(ans)
			o3(ans)
		if arr[n - 2][m - 2] == 1 and arr[n - 1][m - 2] == 1:
			o1(ans)
			o2(ans)
		if arr[n - 1][m - 1] == 1 and arr[n - 2][m - 1] == 1:
			o3(ans)
			o4(ans)
		if arr[n - 1][m - 1] == 1 and arr[n - 1][m - 2] == 1:
			o4(ans)
			o1(ans)
		if arr[n - 1][m - 1] == 1 and arr[n - 2][m - 2] == 1:
			o2(ans)
			o4(ans)
		if arr[n - 2][m - 1] == 1 and arr[n - 1][m - 2] == 1:
			o1(ans)
			o3(ans)
		p(ans)
	if su == 4:
		o2(ans)
		o1(ans)
		o3(ans)
		o4(ans)
		p(ans)
	if su == 3:
		temp = []
		for i in range(n - 2, n):
			for j in range(m - 2, m):
				if arr[i][j] == 1:
					temp.append(i)
					temp.append(j)
		ans.append(temp)
		p(ans)


for __ in range(int(input())):
	(n, m) = list(map(int, input().split()))
	ar = []
	for i in range(n):
		ar.append(list(map(int, input())))
	ans = []
	for i in range(0, n // 2 * 2, 2):
		for j in range(0, m // 2 * 2, 2):
			kek1 = []
			kek2 = []
			if ar[i][j] == 1:
				kek1.append([i + 1, j + 1])
			else:
				kek2.append([i + 1, j + 1])
			if ar[i][j + 1] == 1:
				kek1.append([i + 1, j + 2])
			else:
				kek2.append([i + 1, j + 2])
			if ar[i + 1][j] == 1:
				kek1.append([i + 2, j + 1])
			else:
				kek2.append([i + 2, j + 1])
			if ar[i + 1][j + 1] == 1:
				kek1.append([i + 2, j + 2])
			else:
				kek2.append([i + 2, j + 2])
			if len(kek1) == 3:
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
			elif len(kek1) == 2:
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
				ans.append([kek1[1][0], kek1[1][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
			elif len(kek1) == 1:
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[2][0], kek2[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek2[1][0], kek2[1][1], kek2[2][0], kek2[2][1]])
			elif len(kek1) == 4:
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[3][0], kek1[3][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek1[3][0], kek1[3][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[3][0], kek1[3][1]])
		if m % 2 == 1:
			kek1 = []
			kek2 = []
			j = m - 2
			kek2.append([i + 1, j + 1])
			if ar[i][j + 1] == 1:
				kek1.append([i + 1, j + 2])
			else:
				kek2.append([i + 1, j + 2])
			kek2.append([i + 2, j + 1])
			if ar[i + 1][j + 1] == 1:
				kek1.append([i + 2, j + 2])
			else:
				kek2.append([i + 2, j + 2])
			if len(kek1) == 3:
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
			elif len(kek1) == 2:
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
				ans.append([kek1[1][0], kek1[1][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
			elif len(kek1) == 1:
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[2][0], kek2[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek2[1][0], kek2[1][1], kek2[2][0], kek2[2][1]])
			elif len(kek1) == 4:
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[3][0], kek1[3][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek1[3][0], kek1[3][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[3][0], kek1[3][1]])
	if n % 2 == 1:
		i = n - 2
		for j in range(0, m // 2 * 2, 2):
			kek1 = []
			kek2 = []
			kek2.append([i + 1, j + 1])
			kek2.append([i + 1, j + 2])
			if ar[i + 1][j] == 1:
				kek1.append([i + 2, j + 1])
			else:
				kek2.append([i + 2, j + 1])
			if ar[i + 1][j + 1] == 1:
				kek1.append([i + 2, j + 2])
			else:
				kek2.append([i + 2, j + 2])
			if len(kek1) == 3:
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
			elif len(kek1) == 2:
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
				ans.append([kek1[1][0], kek1[1][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
			elif len(kek1) == 1:
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[2][0], kek2[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek2[1][0], kek2[1][1], kek2[2][0], kek2[2][1]])
			elif len(kek1) == 4:
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[3][0], kek1[3][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek1[3][0], kek1[3][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[3][0], kek1[3][1]])
		if m % 2 == 1:
			(i, j) = (n - 2, m - 2)
			kek1 = []
			kek2 = []
			kek2.append([i + 1, j + 1])
			kek2.append([i + 1, j + 2])
			kek2.append([i + 2, j + 1])
			if ar[i + 1][j + 1] == 1:
				kek1.append([i + 2, j + 2])
			else:
				kek2.append([i + 2, j + 2])
			if len(kek1) == 3:
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
			elif len(kek1) == 2:
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
				ans.append([kek1[1][0], kek1[1][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
			elif len(kek1) == 1:
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[1][0], kek2[1][1]])
				ans.append([kek1[0][0], kek1[0][1], kek2[0][0], kek2[0][1], kek2[2][0], kek2[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek2[1][0], kek2[1][1], kek2[2][0], kek2[2][1]])
			elif len(kek1) == 4:
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[3][0], kek1[3][1], kek1[1][0], kek1[1][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek1[3][0], kek1[3][1], kek1[2][0], kek1[2][1]])
				ans.append([kek1[0][0], kek1[0][1], kek1[1][0], kek1[1][1], kek1[3][0], kek1[3][1]])
	print(len(ans))
	for elem in ans:
		print(*elem)


from itertools import chain as _chain

def how_to_make_zeros(matrix):
	n = len(matrix)
	m = len(matrix[0])
	if n % 2 == 0 and m % 2 == 0:
		for y in range(0, n, 2):
			for x in range(0, m, 2):
				yield from _get_moves_to_invert_2x2(x, y, matrix)
	elif m % 3 != 0:
		if m % 3 == 2:
			offset = 2
		else:
			assert m % 3 == 1
			offset = 4
		odd = [row[:offset] for row in matrix]
		odd = tuple(zip(*odd))
		moves_for_odd = how_to_make_zeros(odd)
		moves_for_odd = map(lambda move: tuple(((y, x) for (x, y) in move)), moves_for_odd)
		yield from moves_for_odd
		remain = [row[offset:] for row in matrix]
		moves_for_remain = how_to_make_zeros(remain)
		moves_for_remain = (tuple(((x + offset, y) for (x, y) in move)) for move in moves_for_remain)
		yield from moves_for_remain
	else:
		for y in range(n):
			for x in range(0, m, 3):
				yield from _get_moves_to_invert_3x1(x, y, matrix)

def _get_moves_to_invert_cell(pos):
	(x, y) = pos
	inv_x = x - 1 if x != 0 else x + 1
	inv_y = y - 1 if y != 0 else y + 1
	return [((x, y), (inv_x, y), (inv_x, inv_y)), ((x, y), (x, inv_y), (inv_x, inv_y)), ((x, y), (inv_x, y), (x, inv_y))]

def _get_moves_to_invert_2x2(x, y, matrix):
	get_val = lambda pos: matrix[pos[1]][pos[0]]
	poses = [(x, y), (x + 1, y), (x, y + 1), (x + 1, y + 1)]
	active_poses = tuple(filter(lambda pos: get_val(pos) == '1', poses))
	active_n = len(active_poses)
	dead_poses = tuple(filter(lambda pos: get_val(pos) == '0', poses))
	if active_n == 0:
		moves = []
	elif active_n == 1:
		((x1, y1),) = active_poses
		moves = _get_moves_to_invert_cell((x1, y1))
	elif active_n == 2:
		(act1, act2) = active_poses
		(dead1, dead2) = dead_poses
		moves = [(dead1, dead2, act1), (dead1, dead2, act2)]
	elif active_n == 3:
		moves = [active_poses]
	else:
		assert active_n == 4
		poses = set(poses)
		moves = [poses - {pos} for pos in poses]
		moves = list(map(tuple, moves))
	return moves

def _get_moves_to_invert_3x1(x, y, matrix):
	inv_y = y - 1 if y != 0 else y + 1
	active_xs = tuple(filter(lambda x: matrix[y][x] == '1', (x, x + 1, x + 2)))
	active_n = len(active_xs)
	if active_n == 0:
		moves = []
	elif active_n == 1:
		(x1,) = active_xs
		moves = _get_moves_to_invert_cell((x1, y))
	elif active_n == 2:
		(x1, x2) = active_xs
		if x1 + 1 == x2:
			moves = [((x1, inv_y), (x2, inv_y), (x1, y)), ((x1, inv_y), (x2, inv_y), (x2, y))]
		else:
			assert x1 + 2 == x2
			mid_x = x1 + 1
			moves = [((mid_x, y), (mid_x, inv_y), (x1, y)), ((mid_x, y), (mid_x, inv_y), (x2, y))]
	elif active_n == 3:
		moves = [((x + 2, y), (x + 1, y), (x + 1, inv_y)), ((x + 1, y), (x, inv_y), (x, y)), ((x + 1, y), (x, inv_y), (x + 1, inv_y))]
	return moves

def main():
	(t,) = _read_ints()
	for i_t in range(t):
		(n, m) = _read_ints()
		matrix = tuple((input() for i in range(n)))
		moves = list(how_to_make_zeros(matrix))
		print(len(moves))
		for move in moves:
			move = tuple(((y + 1, x + 1) for (x, y) in move))
			print(*_chain.from_iterable(move))

def _read_ints():
	return map(int, input().split())
main()


def oneSolve(ones, zeros, M, ans):
	(x1, y1) = ones.pop()
	(x2, y2) = zeros.pop()
	(x3, y3) = zeros.pop()
	M[x1][y1] = 0
	M[x2][y2] = 1
	M[x3][y3] = 1
	zeros.append([x1, y1])
	ones.append([x2, y2])
	ones.append([x3, y3])
	ans.append([x1, y1, x2, y2, x3, y3])
	twoSolve(ones, zeros, M, ans)

def twoSolve(ones, zeros, M, ans):
	(x1, y1) = ones.pop()
	(x2, y2) = zeros.pop()
	(x3, y3) = zeros.pop()
	M[x1][y1] = 0
	M[x2][y2] = 1
	M[x3][y3] = 1
	zeros.append([x1, y1])
	ones.append([x2, y2])
	ones.append([x3, y3])
	ans.append([x1, y1, x2, y2, x3, y3])
	threeSolve(ones, zeros, M, ans)

def threeSolve(ones, zeros, M, ans):
	L = list()
	for _ in range(3):
		(x, y) = ones.pop()
		zeros.append([x, y])
		M[x][y] = 0
		L.append(x)
		L.append(y)
	ans.append(L)

def fourSolve(ones, zeros, M, ans):
	L = list()
	for _ in range(3):
		(x, y) = ones.pop()
		zeros.append([x, y])
		M[x][y] = 0
		L.append(x)
		L.append(y)
	ans.append(L)
	oneSolve(ones, zeros, M, ans)

def solver(x, y, M, ans):
	pos = [[x, y], [x + 1, y], [x, y + 1], [x + 1, y + 1]]
	ones = list()
	zeros = list()
	for (i, j) in pos:
		if M[i][j] == 1:
			ones.append([i, j])
		else:
			zeros.append([i, j])
	c = len(ones)
	if c == 0:
		return
	if c == 1:
		oneSolve(ones, zeros, M, ans)
	elif c == 2:
		twoSolve(ones, zeros, M, ans)
	elif c == 3:
		threeSolve(ones, zeros, M, ans)
	else:
		fourSolve(ones, zeros, M, ans)
t = int(input())
for _ in range(t):
	(n, m) = map(int, input().split())
	M = list()
	for _ in range(n):
		s = input()
		l = list()
		for c in s:
			l.append(int(c))
		M.append(l)
	if n % 2 == 0:
		R = n
	else:
		R = n - 1
	if m % 2 == 0:
		C = m
	else:
		C = m - 1
	ans = list()
	i = 0
	while i < R:
		j = 0
		while j < C:
			solver(i, j, M, ans)
			j += 2
		i += 2
	if n % 2 == 1:
		j = 0
		while j < C:
			solver(n - 2, j, M, ans)
			j += 2
	if m % 2 == 1:
		i = 0
		while i < R:
			solver(i, m - 2, M, ans)
			i += 2
	if n % 2 == 1 and m % 2 == 1:
		solver(n - 2, m - 2, M, ans)
	print(len(ans))
	for line in ans:
		for pos in line:
			print(pos + 1, end=' ')
		print()


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	a = []
	li = []
	for __ in range(n):
		a.append(list(input()))
	for j in range(m - 2, 0, -1):
		for i in range(n - 1):
			if a[i][j + 1] == '1' and a[i + 1][j + 1] == '0':
				li.append([i + 1, j + 1 + 1, i + 1, j + 1, i + 1 + 1, j + 1])
				a[i][j + 1] = str(int(a[i][j + 1]) ^ 1)
				a[i][j] = str(int(a[i][j]) ^ 1)
				a[i + 1][j] = str(int(a[i + 1][j]) ^ 1)
			elif a[i][j + 1] == '0' and a[i + 1][j + 1] == '1':
				li.append([i + 1 + 1, j + 1 + 1, i + 1, j + 1, i + 1 + 1, j + 1])
				a[i + 1][j + 1] = str(int(a[i + 1][j + 1]) ^ 1)
				a[i][j] = str(int(a[i][j]) ^ 1)
				a[i + 1][j] = str(int(a[i + 1][j]) ^ 1)
			elif a[i][j + 1] == '1' and a[i + 1][j + 1] == '1':
				li.append([i + 1 + 1, j + 1 + 1, i + 1, j + 1 + 1, i + 1 + 1, j + 1])
				a[i + 1][j + 1] = str(int(a[i + 1][j + 1]) ^ 1)
				a[i][j + 1] = str(int(a[i][j + 1]) ^ 1)
				a[i + 1][j] = str(int(a[i + 1][j]) ^ 1)
	for i in range(n - 1):
		if a[i][0] == '1' and a[i][1] == '0':
			li.append([i + 1, 0 + 1, i + 1 + 1, 0 + 1, i + 1 + 1, 1 + 1])
			a[i][0] = str(int(a[i][0]) ^ 1)
			a[i + 1][0] = str(int(a[i + 1][0]) ^ 1)
			a[i + 1][1] = str(int(a[i + 1][1]) ^ 1)
		elif a[i][0] == '0' and a[i][1] == '1':
			li.append([i + 1, 1 + 1, i + 1 + 1, 0 + 1, i + 1 + 1, 1 + 1])
			a[i][1] = str(int(a[i][1]) ^ 1)
			a[i + 1][0] = str(int(a[i + 1][0]) ^ 1)
			a[i + 1][1] = str(int(a[i + 1][1]) ^ 1)
		elif a[i][0] == '1' and a[i][1] == '1':
			li.append([i + 1, 0 + 1, i + 1, 1 + 1, i + 1 + 1, 1 + 1])
			a[i][0] = str(int(a[i][0]) ^ 1)
			a[i][1] = str(int(a[i][1]) ^ 1)
			a[i + 1][1] = str(int(a[i + 1][1]) ^ 1)
	if a[n - 1][0] == '1' and a[n - 1][1] == '0':
		li.append([n - 1 + 1, 0 + 1, n - 2 + 1, 0 + 1, n - 2 + 1, 1 + 1])
		a[n - 1][0] = str(int(a[n - 1][0]) ^ 1)
		a[n - 2][0] = str(int(a[n - 2][0]) ^ 1)
		a[n - 2][1] = str(int(a[n - 2][1]) ^ 1)
		li.append([n - 2 + 1, 1 + 1, n - 1 + 1, 0 + 1, n - 1 + 1, 1 + 1])
		a[n - 2][1] = str(int(a[n - 2][1]) ^ 1)
		a[n - 1][0] = str(int(a[n - 1][0]) ^ 1)
		a[n - 1][1] = str(int(a[n - 1][1]) ^ 1)
		li.append([n - 2 + 1, 0 + 1, n - 1 + 1, 0 + 1, n - 1 + 1, 1 + 1])
		a[n - 2][0] = str(int(a[n - 2][0]) ^ 1)
		a[n - 1][0] = str(int(a[n - 1][0]) ^ 1)
		a[n - 1][1] = str(int(a[n - 1][1]) ^ 1)
	elif a[n - 1][0] == '0' and a[n - 1][1] == '1':
		li.append([n - 1 + 1, 1 + 1, n - 2 + 1, 0 + 1, n - 2 + 1, 1 + 1])
		a[n - 1][1] = str(int(a[n - 1][1]) ^ 1)
		a[n - 2][0] = str(int(a[n - 2][0]) ^ 1)
		a[n - 2][1] = str(int(a[n - 2][1]) ^ 1)
		li.append([n - 2 + 1, 1 + 1, n - 1 + 1, 0 + 1, n - 1 + 1, 1 + 1])
		a[n - 2][1] = str(int(a[n - 2][1]) ^ 1)
		a[n - 1][0] = str(int(a[n - 1][0]) ^ 1)
		a[n - 1][1] = str(int(a[n - 1][1]) ^ 1)
		li.append([n - 2 + 1, 0 + 1, n - 1 + 1, 0 + 1, n - 1 + 1, 1 + 1])
		a[n - 2][0] = str(int(a[n - 2][0]) ^ 1)
		a[n - 1][0] = str(int(a[n - 1][0]) ^ 1)
		a[n - 1][1] = str(int(a[n - 1][1]) ^ 1)
	elif a[n - 1][0] == '1' and a[n - 1][1] == '1':
		li.append([n - 1 + 1, 1 + 1, n - 2 + 1, 0 + 1, n - 2 + 1, 1 + 1])
		a[n - 1][1] = str(int(a[n - 1][1]) ^ 1)
		a[n - 2][0] = str(int(a[n - 2][0]) ^ 1)
		a[n - 2][1] = str(int(a[n - 2][1]) ^ 1)
		li.append([n - 1 + 1, 0 + 1, n - 2 + 1, 0 + 1, n - 2 + 1, 1 + 1])
		a[n - 1][0] = str(int(a[n - 1][0]) ^ 1)
		a[n - 2][0] = str(int(a[n - 2][0]) ^ 1)
		a[n - 2][1] = str(int(a[n - 2][1]) ^ 1)
	print(len(li))
	for i in li:
		print(*i, sep=' ')


def fn(ii, jj):
	if grid[ii][jj] == '0':
		grid[ii][jj] = '1'
	else:
		grid[ii][jj] = '0'

def solve(row):
	one = int(grid[row][c - 2]) + int(grid[row][c - 1]) + int(grid[row + 1][c - 2]) + int(grid[row + 1][c - 1])
	if one != 0:
		if one == 4:
			l.append([row + 1, c, row + 2, c - 1, row + 2, c])
			l.append([row + 1, c - 1, row + 2, c - 1, row + 2, c])
			l.append([row + 1, c - 1, row + 1, c, row + 2, c])
			l.append([row + 1, c - 1, row + 1, c, row + 2, c - 1])
		elif one == 3:
			ll = []
			if grid[row][c - 2] == '1':
				ll += [row + 1, c - 1]
			if grid[row][c - 1] == '1':
				ll += [row + 1, c]
			if grid[row + 1][c - 2] == '1':
				ll += [row + 2, c - 1]
			if grid[row + 1][c - 1] == '1':
				ll += [row + 2, c]
			l.append(ll)
		elif one == 2:
			if grid[row][c - 2] == '1' and grid[row][c - 1] == '1':
				l.append([row + 1, c, row + 2, c - 1, row + 2, c])
				l.append([row + 1, c - 1, row + 2, c - 1, row + 2, c])
			elif grid[row + 1][c - 2] == '1' and grid[row + 1][c - 1] == '1':
				l.append([row + 1, c - 1, row + 1, c, row + 2, c])
				l.append([row + 1, c - 1, row + 1, c, row + 2, c - 1])
			elif grid[row][c - 2] == '1' and grid[row + 1][c - 2] == '1':
				l.append([row + 1, c, row + 2, c - 1, row + 2, c])
				l.append([row + 1, c - 1, row + 1, c, row + 2, c])
			elif grid[row][c - 1] == '1' and grid[row + 1][c - 1] == '1':
				l.append([row + 1, c - 1, row + 2, c - 1, row + 2, c])
				l.append([row + 1, c - 1, row + 1, c, row + 2, c - 1])
			elif grid[row][c - 2] == '1' and grid[row + 1][c - 1] == '1':
				l.append([row + 1, c, row + 2, c - 1, row + 2, c])
				l.append([row + 1, c - 1, row + 1, c, row + 2, c - 1])
			else:
				l.append([row + 1, c - 1, row + 2, c - 1, row + 2, c])
				l.append([row + 1, c - 1, row + 1, c, row + 2, c])
		elif grid[row][c - 2] == '1':
			l.append([row + 1, c - 1, row + 2, c - 1, row + 2, c])
			l.append([row + 1, c - 1, row + 1, c, row + 2, c])
			l.append([row + 1, c - 1, row + 1, c, row + 2, c - 1])
		elif grid[row][c - 1] == '1':
			l.append([row + 1, c, row + 2, c - 1, row + 2, c])
			l.append([row + 1, c - 1, row + 1, c, row + 2, c])
			l.append([row + 1, c - 1, row + 1, c, row + 2, c - 1])
		elif grid[row + 1][c - 2] == '1':
			l.append([row + 1, c - 1, row + 1, c, row + 2, c - 1])
			l.append([row + 1, c, row + 2, c - 1, row + 2, c])
			l.append([row + 1, c - 1, row + 2, c - 1, row + 2, c])
		else:
			l.append([row + 1, c - 1, row + 1, c, row + 2, c])
			l.append([row + 1, c, row + 2, c - 1, row + 2, c])
			l.append([row + 1, c - 1, row + 2, c - 1, row + 2, c])
for _ in range(int(input())):
	(r, c) = map(int, input().split())
	grid = []
	for i in range(r):
		grid.append(list(input()))
	l = []
	for j in range(c - 2):
		for i in range(r):
			if grid[i][j] == '1':
				if i == r - 1:
					l.append([i + 1, j + 1, i + 1, j + 2, i, j + 2])
					fn(i - 1, j + 1)
				else:
					l.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 2])
					fn(i + 1, j + 1)
				fn(i, j)
				fn(i, j + 1)
	currow = 0
	if r % 2 != 0:
		if grid[0][c - 2] == '1':
			l.append([1, c - 1, 2, c - 1, 2, c])
			fn(0, c - 2)
			fn(1, c - 2)
			fn(1, c - 1)
		if grid[0][c - 1] == '1':
			l.append([1, c, 2, c - 1, 2, c])
			fn(0, c - 1)
			fn(1, c - 2)
			fn(1, c - 1)
		currow = 1
	while currow < r:
		solve(currow)
		currow += 2
	print(len(l))
	for i in l:
		print(*i)


import math
T = int(input())
for _ in range(T):
	(n, m) = map(int, input().split())
	mat = []
	for i in range(n):
		s = input()
		lis = []
		for j in s:
			lis.append(int(j))
		mat.append(lis)
	op = 0
	ans = []
	for i in range(n):
		for j in range(m):
			if mat[i][j] == 1:
				op += 1
				if i < n - 1:
					d = 1
				else:
					d = -1
				if j < m - 1:
					r = 1
				else:
					r = -1
				ans.append([i + 1, j + 1, i + 1, j + 1 + r, i + 1 + d, j + 1])
				ans.append([i + 1, j + 1, i + 1, j + 1 + r, i + 1 + d, j + 1 + r])
				ans.append([i + 1, j + 1, i + 1 + d, j + 1, i + 1 + d, j + 1 + r])
	print(3 * op)
	for i in ans:
		print(*i)


import sys
input = sys.stdin.readline
for _ in range(int(input())):
	(n, m) = list(map(int, input().split()))
	arr = []
	ans = []
	for i in range(n):
		arr.append([])
		temp = input().rstrip()
		for char in temp:
			if char == '1':
				arr[i].append(True)
			else:
				arr[i].append(False)
	for i in range(n - 1, 1, -1):
		for j in range(m):
			if arr[i][j]:
				if j == m - 1:
					arr[i][j] = not arr[i][j]
					arr[i - 1][j] = not arr[i - 1][j]
					arr[i - 1][j - 1] = not arr[i - 1][j - 1]
					ans.append((i, j, i - 1, j, i - 1, j - 1))
				else:
					arr[i][j] = not arr[i][j]
					arr[i - 1][j] = not arr[i - 1][j]
					arr[i - 1][j + 1] = not arr[i - 1][j + 1]
					ans.append((i, j, i - 1, j, i - 1, j + 1))
	if m & 1:
		if arr[0][m - 1]:
			arr[0][m - 1] = not arr[0][m - 1]
			arr[0][m - 2] = not arr[0][m - 2]
			arr[1][m - 2] = not arr[1][m - 2]
			ans.append((0, m - 1, 0, m - 2, 1, m - 2))
		if arr[1][m - 1]:
			arr[1][m - 1] = not arr[1][m - 1]
			arr[1][m - 2] = not arr[1][m - 2]
			arr[0][m - 2] = not arr[0][m - 2]
			ans.append((1, m - 1, 1, m - 2, 0, m - 2))
	for i in range(0, m - 1, 2):
		count1 = 0
		ones = []
		for x in range(2):
			for y in range(2):
				if arr[y][i + x]:
					ones.append((y, i + x))
					count1 += 1
		if count1 == 0:
			pass
		if count1 == 1:
			x = ones[0][0]
			y = ones[0][1]
			count1 = 2
			ans.append((x, y, x ^ 1, y, x, y ^ 1))
			ones = [(x ^ 1, y), (x, y ^ 1)]
			arr[x][y] = not arr[x][y]
			arr[x ^ 1][y] = not arr[x ^ 1][y]
			arr[x][y ^ 1] = not arr[x][y ^ 1]
		if count1 == 2:
			if ones[0][0] == ones[1][0] or ones[0][1] == ones[1][1]:
				ones = [(ones[0][0] ^ 1, ones[0][1] ^ 1), (ones[1][0] ^ 1, ones[1][1] ^ 1)]
			for one in ones:
				x = one[0]
				y = one[1]
				arr[x][y] = not arr[x][y]
				arr[x ^ 1][y] = not arr[x ^ 1][y]
				arr[x][y ^ 1] = not arr[x][y ^ 1]
				ans.append((x, y, x ^ 1, y, x, y ^ 1))
		if count1 == 3:
			arr[ones[0][0]][ones[0][1]] = not arr[ones[0][0]][ones[0][1]]
			arr[ones[1][0]][ones[1][1]] = not arr[ones[1][0]][ones[1][1]]
			arr[ones[2][0]][ones[2][1]] = not arr[ones[2][0]][ones[2][1]]
			ans.append((ones[0][0], ones[0][1], ones[1][0], ones[1][1], ones[2][0], ones[2][1]))
		if count1 == 4:
			for x in range(2):
				for y in range(2):
					arr[x][y + i] = not arr[x][y + i]
					arr[x ^ 1][y + i] = not arr[x ^ 1][y + i]
					arr[x][y ^ 1 + i] = not arr[x][y ^ 1 + i]
					ans.append((x, y + i, x ^ 1, y + i, x, y ^ 1 + i))
	print(len(ans))
	for move in ans:
		for ele in move:
			print(ele + 1, end=' ')
		print()


for _ in range(int(input())):
	(n, m) = map(int, input().split())
	l = []
	for i in range(n):
		s = str(input())
		t = []
		for i in range(len(s)):
			t.append(int(s[i]))
		l.append(t)
	lf = []
	for i in range(n - 2):
		for j in range(m):
			if j == m - 1:
				if l[i][j] == 1:
					lf.append([i, j, i + 1, j - 1, i + 1, j])
					l[i][j] = 0
					l[i + 1][j - 1] = 1 - l[i + 1][j - 1]
					l[i + 1][j] = 1 - l[i + 1][j]
			elif l[i][j] == 1:
				lf.append([i, j, i + 1, j + 1, i + 1, j])
				l[i][j] = 0
				l[i + 1][j + 1] = 1 - l[i + 1][j + 1]
				l[i + 1][j] = 1 - l[i + 1][j]
	if m % 2 != 0:
		if l[n - 2][m - 1] == 1:
			lf.append([n - 2, m - 1, n - 2, m - 2, n - 1, m - 2])
			l[n - 2][m - 1] = 0
			l[n - 2][m - 2] = 1 - l[n - 2][m - 2]
			l[n - 1][m - 2] = 1 - l[n - 1][m - 2]
		if l[n - 1][m - 1] == 1:
			lf.append([n - 1, m - 1, n - 2, m - 2, n - 1, m - 2])
			l[n - 1][m - 1] = 0
			l[n - 2][m - 2] = 1 - l[n - 2][m - 2]
			l[n - 1][m - 2] = 1 - l[n - 1][m - 2]
	i = n - 2
	for j in range(0, m - 1, 2):
		if l[i][j] == 1 and l[i + 1][j] == 1 and (l[i][j + 1] == 1) and (l[i + 1][j + 1] == 1):
			lf.append([i, j, i + 1, j, i, j + 1])
			lf.append([i, j, i + 1, j, i + 1, j + 1])
			lf.append([i, j, i, j + 1, i + 1, j + 1])
			lf.append([i, j + 1, i + 1, j, i + 1, j + 1])
		elif l[i][j] == 1 and l[i + 1][j] == 1 and (l[i + 1][j + 1] == 1):
			lf.append([i, j, i + 1, j, i + 1, j + 1])
		elif l[i][j] == 1 and l[i][j + 1] == 1 and (l[i + 1][j] == 1):
			lf.append([i, j, i, j + 1, i + 1, j])
		elif l[i][j] == 1 and l[i][j + 1] == 1 and (l[i + 1][j + 1] == 1):
			lf.append([i, j, i, j + 1, i + 1, j + 1])
		elif l[i][j + 1] == 1 and l[i + 1][j] == 1 and (l[i + 1][j + 1] == 1):
			lf.append([i, j + 1, i + 1, j, i + 1, j + 1])
		elif l[i][j] == 1 and l[i + 1][j] == 1:
			lf.append([i, j + 1, i + 1, j + 1, i + 1, j])
			lf.append([i, j, i, j + 1, i + 1, j + 1])
		elif l[i][j] == 1 and l[i][j + 1] == 1:
			lf.append([i, j + 1, i + 1, j, i + 1, j + 1])
			lf.append([i, j, i + 1, j + 1, i + 1, j])
		elif l[i][j + 1] == 1 and l[i + 1][j + 1] == 1:
			lf.append([i, j, i, j + 1, i + 1, j])
			lf.append([i, j, i + 1, j, i + 1, j + 1])
		elif l[i + 1][j] == 1 and l[i + 1][j + 1] == 1:
			lf.append([i, j, i + 1, j, i, j + 1])
			lf.append([i, j, i, j + 1, i + 1, j + 1])
		elif l[i][j] == 1 and l[i + 1][j + 1] == 1:
			lf.append([i, j, i + 1, j, i, j + 1])
			lf.append([i + 1, j + 1, i + 1, j, i, j + 1])
		elif l[i][j + 1] == 1 and l[i + 1][j] == 1:
			lf.append([i, j, i, j + 1, i + 1, j + 1])
			lf.append([i, j, i + 1, j, i + 1, j + 1])
		elif l[i][j] == 1:
			lf.append([i, j, i, j + 1, i + 1, j + 1])
			lf.append([i, j, i + 1, j, i + 1, j + 1])
			lf.append([i, j, i + 1, j, i, j + 1])
		elif l[i][j + 1] == 1:
			lf.append([i, j + 1, i + 1, j, i + 1, j + 1])
			lf.append([i, j, i + 1, j, i, j + 1])
			lf.append([i, j, i, j + 1, i + 1, j + 1])
		elif l[i + 1][j] == 1:
			lf.append([i, j, i, j + 1, i + 1, j])
			lf.append([i, j, i + 1, j, i + 1, j + 1])
			lf.append([i, j + 1, i + 1, j, i + 1, j + 1])
		elif l[i + 1][j + 1] == 1:
			lf.append([i, j, i + 1, j, i + 1, j + 1])
			lf.append([i, j, i, j + 1, i + 1, j + 1])
			lf.append([i + 1, j, i, j + 1, i + 1, j + 1])
	print(len(lf))
	for i in range(0, len(lf)):
		for j in range(6):
			print(lf[i][j] + 1, end=' ')
		print()


def nei(i, j):
	ans = []
	ans += [i + 1 if i % 2 else i - 1, j]
	ans += [i, j + 1 if j % 2 else j - 1]
	return ans

def nei2(i, j):
	ans = []
	ans += [i + 1 if i % 2 else i - 1, j]
	ans += [i, j + 1 if not j % 2 else j - 1]
	return ans

def nei3(i, j):
	ans = []
	ans += [i + 1 if not i % 2 else i - 1, j]
	ans += [i, j + 1 if j % 2 else j - 1]
	return ans
for _ in range(int(input())):
	(m, n) = map(int, input().split())
	A = [[0] * (n + 1)] + [[0] + list(map(int, list(input()))) for _ in range(m)]
	ans = []
	for i in range(1, m, 2):
		for j in range(1, n, 2):
			tmp = [A[i][j:j + 2], A[i + 1][j:j + 2]]
			if tmp == [[0, 0], [0, 0]]:
				continue
			if tmp == [[1, 1], [1, 1]]:
				ans.append([i, j, i, j + 1, i + 1, j])
				ans.append([i, j, i + 1, j, i + 1, j + 1])
				ans.append([i + 1, j, i + 1, j + 1, i, j + 1])
				ans.append([i, j, i, j + 1, i + 1, j + 1])
			elif tmp[0].count(1) + tmp[1].count(1) == 3:
				for (x, y) in [(i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1)]:
					if not A[x][y]:
						cur = [[i, j], [i, j + 1], [i + 1, j], [i + 1, j + 1]]
						cur.remove([x, y])
						cur2 = []
						for c in cur:
							cur2 += c
						ans.append(cur2)
						break
			elif tmp[0].count(1) + tmp[1].count(1) == 1:
				for (x, y) in [(i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1)]:
					if A[x][y]:
						nn = nei(x, y)
						(a, b, c, d) = nn
						ans.append([x, y] + nn)
						ans.append([a, b] + nei(a, b))
						ans.append([c, d] + nei(c, d))
						break
			elif tmp[0].count(1) + tmp[1].count(1) == 2:
				if sum(tmp[0]) == 1 and tmp[0][0] + tmp[1][0] == 1:
					if tmp[0][0]:
						ans.append([i, j, i + 1, j, i, j + 1])
						ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
					else:
						ans.append([i, j, i, j + 1, i + 1, j + 1])
						ans.append([i, j, i + 1, j, i + 1, j + 1])
				else:
					for (x, y) in [(i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1)]:
						if not A[x][y]:
							nn = nei(x, y)
							ans.append([x, y] + nn)
	if n % 2:
		j = n - 1
		for i in range(1, m, 2):
			tmp = [[0, A[i][-1]], [0, A[i + 1][-1]]]
			A[i][-2] = A[i + 1][-2] = 0
			if tmp == [[0, 0], [0, 0]]:
				continue
			elif tmp[0].count(1) + tmp[1].count(1) == 1:
				for (x, y) in [(i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1)]:
					if A[x][y]:
						nn = nei2(x, y)
						(a, b, c, d) = nn
						ans.append([x, y] + nn)
						ans.append([a, b] + nei2(a, b))
						ans.append([c, d] + nei2(c, d))
						break
			elif tmp[0].count(1) + tmp[1].count(1) == 2:
				if sum(tmp[0]) == 1 and tmp[0][0] + tmp[1][0] == 1:
					if tmp[0][0]:
						ans.append([i, j, i + 1, j, i, j + 1])
						ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
					else:
						ans.append([i, j, i, j + 1, i + 1, j + 1])
						ans.append([i, j, i + 1, j, i + 1, j + 1])
				else:
					for (x, y) in [(i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1)]:
						if not A[x][y]:
							nn = nei2(x, y)
							ans.append([x, y] + nn)
	if m % 2:
		i = m - 1
		for j in range(1, n, 2):
			tmp = [[0, 0], A[m][j:j + 2]]
			A[-2][j] = A[-2][j + 1] = 0
			if tmp == [[0, 0], [0, 0]]:
				continue
			elif tmp[0].count(1) + tmp[1].count(1) == 1:
				for (x, y) in [(i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1)]:
					if A[x][y]:
						nn = nei3(x, y)
						(a, b, c, d) = nn
						ans.append([x, y] + nn)
						ans.append([a, b] + nei3(a, b))
						ans.append([c, d] + nei3(c, d))
						break
			elif tmp[0].count(1) + tmp[1].count(1) == 2:
				if sum(tmp[0]) == 1 and tmp[0][0] + tmp[1][0] == 1:
					if tmp[0][0]:
						ans.append([i, j, i + 1, j, i, j + 1])
						ans.append([i, j + 1, i + 1, j, i + 1, j + 1])
					else:
						ans.append([i, j, i, j + 1, i + 1, j + 1])
						ans.append([i, j, i + 1, j, i + 1, j + 1])
				else:
					for (x, y) in [(i, j), (i, j + 1), (i + 1, j), (i + 1, j + 1)]:
						if not A[x][y]:
							nn = nei3(x, y)
							ans.append([x, y] + nn)
	if n % 2 and m % 2 and A[-1][-1]:
		ans.append([m, n, m - 1, n, m, n - 1])
		ans.append([m - 1, n - 1, m - 1, n, m, n])
		ans.append([m - 1, n - 1, m, n - 1, m, n])
	print(len(ans))
	for a in ans:
		print(*a)


from sys import stdout, stdin
from collections import defaultdict, deque
import math
d = defaultdict(tuple)
d['1', '1', '1', '1'] = ('0', '0', '1', '0')
d['1', '1', '1', '0'] = ('0', '0', '0', '0')
d['1', '1', '0', '1'] = ('0', '0', '0', '0')
d['1', '1', '0', '0'] = ('0', '0', '1', '0')
d['1', '0', '1', '1'] = ('0', '0', '0', '0')
d['1', '0', '1', '0'] = ('0', '0', '0', '1')
d['1', '0', '0', '1'] = ('1', '1', '1', '0')
d['1', '0', '0', '0'] = ('0', '1', '1', '0')
d['0', '1', '1', '1'] = ('0', '0', '0', '0')
d['0', '1', '1', '0'] = ('1', '0', '1', '1')
d['0', '1', '0', '1'] = ('1', '0', '0', '0')
d['0', '1', '0', '0'] = ('1', '0', '0', '1')
d['0', '0', '1', '1'] = ('0', '1', '0', '0')
d['0', '0', '1', '0'] = ('1', '0', '0', '1')
d['0', '0', '0', '1'] = ('0', '1', '1', '0')
d['0', '0', '0', '0'] = ('0', '0', '0', '0')
t = int(stdin.readline())
for _ in range(t):
	(n, m) = map(int, stdin.readline().split())
	l = []
	for i in range(n):
		l.append(list(stdin.readline().strip()))
	(x, y) = (False, False)
	if n % 2 != 0:
		n -= 1
		x = True
	if m % 2 != 0:
		m -= 1
		y = True
	an = 0
	ans = []
	for i in range(0, n, 2):
		for j in range(0, m, 2):
			temp = (l[i][j], l[i][j + 1], l[i + 1][j], l[i + 1][j + 1])
			while temp != ('0', '0', '0', '0'):
				an += 1
				ll = []
				kk = d[temp]
				if kk[0] != temp[0]:
					ll.append(i + 1)
					ll.append(j + 1)
				if kk[1] != temp[1]:
					ll.append(i + 1)
					ll.append(j + 2)
				if kk[2] != temp[2]:
					ll.append(i + 2)
					ll.append(j + 1)
				if kk[3] != temp[3]:
					ll.append(i + 2)
					ll.append(j + 2)
				temp = kk
				ans.append(ll)
	if x:
		for j in range(0, m, 2):
			temp = ('0', '0', l[n][j], l[n][j + 1])
			while temp != ('0', '0', '0', '0'):
				an += 1
				ll = []
				kk = d[temp]
				if kk[0] != temp[0]:
					ll.append(n)
					ll.append(j + 1)
				if kk[1] != temp[1]:
					ll.append(n)
					ll.append(j + 2)
				if kk[2] != temp[2]:
					ll.append(n + 1)
					ll.append(j + 1)
				if kk[3] != temp[3]:
					ll.append(n + 1)
					ll.append(j + 2)
				temp = kk
				ans.append(ll)
	if y:
		for i in range(0, n, 2):
			temp = ('0', l[i][m], '0', l[i + 1][m])
			while temp != ('0', '0', '0', '0'):
				an += 1
				ll = []
				kk = d[temp]
				if kk[0] != temp[0]:
					ll.append(i + 1)
					ll.append(m)
				if kk[1] != temp[1]:
					ll.append(i + 1)
					ll.append(m + 1)
				if kk[2] != temp[2]:
					ll.append(i + 2)
					ll.append(m)
				if kk[3] != temp[3]:
					ll.append(i + 2)
					ll.append(m + 1)
				temp = kk
				ans.append(ll)
	if x & y:
		temp = ('0', '0', '0', l[n][m])
		while temp != ('0', '0', '0', '0'):
			an += 1
			ll = []
			kk = d[temp]
			if kk[0] != temp[0]:
				ll.append(n)
				ll.append(m)
			if kk[1] != temp[1]:
				ll.append(n)
				ll.append(m + 1)
			if kk[2] != temp[2]:
				ll.append(n + 1)
				ll.append(m)
			if kk[3] != temp[3]:
				ll.append(n + 1)
				ll.append(m + 1)
			temp = kk
			ans.append(ll)
	print(an)
	for i in range(an):
		print(*ans[i])


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline()

def RL():
	return map(int, sys.stdin.readline().split())

def RLL():
	return list(map(int, sys.stdin.readline().split()))

def N():
	return int(input())

def print_list(l):
	print(' '.join(map(str, l)))

def o():
	t = []
	if len(one) == 3:
		for (x, y) in one:
			t.append(x + 1)
			t.append(y + 1)
		res.append(t)
	elif len(one) == 4:
		for _ in range(3):
			(x, y) = one.pop()
			t.append(x + 1)
			t.append(y + 1)
			zero.append((x, y))
		res.append(t)
		o()
	elif len(one) == 1:
		tmp = one.pop()
		t.append(tmp[0] + 1)
		t.append(tmp[1] + 1)
		for _ in range(2):
			(x, y) = zero.pop()
			t.append(x + 1)
			t.append(y + 1)
			one.append((x, y))
		zero.append(tmp)
		res.append(t)
		o()
	elif len(one) == 2:
		tmp = one.pop()
		t.append(tmp[0] + 1)
		t.append(tmp[1] + 1)
		for _ in range(2):
			(x, y) = zero.pop()
			t.append(x + 1)
			t.append(y + 1)
			one.append((x, y))
		zero.append(tmp)
		res.append(t)
		o()
for _ in range(N()):
	(n, m) = RL()
	g = []
	for _ in range(n):
		g.append(list(map(int, list(input().strip()))))
	res = []
	for i in range(0, n - 2):
		for j in range(0, m - 1, 2):
			if g[i][j] == 1 and g[i][j + 1] == 1:
				res.append([i + 1, j + 1, i + 1, j + 2, i + 2, j + 1])
				g[i + 1][j] ^= 1
			elif g[i][j] == 1:
				res.append([i + 1, j + 1, i + 2, j + 2, i + 2, j + 1])
				g[i + 1][j] ^= 1
				g[i + 1][j + 1] ^= 1
			elif g[i][j + 1] == 1:
				res.append([i + 1, j + 2, i + 2, j + 2, i + 2, j + 1])
				g[i + 1][j] ^= 1
				g[i + 1][j + 1] ^= 1
		if m & 1 and g[i][m - 1] == 1:
			res.append([i + 1, m, i + 2, m, i + 2, m - 1])
			g[i + 1][-1] ^= 1
			g[i + 1][-2] ^= 1
	i = n - 2
	for j in range(m - 2):
		if g[i][j] == 1 and g[i + 1][j] == 1:
			res.append([i + 1, j + 1, i + 2, j + 1, i + 1, j + 2])
			g[i][j + 1] ^= 1
		elif g[i][j] == 1:
			res.append([i + 1, j + 1, i + 2, j + 2, i + 1, j + 2])
			g[i][j + 1] ^= 1
			g[i + 1][j + 1] ^= 1
		elif g[i + 1][j] == 1:
			res.append([i + 2, j + 1, i + 2, j + 2, i + 1, j + 2])
			g[i][j + 1] ^= 1
			g[i + 1][j + 1] ^= 1
	(one, zero) = ([], [])
	for i in range(n - 2, n):
		for j in range(m - 2, m):
			if g[i][j] == 1:
				one.append((i, j))
			else:
				zero.append((i, j))
	o()
	print(len(res))
	for l in res:
		print_list(l)


def correct(x, y):
	ans.append([x + 1, y + 1, x + 1, y + 2, x + 2, y + 2])
	ans.append([x + 1, y + 1, x + 2, y + 1, x + 2, y + 2])
	ans.append([x + 1, y + 1, x + 1, y + 2, x + 2, y + 1])
for nt in range(int(input())):
	(n, m) = map(int, input().split())
	(a, ans) = ([], [])
	for i in range(n):
		a.append(list(map(int, list(input()))))
	for i in range(n - 1):
		for j in range(m - 1):
			if a[i][j] == 1:
				correct(i, j)
	for i in range(n - 1):
		if a[i][-1] == 1:
			ans.append([i + 1, m, i + 2, m, i + 1, m - 1])
			ans.append([i + 1, m, i + 2, m, i + 2, m - 1])
			ans.append([i + 1, m, i + 1, m - 1, i + 2, m - 1])
	for i in range(m - 1):
		if a[-1][i] == 1:
			ans.append([n, i + 1, n - 1, i + 1, n - 1, i + 2])
			ans.append([n, i + 1, n - 1, i + 1, n, i + 2])
			ans.append([n, i + 1, n - 1, i + 2, n, i + 2])
	if a[-1][-1] == 1:
		ans.append([n, m, n - 1, m, n - 1, m - 1])
		ans.append([n, m, n - 1, m, n, m - 1])
		ans.append([n, m, n - 1, m - 1, n, m - 1])
	print(len(ans))
	for i in ans:
		print(*i)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))

def input():
	return sys.stdin.readline().rstrip('\r\n')

def getint():
	return int(input())

def getints():
	return list(map(int, input().split()))

def getint1():
	return list(map(lambda x: int(x) - 1, input().split()))

def main():
	d = {'0': 0, '1': 1}
	cases = getint()
	for t in range(cases):
		(n, m) = getints()
		matrix = []
		for i in range(n):
			matrix.append([d[i] for i in input()])
		k = 0
		out = []
		for i in range(n - 2):
			for j in range(m):
				if matrix[i][j]:
					k += 1
					if j < m - 1:
						matrix[i][j] = 0
						matrix[i + 1][j] ^= 1
						matrix[i + 1][j + 1] ^= 1
						out.append([i, j, i + 1, j, i + 1, j + 1])
					elif j == m - 1:
						matrix[i][j] = 0
						matrix[i + 1][j] ^= 1
						matrix[i + 1][j - 1] ^= 1
						out.append([i, j, i + 1, j, i + 1, j - 1])
		for i in range(m - 1):
			(x1, x2) = (matrix[n - 2][i], matrix[n - 1][i])
			if x1 == 0 and x2 == 0:
				continue
			elif x1 == 1 and x2 == 1:
				out.append([n - 2, i, n - 1, i, n - 1, i + 1])
				matrix[n - 2][i] ^= 1
				matrix[n - 1][i] ^= 1
				matrix[n - 1][i + 1] ^= 1
			elif x1 == 0 and x2 == 1:
				out.append([n - 2, i + 1, n - 1, i, n - 1, i + 1])
				matrix[n - 2][i + 1] ^= 1
				matrix[n - 1][i] ^= 1
				matrix[n - 1][i + 1] ^= 1
			elif x1 == 1 and x2 == 0:
				out.append([n - 2, i, n - 2, i + 1, n - 1, i + 1])
				matrix[n - 2][i] ^= 1
				matrix[n - 2][i + 1] ^= 1
				matrix[n - 1][i + 1] ^= 1
			k += 1
		if matrix[-1][-1] or matrix[-2][-1]:
			(x1, x2, x3, x4) = (matrix[n - 2][m - 2], matrix[n - 2][m - 1], matrix[n - 1][m - 2], matrix[n - 1][m - 1])
			if x2 == 1 and x4 == 1:
				out.append([n - 2, m - 2, n - 2, m - 1, n - 1, m - 2])
				out.append([n - 2, m - 2, n - 1, m - 2, n - 1, m - 1])
				(matrix[n - 2][m - 1], matrix[n - 1][m - 1]) = (0, 0)
				k += 2
			elif x2 == 0 and x4 == 1:
				out.append([n - 2, m - 2, n - 1, m - 2, n - 1, m - 1])
				out.append([n - 2, m - 2, n - 2, m - 1, n - 1, m - 1])
				out.append([n - 2, m - 1, n - 1, m - 2, n - 1, m - 1])
				matrix[n - 1][m - 1] = 0
				k += 3
			elif x2 == 1 and x4 == 0:
				out.append([n - 2, m - 2, n - 2, m - 1, n - 1, m - 2])
				out.append([n - 2, m - 2, n - 2, m - 1, n - 1, m - 1])
				out.append([n - 2, m - 1, n - 1, m - 2, n - 1, m - 1])
				matrix[n - 2][m - 1] = 0
				k += 3
		print(k)
		for (x1, y1, x2, y2, x3, y3) in out:
			print(x1 + 1, y1 + 1, x2 + 1, y2 + 1, x3 + 1, y3 + 1)
main()


import sys

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for k in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e] * d for k in range(c)] for k in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
INF = 10 ** 19
MOD = 10 ** 9 + 7
EPS = 10 ** (-10)

def check1(i, j):
	pattern = [[(i, j), (i + 1, j), (i, j + 1)], [(i + 1, j), (i, j + 1), (i + 1, j + 1)], [(i, j + 1), (i + 1, j + 1), (i, j)], [(i + 1, j + 1), (i, j), (i + 1, j)]]
	for bit in range(1 << 4):
		res = []
		for k in range(4):
			if bit >> k & 1:
				row = []
				for (h, w) in pattern[k]:
					grid[h][w] ^= 1
					row += [h, w]
				res.append(row)
		cnt = 0
		for h in range(i, i + 2):
			for w in range(j, j + 2):
				cnt += grid[h][w]
		for k in range(4):
			if bit >> k & 1:
				for (h, w) in pattern[k]:
					grid[h][w] ^= 1
		if not cnt:
			return res
	raise Exception

def check2(i, j):
	res = []
	if grid[i][j] and grid[i - 1][j]:
		res.append([i, j, i, j - 1, i - 1, j - 1])
		res.append([i - 1, j, i, j - 1, i - 1, j - 1])
	elif grid[i][j]:
		res.append([i, j, i, j - 1, i - 1, j - 1])
		grid[i][j - 1] ^= 1
		grid[i - 1][j - 1] ^= 1
	elif grid[i - 1][j]:
		res.append([i - 1, j, i, j - 1, i - 1, j - 1])
		grid[i][j - 1] ^= 1
		grid[i - 1][j - 1] ^= 1
	grid[i][j] = grid[i - 1][j] = 0
	return res
for _ in range(INT()):
	(H, W) = MAP()
	grid = [[]] * H
	for i in range(H):
		grid[i] = list(map(int, input()))
	ans = []
	if H % 2 == 1:
		grid = [list(row) for row in list(zip(*grid))]
		(H, W) = (W, H)
		for i in range(1, H):
			res = check2(i, W - 1)
			if res:
				for k in range(len(res)):
					for l in range(0, 6, 2):
						(res[k][l], res[k][l + 1]) = (res[k][l + 1], res[k][l])
				ans += res
		grid = [list(row) for row in list(zip(*grid))]
		(H, W) = (W, H)
	if W % 2 == 1:
		for i in range(1, H):
			ans += check2(i, W - 1)
	for i in range(0, H - H % 2, 2):
		for j in range(0, W - W % 2, 2):
			ans += check1(i, j)
	print(len(ans))
	for row in ans:
		print(*[a + 1 for a in row])