import qualified Data.ByteString.Char8 as B
import Data.List (foldl')
import Data.Array.IArray
import Data.Array.ST.Safe (STArray,STUArray,newArray,readArray,writeArray)
import Data.STRef (newSTRef,readSTRef,writeSTRef)
import Control.Monad (when)
import Control.Monad.ST.Safe (ST,runST)
main = do
  (n:ns) <- fmap (map read' . B.words) B.getContents
  let prep = do
        m2 <- newArray (0,n) (maxBound `div` 2) :: ST s (STUArray s Int Int)
        p2 <- newArray (0,n) "E"                :: ST s (STArray s Int String)
        writeArray m2 1 0
        writeArray p2 1 ""
        return (m2,p2)
  let dp ns = runST $ do
        zero <- newSTRef Nothing
        (m2,p2) <- prep
        (m5,p5) <- prep
        let dp' ns = go ns 1 where
              go [] _ = return ()
              go (x:xs) i = do
                when (x == 0) $ writeSTRef zero (Just i)
                l2  <- readArray m2 (i-1)
                l2p <- readArray p2 (i-1)
                l5  <- readArray m5 (i-1)
                l5p <- readArray p5 (i-1)
                u2  <- readArray m2  i
                u2p <- readArray p2  i
                u5  <- readArray m5  i
                u5p <- readArray p5  i
                let n2 = factors 2 x
                    n5 = factors 5 x
                    (e2,e2p) = min ((l2+n2),('R':l2p)) ((u2+n2),('D':u2p))
                    (e5,e5p) = min ((l5+n5),('R':l5p)) ((u5+n5),('D':u5p))
                writeArray m2 i e2
                writeArray p2 i e2p
                writeArray m5 i e5
                writeArray p5 i e5p
                go xs $! i+1
        mapM_ dp' ns
        b2  <- readArray m2 n
        b2p <- readArray p2 n
        b5  <- readArray m5 n
        b5p <- readArray p5 n
        z <- readSTRef zero
        let (m,p) = min (b2,b2p) (b5,b5p)
        return $ case z of
          Nothing -> (m,p)
          Just j -> min (m,p) (1,replicate (n-j) 'R' ++
                                 replicate (n-1) 'D' ++
                                 replicate (j-1) 'R' ++ "E")
      (m,p) = dp (chunksOf n ns)
  print m
  putStrLn (tail $ reverse p)
{-# INLINE factors #-}
factors _ 0 = 1
factors n x = go x 0 where
  go x a | r == 0    = go q $! a + 1
         | otherwise = a
    where (q,r) = x `divMod` n
{-# INLINE chunksOf #-}
chunksOf n = go where
  go [] = []
  go xs = l : go r where (l,r) = splitAt n xs
{-# INLINE read' #-}
read' s = r where Just (r,_) = B.readInt s

import Data.List
import Data.Maybe (maybeToList)
import Data.Functor ((<$>))
import Data.Function (on)
import qualified Data.Array.Unboxed as U
import qualified Data.Array.ST as ST
import qualified Data.ByteString.Char8 as B hiding (minimum)

getPows :: Int -> Int -> Int
getPows b x = case x `divMod` b of
                 (x', 0) -> 1 + getPows b x'
                 _ -> 0

solve :: Int -> U.UArray (Int, Int) Int -> Int -> (Int, String)
solve n mat b = (dp U.! (0, 0), findPath 0 0)
  where dp = ST.runSTUArray $ do
          let thunk = -1
          dp' <- ST.thaw (U.listArray ((0, 0), (n, n)) (repeat thunk) :: U.UArray (Int, Int) Int)

          let f i j = do
                tmp <- ST.readArray dp' (i, j)
                if tmp /= thunk
                  then return tmp
                  else do
                    ans <- f' i j
                    ST.writeArray dp' (i, j) $! ans
                    return ans

              f' i j
                | i == n-1 && j == n-1 = return gridWeight
                | i == n-1 = rpath
                | j == n-1 = dpath
                | otherwise = minimum <$> sequence [dpath, rpath]
                where gridWeight = getPows b $ mat U.! (i, j)
                      dpath = (gridWeight + ) <$> f (i+1) j
                      rpath = (gridWeight + ) <$> f i (j+1)

          ST.writeArray dp' (0, 0) =<< f 0 0
          return dp'

        findPath i j
          | i == n-1 = replicate (n-j-1) 'R'
          | j == n-1 = replicate (n-i-1) 'D'
          | otherwise =
            if dp U.! (i, j+1) > dp U.! (i+1, j)
            then 'D' : findPath (i+1) j
            else 'R' : findPath i (j+1)

readInt :: B.ByteString -> Int
readInt = maybe 0 fst . B.readInt

main :: IO ()
main = do
  n : mat' <- map readInt . B.words <$> B.getContents
  let zeroPath idx = (1, replicate x 'R' ++ replicate (n-1) 'D' ++ replicate (n-1-x) 'R')
        where x = idx `mod` n
      maybeZeroPath = maybeToList $ zeroPath <$> elemIndex 0 mat'
      mat = U.listArray ((0, 0), (n-1, n-1)) (map (\x -> if x == 0 then 10 else x) mat')

  let ans2 = solve n mat 2
      ans5 = solve n mat 5
      cands = maybeZeroPath ++ [ans2, ans5]
      (ansWeight, ansPath) = minimumBy (compare `on` fst) cands

  print ansWeight
  putStrLn ansPath

{-# LANGUAGE DerivingVia #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word
import GHC.List (scanl')

type V = Int

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
    n <- readLn
    replicateM n $ B.getLine <&> forced . readLine
  where
    readLine = map (fst . fromJust . B.readInt) . B.words
    forced xs = forceElements xs `seq` xs

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = scanl step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

forceElements :: [a] -> ()
forceElements = foldr seq ()

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

{-# LANGUAGE DerivingVia #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word

type V = Int

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
    n <- readLn
    replicateM n $ B.getLine <&> forced . readLine
  where
    readLine = map (fst . fromJust . B.readInt) . B.words

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = scanl' step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

forceElements :: [a] -> ()
forceElements = foldr seq ()

forced :: [a] -> [a]
forced xs = forceElements xs `seq` xs

scanl' :: (b -> a -> b) -> b -> [a] -> [b]
scanl' f q [] = q `seq` [q]
scanl' f q (x:xs) = q `seq` rest `seq` q:rest
  where
    rest = scanl' f (f q x) xs

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

{-# LANGUAGE DerivingVia #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word

type V = Int

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
    n <- readLn
    rows <- replicateM n $ B.getLine <&> readLine
    return (forced rows)
  where
    readLine = map' (fst . fromJust . B.readInt) . B.words

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = scanl' step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

forceElements :: [a] -> ()
forceElements = foldr seq ()

forced :: [a] -> [a]
forced xs = forceElements xs `seq` xs

scanl' :: (b -> a -> b) -> b -> [a] -> [b]
scanl' f q [] = q `seq` [q]
scanl' f q (x:xs) = q `seq` rest `seq` q:rest
  where
    rest = scanl' f (f q x) xs

map' :: (a -> b) -> [a] -> [b]
map' f [] = []
map' f (x:xs) = y `seq` y:map' f xs
  where y = f x

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

{-# LANGUAGE DerivingVia #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word
import GHC.List (scanl')

type V = Int

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
    n <- readLn
    rows <- replicateM n $ B.getLine <&> forced . readLine
    return (forced rows)
  where
    readLine = map (fst . fromJust . B.readInt) . B.words

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = forced $ scanl step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = forced $ scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

forceElements :: [a] -> ()
forceElements = foldr seq ()

forced :: [a] -> [a]
forced xs = forceElements xs `seq` xs

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

{-# LANGUAGE DerivingVia #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word

type V = Int

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
    n <- readLn
    replicateM n $ B.getLine <&> forced . readLine
  where
    readLine = map (fst . fromJust . B.readInt) . B.words

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = scanl' step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

forceElements :: [a] -> ()
forceElements = foldr seq ()

forced :: [a] -> [a]
forced xs = forceElements xs `seq` xs

scanl' :: (b -> a -> b) -> b -> [a] -> [b]
scanl' f q ls = forced (scanl f q ls)

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE BangPatterns #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Data.Array.Unboxed (UArray)

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word
import GHC.List (scanl')

type V = Int
type R = UArray Int V

badInput :: [R]
badInput = replicate 1000 $ I.listArray (1, 1000) (replicate 1000 646642320)

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [R]
readInput = do
    n <- readLn
    replicateM n $ B.getLine <&> I.listArray (1, n) . readLine
  where
    readLine = map (fst . fromJust . B.readInt) . B.words

solve :: [R] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [R] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> R -> [Answer]
firstRow p row = scanl step initial rest
  where
    (first:rest) = I.elems row
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> R -> [Answer]
nextRow p (firstUp:restUp) row = scanl' step initial (zip restUp rest)
  where
    (first:rest) = I.elems row
    initial = moveDown firstUp $ toWeight p first
    step !left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

{-# LANGUAGE DerivingVia #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word
import GHC.List (scanl')

type V = Int

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
    n <- readLn
    rows <- replicateM n $ B.getLine <&> forced . readLine
    return (forced rows)
  where
    readLine = map (fst . fromJust . B.readInt) . B.words
    forced xs = forceElements xs `seq` xs

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = scanl step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

forceElements :: [a] -> ()
forceElements = foldr seq ()

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

{-# LANGUAGE DerivingVia #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word

type V = Int

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
    n <- readLn
    replicateM n $ B.getLine <&> readLine
  where
    readLine = map' (fst . fromJust . B.readInt) . B.words

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = scanl' step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

forceElements :: [a] -> ()
forceElements = foldr seq ()

forced :: [a] -> [a]
forced xs = forceElements xs `seq` xs

scanl' :: (b -> a -> b) -> b -> [a] -> [b]
scanl' f q [] = q `seq` [q]
scanl' f q (x:xs) = q `seq` rest `seq` q:rest
  where
    rest = scanl' f (f q x) xs

map' :: (a -> b) -> [a] -> [b]
map' f [] = []
map' f (x:xs) = y `seq` y:map' f xs
  where y = f x

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

{-# LANGUAGE DerivingVia #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word

type V = Int

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
    n <- readLn
    replicateM n $ B.getLine <&> readLine
  where
    readLine = map (fst . fromJust . B.readInt) . B.words

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = scanl' step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

forceElements :: [a] -> ()
forceElements = foldr seq ()

forced :: [a] -> [a]
forced xs = forceElements xs `seq` xs

scanl' :: (b -> a -> b) -> b -> [a] -> [b]
scanl' f q ls = forced (scanl f q ls)

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

import Data.List
import Data.Maybe (maybeToList)
import Data.Functor ((<$>))
import Data.Function (on)
import Control.Monad (when)
import qualified Data.Array.Unboxed as U
import qualified Data.Array.ST as ST
import qualified Data.ByteString.Char8 as B hiding (minimum)

getPows :: Int -> Int -> Int
getPows b x = case x `divMod` b of
                 (x', 0) -> 1 + getPows b x'
                 _ -> 0

solve :: Int -> U.UArray (Int, Int) Int -> Int -> (Int, String)
solve n mat b = (dp U.! (0, 0), findPath 0 0)
  where dp = ST.runSTUArray $ do
          let thunk = -1
          dp' <- ST.thaw (U.listArray ((0, 0), (n, n)) (repeat thunk) :: U.UArray (Int, Int) Int)

          let f i j = do
                tmp <- ST.readArray dp' (i, j)
                when (tmp == thunk) $ ST.writeArray dp' (i, j) =<< f' i j
                ST.readArray dp' (i, j)

              f' i j
                | i == n-1 && j == n-1 = return gridWeight
                | i == n-1 = rpath
                | j == n-1 = dpath
                | otherwise = minimum <$> sequence [dpath, rpath]
                where gridWeight = getPows b $ mat U.! (i, j)
                      dpath = (gridWeight + ) <$> f (i+1) j
                      rpath = (gridWeight + ) <$> f i (j+1)

          ST.writeArray dp' (0, 0) =<< f 0 0
          return dp'

        findPath i j
          | i == n-1 = replicate (n-j-1) 'R'
          | j == n-1 = replicate (n-i-1) 'D'
          | otherwise =
            if dp U.! (i, j+1) > dp U.! (i+1, j)
            then 'D' : findPath (i+1) j
            else 'R' : findPath i (j+1)

readInt :: B.ByteString -> Int
readInt = maybe 0 fst . B.readInt

main :: IO ()
main = do
  n : mat' <- map readInt . B.words <$> B.getContents
  let zeroPath idx = (1, replicate x 'R' ++ replicate (n-1) 'D' ++ replicate (n-1-x) 'R')
        where x = idx `mod` n
      maybeZeroPath = maybeToList $ zeroPath <$> elemIndex 0 mat'
      mat = U.listArray ((0, 0), (n-1, n-1)) (map (\x -> if x == 0 then 10 else x) mat')

  let cands = maybeZeroPath ++ map (solve n mat) [2, 5]
      (ansWeight, ansPath) = minimumBy (compare `on` fst) cands

  print ansWeight
  putStrLn ansPath

{-# LANGUAGE DerivingVia #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word

type V = Int

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
    n <- readLn
    rows <- replicateM n $ B.getLine <&> forced . readLine
    return $ forced rows
  where
    readLine = map (fst . fromJust . B.readInt) . B.words

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = scanl' step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

forceElements :: [a] -> ()
forceElements = foldr seq ()

forced :: [a] -> [a]
forced xs = forceElements xs `seq` xs

scanl' :: (b -> a -> b) -> b -> [a] -> [b]
scanl' f q ls = forced (scanl f q ls)

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

{-# LANGUAGE DerivingVia #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word

type V = Int

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
    n <- readLn
    replicateM n $ B.getLine <&> readLine
  where
    readLine = map (fst . fromJust . B.readInt) . B.words

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = scanl' step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

forceElements :: [a] -> ()
forceElements = foldl' (flip seq) ()

forced :: [a] -> [a]
forced xs = forceElements xs `seq` xs

scanl' :: (b -> a -> b) -> b -> [a] -> [b]
scanl' f q = forced . scanl f q

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

{-# LANGUAGE BangPatterns #-}

import Control.Monad
import Data.Array
import qualified Data.Array as A
import qualified Data.Array.Unboxed as U
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import Data.List
import Debug.Trace
import Control.Monad.ST
import Data.Array.ST

data Path = PathUp | PathLeft | NoPath
	deriving (Show, Eq)
--data Cell = Cell !Int !Path -- Cost Path
--	deriving (Show)

--cost (Cell c _) = c

decide up left = if up == noVal
		then if left == 0 then PathLeft else PathUp
		else if left == noVal
			then if up == 0 then PathUp else PathLeft
			else if left <= up then PathLeft else PathUp

path (i, j) arr
	| (i == 1) && (j == 1) = NoPath
	| (i == 1) && (j > 1) = PathUp
	| (i > 1) && (j == 1) = PathLeft
	| (i > 1) && (j > 1) = decide up left
		where
			up = arr ! (i, j - 1)
			left = arr ! (i - 1, j)

noVal = -1

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n B.getLine
	let arr = map (B.split 0x20) lines
	return $! (n, U.array ((1, 1), (n, n)) [((i, j), v) | (line, j) <- (zip arr [1..n]), (num, i) <- (zip line [1..n]), let !v = readNumber num])
	where
		readNumber x = case B8.readInt x of
			Just (!num, _) -> num
			Nothing -> error "Unable to read input"

calcPaths :: U.Array (Int, Int) Int -> Int -> Int -> Array (Int, Int) Int
calcPaths arr n divisor = runSTArray $ do
	a <- newArray ((1, 1), (n, n)) 0 :: ST s (STArray s (Int,Int) Int)
	forM_ [1..n] $! \diag -> do
		let indices = diagIndices $! diag
		forM_ indices $! \(i, j) -> case () of
			_ | (i == 1) && (j == 1) -> writeArray a (i, j) current
				| (i == 1) && (j > 1) -> do
					up <- readArray a (i, j - 1)
					writeArray a (i, j) $! normalize current up
				| (i > 1) && (j == 1) -> do
					left <- readArray a (i - 1, j)
					writeArray a (i, j) $! normalize current left
				| (i > 1) && (j > 1) -> do
					up <- readArray a (i, j - 1)
					left <- readArray a (i - 1, j)
					writeArray a (i, j) $! if decide up left == PathLeft
						then normalize current left
						else normalize current up
				where
					current = if (arr U.! (i, j) /= 0)
						then powerOf divisor (arr ! (i, j))
						else noVal
	return a
	where
		normalize !value !addend = (if value == noVal || addend == noVal then noVal else value + addend)
		diagIndices diag = if diag == n then [(diag, diag)] else
			zip [diag..n] (repeat diag) ++ zip (repeat diag) [(diag + 1)..n]

powerOf :: Int -> Int -> Int
powerOf q p = powerOf' q p 0
	where
		powerOf' q p n = if p `mod` q /= 0 then n else powerOf' q (p `div` q) (n + 1)

getPath arr n = reverse $ getPath' (n, n)
	where
		getPath' (i, j)
			| (i, j) == (1, 1) = ""
			| otherwise = if path (i,j) arr == PathUp
				then 'D' : getPath' (i, j - 1)
				else 'R' : getPath' (i - 1, j)

main = do
	(n, matrix) <- getInput
	let paths2 = calcPaths matrix n 2
	let cost2 = (paths2 ! (n, n))
	path2 <- do
		return $ getPath paths2 n

	let paths5 = calcPaths matrix n 5
	let cost5 = (paths5 ! (n, n))
	path5 <- do
		return $ getPath paths5 n

	if abs cost2 < abs cost5
		then do
			if cost2 < 0 then print 1 else print cost2
			putStrLn path2
		else do
			if cost5 < 0 then print 1 else print cost5
			putStrLn path5

module Main where

import Data.Array.IArray
import qualified Data.Array as A
import Data.List (foldl')
import qualified Data.ByteString.Char8 as B

scanl' :: (a -> b -> a) -> a -> [b] -> [a]
scanl' _ z  []    = [z]
scanl' f z (x:xs) = let u = f z x
                        ys = z:scanl' f u xs
                    in u `seq` ys `seq` ys

powerOf :: Int -> Int -> Int
powerOf _ 0 = error "powerOf 0"
powerOf p n = case n `mod` p of
  0 -> 1 + powerOf p (n `div` p)
  _ -> 0

data DP = DP { isZero :: !Bool
             , minNum :: !Int
             , go :: !String }
             deriving (Show)

dpCost :: DP -> Int
dpCost (DP True  _ _) = 1
dpCost (DP False c _) = c

dp :: Int -> Int -> [[Int]] -> DP
dp n p (row:rows) = (foldl' (dpRow n p) (dpFirstRow n p row) rows)!(n-1)

dpRow :: Int -> Int -> A.Array Int DP -> [Int] -> A.Array Int DP
dpRow n p ups (cur:curs) = listArray (0,n-1) $ scanl' step dpInit (zip [1..] curs) where
  step (DP _        _       leftGo) (i, 0)
                        = DP True 1 ('R':leftGo)
  step (DP leftZero leftNum leftGo) (i, k)
    | upCost < leftCost = DP upZero   upCost   ('D':upGo)
    | otherwise         = DP leftZero leftCost ('R':leftGo)
    where DP upZero upNum upGo = ups!i
          k' = powerOf p k
          upCost = if upZero then 1 else k' + upNum
          leftCost = if leftZero then 1 else k' + leftNum
  dpInit = case cur of
            0 -> DP True 1 ('D':go up)
            k -> DP False (powerOf p k + minNum up) ('D':go up)
  up = ups!0

dpFirstRow :: Int -> Int -> [Int] -> A.Array Int DP
dpFirstRow n p currs = listArray (0,n-1) $ zipWith zipper costs rs where
  zipper (dpZero, cost) dir = DP dpZero cost dir
  costs = tail $ scanl' step (False, 0) currs
  step (True, _)    _ = (True, 1)
  step (_,    cost) 0 = (True, 1)
  step (_,    cost) k = (False, cost + powerOf p k)
  rs = iterate ('R':) []

inputGrids :: IO (Int, [[Int]])
inputGrids = do
  n <- readLn
  grids <- sequence $ replicate n $ do
    line <- B.getLine
    return $ map (maybe (error "Read") fst) . map B.readInt . B.words $ line
  return (n, grids)

main :: IO ()
main = do
  (n, grids) <- inputGrids
  let dp2 = dp n 2 grids
      dp5 = dp n 5 grids
  if dpCost dp2 <= dpCost dp5
    then (print . dpCost $ dp2) >> (putStrLn . reverse . go $ dp2)
    else (print . dpCost $ dp5) >> (putStrLn . reverse . go $ dp5)

{-# LANGUAGE DerivingVia #-}
module Main where

import Data.List (foldl')

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import qualified Data.ByteString.Char8 as B

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Maybe (fromJust)
import Data.Word

type V = Int

main :: IO ()
main = do
  Answer w p <- solve <$> readInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
    n <- readLn
    rows <- replicateM n $ B.getLine <&> forced . readLine
    return (forced rows)
  where
    readLine = map (fst . fromJust . B.readInt) . B.words

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = scanl' step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

forceElements :: [a] -> ()
forceElements = foldr seq ()

forced :: [a] -> [a]
forced xs = forceElements xs `seq` xs

scanl' :: (b -> a -> b) -> b -> [a] -> [b]
scanl' f q [] = q `seq` [q]
scanl' f q (x:xs) = q `seq` rest `seq` q:rest
  where
    rest = scanl' f (f q x) xs

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

module Main where

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import Data.Array.Unboxed
import Data.List (foldl')
import qualified Data.ByteString.Char8 as B

scanl' :: (a -> b -> a) -> a -> [b] -> [a]
scanl' _ z  []    = [z]
scanl' f z (x:xs) = let u = f z x
                        ys = z:scanl' f u xs
                    in u `seq` ys `seq` ys

powerOf :: Int -> Int -> Int
powerOf _ 0 = error "powerOf 0"
powerOf p n = case n `mod` p of
  0 -> 1 + powerOf p (n `div` p)
  _ -> 0

data DP = DP { isZero :: !Bool
             , minNum :: !Int
             , go :: !String }
             deriving (Show)

dpCost :: DP -> Int
dpCost (DP True  _ _) = 1
dpCost (DP False c _) = c

dp :: Int -> Int -> [UArray Int Int] -> DP
dp n p (row:rows) = (foldl' (dpRow n p) (dpFirstRow n p (I.elems row)) rows)!(n-1)

dpRow :: Int -> Int -> A.Array Int DP -> UArray Int Int -> A.Array Int DP
dpRow n p ups curs = I.listArray (0,n-1) $ scanl' step dpInit [1..n-1] where
  step (DP _        _       leftGo) n
    | curs!n == 0       = DP True 1 ('R':leftGo)
  step (DP leftZero leftNum leftGo) n
    | upCost < leftCost = DP upZero   upCost   ('D':upGo)
    | otherwise         = DP leftZero leftCost ('R':leftGo)
    where DP upZero upNum upGo = ups!n
          cur = powerOf p (curs!n)
          upCost = if upZero then 1 else cur + upNum
          leftCost = if leftZero then 1 else cur + leftNum
  dpInit = case curs!0 of
            0 -> DP True 1 ('D':go up)
            k -> DP False (powerOf p k + minNum up) ('D':go up)
  up = ups!0

dpFirstRow :: Int -> Int -> [Int] -> A.Array Int DP
dpFirstRow n p currs = I.listArray (0, n-1) $ zipWith zipper costs rs where
  zipper (dpZero, cost) dir = DP dpZero cost dir
  costs = tail $ scanl' step (False, 0) currs
  step (True, _)    _ = (True, 1)
  step (_,    cost) 0 = (True, 1)
  step (_,    cost) k = (False, let u = cost + powerOf p k in u `seq` u)
  rs = iterate ('R':) []

inputGrids :: IO (Int, [UArray Int Int])
inputGrids = do
  n <- readLn
  grids <- sequence $ replicate n $ do
    line <- B.getLine
    let ns = map (maybe (error "Read") fst) . map B.readInt . B.words $ line
    return $! I.listArray (0, n-1) ns
  return (n, grids)

main :: IO ()
main = do
  (n, grids) <- inputGrids
  let dp2 = dp n 2 grids
      dp5 = dp n 5 grids
  if dpCost dp2 <= dpCost dp5
    then (print . dpCost $ dp2) >> (putStrLn . reverse . go $ dp2)
    else (print . dpCost $ dp5) >> (putStrLn . reverse . go $ dp5)

module Main where

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import Data.Array.Unboxed
import Data.List (foldl')
import qualified Data.ByteString.Char8 as B

scanl' :: (a -> b -> a) -> a -> [b] -> [a]
scanl' _ z  []    = [z]
scanl' f z (x:xs) = let u = f z x
                        ys = z:scanl' f u xs
                    in u `seq` ys `seq` ys

powerOf :: Int -> Int -> Int
powerOf _ 0 = error "powerOf 0"
powerOf p n = case n `mod` p of
  0 -> 1 + powerOf p (n `div` p)
  _ -> 0

data DP = DP { isZero :: !Bool
             , minNum :: !Int
             , go :: !String }
             deriving (Show)

dpCost :: DP -> Int
dpCost (DP True  _ _) = 1
dpCost (DP False c _) = c

dp :: Int -> Int -> [UArray Int Int] -> DP
dp n p (row:rows) = last $ foldl' (dpRow n p) (dpFirstRow n p row) rows

dpRow :: Int -> Int -> [DP] -> UArray Int Int -> [DP]
dpRow n p (up:ups) curs = scanl' step dpInit $ zip [1..] ups where
  step (DP _        _       leftGo) (k, _)
    | curs!k == 0       = DP True 1 ('R':leftGo)
  step (DP leftZero leftNum leftGo) (k, DP upZero upNum upGo)
    | upCost < leftCost = DP upZero   upCost   ('D':upGo)
    | otherwise         = DP leftZero leftCost ('R':leftGo)
    where k' = powerOf p (curs!k)
          upCost = if upZero then 1 else k' + upNum
          leftCost = if leftZero then 1 else k' + leftNum
  dpInit = case curs!0 of
            0 -> DP True 1 ('D':go up)
            k -> DP False (powerOf p k + minNum up) ('D':go up)

dpFirstRow :: Int -> Int -> UArray Int Int -> [DP]
dpFirstRow n p currs = zipWith zipper costs rs where
  zipper (dpZero, cost) dir = DP dpZero cost dir
  costs = tail $ scanl' step (False, 0) (I.elems currs)
  step (True, _)    _ = (True, 1)
  step (_,    cost) 0 = (True, 1)
  step (_,    cost) k = (False, cost + powerOf p k)
  rs = iterate ('R':) []

inputGrids :: IO (Int, [UArray Int Int])
inputGrids = do
  n <- readLn
  grids <- sequence $ replicate n $ do
    line <- B.getLine
    let ns = map (maybe (error "Read") fst) . map B.readInt . B.words $ line
    return (I.listArray (0, n-1) ns)
  return (n, grids)

main :: IO ()
main = do
  (n, grids) <- inputGrids
  let dp2 = dp n 2 grids
      dp5 = dp n 5 grids
  if dpCost dp2 <= dpCost dp5
    then (print . dpCost $ dp2) >> (putStrLn . reverse . go $ dp2)
    else (print . dpCost $ dp5) >> (putStrLn . reverse . go $ dp5)

module Main where

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import Data.Array.Unboxed
import Data.List (foldl')
import qualified Data.ByteString.Char8 as B

scanl' :: (a -> b -> a) -> a -> [b] -> [a]
scanl' _ z  []    = [z]
scanl' f z (x:xs) = let u = f z x
                        ys = z:scanl' f u xs
                    in u `seq` ys `seq` ys

powerOf :: Int -> Int -> Int
powerOf _ 0 = error "powerOf 0"
powerOf p n = case n `mod` p of
  0 -> 1 + powerOf p (n `div` p)
  _ -> 0

data DP = DP { isZero :: !Bool
             , minNum :: !Int
             , go :: !String }
             deriving (Show)

dpCost :: DP -> Int
dpCost (DP True  _ _) = 1
dpCost (DP False c _) = c

dp :: Int -> Int -> [UArray Int Int] -> DP
dp n p (row:rows) = (foldl' (dpRow n p) (dpFirstRow n p (I.elems row)) rows)!(n-1)

dpRow :: Int -> Int -> A.Array Int DP -> UArray Int Int -> A.Array Int DP
dpRow n p ups curs = I.listArray (0,n-1) $ scanl' step dpInit [1..n-1] where
  step (DP _        _       leftGo) n
    | curs!n == 0       = DP True 1 ('R':leftGo)
  step (DP leftZero leftNum leftGo) n
    | upCost < leftCost = DP upZero   upCost   ('D':upGo)
    | otherwise         = DP leftZero leftCost ('R':leftGo)
    where DP upZero upNum upGo = ups!n
          cur = powerOf p (curs!n)
          upCost = if upZero then 1 else cur + upNum
          leftCost = if leftZero then 1 else cur + leftNum
  dpInit = case curs!0 of
            0 -> DP True 1 ('D':go up)
            k -> DP False (powerOf p k + minNum up) ('D':go up)
  up = ups!0

dpFirstRow :: Int -> Int -> [Int] -> A.Array Int DP
dpFirstRow n p currs = I.listArray (0, n-1) $ zipWith zipper costs rs where
  zipper (dpZero, cost) dir = DP dpZero cost dir
  costs = tail $ scanl' step (False, 0) currs
  step (True, _)    _ = (True, 1)
  step (_,    cost) 0 = (True, 1)
  step (_,    cost) k = (False, cost + powerOf p k)
  rs = iterate ('R':) []

inputGrids :: IO (Int, [UArray Int Int])
inputGrids = do
  n <- readLn
  grids <- sequence $ replicate n $ do
    line <- B.getLine
    let ns = map (maybe (error "Read") fst) . map B.readInt . B.words $ line
    return $! I.listArray (0, n-1) ns
  return (n, grids)

main :: IO ()
main = do
  (n, grids) <- inputGrids
  let dp2 = dp n 2 grids
      dp5 = dp n 5 grids
  if dpCost dp2 <= dpCost dp5
    then (print . dpCost $ dp2) >> (putStrLn . reverse . go $ dp2)
    else (print . dpCost $ dp5) >> (putStrLn . reverse . go $ dp5)

import Data.List
import Data.Maybe (maybeToList)
import Data.Functor ((<$>))
import Data.Function (on)
import qualified Data.Array as A
import qualified Data.Array.Unboxed as U
import qualified Data.ByteString.Char8 as B

getPows :: Int -> Int -> Int
getPows b x = case x `divMod` b of
  (x', 0) -> 1 + getPows b x'
  _ -> 0

solve :: Int -> U.Array (Int, Int) Int -> (Int, String)
solve n mat = dp A.! (0, 0)
  where dp = A.array ((0, 0), (n-1, n-1)) [((i, j), f i j) | i <- [0..n-1], j <- [0..n-1]]
        f i j
          | i == n-1 && j == n-1 = (0, "")
          | i == n-1 = dpath
          | j == n-1 = rpath
          | otherwise = minimumBy (compare `on` fst) [dpath, rpath]
          where gridWeight = mat U.! (i, j)

                (dweight', dpath') = dp A.! (i, j+1)
                dpath = (gridWeight + dweight', 'R' : dpath')

                (rweight', rpath') = dp A.! (i+1, j)
                rpath = (gridWeight + rweight', 'D' : rpath')

main :: IO ()
main = do
  n : mat' <- map (maybe 0 fst . B.readInt) . B.words <$> B.getContents

  let mat = U.listArray ((0, 0), (n-1, n-1)) (map (\x -> if x == 0 then 10 else x) mat')

      mat2 = U.amap (getPows 2) mat
      mat5 = U.amap (getPows 5) mat

      zeroPath idx = (1, replicate x 'R' ++ replicate n 'D' ++ replicate (n-x) 'R')
        where x = idx `mod` n
      cands = [solve n mat2, solve n mat5] ++ maybeToList (zeroPath <$> elemIndex 0 mat')

      (ansWeight, ansPath) = minimumBy (compare `on` fst) cands

  print ansWeight
  putStrLn ansPath

import Control.Monad
import Data.Array
import Data.List
import Debug.Trace

data Path = Down | Right
data Cell = Cell Integer Integer Integer -- Cost Up left
	deriving (Show)

up (Cell _ u _) = u
left (Cell _ _ l) = l
cost (Cell c _ _) = c

noVal = 10000000

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n getLine
	let arr = map words lines
	return $ (n, array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = read $ (arr !! (j - 1)) !! (i - 1) :: Integer])

trailingZeroes :: Integer -> Int
trailingZeroes x = length $ takeWhile (== '0') $ (reverse . show) x

calcPaths arr n divisor = a
		where
			a = array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = calcCell i j]
			calcCell i j
				| (i == 1) && (j == 1) = Cell current noVal noVal
				| (i == 1) && (j > 1) = Cell (normalize current costUp) (normalize current costUp) noVal
				| (i > 1) && (j == 1) = Cell (normalize current costLeft) noVal (normalize current costLeft)
				| (i > 1) && (j > 1) = Cell (normalize current $ minimum [costLeft, costUp]) (normalize current costUp) (normalize current costLeft)
				where
					costUp = cost (a ! (i, j - 1))
					costLeft = cost (a ! (i - 1, j))
					current = if (arr ! (i, j) /= 0)
						then powerOf divisor (arr ! (i, j))
						else noVal
					normalize value addend = (if value == noVal then 1 else value + addend)

powerOf :: Integer -> Integer -> Integer
powerOf q p = toInteger $ length $ takeWhile (== 0) $ map ((flip mod) q) $ iterate ((flip div) q) p

getPath arr1 arr2 n = reverse $ getPath' (n, n)
	where
		getPath' (i, j)
			| (i, j) == (1, 1) = ""
			| otherwise = if max (up cell_1) (up cell_2) < max (left cell_1) (left cell_2)
				then 'D' : getPath' (i, j - 1)
				else 'R' : getPath' (i - 1, j)
			where
				cell_1 = arr1 ! (i, j)
				cell_2 = arr2 ! (i, j)

main = do
	(n, matrix) <- getInput
	--print matrix
	let paths2 = calcPaths matrix n 2
	let paths5 = calcPaths matrix n 5
{-	putStrLn "------"
	print paths2
	putStrLn "------"
	print paths5
	putStrLn "------"
	-}

	print $ min (cost $ paths2 ! (n, n)) (cost $ paths5 ! (n, n))
	putStrLn $ getPath paths2 paths5 n

import Control.Monad
import Data.Array
import Data.List
import Debug.Trace

data Path = Down | Right
data Cell = Cell Integer Integer Integer -- Cost Up left
	deriving (Show)

up (Cell _ u _) = u
left (Cell _ _ l) = l
cost (Cell c _ _) = c

noVal = 10000000

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n getLine
	let arr = map words lines
	return $ (n, array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = read $ (arr !! (j - 1)) !! (i - 1) :: Integer])

trailingZeroes :: Integer -> Int
trailingZeroes x = length $ takeWhile (== '0') $ (reverse . show) x

calcPaths arr n divisor = a
		where
			a = array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = calcCell i j]
			calcCell i j
				| (i == 1) && (j == 1) = Cell current noVal noVal
				| (i == 1) && (j > 1) = Cell (normalize current costUp) (normalize current costUp) noVal
				| (i > 1) && (j == 1) = Cell (normalize current costLeft) noVal (normalize current costLeft)
				| (i > 1) && (j > 1) = Cell (normalize current $ minimum [costLeft, costUp]) (normalize current costUp) (normalize current costLeft)
				where
					costUp = cost (a ! (i, j - 1))
					costLeft = cost (a ! (i - 1, j))
					current = if (arr ! (i, j) /= 0)
						then powerOf divisor (arr ! (i, j))
						else noVal
					normalize value addend = (if value == noVal then 1 else value + addend)

powerOf :: Integer -> Integer -> Integer
powerOf q p = toInteger $ length $ takeWhile (== 0) $ map ((flip mod) q) $ iterate ((flip div) q) p

getPath arr1 arr2 n = reverse $ getPath' (n, n)
	where
		getPath' (i, j)
			| (i, j) == (1, 1) = ""
			| otherwise = if decide (up cell_1) (up cell_2) (left cell_1) (left cell_2)
				then 'D' : getPath' (i, j - 1)
				else 'R' : getPath' (i - 1, j)
			where
				cell_1 = arr1 ! (i, j)
				cell_2 = arr2 ! (i, j)
				decide cu1 cu2 cl1 cl2 =
					case min cu1 cu2 `compare` min cl1 cl2 of
						LT -> True
						GT -> False
						EQ -> max cu1 cu2 < max cl1 cl2

main = do
	(n, matrix) <- getInput
--	print matrix
	let paths2 = calcPaths matrix n 2
	let paths5 = calcPaths matrix n 5
--	putStrLn "------"
--	print paths2
--	putStrLn "------"
--	print paths5
--	putStrLn "------"

	print $ min (cost $ paths2 ! (n, n)) (cost $ paths5 ! (n, n))
	putStrLn $ getPath paths2 paths5 n

import Control.Monad
import Data.Array
import Data.List

data Path = Down | Right
data Cell = Cell Integer Integer Integer -- Cost Up left
	deriving (Show)

up (Cell _ u _) = u
left (Cell _ _ l) = l
cost (Cell c _ _) = c

noVal = 1000000

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n getLine
	let arr = map words lines
	return $ (n, array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = read $ (arr !! (j - 1)) !! (i - 1) :: Integer])

trailingZeroes :: Integer -> Int
trailingZeroes x = length $ takeWhile (== '0') $ (reverse . show) x

calcPaths arr n = a
		where
			a = array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = calcCell i j]
			calcCell i j
				| (i == 1) && (j == 1) = Cell (arr ! (i, j)) noVal noVal
				| (i == 1) && (j > 1) = Cell costUp costUp noVal
				| (i > 1) && (j == 1) = Cell costLeft noVal costLeft
				| (i > 1) && (j > 1) = Cell (minimumBy (\x y -> trailingZeroes x `compare` trailingZeroes y ) [costUp, costLeft]) costUp costLeft
				where
					costUp = (arr ! (i, j) * cost (a ! (i, j - 1)))
					costLeft = (arr ! (i, j) * cost (a ! (i - 1, j)))

getPath arr n = reverse $ getPath' arr n (n, n)
	where
		getPath' arr n (i, j)
			| (i, j) == (1, 1) = ""
			| otherwise = if (trailingZeroes . up) cell < (trailingZeroes . left) cell
				then 'D' : getPath' arr n (i, j - 1)
				else 'R' : getPath' arr n (i - 1, j)
			where cell = arr ! (i, j)

main = do
	(n, matrix) <- getInput
	let paths = calcPaths matrix n
	--print paths
	print $ trailingZeroes $ cost $ paths ! (n, n)
	putStrLn $ getPath paths n

import Control.Monad
import Data.Array
import Data.List

data Path = Down | Right
data Cell = Cell Integer Integer Integer -- Cost Down Right
	deriving (Show)

down (Cell _ d _) = d
right (Cell _ _ r) = r
cost (Cell c _ _) = c
value (Cell _ d r) = undefined

noVal = 1000000

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n getLine
	let arr = map words lines
	return $ (n, array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = read $ (arr !! (i - 1)) !! (j - 1) :: Integer])

trailingZeroes :: Integer -> Int
trailingZeroes x = length $ takeWhile (== '0') $ (reverse . show) x

calcPaths arr n = a
		where
			a = array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = calcCell i j]
			calcCell i j
				| (i == n) && (j == n) = Cell (arr ! (i, j)) noVal noVal
				| (i == n) && (j < n) = Cell costDown costDown  noVal
				| (i < n) && (j == n) = Cell costRight noVal costRight
				| (i < n) && (j < n) = Cell (minimumBy (\x y -> trailingZeroes x `compare` trailingZeroes y ) [costDown, costRight]) costDown costRight
				where
					costDown = (arr ! (i, j) * cost (a ! (i, j + 1)))
					costRight = (arr ! (i, j) * cost (a ! (i + 1, j)))

getPath arr n = getPath' arr n (1, 1)
	where
		getPath' arr n (i, j)
			| (i, j) == (n, n) = ""
			| otherwise = if (trailingZeroes . down) cell < (trailingZeroes . right) cell
				then 'R' : getPath' arr n (i, j + 1)
				else 'D' : getPath' arr n (i + 1, j)
			where cell = arr ! (i, j)

main = do
	(n, matrix) <- getInput
	let paths = calcPaths matrix n
	print $ trailingZeroes $ cost $ paths ! (1, 1)
	putStrLn $ getPath paths n

{-# LANGUAGE BangPatterns #-}

import Control.Monad
import Data.Array
import qualified Data.Array as A
import qualified Data.Array.Unboxed as U
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import Data.List
import Debug.Trace
import Control.Monad.ST
import Data.Array.ST

data Path = PathUp | PathLeft | NoPath
	deriving (Show, Eq)
--data Cell = Cell !Int !Path -- Cost Path
--	deriving (Show)

--cost (Cell c _) = c

path (i, j) arr
	| (i == 1) && (j == 1) = NoPath
	| (i == 1) && (j > 1) = PathUp
	| (i > 1) && (j == 1) = PathLeft
	| (i > 1) && (j > 1) = if up <= left then PathUp else PathLeft
		where
			up = arr ! (i, j - 1)
			left = arr ! (i - 1, j)

noVal = -1

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n B.getLine
	let arr = map (B.split 0x20) lines
	return $! (n, U.array ((1, 1), (n, n)) [((i, j), v) | (line, j) <- (zip arr [1..n]), (num, i) <- (zip line [1..n]), let !v = readNumber num])
	where
		readNumber x = case B8.readInt x of
			Just (!num, _) -> num
			Nothing -> error "Unable to read input"

trailingZeroes :: Int -> Int
trailingZeroes x = length $ takeWhile (== '0') $ (reverse . show) x

calcPaths :: U.Array (Int, Int) Int -> Int -> Int -> Array (Int, Int) Int
calcPaths arr n divisor = runSTArray $ do
	a <- newArray ((1, 1), (n, n)) 0 :: ST s (STArray s (Int,Int) Int)
	forM_ [1..n] $! \diag -> do
		let indices = diagIndices $! diag
		forM_ indices $! \(i, j) -> case () of
			_ | (i == 1) && (j == 1) -> writeArray a (i, j) current
				| (i == 1) && (j > 1) -> do
					up <- readArray a (i, j - 1)
					writeArray a (i, j) $! normalize current up
				| (i > 1) && (j == 1) -> do
					left <- readArray a (i - 1, j)
					writeArray a (i, j) $! normalize current left
				| (i > 1) && (j > 1) -> do
					up <- readArray a (i, j - 1)
					left <- readArray a (i - 1, j)
					writeArray a (i, j) $! if left <= up
						then normalize current left
						else normalize current up
				where
					current = if (arr U.! (i, j) /= 0)
						then powerOf divisor (arr ! (i, j))
						else noVal
	return a
	where
		normalize !value !addend = (if value == noVal then 1 else value + addend)
		diagIndices diag = if diag == n then [(diag, diag)] else
			zip [diag..n] (repeat diag) ++ zip (repeat diag) [(diag + 1)..n]

powerOf :: Int -> Int -> Int
powerOf q p = powerOf' q p 0
	where
		powerOf' q p n = if p `mod` q /= 0 then n else powerOf' q (p `div` q) (n + 1)

getPath arr n = reverse $ getPath' (n, n)
	where
		getPath' (i, j)
			| (i, j) == (1, 1) = ""
			| otherwise = if path (i,j) arr == PathUp
				then 'D' : getPath' (i, j - 1)
				else 'R' : getPath' (i - 1, j)

main = do
	(n, matrix) <- getInput
	let paths2 = calcPaths matrix n 2
	let cost2 = (paths2 ! (n, n))
	path2 <- do
		return $ getPath paths2 n

	let paths5 = calcPaths matrix n 5
	let cost5 = (paths5 ! (n, n))
	path5 <- do
		return $ getPath paths5 n

	if cost2 < cost5
		then do
			print cost2
			putStrLn path2
		else do
			print cost5
			putStrLn path5

import Control.Monad
import Data.Array
import Data.List
import Debug.Trace

data Path = Down | Right
data Cell = Cell Integer Integer Integer -- Cost Up left
	deriving (Show)

up (Cell _ u _) = u
left (Cell _ _ l) = l
cost (Cell c _ _) = c

noVal = 10000000

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n getLine
	let arr = map words lines
	return $ (n, array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = read $ (arr !! (j - 1)) !! (i - 1) :: Integer])

trailingZeroes :: Integer -> Int
trailingZeroes x = length $ takeWhile (== '0') $ (reverse . show) x

calcPaths arr n divisor = a
		where
			a = array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = calcCell i j]
			calcCell i j
				| (i == 1) && (j == 1) = Cell current noVal noVal
				| (i == 1) && (j > 1) = Cell (normalize current costUp) (normalize current costUp) noVal
				| (i > 1) && (j == 1) = Cell (normalize current costLeft) noVal (normalize current costLeft)
				| (i > 1) && (j > 1) = Cell (normalize current $ minimum [costLeft, costUp]) (normalize current costUp) (normalize current costLeft)
				where
					costUp = cost (a ! (i, j - 1))
					costLeft = cost (a ! (i - 1, j))
					current = if (arr ! (i, j) /= 0)
						then powerOf divisor (arr ! (i, j))
						else noVal
					normalize value addend = (if value == noVal then 1 else value + addend)

powerOf :: Integer -> Integer -> Integer
powerOf q p = toInteger $ length $ takeWhile (== 0) $ map ((flip mod) q) $ iterate ((flip div) q) p

getPath arr1 arr2 n = reverse $ getPath' (n, n)
	where
		getPath' (i, j)
			| (i, j) == (1, 1) = ""
			| otherwise = if min (up cell_1) (up cell_2) < min (left cell_1) (left cell_2)
				then 'D' : getPath' (i, j - 1)
				else 'R' : getPath' (i - 1, j)
			where
				cell_1 = arr1 ! (i, j)
				cell_2 = arr2 ! (i, j)

main = do
	(n, matrix) <- getInput
--	print matrix
	let paths2 = calcPaths matrix n 2
	let paths5 = calcPaths matrix n 5
{-
	putStrLn "------"
	print paths2
	putStrLn "------"
	print paths5
	putStrLn "------"
-}

	print $ min (cost $ paths2 ! (n, n)) (cost $ paths5 ! (n, n))
	putStrLn $ getPath paths2 paths5 n

{-# LANGUAGE BangPatterns #-}

import Control.Monad
import Data.Array
import qualified Data.Array as A
import qualified Data.Array.Unboxed as U
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import Data.List
import Debug.Trace
import Control.Monad.ST
import Data.Array.ST

data Path = PathUp | PathLeft | NoPath
	deriving (Show, Eq)
--data Cell = Cell !Int !Path -- Cost Path
--	deriving (Show)

--cost (Cell c _) = c

path (i, j) arr
	| (i == 1) && (j == 1) = NoPath
	| (i == 1) && (j > 1) = PathUp
	| (i > 1) && (j == 1) = PathLeft
	| (i > 1) && (j > 1) = if up == noVal then PathUp
	else if left == noVal then PathLeft else
		if up <= left then PathUp else PathLeft
			where
				up = arr ! (i, j - 1)
				left = arr ! (i - 1, j)

noVal = -1

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n B.getLine
	let arr = map (B.split 0x20) lines
	return $! (n, U.array ((1, 1), (n, n)) [((i, j), v) | (line, j) <- (zip arr [1..n]), (num, i) <- (zip line [1..n]), let !v = readNumber num])
	where
		readNumber x = case B8.readInt x of
			Just (!num, _) -> num
			Nothing -> error "Unable to read input"

calcPaths :: U.Array (Int, Int) Int -> Int -> Int -> Array (Int, Int) Int
calcPaths arr n divisor = runSTArray $ do
	a <- newArray ((1, 1), (n, n)) 0 :: ST s (STArray s (Int,Int) Int)
	forM_ [1..n] $! \diag -> do
		let indices = diagIndices $! diag
		forM_ indices $! \(i, j) -> case () of
			_ | (i == 1) && (j == 1) -> writeArray a (i, j) current
				| (i == 1) && (j > 1) -> do
					up <- readArray a (i, j - 1)
					writeArray a (i, j) $! normalize current up
				| (i > 1) && (j == 1) -> do
					left <- readArray a (i - 1, j)
					writeArray a (i, j) $! normalize current left
				| (i > 1) && (j > 1) -> do
					up <- readArray a (i, j - 1)
					left <- readArray a (i - 1, j)
					writeArray a (i, j) $! if left <= up
						then normalize current left
						else normalize current up
				where
					current = if (arr U.! (i, j) /= 0)
						then powerOf divisor (arr ! (i, j))
						else noVal
	return a
	where
		normalize !value !addend = (if value == noVal || addend == noVal then noVal else value + addend)
		diagIndices diag = if diag == n then [(diag, diag)] else
			zip [diag..n] (repeat diag) ++ zip (repeat diag) [(diag + 1)..n]

powerOf :: Int -> Int -> Int
powerOf q p = powerOf' q p 0
	where
		powerOf' q p n = if p `mod` q /= 0 then n else powerOf' q (p `div` q) (n + 1)

getPath arr n = reverse $ getPath' (n, n)
	where
		getPath' (i, j)
			| (i, j) == (1, 1) = ""
			| otherwise = if path (i,j) arr == PathUp
				then 'D' : getPath' (i, j - 1)
				else 'R' : getPath' (i - 1, j)

main = do
	(n, matrix) <- getInput
	let paths2 = calcPaths matrix n 2
	let cost2 = (paths2 ! (n, n))
	path2 <- do
		return $ getPath paths2 n

	let paths5 = calcPaths matrix n 5
	let cost5 = (paths5 ! (n, n))
	path5 <- do
		return $ getPath paths5 n

	if cost2 < cost5
		then do
			if cost2 < 0 then print 1 else print cost2
			putStrLn path2
		else do
			if cost5 < 0 then print 1 else print cost5
			putStrLn path5

import Control.Monad
import Data.Array
import Data.List

data Path = Down | Right
data Cell = Cell Int Int Int -- Cost Down Right
	deriving (Show)

down (Cell _ d _) = d
right (Cell _ _ r) = r
cost (Cell c _ _) = c
value (Cell _ d r) = undefined

noVal = 1000000

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n getLine
	let arr = map words lines
	return $ (n, array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = read $ (arr !! (i - 1)) !! (j - 1) :: Int])

trailingZeroes :: Int -> Int
trailingZeroes x = length $ takeWhile (== '0') $ (reverse . show) x

calcPaths arr n = a
		where
			a = array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = calcCell i j]
			calcCell i j
				| (i == n) && (j == n) = Cell (arr ! (i, j)) noVal noVal
				| (i == n) && (j < n) = Cell costDown costDown  noVal
				| (i < n) && (j == n) = Cell costRight noVal costRight
				| (i < n) && (j < n) = Cell (minimumBy (\x y -> trailingZeroes x `compare` trailingZeroes y ) [costDown, costRight]) costDown costRight
				where
					costDown = (arr ! (i, j) * cost (a ! (i, j + 1)))
					costRight = (arr ! (i, j) * cost (a ! (i + 1, j)))

getPath arr n = getPath' arr n (1, 1)
	where
		getPath' arr n (i, j)
			| (i, j) == (n, n) = ""
			| otherwise = if (trailingZeroes . down) cell < (trailingZeroes . right) cell
				then 'R' : getPath' arr n (i, j + 1)
				else 'D' : getPath' arr n (i + 1, j)
			where cell = arr ! (i, j)

main = do
	(n, matrix) <- getInput
	let paths = calcPaths matrix n
	print $ trailingZeroes $ cost $ paths ! (1, 1)
	putStrLn $ getPath paths n

import Control.Monad
import Data.Array
import Data.List
import Debug.Trace

data Path = Down | Right
data Cell = Cell Integer Integer Integer -- Cost Up left
	deriving (Show)

up (Cell _ u _) = u
left (Cell _ _ l) = l
cost (Cell c _ _) = c

noVal = 10000000

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n getLine
	let arr = map words lines
	return $ (n, array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = read $ (arr !! (j - 1)) !! (i - 1) :: Integer])

trailingZeroes :: Integer -> Int
trailingZeroes x = length $ takeWhile (== '0') $ (reverse . show) x

calcPaths arr n divisor = a
		where
			a = array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = calcCell i j]
			calcCell i j
				| (i == 1) && (j == 1) = Cell current noVal noVal
				| (i == 1) && (j > 1) = Cell (normalize current costUp) (normalize current costUp) noVal
				| (i > 1) && (j == 1) = Cell (normalize current costLeft) noVal (normalize current costLeft)
				| (i > 1) && (j > 1) = Cell (normalize current $ minimum [costLeft, costUp]) (normalize current costUp) (normalize current costLeft)
				where
					costUp = cost (a ! (i, j - 1))
					costLeft = cost (a ! (i - 1, j))
					current = if (arr ! (i, j) /= 0)
						then powerOf divisor (arr ! (i, j))
						else noVal
					normalize value addend = (if value == noVal then 1 else value + addend)

powerOf :: Integer -> Integer -> Integer
powerOf q p = toInteger $ length $ takeWhile (== 0) $ map ((flip mod) q) $ iterate ((flip div) q) p

getPath arr1 arr2 n = reverse $ getPath' (n, n) (0, 0)
	where
		getPath' (i, j) (fives, twos)
			| (i, j) == (1, 1) = ""
			| otherwise = if decide (up cell_1) (up cell_2) (left cell_1) (left cell_2)
				then 'D' : getPath' (i, j - 1) (fives, twos)
				else 'R' : getPath' (i - 1, j) (fives, twos)
			where
				cell_1 = arr1 ! (i, j)
				cell_2 = arr2 ! (i, j)
				decide cu1 cu2 cl1 cl2 =
					if min (cl1 + twos) (cl2 + fives) < min (cu1 + twos) (cu2 + fives)
						then False
						else True

main = do
	(n, matrix) <- getInput
--	print matrix
	let paths2 = calcPaths matrix n 2
	let paths5 = calcPaths matrix n 5
{-	putStrLn "------"
	print paths2
	putStrLn "------"
	print paths5
	putStrLn "------" -}

	print $ min (cost $ paths2 ! (n, n)) (cost $ paths5 ! (n, n))
	putStrLn $ getPath paths2 paths5 n

import Control.Monad
import Data.Array
import Data.List
import Debug.Trace

data Path = Down | Right
data Cell = Cell Integer Integer Integer -- Cost Up left
	deriving (Show)

up (Cell _ u _) = u
left (Cell _ _ l) = l
cost (Cell c _ _) = c

noVal = 10000000

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n getLine
	let arr = map words lines
	return $ (n, array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = read $ (arr !! (j - 1)) !! (i - 1) :: Integer])

trailingZeroes :: Integer -> Int
trailingZeroes x = length $ takeWhile (== '0') $ (reverse . show) x

calcPaths arr n divisor = a
		where
			a = array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = calcCell i j]
			calcCell i j
				| (i == 1) && (j == 1) = Cell current noVal noVal
				| (i == 1) && (j > 1) = Cell (if current == noVal then 1 else current + costUp) costUp noVal
				| (i > 1) && (j == 1) = Cell (if current == noVal then 1 else current + costLeft) noVal costLeft
				| (i > 1) && (j > 1) = Cell (if current == noVal then 1 else current + minimum [costLeft, costUp]) costUp costLeft
				where
					costUp = cost (a ! (i, j - 1))
					costLeft = cost (a ! (i - 1, j))
					current = if (arr ! (i, j) /= 0)
						then powerOf divisor (arr ! (i, j))
						else noVal

powerOf :: Integer -> Integer -> Integer
powerOf q p = toInteger $ length $ takeWhile (== 0) $ map ((flip mod) q) $ iterate ((flip div) q) p

getPath arr1 arr2 n = reverse $ getPath' (n, n)
	where
		getPath' (i, j)
			| (i, j) == (1, 1) = ""
			| otherwise = if max (up cell_1) (up cell_2) < max (left cell_1) (left cell_2)
				then 'D' : getPath' (i, j - 1)
				else 'R' : getPath' (i - 1, j)
			where
				cell_1 = arr1 ! (i, j)
				cell_2 = arr2 ! (i, j)

main = do
	(n, matrix) <- getInput
	let paths2 = calcPaths matrix n 2
	let paths5 = calcPaths matrix n 5

	print $ min (cost $ paths2 ! (n, n)) (cost $ paths5 ! (n, n))
	putStrLn $ getPath paths2 paths5 n

import Control.Monad
import Data.Array
import Data.List
import Debug.Trace

data Path = Down | Right
data Cell = Cell Integer Integer Integer -- Cost Up left
	deriving (Show)

up (Cell _ u _) = u
left (Cell _ _ l) = l
cost (Cell c _ _) = c

noVal = 10000000

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n getLine
	let arr = map words lines
	return $ (n, array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = read $ (arr !! (j - 1)) !! (i - 1) :: Integer])

trailingZeroes :: Integer -> Int
trailingZeroes x = length $ takeWhile (== '0') $ (reverse . show) x

calcPaths arr n divisor = a
		where
			a = array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = calcCell i j]
			calcCell i j
				| (i == 1) && (j == 1) = Cell current noVal noVal
				| (i == 1) && (j > 1) = Cell (normalize current costUp) (normalize current costUp) noVal
				| (i > 1) && (j == 1) = Cell (normalize current costLeft) noVal (normalize current costLeft)
				| (i > 1) && (j > 1) = Cell (normalize current $ minimum [costLeft, costUp]) (normalize current costUp) (normalize current costLeft)
				where
					costUp = cost (a ! (i, j - 1))
					costLeft = cost (a ! (i - 1, j))
					current = if (arr ! (i, j) /= 0)
						then powerOf divisor (arr ! (i, j))
						else noVal
					normalize value addend = (if value == noVal then 1 else value + addend)

powerOf :: Integer -> Integer -> Integer
powerOf q p = toInteger $ length $ takeWhile (== 0) $ map ((flip mod) q) $ iterate ((flip div) q) p

getPath arr1 arr2 n = reverse $ getPath' (n, n)
	where
		getPath' (i, j)
			| (i, j) == (1, 1) = ""
			| otherwise = if decide (up cell_1) (up cell_2) (left cell_1) (left cell_2)
				then 'D' : getPath' (i, j - 1)
				else 'R' : getPath' (i - 1, j)
			where
				cell_1 = arr1 ! (i, j)
				cell_2 = arr2 ! (i, j)
				decide cu1 cu2 cl1 cl2 =
					case max cu1 cu2 `compare` max cl1 cl2 of
						LT -> True
						GT -> False
						EQ -> min cu1 cu2 < min cl1 cl2

main = do
	(n, matrix) <- getInput
--	print matrix
	let paths2 = calcPaths matrix n 2
	let paths5 = calcPaths matrix n 5
--	putStrLn "------"
--	print paths2
--	putStrLn "------"
--	print paths5
--	putStrLn "------"

	print $ min (cost $ paths2 ! (n, n)) (cost $ paths5 ! (n, n))
	putStrLn $ getPath paths2 paths5 n

import Control.Monad
import Data.Array
import Data.List

data Path = Down | Right
data Cell = Cell Int Int Int -- Cost Down Right
	deriving (Show)

down (Cell _ d _) = d
right (Cell _ _ r) = r
cost (Cell c _ _) = c
value (Cell _ d r) = undefined

noVal = 1000000

getInput = do
	n <- (liftM read) getLine
	lines <- sequence $ replicate n getLine
	let arr = map words lines
	return $ (n, array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = read $ (arr !! (i - 1)) !! (j - 1) :: Int])

trailingZeroes :: Int -> Int
trailingZeroes x = length $ takeWhile (== '0') $ (reverse . show) x

calcPaths arr n = a
		where
			a = array ((1, 1), (n, n)) [((i, j), v) | i <- [1..n], j <- [1..n], let v = calcCell i j]
			calcCell i j
				| (i == n) && (j == n) = Cell (arr ! (i, j)) noVal noVal
				| (i == n) && (j < n) = Cell costDown costDown  noVal
				| (i < n) && (j == n) = Cell costRight noVal costRight
				| (i < n) && (j < n) = Cell (minimumBy (\x y -> trailingZeroes x `compare` trailingZeroes y ) [costDown, costRight]) costDown costRight
				where
					costDown = (arr ! (i, j) * cost (a ! (i, j + 1)))
					costRight = (arr ! (i, j) * cost (a ! (i + 1, j)))

getPath arr n = getPath' arr n (1, 1)
	where
		getPath' arr n (i, j)
			| (i, j) == (n, n) = ""
			| otherwise = if (trailingZeroes . down) cell < (trailingZeroes . right) cell
				then 'R' : getPath' arr n (i, j + 1)
				else 'D' : getPath' arr n (i + 1, j)
			where cell = arr ! (i, j)

main = do
	(n, matrix) <- getInput
	print matrix
	let paths = calcPaths matrix n
	print $ paths ! (1, 1)
	print $ getPath paths n

import Data.List (foldl')
import Control.DeepSeq
main = do
  n <- readLn
  ns <- fmap (chunksOf n . map read . words) getContents
  let start = ((0 :: Int,""),(0,""))
      iv = start : replicate (n-1) junk
      (m,p) =  uncurry min $last $ foldl' dp iv ns
  print m
  putStrLn (tail $ reverse p)
junk = ((maxBound,"E"),(maxBound,"E"))
dp prev cur = force $ go junk prev cur where
  go _ _ [] = []
  go ((l2,l2p),(l5,l5p)) (((u2,u2p),(u5,u5p)):u) (x:xs) =
    b2 `seq` b5 `seq` (b : go b u xs) where
      b = (b2,b5)
      n2 = factors 2 x
      n5 = factors 5 x
      b2 = min ((l2+n2),('R' : l2p)) ((u2+n2),('D' : u2p))
      b5 = min ((l5+n5),('R' : l5p)) ((u5+n5),('D' : u5p))
factors n x = go x 0 where
  go x a | r == 0 = go q $! a + 1
         | otherwise = a
    where (q,r) = x `divMod` n
chunksOf _ [] = []
chunksOf n xs = l : chunksOf n r where (l,r) = splitAt n xs

import qualified Data.ByteString.Char8 as B
import Data.List (foldl')
import Data.Array.IArray
import Data.Array.ST.Safe (STArray,STUArray,newArray,readArray,writeArray)
import Data.STRef (newSTRef,readSTRef,writeSTRef)
import Control.Monad (when)
import Control.Monad.ST.Safe (ST,runST)
main = do
  (n:ns) <- fmap (map read' . B.words) B.getContents
  let prep = do
        m2 <- newArray (0,n) (maxBound `div` 2) :: ST s (STUArray s Int Int)
        p2 <- newArray (0,n) "E"                :: ST s (STArray s Int String)
        writeArray m2 1 0
        writeArray p2 1 ""
        return (m2,p2)
  let dp ns = runST $ do
        zero <- newSTRef Nothing
        (m2,p2) <- prep
        (m5,p5) <- prep
        let dp' ns = go ns 1 where
              go [] _ = return ()
              go (x:xs) i = do
                when (x == 0) $ writeSTRef zero (Just i)
                l2  <- readArray m2 (i-1)
                l2p <- readArray p2 (i-1)
                l5  <- readArray m5 (i-1)
                l5p <- readArray p5 (i-1)
                u2  <- readArray m2  i
                u2p <- readArray p2  i
                u5  <- readArray m5  i
                u5p <- readArray p5  i
                let n2 = factors 2 x
                    n5 = factors 5 x
                    (e2,e2p) = min ((l2+n2),('R':l2p)) ((u2+n2),('D':u2p))
                    (e5,e5p) = min ((l5+n5),('R':l5p)) ((u5+n5),('D':u5p))
                writeArray m2 i e2
                writeArray p2 i e2p
                writeArray m5 i e5
                writeArray p5 i e5p
                go xs $! i+1
        mapM_ dp' ns
        b2  <- readArray m2 n
        b2p <- readArray p2 n
        b5  <- readArray m5 n
        b5p <- readArray p5 n
        z <- readSTRef zero
        let (m,p) = min (b2,b2p) (b5,b5p)
        return $ case z of
          Nothing -> (m,p)
          Just j -> min (m,p) (1,replicate (j-1) 'R' ++
                                 replicate (n-1) 'D' ++
                                 replicate (n-j) 'R')
      (m,p) = dp (chunksOf n ns)
  print m
  putStrLn (tail $ reverse p)
{-# INLINE factors #-}
factors _ 0 = 1
factors n x = go x 0 where
  go x a | r == 0    = go q $! a + 1
         | otherwise = a
    where (q,r) = x `divMod` n
{-# INLINE chunksOf #-}
chunksOf n = go where
  go [] = []
  go xs = l : go r where (l,r) = splitAt n xs
{-# INLINE read' #-}
read' s = r where Just (r,_) = B.readInt s

import Data.List
import Control.Monad

main = do
  n <- readLn
  r <- liftM (solve . parse) (replicateM n getLine)
  print r

parse = map (map read . words)
big = 60000

solve ls = (z,tail (reverse t))
    where i = ((0,""),(0,"")) : repeat ((big,undefined),(big,undefined))
          d ((a,p2),(b,p5)) (c,d) = ((a+c,'D':p2),(b+d,'D':p5))
          r ((a,p2),(b,p5)) ((c,d),((e,p2'),(f,p5'))) = (s,s)
              where s = ((g,p2''),(h,p5''))
                    (g,p2'') = if a+c <= e then (a+c,'R':p2) else (e,p2')
                    (h,p5'') = if b+d <= f then (b+d,'R':p5) else (f,p5'')
          p (h:t) = (snd h) : snd (mapAccumL r (snd h) t)
          l a b = p $ zip b $ zipWith d a b
          (z,t) = uncurry min $ last $ foldl' l i $ map (map factor) ls

factor n = (m2,m5)
    where (m2,r) = f 2 n
          (m5,_) = f 5 r
          f b n = go n 0
              where go n a | r == 0    = go q $! a+1
                           | otherwise = (a,n)
                        where (q,r) = n `divMod` b

{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE BangPatterns #-}
module Main where

import Data.List (foldl')

import Data.Array (listArray, elems)

import Control.Monad (forM_, replicateM)
import Data.Functor ((<&>))
import Data.Semigroup (Sum(..))
import Data.Ord (comparing)
import Data.Word
import GHC.List (scanl')

type V = Int

badInput :: [[V]]
badInput = replicate 1000 $ replicate 1000 1

main :: IO ()
main = do
  Answer w p <- solve <$> pure badInput
  print (unWeight w)
  putStrLn (reverse p)

readInput :: IO [[V]]
readInput = do
  n <- readLn
  replicateM n $ getLine <&> map read . words

solve :: [[V]] -> Answer
solve rows = min a2 a5
  where
    a2 = findAnswer (Factor 2) rows
    a5 = findAnswer (Factor 5) rows

findAnswer :: Factor -> [[V]] -> Answer
findAnswer p (row:rows) = last $ foldl' (nextRow p) (firstRow p row) rows

firstRow :: Factor -> [V] -> [Answer]
firstRow p (first:rest) = scanl step initial rest
  where
    initial = Answer (toWeight p first) ""
    step a v = moveRight a (toWeight p v)

nextRow :: Factor -> [Answer] -> [V] -> [Answer]
nextRow p (firstUp:restUp) (first:rest) = scanl' step initial (zip restUp rest)
  where
    initial = moveDown firstUp $ toWeight p first
    step !left (up, v)  = let w = toWeight p v
     in min (moveRight left w) (moveDown up w)

moveRight :: Answer -> Weight -> Answer
moveRight (Answer w1 p) w2 = Answer (w1 <> w2) ('R':p)

moveDown :: Answer -> Weight -> Answer
moveDown (Answer w1 p) w2 = Answer (w1 <> w2) ('D':p)

toWeight :: Factor -> V -> Weight
toWeight _ 0 = Zeroed
toWeight p k = Amount (count p k)

unWeight :: Weight -> V
unWeight Zeroed = 1
unWeight (Amount a) = unCounted a

count :: Factor -> V -> Counted
count (Factor d) value = countD0 value 0
  where
    countD0 value acc = let (q, r) = quotRem value d
     in if r == 0 then countD0 q (acc + 1) else Counted acc

newtype Size = Size { unSize :: V } deriving (Show)
newtype Factor = Factor V
newtype Counted = Counted { unCounted :: V }
 deriving (Show, Eq, Ord)
 deriving Semigroup via (Sum V)

data Weight = Zeroed | Amount !Counted
  deriving (Show, Eq)

instance Ord Weight where
  compare a b = compare (unWeight a) (unWeight b)

instance Semigroup Weight where
  Zeroed <> _ = Zeroed
  _ <> Zeroed = Zeroed
  (Amount a) <> (Amount b) = Amount (a <> b)

data Answer = Answer { weight :: !Weight
                     , path :: String
                     } deriving (Show)

instance Eq Answer where
  a == b = weight a == weight b

instance Ord Answer where
  compare = comparing weight

{-# LANGUAGE BangPatterns #-}
module Main where

import qualified Data.Array.MArray.Safe as MA
import qualified Data.Array.IO.Safe as IA
import qualified Data.Array as A
import Data.Array ((!))
import Data.Int
import Control.Monad

type V = Int64
type I = Int
type Matrix = A.Array I (A.Array I V)
type Arr = IA.IOArray I
type D = Arr (Arr Solution)

readMatrix :: Int -> [String] -> Matrix
readMatrix n = A.listArray (1, n) . map (A.listArray (1, n) . fmap read . words)

data Solution = Solution {
  result :: V,
  path :: String
} deriving (Show)

countZeros :: V -> Int
countZeros value = countZeros0 value 0
  where
    countZeros0 !value !acc = let (q, r) = quotRem value 10
     in if r == 0 then countZeros0 q (acc + 1) else acc

initD :: Matrix -> IO D
initD m = do
    result <- MA.newArray_ bounds :: IO D
    forM_ [from .. to] $ \i -> MA.newArray_ bounds >>= MA.writeArray result i
    return result
  where
    bounds@(from, to) = A.bounds m

writeV :: D -> I -> I -> Solution -> IO ()
writeV m i j e = MA.readArray m i >>= \a -> MA.writeArray a j e

readV :: D -> I -> I -> IO Solution
readV m i j = MA.readArray m i >>= \a -> MA.readArray a j

debug :: D -> I -> I -> IO ()
debug m i j = do
    s <- readV m i j
    putStrLn $ show i <> " " <> show j <> " " <> show s

solve :: Matrix -> IO Solution
solve m = do
    arr <- initD m
    writeV arr 1 1 $ Solution (m ! 1 ! 1) ""
    forM_ [2 .. n] $ \i -> do
      Solution cr cp <- readV arr 1 (i - 1)
      Solution rr rp <- readV arr (i - 1) 1
      writeV arr 1 i $ Solution (cr * m ! 1 ! i) ('R':cp)
      writeV arr i 1 $ Solution (rr * m ! i ! 1) ('D':rp)
      -- debug arr 1 i
      -- debug arr i 1
    forM_ [(i, j) | i <- [2..n], j <- [2..n]] $ \(i, j) -> do
      Solution cr cp <- readV arr (i - 1) j
      Solution rr rp <- readV arr i (j - 1)
      let curV = m ! i ! j
          downR = cr * curV
          rightR = rr * curV
          res = if countZeros downR < countZeros rightR then Solution downR ('D':cp) else Solution rightR ('R':rp)
        in writeV arr i j res
      -- debug arr i j
    readV arr n n
  where
    n = length m

main :: IO ()
main = do
  n <- read `fmap` getLine :: IO Int
  m <- readMatrix n `fmap` replicateM n getLine
  res <- solve m
  print . countZeros $ result res
  putStrLn . reverse $ path res

module Main where

import Control.Applicative ((<$>))
import Data.List (foldl')

powerOf :: Int -> Int -> Int
powerOf p n = case n `mod` p of
  0 -> 1 + powerOf p (n `div` p)
  _ -> 0

data DP = DP { minNum :: !Int
             , go :: !String }
             deriving (Show)

dp :: [[Int]] -> DP
dp (row:rows) = last $ foldl' dpRow (dpFirstRow row) rows

dpRow :: [DP] -> [Int] -> [DP]
dpRow (up:ups) (cur:curs) = scanl step dpInit $ zip ups curs where
  step (DP leftNum leftGo) (DP upNum upGo, n)
    | upNum < leftNum = DP (n + upNum)   ('D':upGo)
    | otherwise       = DP (n + leftNum) ('R':leftGo)
  dpInit = DP (cur + minNum up) ('D':go up)

dpFirstRow :: [Int] -> [DP]
dpFirstRow currs = zipWith DP sums rs where
  sums = scanl1 (+) currs
  rs = iterate ('R':) []

inputGrids :: IO [[(Int, Int)]]
inputGrids = do
  n <- readLn :: IO Int
  let getPowers a = (powerOf 2 a, powerOf 5 a)
  input <- getContents
  return $ map (map getPowers . map read . words) (lines input)

main :: IO ()
main = do
  (grids2, grids5) <- unzip . map unzip <$> inputGrids
  let DP min2 go2 = dp grids2
      DP min5 go5 = dp grids5
  if min2 <= min5
    then print min2 >> putStrLn go2
    else print min5 >> putStrLn go5

module Main where

import qualified Data.Array.IArray as I
import qualified Data.Array as A
import Data.Array.Unboxed
import Data.Maybe (maybe)
import Data.List (foldl')
import qualified Data.ByteString.Char8 as C

import Debug.Trace

powerOf :: Int -> Int -> Int
powerOf p n = case n `mod` p of
  0 -> 1 + powerOf p (n `div` p)
  _ -> 0

data DP = DP { minNum :: !Int
             , go :: !String }
             deriving (Show)

dp :: Int -> Int -> [UArray Int Int] -> DP
dp n p (row:rows) = (foldl' (dpRow n p) (dpFirstRow n p (I.elems row)) rows)!(n-1)

dpRow :: Int -> Int -> A.Array Int DP -> UArray Int Int -> A.Array Int DP
dpRow n p ups curs = I.listArray (0,n-1) $ scanl step dpInit [1..n-1] where
  step (DP leftNum leftGo) n
    | upNum < leftNum = DP (powerOf p (curs!n) + upNum)   ('D':upGo)
    | otherwise       = DP (powerOf p (curs!n) + leftNum) ('R':leftGo)
    where DP upNum upGo = ups!n
  dpInit = DP (powerOf p (curs!0) + minNum up) ('D':go up)
  up = ups!0

dpFirstRow :: Int -> Int -> [Int] -> A.Array Int DP
dpFirstRow n p currs = I.listArray (0, n-1) $ zipWith DP sums rs where
  sums = scanl1 ((+) . powerOf p) currs
  rs = iterate ('R':) []

inputGrids :: IO (Int, [UArray Int Int])
inputGrids = do
  n <- readLn
  grids <- sequence $ replicate n $ do
    line <- C.getLine
    let ns = map (maybe (error "Read") fst) . map C.readInt . C.words $ line
    return $! I.listArray (0, n-1) ns
  return (n, grids)

main :: IO ()
main = do
  (n, grids) <- inputGrids
  let DP min2 go2 = dp n 2 grids
      DP min5 go5 = dp n 5 grids
  if min2 <= min5
    then print min2 >> putStrLn (reverse go2)
    else print min5 >> putStrLn (reverse go5)

import Data.List
import Data.Maybe (maybeToList)
import Data.Functor ((<$>))
import Data.Function (on)
import qualified Data.Array as A
import qualified Data.Array.Unboxed as U
import qualified Data.ByteString.Char8 as B

getPows :: Int -> Int -> Int
getPows b x = case x `divMod` b of
  (x', 0) -> 1 + getPows b x'
  _ -> 0

solve :: Int -> U.Array (Int, Int) Int -> (Int, String)
solve n mat = dp A.! (0, 0)
  where dp = A.array ((0, 0), (n-1, n-1)) [((i, j), f i j) | i <- [0..n-1], j <- [0..n-1]]
        f i j
          | i == n-1 && j == n-1 = (0, "")
          | i == n-1 = dpath
          | j == n-1 = rpath
          | otherwise = minimumBy (compare `on` fst) [dpath, rpath]
          where gridWeight = mat U.! (i, j)

                (dweight', dpath') = dp A.! (i, j+1)
                dpath = (gridWeight + dweight', 'D' : dpath')

                (rweight', rpath') = dp A.! (i+1, j)
                rpath = (gridWeight + rweight', 'R' : rpath')

main :: IO ()
main = do
  n : mat' <- map (maybe 0 fst . B.readInt) . B.words <$> B.getContents

  let mat = U.listArray ((0, 0), (n-1, n-1)) (map (\x -> if x == 0 then 10 else x) mat')

      mat2 = U.amap (getPows 2) mat
      mat5 = U.amap (getPows 5) mat

      zeroPath idx = (1, replicate x 'R' ++ replicate n 'D' ++ replicate (n-x) 'R')
        where x = idx `div` n
      cands = [solve n mat2, solve n mat5] ++ maybeToList (zeroPath <$> elemIndex 0 mat')

      (ansWeight, ansPath) = minimumBy (compare `on` fst) cands

  print ansWeight
  putStrLn ansPath

import Data.List
import Data.Maybe (maybeToList)
import Data.Functor ((<$>))
import Data.Function (on)
import qualified Data.Array.Unboxed as U
import qualified Data.ByteString.Char8 as B

getPows :: Int -> Int -> Int
getPows b =
  let getPows' b' callback acc x = case x `divMod` b' of
        (x', 0) -> getPows' b' callback (acc + 1) x'
        _ -> callback acc x
  in getPows' (b ^ 5) (getPows' b const . (* 5)) 0

solve :: Int -> U.UArray (Int, Int) Int -> Int -> (Int, String)
solve n mat b = foldl' seq n [f i j | i <- steps, j <- steps]
                `seq` (dp U.! (0, 0), findPath 0 0)

  where step = min (n `div` 2) 30
        steps = reverse [0, step .. n-1]

        getPow = getPows n

        dp :: U.Array (Int, Int) Int
        dp = U.listArray ((0, 0), (n-1, n-1)) [f i j | i <- [0..n-1], j <- [0..n-1]]

        findPath i j
          | i == n-1 = replicate (n-j-1) 'R'
          | j == n-1 = replicate (n-i-1) 'D'
          | otherwise =
            if dp U.! (i, j+1) > dp U.! (i+1, j)
            then 'D' : findPath (i+1) j
            else 'R' : findPath i (j+1)

        f i j
          | i == n-1 && j == n-1 = gridWeight
          | i == n-1 = rpath
          | j == n-1 = dpath
          | otherwise = min dpath rpath
          where gridWeight = getPow $ mat U.! (i, j)
                dpath = dp U.! (i+1, j) + gridWeight
                rpath = dp U.! (i, j+1) + gridWeight

readInt :: B.ByteString -> Int
readInt' word = case B.readInt word of
  Just (num, _) -> num
  Nothing -> 0
readInt = maybe 0 fst . B.readInt

readInput :: IO (Int, U.UArray (Int, Int) Int, [(Int, String)])
readInput = do
  n : mat' <- map readInt . B.words <$> B.getContents
  let zeroPath idx = (1, replicate x 'R' ++ replicate (n-1) 'D' ++ replicate (n-1-x) 'R')
        where x = idx `mod` n
      maybeZeroPath = maybeToList $ zeroPath <$> elemIndex 0 mat'

      mat = U.listArray ((0, 0), (n-1, n-1)) (map (\x -> if x == 0 then 10 else x) mat')
  return (n, mat, maybeZeroPath)

main :: IO ()
main = do
  (n, mat, maybeZeroPath) <- readInput

  let ans2 = solve n mat 2
      ans5 = solve n mat 5
      cands = maybeZeroPath ++ [ans2, ans5]
      (ansWeight, ansPath) = minimumBy (compare `on` fst) cands

  print ansWeight
  putStrLn ansPath

import Data.List
import Data.Maybe (maybeToList)
import Data.Functor ((<$>))
import Data.Function (on)
import qualified Data.Array as A
import qualified Data.Array.Unboxed as U
import qualified Data.ByteString.Char8 as B

getPows :: Int -> Int -> Int
getPows b x = case x `divMod` b of
  (x', 0) -> 1 + getPows b x'
  _ -> 0

solve :: Int -> U.Array (Int, Int) Int -> (Int, String)
solve n mat = dp A.! (0, 0)
  where dp = A.array ((0, 0), (n-1, n-1)) [((i, j), f i j) | i <- [0..n-1], j <- [0..n-1]]
        f i j
          | i == n-1 && j == n-1 = (0, "")
          | i == n-1 = rpath
          | j == n-1 = dpath
          | otherwise = minimumBy (compare `on` fst) [dpath, rpath]
          where gridWeight = mat U.! (i, j)

                (dweight', dpath') = dp A.! (i+1, j)
                dpath = (gridWeight + dweight', 'D' : dpath')

                (rweight', rpath') = dp A.! (i, j+1)
                rpath = (gridWeight + rweight', 'R' : rpath')

main :: IO ()
main = do
  n : mat' <- map (maybe 0 fst . B.readInt) . B.words <$> B.getContents

  let mat = U.listArray ((0, 0), (n-1, n-1)) (map (\x -> if x == 0 then 10 else x) mat')

      mat2 = U.amap (getPows 2) mat
      mat5 = U.amap (getPows 5) mat

      zeroPath idx = (1, replicate x 'R' ++ replicate n 'D' ++ replicate (n-x) 'R')
        where x = idx `mod` n
      cands = [solve n mat2, solve n mat5] ++ maybeToList (zeroPath <$> elemIndex 0 mat')

      (ansWeight, ansPath) = minimumBy (compare `on` fst) cands

  print ansWeight
  putStrLn ansPath