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()
}