```go
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
var n, m int
if _, err := fmt.Fscan(in, &n, &m); err != nil {
return
}
initial := make([][]string, n)
for i := 0; i < n; i++ {
initial[i] = make([]string, m)
for j := 0; j < m; j++ {
fmt.Fscan(in, &initial[i][j])
}
}
target := make([][]string, n)
for i := 0; i < n; i++ {
target[i] = make([]string, m)
for j := 0; j < m; j++ {
fmt.Fscan(in, &target[i][j])
}
}
var ops []string
move := func(r1, c1, r2, c2 int) {
ops = append(ops, fmt.Sprintf("%d %d %d %d", r1+1, c1+1, r2+1, c2+1))
s := initial[r1][c1]
ch := s[len(s)-1]
initial[r1][c1] = s[:len(s)-1]
initial[r2][c2] = string(ch) + initial[r2][c2]
}
if n > 2 || m > 2 {
for i := 0; i < len(initial[0][0]); i++ {
move(0, 0, 1, 0)
}
for i := 0; i < len(initial[0][1]); i++ {
move(0, 1, 1, 1)
}
for c := 2; c < m; c++ {
for len(initial[0][c]) > 0 {
if initial[0][c][len(initial[0][c])-1] == '0' {
move(0, c, 0, 0)
} else {
move(0, c, 0, 1)
}
}
}
for r := 1; r < n; r++ {
for len(initial[r][1]) > 0 {
if initial[r][1][len(initial[r][1])-1] == '1' {
move(r, 1, 0, 1)
} else {
move(r, 1, r, 0)
}
}
for len(initial[r][0]) > 0 {
if initial[r][0][len(initial[r][0])-1] == '0' {
move(r, 0, 0, 0)
} else {
move(r, 0, r, 1)
move(r, 1, 0, 1)
}
}
for c := 2; c < m; c++ {
for len(initial[r][c]) > 0 {
if initial[r][c][len(initial[r][c])-1] == '0' {
move(r, c, r, 0)
move(r, 0, 0, 0)
} else {
move(r, c, r, 1)
move(r, 1, 0, 1)
}
}
}
}
for i := len(target[0][0]) - 1; i >= 0; i-- {
if target[0][0][i] == '0' {
move(0, 0, 1, 0)
move(1, 0, 0, 0)
} else {
move(0, 1, 0, 0)
}
}
for i := len(target[0][1]) - 1; i >= 0; i-- {
if target[0][1][i] == '1' {
move(0, 1, 1, 1)
move(1, 1, 0, 1)
} else {
move(0, 0, 0, 1)
}
}
for r := n - 1; r >= 1; r-- {
for c := m - 1; c >= 3; c-- {
for i := len(target[r][c]) - 1; i >= 0; i-- {
if target[r][c][i] == '0' {
move(0, 0, 0, c)
move(0, c, r, c)
} else {
move(0, 1, 0, c)
move(0, c, r, c)
}
}
}
if m >= 3 {
for i := len(target[r][1]) - 1; i >= 0; i-- {
if target[r][1][i] == '0' {
move(0, 0, r, 0)
} else {
move(0, 1, r, 1)
move(r, 1, r, 0)
}
}
for i := len(target[r][0]) - 1; i >= 0; i-- {
if target[r][0][i] == '0' {
move(0, 0, 0, 2)
move(0, 2, r, 2)
move(r, 2, r, 0)
} else {
move(0, 1, 0, 2)
move(0, 2, r, 2)
move(r, 2, r, 0)
}
}
for i := len(target[r][2]) - 1; i >= 0; i-- {
if target[r][2][i] == '0' {
move(0, 0, 0, 2)
move(0, 2, r, 2)
} else {
move(0, 1, 0, 2)
move(0, 2, r, 2)
}
}
} else {
for i := len(target[r][1]) - 1; i >= 0; i-- {
if target[r][1][i] == '1' {
move(0, 1, r, 1)
} else {
move(0, 0, r, 0)
move(r, 0, r, 1)
}
}
for i := len(target[r][0]) - 1; i >= 0; i-- {
if target[r][0][i] == '0' {
move(0, 0, r, 0)
} else {
if r > 1 {
move(0, 1, 1, 1)
move(1, 1, 1, 0)
move(1, 0, r, 0)
} else {
for j := len(target[0][1]) - 1; j >= 0; j-- {
move(0, 1, 1, 1)
}
move(0, 1, 1, 1)
move(1, 1, 1, 0)
for j := 0; j < len(target[0][1]); j++ {
move(1, 1, 0, 1)
}
}
}
}
}
}
for c := 2; c < m; c++ {
for i := len(target[0][c]) - 1; i >= 0; i-- {
if target[0][c][i] == '0' {
move(0, 0, 0, c)
} else {
move(0, 1, 0, c)
}
}
}
} else {
for len(initial[0][0]) > 0 {
move(0, 0, 1, 0)
}
for len(initial[0][1]) > 0 {
move(0, 1, 1, 1)
}
for len(initial[1][1]) > 0 {
if initial[1][1][len(initial[1][1])-1] == '1' {
move(1, 1, 0, 1)
} else {
move(1, 1, 1, 0)
}
}
for len(initial[1][0]) > 0 {
if initial[1][0][len(initial[1][0])-1] == '0' {
move(1, 0, 0, 0)
} else {
move(1, 0, 1, 1)
move(1, 1, 0, 1)
}
}
for i := len(target[0][0]) - 1; i >= 0; i-- {
if target[0][0][i] == '0' {
move(0, 0, 1, 0)
move(1, 0, 0, 0)
} else {
move(0, 1, 0, 0)
}
}
for i := len(target[0][1]) - 1; i >= 0; i-- {
if target[0][1][i] == '1' {
move(0, 1, 1, 1)
move(1, 1, 0, 1)
} else {
move(0, 0, 0, 1)
}
}
for i := len(target[1][1]) - 1; i >= 0; i-- {
if target[1][1][i] == '1' {
move(0, 1, 1, 1)
} else {
move(0, 0, 1, 0)
move(1, 0, 1, 1)
}
}
for i := len(target[1][0]) - 1; i >= 0; i-- {
if target[1][0][i] == '0' {
move(0, 0, 1, 0)
} else {
for j := len(target[0][1]) - 1; j >= 0; j-- {
move(0, 1, 1, 1)
}
move(0, 1, 1, 1)
move(1, 1, 1, 0)
for j := 0; j < len(target[0][1]); j++ {
move(1, 1, 0, 1)
}
}
}
}
fmt.Fprintln(out, len(ops))
for _, op := range ops {
fmt.Fprintln(out, op)
}
}
```