Buggy python submission (verdict: Runtime Error):
#coding: utf-8
from collections import deque

H, W = (int(x) for x in input().split())
A = []

posOdd = deque() 
i = 0
j = 0

while (i, j) != H-1, W-1:
    if i

for i in range(H):
    row = [int(x) for x in input().split()]
    A.append(row)



def move(src, dst):
    ret = []
    while src[0] != dst[0]:
        if src[0] > dst[0]:
            di = -1
        else:
            di = 1
        ret.append((src[0], src[1], src[0]+di, src[1]))
        src[0] += di 
    return ret

    while src[1] != dst[1]:
        if src[1] > dst[1]:
            dj = -1
        else:
            dj = 1
        ret.append((src[0], src[1], src[0], src[1]+dj))
        src[1] += dj 

moves = []
while len(posOdd) > 1:
    dst = posOdd.popleft()
    src = posOdd.popleft()
    moves += move(src, dst)

print(len(moves))
for m in moves:
    print(" ".join((str(i+1) for i in m)))


Fixed submission:
#coding: utf-8
from collections import deque

H, W = (int(x) for x in input().split())
A = []

curMove = []
moves = []
hasOdd = False
pi = -1
pj = -1
for i in range(H):
    row = [int(x) for x in input().split()]
    if i % 2 == 0:
        start, end, diff = 0, W, 1
    else:
        start, end, diff = W-1, 0-1, -1

    for j in range(start, end, diff):
        if row[j] % 2 == 1:
            if hasOdd:
                curMove.append((pi,pj, i, j))
                moves += curMove
                curMove = []
                hasOdd = False
            else:
                hasOdd = True
        else:
            if hasOdd:
                curMove.append((pi,pj, i, j))
        pi = i
        pj = j

print(len(moves))
for m in moves:
    print(" ".join((str(i+1) for i in m)))

Buggy python submission (verdict: Runtime Error):
#coding: utf-8
from collections import deque

H, W = (int(x) for x in input().split())
A = []

posOdd = deque() 
for i in range(H):
    row = [int(x) for x in input().split()]
    A.append(row)
    if i % 2 == 0:
        for j in range(W):
            if row[j] % 2 == 1:
                posOdd.append([i, j])
    else:
        for j in reversed(range(W)):
            if row[j] % 2 == 1:
                posOdd.append([i, j])


def move(src, dst):
    ret = []
    while src[1] != dst[1]:
        if src[1] > dst[1]:
            dj = -1
        else:
            dj = 1
        ret.append((src[0], src[1], src[0], src[1]+dj))
        src[1] += dj 

    while src[0] != dst[0]:
        if src[0] > dst[0]:
            di = -1
        else:
            di = 1
        ret.append(src[0], src[1], src[0]+di, src[1])
        src[0] += di 
    return ret

moves = []
while len(posOdd) > 1:
    dst = posOdd.popleft()
    src = posOdd.popleft()
    moves += move(src, dst)

print(len(moves))
for m in moves:
    print(" ".join((str(i+1) for i in m)))


Fixed submission:
#coding: utf-8
from collections import deque

H, W = (int(x) for x in input().split())
A = []

curMove = []
moves = []
hasOdd = False
pi = -1
pj = -1
for i in range(H):
    row = [int(x) for x in input().split()]
    if i % 2 == 0:
        start, end, diff = 0, W, 1
    else:
        start, end, diff = W-1, 0-1, -1

    for j in range(start, end, diff):
        if row[j] % 2 == 1:
            if hasOdd:
                curMove.append((pi,pj, i, j))
                moves += curMove
                curMove = []
                hasOdd = False
            else:
                hasOdd = True
        else:
            if hasOdd:
                curMove.append((pi,pj, i, j))
        pi = i
        pj = j

print(len(moves))
for m in moves:
    print(" ".join((str(i+1) for i in m)))