{-# LANGUAGE BangPatterns, MultiWayIf #-}
import Control.Arrow
import Control.Monad.Fix
import Data.Foldable
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import qualified Data.ByteString.Char8 as B
import Data.ByteString.Internal (accursedUnutterablePerformIO)
import Debug.Trace

solve :: Int -> Int -> V.Vector (VU.Vector Bool) -> [(Int, Int, Int, Int)]
solve !h !w !aij =
  concat
    $ reverse
    $ (\(ps, rs) -> lastColumnFoldDown (VU.fromList $ reverse rs) : ps)
    $ foldl'
        (\(!procs, !rs) (!i) ->
          let (ps, r) = rowFoldRight i in (ps : procs, r : rs)
        )
        ([], [])
        [0 .. h - 1]
 where
  fold s i = first reverse . VU.ifoldl'
    (\(!acc, !isCarrying) (!j) (!b) -> if
      | not isCarrying && b
      -> ((if j /= s then ((i, j, i, j + 1) :) else id) acc, True)
      | isCarrying && b
      -> (acc, False)
      | isCarrying && not b
      -> ((if j /= s then ((i, j, i, j + 1) :) else id) acc, True)
      | otherwise
      -> (acc, isCarrying)
    )
    ([], False)

  lastColumnFoldDown =
    map (\(y, x, y', x') -> (x, y, x', y)) . fst . fold (h - 1) (w - 1)

  rowFoldRight i = fold (w - 1) i $ aij V.! i

main = do
  let readInt = fmap (second B.tail) . B.readInt

  (h, w) <-
    (\vec -> (vec VU.! 0, vec VU.! 1)) . VU.unfoldrN 2 readInt <$> B.getLine
  aij <-
    V.replicateM h $ VU.map (\i -> odd i) . VU.unfoldrN w readInt <$> B.getLine

  let rs = solve h w aij
  print $ length rs
  forM_ rs $ \(y, x, y', x') ->
    putStrLn
      $  show (y + 1)
      ++ " "
      ++ show (x + 1)
      ++ " "
      ++ show (y' + 1)
      ++ " "
      ++ show (x' + 1)
