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