← Home
package main

import (
	"bufio"
	"io"
	"os"
)

type FastScanner struct {
	data []byte
	idx  int
	n    int
}

func NewFastScanner() *FastScanner {
	data, _ := io.ReadAll(os.Stdin)
	return &FastScanner{data: data, n: len(data)}
}

func (fs *FastScanner) nextInt() int {
	for fs.idx < fs.n && fs.data[fs.idx] <= ' ' {
		fs.idx++
	}
	val := 0
	for fs.idx < fs.n && fs.data[fs.idx] > ' ' {
		val = val*10 + int(fs.data[fs.idx]-'0')
		fs.idx++
	}
	return val
}

func (fs *FastScanner) nextString() string {
	for fs.idx < fs.n && fs.data[fs.idx] <= ' ' {
		fs.idx++
	}
	start := fs.idx
	for fs.idx < fs.n && fs.data[fs.idx] > ' ' {
		fs.idx++
	}
	return string(fs.data[start:fs.idx])
}

type Op struct {
	a, b, c, d int
}

func writeInt(w *bufio.Writer, x int) {
	if x == 0 {
		w.WriteByte('0')
		return
	}
	var buf [20]byte
	i := len(buf)
	for x > 0 {
		i--
		buf[i] = byte('0' + x%10)
		x /= 10
	}
	w.Write(buf[i:])
}

func main() {
	fs := NewFastScanner()
	n := fs.nextInt()
	m := fs.nextInt()

	init := make([][]string, n)
	s := 0
	for i := 0; i < n; i++ {
		init[i] = make([]string, m)
		for j := 0; j < m; j++ {
			init[i][j] = fs.nextString()
			s += len(init[i][j])
		}
	}

	fin := make([][]string, n)
	for i := 0; i < n; i++ {
		fin[i] = make([]string, m)
		for j := 0; j < m; j++ {
			fin[i][j] = fs.nextString()
		}
	}

	ops := make([]Op, 0, 4*s)
	add := func(a, b, c, d int) {
		ops = append(ops, Op{a, b, c, d})
	}

	for k := len(init[0][0]) - 1; k >= 0; k-- {
		if init[0][0][k] == '0' {
			add(1, 1, 2, 1)
		} else {
			add(1, 1, 1, 2)
		}
	}

	for i := 1; i < n; i++ {
		st := init[i][0]
		for k := len(st) - 1; k >= 0; k-- {
			ch := st[k]
			add(i+1, 1, 1, 1)
			if ch == '0' {
				add(1, 1, 2, 1)
			} else {
				add(1, 1, 1, 2)
			}
		}
	}

	for j := 1; j < m; j++ {
		st := init[0][j]
		for k := len(st) - 1; k >= 0; k-- {
			ch := st[k]
			add(1, j+1, 1, 1)
			if ch == '0' {
				add(1, 1, 2, 1)
			} else {
				add(1, 1, 1, 2)
			}
		}
	}

	for i := 1; i < n; i++ {
		for j := 1; j < m; j++ {
			st := init[i][j]
			for k := len(st) - 1; k >= 0; k-- {
				ch := st[k]
				if ch == '0' {
					if i == 1 {
						add(i+1, j+1, 2, 1)
					} else {
						add(i+1, j+1, i+1, 1)
						add(i+1, 1, 2, 1)
					}
				} else {
					if j == 1 {
						add(i+1, j+1, 1, 2)
					} else {
						add(i+1, j+1, 1, j+1)
						add(1, j+1, 1, 2)
					}
				}
			}
		}
	}

	for i := 1; i < n; i++ {
		for j := 1; j < m; j++ {
			st := fin[i][j]
			for k := len(st) - 1; k >= 0; k-- {
				ch := st[k]
				if ch == '0' {
					if i == 1 {
						add(2, 1, i+1, j+1)
					} else {
						add(2, 1, i+1, 1)
						add(i+1, 1, i+1, j+1)
					}
				} else {
					if j == 1 {
						add(1, 2, i+1, j+1)
					} else {
						add(1, 2, 1, j+1)
						add(1, j+1, i+1, j+1)
					}
				}
			}
		}
	}

	for i := 2; i < n; i++ {
		st := fin[i][0]
		for k := len(st) - 1; k >= 0; k-- {
			ch := st[k]
			if ch == '0' {
				add(2, 1, i+1, 1)
			} else {
				add(1, 2, 1, 1)
				add(1, 1, i+1, 1)
			}
		}
	}

	for j := 2; j < m; j++ {
		st := fin[0][j]
		for k := len(st) - 1; k >= 0; k-- {
			ch := st[k]
			if ch == '1' {
				add(1, 2, 1, j+1)
			} else {
				add(2, 1, 1, 1)
				add(1, 1, 1, j+1)
			}
		}
	}

	st := fin[0][1]
	for k := len(st) - 1; k >= 0; k-- {
		ch := st[k]
		if ch == '1' {
			add(1, 2, 1, 1)
			add(1, 1, 1, 2)
		} else {
			add(2, 1, 1, 1)
			add(1, 1, 1, 2)
		}
	}

	st = fin[1][0]
	for k := len(st) - 1; k >= 0; k-- {
		ch := st[k]
		if ch == '0' {
			add(2, 1, 1, 1)
			add(1, 1, 2, 1)
		} else {
			add(1, 2, 1, 1)
			add(1, 1, 2, 1)
		}
	}

	st = fin[0][0]
	for k := len(st) - 1; k >= 0; k-- {
		if st[k] == '0' {
			add(2, 1, 1, 1)
		} else {
			add(1, 2, 1, 1)
		}
	}

	w := bufio.NewWriterSize(os.Stdout, 1<<20)
	writeInt(w, len(ops))
	w.WriteByte('\n')
	for _, op := range ops {
		writeInt(w, op.a)
		w.WriteByte(' ')
		writeInt(w, op.b)
		w.WriteByte(' ')
		writeInt(w, op.c)
		w.WriteByte(' ')
		writeInt(w, op.d)
		w.WriteByte('\n')
	}
	w.Flush()
}