    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
                    newParity = mod (parity + elem) 2
                    newCum = if newParity /= 0 then (prevCoord, coord):cum else cum
                in
                    (newParity, coord, newCum)
            firstCoord = fst $ head array
            firstElem = snd $ head array
        in
            third $ foldl foldFunction (firstElem, firstCoord, []) (drop 1 array)

    main = do
        [h, w] <- map read . words <$> getLine
        a <- sequence (replicate h $ (map (read :: String -> Int) . 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
