import Control.Monad(join)

type Coord = (Int, Int)

flipZigzag :: [[a]] -> [[a]]
flipZigzag l =
    let
        f :: Bool -> [[a]] -> [[a]]
        f _ [] = []
        f False (x:xs) = x:(f True xs)
        f True (x:xs) = (reverse x):(f False xs)
    in f False l

zipWithIndex :: [a] -> [(Int, a)]
zipWithIndex = zip [1..]

zipAdj :: [a] -> [(a, a)]
zipAdj x = zip x $ tail x

third :: (a, b, c) -> c
third (a, b, c) = c

collectParity :: [(Coord, Int)] -> [(Coord, Coord)]
collectParity array =
    let 
        foldFunction :: (Int, Coord, [(Coord, Coord)]) -> (Coord, Int) -> (Int, Coord, [(Coord, Coord)])
        foldFunction (parity, prevCoord, cum) (coord, elem) =
            let
                newCum = if parity /= 0 then (prevCoord, coord):cum else cum
            in
                (mod (parity + elem) 2, coord, newCum)
        firstCoord = fst $ head array
        firstElem = snd $ head array
    in
        third $ foldl foldFunction (mod firstElem 2, firstCoord, []) (drop 1 array)

main = do
    [h, w] <- map read . words <$> getLine
    a <- sequence (replicate h $ (map read . words <$> getLine))
    let indexZipped = fmap (\(rowIndex, row) -> fmap (\(columnIndex, elem) -> ((rowIndex, columnIndex), elem)) (zipWithIndex row)) (zipWithIndex a)
    let array = join $ flipZigzag $ indexZipped
    let operations = collectParity array
    let flattendOperations = fmap (\((y1, x1), (y2, x2)) -> unwords $ fmap show [y1, x1, y2, x2]) operations
    putStrLn $ show $ length flattendOperations
    sequence $ fmap putStrLn flattendOperations
