{-# OPTIONS_GHC -O2 -funbox-strict-fields #-}
import           Control.Monad         (replicateM)
import           Control.Monad.ST
import           Control.Monad.State
import           Data.Array.MArray
import           Data.Array.ST
import qualified Data.ByteString.Char8 as BC
import           Data.Maybe            (fromJust)

main :: IO ()
main = do
  [h, w] <- getInts
  ass <- replicateM h getInts
  let (n, yxs) = solve h w ass
  print n
  putStr . unlines
    $ map (\(y, x, y', x') -> unwords [show y, show x, show y', show x']) yxs


solve :: Int -> Int -> [[Int]] -> (Int, [(Int, Int, Int, Int)])
solve h w ass = runST $ flip execStateT (0, []) $ do
  arr <- lift $ (newListArray ((1, 1), (h, w)) $ concat ass
    :: ST s (STUArray s (Int, Int) Int))
  let
    yxs = [(i, j) | i <- [1 .. h]
                  , j <- if odd i then [1 .. w] else reverse [1 .. w]]
  forM_ (zip yxs (tail yxs)) $ \(yx, yx') -> do
    a <- lift $ readArray arr yx
    a' <- lift $ readArray arr yx'
    when (odd a) $ do
      lift $ writeArray arr yx (a - 1)
      lift $ writeArray arr yx' (a' + 1)
      let yxyx' = (fst yx, snd yx, fst yx', snd yx')
      modify (\(n, yxyxs') -> (n + 1, yxyx':yxyxs'))
  modify (\(n, yxyxs') -> (n, reverse yxyxs'))

readInts :: BC.ByteString -> [Int]
readInts = map (fst . fromJust . BC.readInt) . BC.words

getInts :: IO [Int]
getInts = readInts <$> BC.getLine
