There is a square matrix n × n, consisting of non-negative integer numbers. You should find such a way on it that   starts in the upper left cell of the matrix;  each following cell is to the right or down from the current cell;  the way ends in the bottom right cell. Moreover, if we multiply together all the numbers along the way, the result should be the least "round". In other words, it should end in the least possible number of zeros.

The first line contains an integer number n (2 ≤ n ≤ 1000), n is the size of the matrix. Then follow n lines containing the matrix elements (non-negative integer numbers not exceeding 109).

In the first line print the least number of trailing zeros. In the second line print the correspondent way itself.

import java.util._
import java.io._
import scala.annotation.tailrec

object P2B extends App {
  object ReaderWriter {
    val reader = new BufferedReader(new InputStreamReader(System.in))
    val writer = new PrintWriter(System.out)
    var tok: StringTokenizer = null

    @tailrec
    def readToken(): String = {
      if (tok != null && tok.hasMoreTokens()) {
        tok.nextToken()
      } else {
        val line = reader.readLine()
        tok = null
        if (line == null) {
          null
        } else {
          tok = new StringTokenizer(line)
          readToken()
        }
      }
    }
  }

  import ReaderWriter._

  def readInt(): Int = readToken().toInt

  def log(value: Int, base: Int): Int = {
    @tailrec
    def rec(value: Int, acc: Int): Int = {
      if (value == 0) {
        1
      } else if (value % base == 0) {
        rec(value / base, acc + 1)
      } else {
        acc
      }
    }
    rec(value, 0)
  }

  val n = readInt()
  var cur = 0
  var next = 1 - cur
  val m = Array.ofDim[Int](n, n)
  for {
    row <- 0 until n
    column <- 0 until n
  } {
    m(row)(column) = readInt()
  }

  object Direction {
    sealed trait Type
    case object No extends Type
    case object Up extends Type
    case object Left extends Type
  }

  def minSumAndPath(functor: Int => Int): (Int, Seq[Char]) = {
    val d = Array.ofDim[Int](n, n)
    val prev = Array.fill[Direction.Type](n, n)(Direction.No)
    for {
      row <- 0 until n
      column <- 0 until n
    } {
      val value = functor(m(row)(column))
      val dUpOpt: Option[Int] = if (row > 0) Some(d(row - 1)(column)) else None
      val dLeftOpt: Option[Int] = if (column > 0) Some(d(row)(column - 1)) else None
      val dUp = dUpOpt.getOrElse(Integer.MAX_VALUE)
      val dLeft = dLeftOpt.getOrElse(Integer.MAX_VALUE)
      if (!dUpOpt.isDefined && !dLeftOpt.isDefined) {
        d(row)(column) = value
        prev(row)(column) = Direction.No
      } else {
        if (dUp < dLeft) {
          d(row)(column) = dUp + value
          prev(row)(column) = Direction.Up
        } else {
          d(row)(column) = dLeft + value
          prev(row)(column) = Direction.Left
        }
      }
    }

    var row = n - 1
    var column = n - 1
    var path = Seq.empty[Char]
    while (!(row == 0 && column == 0)) {
      prev(row)(column) match {
        case Direction.Up =>
          path :+= 'D'
          row -= 1
        case Direction.Left =>
          path :+= 'R'
          column -= 1
        case _ =>
          row = 0
          column = 0
      }
    }

    (d(n - 1)(n - 1), path.reverse)
  }

  val (zeroSum, zeroPath) = minSumAndPath({ value => if (value == 0) -1 else 0 })
  val (twoSum, twoPath) = minSumAndPath({ value => log(value, 2) })
  val (fiveSum, fivePath) = minSumAndPath({ value => log(value, 5) })

  val bestSum = Math.min(twoSum, fiveSum)
  val bestPath = if (twoSum < fiveSum) twoPath else fivePath
  if ((zeroSum < 0) && (bestSum > 1)) {
    writer.println(1)
    writer.println(zeroPath.mkString(""))
  } else {
    writer.println(bestSum)
    writer.println(bestPath.mkString(""))
  }

  writer.flush()
}

import io.Source
import annotation.tailrec

object LeastRound {
    def main(args: Array[String]) = {
        val lines = Source.stdin.getLines()
        val size = lines.next().toInt

        val numMatrix = readMatrix(lines, size)
        val zeroCoords = zeroPass(numMatrix)

        calculatePathCost(numMatrix)
        printBestPath(numMatrix, zeroCoords)
    }

    def readMatrix(lines: Iterator[String], matrixSize: Int) = {
        val matrix = new Array[Array[Int]](matrixSize)

        for (row <- 0 until matrixSize) {
            matrix(row) = lines.next().split(" ").map(_.toInt)
        }
        matrix
    }

    def zeroPass(rawNumMatrix: Array[Array[Int]]) = {
        val size = rawNumMatrix.length
        var seenZero = false
        var zeroCoords: Option[Pair[Int, Int]] = None

        for (row <- 0 until size) {
            for (col <- 0 until size) {
                if (rawNumMatrix(row)(col) == 0) {
                    rawNumMatrix(row)(col) = 10
                    if (!seenZero) {
                        seenZero = true
                        zeroCoords = Some(Pair(row, col))
                    }
                }
            }
        }
        zeroCoords
    }

    def calculatePathCost(numMatrix: Array[Array[Int]]) = {
        // mutate in place!
        val size = numMatrix.length
        def extractExponent(divisor: Int) (toFactor: Int) = {
            @tailrec
            def runningExponentCount(currExp: Int, currN: Int): Int =
                if (currN % divisor == 0) runningExponentCount(currExp + 1, currN / divisor) else currExp
            runningExponentCount(0, toFactor)
        }
        def factorizer(n: Int) = Pair(extractExponent(2)(n), extractExponent(5)(n))

        numMatrix(0)(0) = encodeAsInt(factorizer(numMatrix(0)(0)))
        for (col <- 1 until size) {
            val row = 0
            numMatrix(row)(col) = encodeAsInt(addTuples(decodeToTuple(numMatrix(row)(col - 1)), factorizer(numMatrix(row)(col))))
        }
        for (row <- 1 until size) {
            val col = 0
            numMatrix(row)(col) = encodeAsInt(addTuples(decodeToTuple(numMatrix(row-1)(col)), factorizer(numMatrix(row)(col))))
        }
        for (row <- 1 until size) {
            for (col <- 1 until size) {
                val currCellFactorized = factorizer(numMatrix(row)(col))
                val top = decodeToTuple(numMatrix(row-1)(col))
                val left = decodeToTuple(numMatrix(row)(col-1))
                val bestPaths = Pair(top._1 min left._1, top._2 min left._2)
                numMatrix(row)(col) = encodeAsInt(addTuples(bestPaths, currCellFactorized))
            }
        }
    }

    def printBestPath(pathMatrix: Array[Array[Int]], zeroCoord: Option[Pair[Int, Int]]) = {
        val size = pathMatrix.size
        val last = decodeToTuple(pathMatrix(size - 1)(size - 1))
        if (zeroCoord.isEmpty || (last._1 min last._2) == 0) {
            // regular case
            val path = (if (last._1 < last._2) {
                           println(last._1)
                           tracePath(pathMatrix, _._1)
                        }
                        else {
                           println(last._2)
                           tracePath(pathMatrix, _._2)
                        })

            path.foreach(print)
            println()
        }
        else {
            println(1)
            printZeroPath(zeroCoord.get, size)
            println()
        }
    }

    def tracePath(pathMatrix: Array[Array[Int]], chooser: Pair[Int, Int] => Int) = {
        val size = pathMatrix.size

        var currRow = size - 1
        var currCol = size - 1
        var path: List[Char] = Nil

        while (currRow != 0 && currCol != 0) {
            val top = decodeToTuple(pathMatrix(currRow - 1)(currCol))
            val left = decodeToTuple(pathMatrix(currRow)(currCol-1))
            if (chooser(top) < chooser(left)) {
                path = 'D' :: path
                currRow -= 1
            }
            else {
                path = 'R' :: path
                currCol -= 1
            }
        }
        while (currRow == 0 && currCol != 0) {
            path = 'R' :: path
            currCol -= 1
        }

        while (currCol == 0 && currRow != 0) {
            path = 'D' :: path
            currRow -= 1
        }
        path
    }

    def printZeroPath(zeroCoord: Pair[Int, Int], size: Int) = {
        printN('D', zeroCoord._1)
        printN('R', zeroCoord._2)
        printN('D', size - zeroCoord._1 - 1)
        printN('R', size - zeroCoord._2 - 1)
    }

    def printN(item: Char, numTimes: Int) = {
        for (i <- 0 until numTimes)
            print(item)
    }

    def decodeToTuple(m: Int) = {
        // want the pair: (i,j)
        // put k = i + j
        val k = ((-1 + math.sqrt(1 + 8*m)) / 2).toInt
        val j = m - k*(k + 1)/2
        val i = k - j
        (i, j)
    }

    def encodeAsInt(pair: Pair[Int, Int]) =
        pair match {
            case (i, j) => (i + j)*(i + j + 1) / 2 + j
        }

    def addTuples(tuple1: Pair[Int, Int], tuple2: Pair[Int, Int]) =
        Pair(tuple1._1 + tuple2._1, tuple1._2 + tuple2._2)

    // ok, works on everything (functions are the identity, composed either way)
    def testEncodeDecode(factorizer: (Int) => Pair[Int, Int]) = {
        for (n <- 0 to 1000000000) {
            if (n % 10000000 == 0) {
                println(s"examining $n.")
            }
            if (encodeAsInt(decodeToTuple(n)) != n) {
                println("mistake on " + n)
            }
        }
        for (twos <- 0 to 9) {
            println(s"examining $twos")
            for (fives <- 0 to twos) {
                if (decodeToTuple(encodeAsInt(Pair(twos, fives))) != Pair(twos, fives)) {
                    println(s"mistake on ${Pair(twos, fives)}")
                }
                if (Pair(twos, fives) != factorizer(math.pow(2, twos).toInt * math.pow(5, fives).toInt))
                    println(s"mistake, didn't factor ${Pair(twos, fives)} which is ${twos * fives}")
            }
        }
    }
}

object solution {
  def solve(n: Int, cost: Array[Array[Int]]): (Int, String) = {
    val INF = 100000
    val rv = Array.fill[Int](n, n)(0)
    val rp = Array.fill[Char](n, n)(' ')
    rv(0)(0) = cost(0)(0)
    for (y <- 0 until n; x <- 0 until n if x + y > 0) {
      var res = INF
      var resp = ' '
      if (y > 0) {
        res = rv(y - 1)(x)
        resp = 'D'
      }
      if (x > 0 && res > rv(y)(x-1)) {
        res = rv(y)(x - 1)
        resp = 'R'
      }
      rv(y)(x) = res + cost(y)(x)
      rp(y)(x) = resp
    }
    var (y, x) = (n-1, n-1)
    var path = new StringBuilder()
    while (y + x > 0) {
      if (rp(y)(x) == 'R') {
        path += 'R'
        x -= 1
      } else {
        path += 'D'
        y -= 1
      }
    }
    (rv(n-1)(n-1), path.reverse.toString())
  }

  def main(args: Array[String]) = {
    val n = io.StdIn.readInt()
    val twos = Array.fill[Int](n, n)(0)
    val fives = Array.fill[Int](n, n)(0)

    def power_of(x: Int, p: Int): Int = {
      var result = 0
      var left = x
      while (left % p == 0) {
        result += 1
        left /= p
      }
      result
    }
    var zero_point: Option[(Int, Int)] = None
    for (y <- 0 until n) {
      val line = io.StdIn.readLine().split(" ").map(_.toInt)
      for (x <- 0 until n) {
        if (line(x) > 0) {
          twos(y)(x) = power_of(line(x), 2)
          fives(y)(x) = power_of(line(x), 5)
        } else {
          zero_point = Some((x, y))
          twos(y)(x) = 1
          fives(y)(x) = 1
        }
      }
    }
    val s2 = solve(n, twos)
    val s5 = solve(n, fives)

    if (math.min(s2._1, s5._1) == 0 || !zero_point.isDefined) {
      if (s2._1 <= s5._1)
        printf("%d\n%s\n", s2._1, s2._2)
      else
        printf("%d\n%s\n", s5._1, s5._2)
    } else {
      val (x, y) = zero_point.get
      printf("1\n")
      println(("R" * x) + ("D" * y) + ("R" * (n - x - 1)) + ("D" * (n - y - 1)))
    }
  }

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val n = in.next().toInt

  val line = in.take(n).map(_.split(' ').map(_.toInt)).toArray

  def f(a: Int, k: Int) = {
    var r = 0
    var m = a

    while (m != 0 && m % k == 0) {
      m /= k
      r += 1
    }
    r
  }

  def dp(k: Int) = {
    val dp = line.map(_.map(i => f(i, k)))

    (1 until n).foreach { i =>
      dp(i)(0) += dp(i - 1)(0)
      dp(0)(i) += dp(0)(i - 1)
    }

    (1 until n).foreach { i =>
      (1 until n).foreach { j =>
        dp(i)(j) += Math.min(dp(i - 1)(j), dp(i)(j - 1))
      }
    }

    dp
  }

  val dpr = List(2, 5).map(dp).minBy(d => d(n - 1)(n - 1))

  var min = dpr(n - 1)(n - 1)

  val maybeZero = (0 until n).find { i =>
    line(i).contains(0)
  }

  if (min > 1 && maybeZero.nonEmpty) {
    println(1)
    println("D" * maybeZero.get + "R" * (n - 1) + "D" * (n - 1 - maybeZero.get))
  }
  else {
    println(min)
    var x = n - 1
    var y = n - 1
    var answer = List.empty[Char]

    while (x != 0 || y != 0) {
      val upCandidate = y != 0 && (x == 0 || dpr(y - 1)(x) <= dpr(y)(x - 1))
      if (upCandidate) {
        answer ::= 'D'
        y -= 1
      } else {
        answer ::= 'R'
        x -= 1
      }
    }
    println(answer.mkString)
  }
}

import scala.collection.mutable.HashMap
import scala.math.min

object testing {

    def findPower5(input : Int) : Int = {
        if (input == 0) {
            return 50000
        }
        var temp = input
        var returnValue = 0
        while (temp % 5 == 0) {
            returnValue += 1
            temp /= 5
        }
        return returnValue
    }

    def findPower2(input : Int) : Int = {
        if (input == 0) {
            return 50000
        }
        var temp = input
        var returnValue = 0
        while (temp % 2 == 0) {
            returnValue += 1
            temp /= 2
        }
        return returnValue
    }

    def main(args: Array[String]) : Unit = {
        var matrixSize: Int = scala.io.StdIn.readInt()
        var inputMatrix = Array.ofDim[Int](matrixSize,matrixSize)
        var fiveMatrix = Array.ofDim[Int](matrixSize,matrixSize)
        var twoMatrix = Array.ofDim[Int](matrixSize,matrixSize)
        var existsZero = false
        var zeroX = -1
        var zeroY = -1
        for (i <- 0 until matrixSize) {
            var inputLine = scala.io.StdIn.readLine()
            var inputSplit = inputLine.split(" ")
            for (j <- 0 until matrixSize) {
                inputMatrix(i)(j) = inputSplit(j).toInt
                if (inputMatrix(i)(j) == 0) {
                    existsZero = true
                    zeroY = i
                    zeroX = j
                }
                fiveMatrix(i)(j) = 0
                twoMatrix(i)(j) = 0
            }
        }
        fiveMatrix(0)(0) = findPower5(inputMatrix(0)(0))
        for (i <- 1 until matrixSize) {
            fiveMatrix(0)(i) = fiveMatrix(0)(i-1) + findPower5(inputMatrix(0)(i))
        }
        for (i <- 1 until matrixSize) {
            fiveMatrix(i)(0) = fiveMatrix(i-1)(0) + findPower5(inputMatrix(i)(0))
        }
        for (i <- 1 until matrixSize;
            j <- 1 until matrixSize) {
            fiveMatrix(i)(j) = min(fiveMatrix(i)(j-1) + findPower5(inputMatrix(i)(j)),
                fiveMatrix(i-1)(j) + findPower5(inputMatrix(i)(j)))
        }

        twoMatrix(0)(0) = findPower2(inputMatrix(0)(0))
        for (i <- 1 until matrixSize) {
            twoMatrix(0)(i) = twoMatrix(0)(i-1) + findPower2(inputMatrix(0)(i))
        }
        for (i <- 1 until matrixSize) {
            twoMatrix(i)(0) = twoMatrix(i-1)(0) + findPower2(inputMatrix(i)(0))
        }
        for (i <- 1 until matrixSize;
            j <- 1 until matrixSize) {
            twoMatrix(i)(j) = min(twoMatrix(i)(j-1) + findPower2(inputMatrix(i)(j)),
                twoMatrix(i-1)(j) + findPower2(inputMatrix(i)(j)))
        }

        var output : String = ""
        if (min(twoMatrix(matrixSize - 1)(matrixSize - 1),
            fiveMatrix(matrixSize - 1)(matrixSize - 1)) > 1 && existsZero) {
            // find zero path
            for (i <- 0 until zeroX) {
                output = output + "R"
            }
            for (i <- 0 until matrixSize - 1) {
                output = output + "D"
            }
            for (i <- zeroX until matrixSize - 1) {
                output = output + "R"
            }
            println(1)
            println(output)
            return;
        }

        if (twoMatrix(matrixSize - 1)(matrixSize - 1) < fiveMatrix(matrixSize - 1)(matrixSize - 1)) {
            var currX = matrixSize - 1
            var currY = matrixSize - 1
            while (currX != 0 || currY != 0) {
                if (currX != 0 && twoMatrix(currY)(currX - 1) + findPower2(inputMatrix(currY)(currX)) == twoMatrix(currY)(currX)) {
                    output = "R" + output
                    currX = currX - 1
                } else {
                    output = "D" + output
                    currY = currY - 1
                }
            }
            println(twoMatrix(matrixSize - 1)(matrixSize - 1))
            println(output)
            return
        } else {
            var currX = matrixSize - 1
            var currY = matrixSize - 1
            while (currX != 0 || currY != 0) {
                if (currX != 0 && fiveMatrix(currY)(currX - 1) + findPower5(inputMatrix(currY)(currX)) == fiveMatrix(currY)(currX)) {
                    output = "R" + output
                    currX = currX - 1
                } else {
                    output = "D" + output
                    currY = currY - 1
                }
            }
            println(fiveMatrix(matrixSize - 1)(matrixSize - 1))
            println(output)
            return
        }
    }
}

import java.util.Scanner

object BLessRoundTripDynamic extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.next.toInt

  val matrix = Array.ofDim[Long](dim, dim)

  var zeroPoint: Option[(Int, Int)] = None

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.next().toLong
          if (matrix(x)(y) == 0) {
            zeroPoint = Some((x, y))
            matrix(x)(y) = 10
          }
      }
  }

  def printZeroPath(p: (Int, Int)): Unit = {
    println(1)
    (0 until p._1).foreach(t => print("R"))
    (0 until dim - 1).foreach(t => print("D"))
    (p._1 until dim - 1).foreach(t => print("R"))
  }

  case class Direction(value: Int, dir: Boolean)

  val divs = Array.ofDim[Int](dim, dim)
  val dirs = Array.ofDim[Boolean](dim, dim)
  val fiveWeight = countWeights(divs, 5)
  val fivePath = getPath(dirs)
  val twoWeight = countWeights(divs, 2)
  val twoPath = getPath(dirs)

  if (math.min(twoWeight, fiveWeight) > 0 && zeroPoint.isDefined) {
    printZeroPath(zeroPoint.get)
  } else if (twoWeight < fiveWeight) {
    println(twoWeight)
    println(twoPath)
  } else {
    println(fiveWeight)
    println(fivePath)
  }

  def getPath(divs: Array[Array[Boolean]]): String = {
    def traceBack(x: Int, y: Int): List[Char] = {
      if (x == 0 && y == 0) Nil
      else if (divs(x)(y)) 'R' :: traceBack(x - 1, y)
      else 'D' :: traceBack(x, y - 1)
    }
    traceBack(dim - 1, dim - 1).reverse.mkString
  }

  def countWeights(divs: Array[Array[Int]], num: Int): Long = {
    var x = 0
    var y = 0
    while (y < dim) {
      while (x < dim) {
        val curValue = findDivNum(matrix(x)(y), num)
        if (y == 0 && x == 0) {
          divs(x)(y) = curValue
          dirs(x)(y) = false
        } else if (y == 0) {
          divs(x)(y) = curValue + divs(x - 1)(y)
          dirs(x)(y) = true
        } else if (x == 0) {
          divs(x)(y) = curValue + divs(x)(y - 1)
          dirs(x)(y) = false
        } else {
          if (divs(x)(y - 1) < divs(x - 1)(y)) {
            divs(x)(y) = curValue + divs(x)(y - 1)
            dirs(x)(y) = false
          } else {
            divs(x)(y) = curValue + divs(x - 1)(y)
            dirs(x)(y) = true
          }
        }
        x += 1
      }
      x = 0
      y += 1
    }
    divs(dim - 1)(dim - 1)
  }

  def findDivNum(item: Long, num: Int): Int = {
    var it = item
    var res = 0
    while (it % num == 0) {
      it = it / num
      res = res + 1
    }
    res
  }

  def forEach[T](arr: Array[Array[T]], func: (Int, Int, T) => Unit): Unit = {
    (0 until dim) foreach {
      y =>
        (0 until dim) foreach {
          x =>
            func(x, y, arr(x)(y))
        }
    }
  }

}

object B2 {

  import IO._
  import collection.{mutable => cu}

  def main(args: Array[String]): Unit = {
    val Array(n) = readInts(1)
    val in = Array.fill(n)(readInts(n))
    val two = Array.ofDim[Int](n, n)
    val five = Array.ofDim[Int](n, n)
    var zeroi, zeroj = -1

    for(i <- 0 until n; j <- 0 until n if in(i)(j) == 0) {
      zeroi = i
      zeroj = j
      two(i)(j) = 1
      five(i)(j) = 1
    }

    for(i <- 0 until n; j <- 0 until n) {
      var num = in(i)(j)
      var t, f = 0
      while(num != 0 && num%2 == 0) {
        num /= 2
        t += 1
      }
      while(num != 0 && num%5 == 0) {
        num /= 5
        f += 1
      }
      if(i == 0 && j == 0) {
        two(i)(j) += t
        five(i)(j) += f
      } else if(i == 0) {
        two(i)(j) += two(i)(j-1) + t
        five(i)(j) += five(i)(j-1) + f
      } else if(j == 0) {
        two(i)(j) += two(i-1)(j) + t
        five(i)(j) += five(i-1)(j) + f
      } else {
        two(i)(j) += math.min(two(i-1)(j), two(i)(j-1)) + t
        five(i)(j) += math.min(five(i-1)(j), five(i)(j-1)) + f
      }
    }
    val dp = if (two(n - 1)(n - 1) < five(n - 1)(n - 1)) two else five
    if(zeroi != -1 && dp(n-1)(n-1) != 0) {
      println("1")
      println("R"*zeroj ++ "D"*zeroi ++ "R"*(n-zeroj-1) ++ "D"*(n-zeroi-1))
    } else {
      println(dp(n - 1)(n - 1))
      val res = cu.ArrayBuffer.empty[Char]
      var i = n - 1
      var j = n - 1
      while (i != 0 || j != 0) {
        if (i > 0 && (j == 0 || dp(i)(j - 1) >= dp(i - 1)(j))) {
          res.append('D')
          i -= 1
        } else {
          res.append('R')
          j -= 1
        }
      }
      println(res.reverse.mkString(""))
    }
  }

  object IO {
    private val input = new java.io.BufferedReader(new java.io.InputStreamReader(System.in))

    @inline def read: String = input.readLine()

    @inline def tokenizeLine = new java.util.StringTokenizer(read)

    def readInt: Int = tokenizeLine.nextToken.toInt

    def readInts(n: Int): Array[Int] = {
      val tl = tokenizeLine
      Array.fill(n)(tl.nextToken.toInt)
    }

    def readLongs(n: Int): Array[Long] = {
      val tl = tokenizeLine
      Array.fill(n)(tl.nextToken.toLong)
    }

    def readBigs(n: Int): Array[BigInt] = {
      val tl = tokenizeLine
      Array.fill(n)(BigInt(tl.nextToken))
    }
  }

}

import scala.reflect.ClassTag
import scala.annotation.tailrec
object X extends App {
  def dynamicSolveMatrixRightDown[T, U: ClassTag](
      matrix: Array[Array[T]],
      initialValue: U
  )(
      combiner: (U, U, T) => U
  ) = {

    val len = matrix.length

    val solutionMatrix = Array.ofDim[U](len, len)

    solutionMatrix(0)(0) = combiner(initialValue, initialValue, matrix(0)(0))

    (0 until len).foreach(b => {
      (0 to b).foreach(i => {
        // row
        val rowWeight = solutionMatrix(i)(b)
        val colWeight = solutionMatrix(b)(i)

        if (!(b + 1 > len - 1)) {
          solutionMatrix(i)(b + 1) =
            combiner(rowWeight, solutionMatrix(i)(b + 1), matrix(i)(b + 1))
          solutionMatrix(b + 1)(i) =
            combiner(colWeight, solutionMatrix(b + 1)(i), matrix(b + 1)(i))
        }

        if (!(i + 1 > len - 1)) {
          val rightWeight = matrix(i + 1)(b)

          val candidateWeight =
            combiner(rowWeight, solutionMatrix(i + 1)(b), rightWeight)

          solutionMatrix(i + 1)(b) = candidateWeight

          val downWeight = matrix(b)(i + 1)

          val otherCandidateWeight =
            combiner(colWeight, solutionMatrix(b)(i + 1), downWeight)

          solutionMatrix(b)(i + 1) = otherCandidateWeight

        }

        if (b < len - 1 && i == b) {
          val leftWeight =
            combiner(
              solutionMatrix(b)(b + 1),
              solutionMatrix(b + 1)(b + 1),
              matrix(b + 1)(b + 1)
            )

          solutionMatrix(b + 1)(b + 1) = leftWeight

          val upWeight =
            combiner(
              solutionMatrix(b + 1)(b),
              solutionMatrix(b + 1)(b + 1),
              matrix(b + 1)(b + 1)
            )

          solutionMatrix(b + 1)(b + 1) = upWeight
        }

      })

    })

    solutionMatrix
  }

  def dynamicSolveMatrixRightDownInPlace[T](
      matrix: Array[Array[T]],
      initialValue: T
  )(
      combiner: (T, T, T) => T
  ): Array[Array[T]] = {

    val len = matrix.length

    matrix(0)(0) = initialValue

    (1 until len).foreach(i => {
      matrix(0)(i) = combiner(matrix(0)(i - 1), matrix(0)(i - 1), matrix(0)(i))
      matrix(i)(0) = combiner(matrix(i - 1)(0), matrix(i - 1)(0), matrix(i)(0))
    })

    (1 until len).foreach(i => {
      (1 until len).foreach(j => {
        matrix(i)(j) =
          combiner(matrix(i - 1)(j), matrix(i)(j - 1), matrix(i)(j))
      })
    })

    matrix
  }

  def highestFactor(f: Int, n: Int) = {
    var m = n
    var c = 0
    while (m % f == 0) {
      c = c + 1
      m = m / f
    }
    (c, m)
  }

  @tailrec
  def getPath[U](
      solnMatrix: Array[Array[U]],
      start: (Int, Int),
      path: List[String] = List(),
      end: (Int, Int) = (0, 0)
  )(implicit ord: Ordering[U]): String = {
    if (start == end) {
      path.mkString("")
    } else {
      start match {
        case (0, s) =>
          getPath(solnMatrix, (start._1, start._2 - 1), "R" +: path)
        case (s, 0) =>
          getPath(solnMatrix, (start._1 - 1, start._2), "D" +: path)
        case (u, v) => {
          if (ord.lt(solnMatrix(u - 1)(v), solnMatrix(u)(v - 1)))
            getPath(solnMatrix, (start._1 - 1, start._2), "D" +: path)
          else getPath(solnMatrix, (start._1, start._2 - 1), "R" +: path)
        }
      }
    }
  }

  val lineCount = scala.io.StdIn.readInt()

  val inpMatrix = Array.ofDim[(Int, Int)](lineCount, lineCount)

  var hasZero = Option.empty[(Int, Int)]

  (0 until lineCount).foreach(r => {
    var i = 0
    val line = scala.io.StdIn
      .readLine()
      .split(" ")
      .foreach(w => {
        val cell = w.toInt
        if (cell == 0) {
          hasZero = Some((r, i))
          inpMatrix(r)(i) = (1, 1)
        } else {
          val (p10, t) = highestFactor(10, cell)

          val (p2, k) = highestFactor(2, t)
          val p5 = highestFactor(5, k)._1
          inpMatrix(r)(i) = (p2 + p10, p5 + p10)

        }
        i = i + 1
      })
  })
//   println(inpMatrix.map(_.mkString("\t")).mkString("\n"))
//   println()

  val smaller = (x: Int, y: Int) => if (x < y) x else y

  val solutionMatrix = dynamicSolveMatrixRightDownInPlace(
    inpMatrix,
    inpMatrix(0)(0)
  )((left, up, y) => {
    val fstCont = smaller(left._1, up._1)
    val sndCont = smaller(left._2, up._2)
    (
      fstCont + y._1,
      sndCont + y._2
    )

  })

  val ending = solutionMatrix(lineCount - 1)(lineCount - 1)
  val smallest = smaller(ending._1, ending._2)

  val bestPath = if (ending._1 < ending._2) {
    getPath(solutionMatrix, (lineCount - 1, lineCount - 1))(
      new Ordering[(Int, Int)] {
        def compare(x: (Int, Int), y: (Int, Int)): Int = x._1.compare(y._1)
      }
    )
  } else {
    getPath(solutionMatrix, (lineCount - 1, lineCount - 1))(
      new Ordering[(Int, Int)] {
        def compare(x: (Int, Int), y: (Int, Int)): Int = x._2.compare(y._2)
      }
    )
  }

  val (p, s) = hasZero match {
    case None => (bestPath, smallest)
    case Some(value) =>
      if (smallest == 0) {
        (bestPath, smallest)
      } else {
        val x = value._1

        val s = (0 until x).map(_ => "D").mkString("")
        val d = (0 until lineCount - 1).map(_ => "R").mkString("")
        val r = (0 until lineCount - x - 1).map(_ => "D").mkString("")

        (s + d + r, 1)
      }
  }

//   println(solutionMatrix.map(_.mkString("\t")).mkString("\n"))

  println(s)
  println(p)
}

import scala.annotation.tailrec
import scala.io.StdIn

object Main extends App {
  val n = StdIn.readInt()
  val m = Array.ofDim[Int](n, n)
  (0 until n).foreach { i =>
    m(i) = StdIn.readLine().split(" ").map(_.toInt)
  }

  val t2 = Array.ofDim[Short](n, n)
  val t5 = Array.ofDim[Short](n, n)
  val d2 = Array.ofDim[Char](n, n)
  val d5 = Array.ofDim[Char](n, n)

  val corner = m(0)(0)
  t2(0)(0) = factorN(corner, 2, 0)
  t5(0)(0) = factorN(corner, 5, 0)
  d2(0)(0) = ' '
  d5(0)(0) = ' '

  (1 until n).foreach { i =>
    t2(i)(0) = (factorN(m(i)(0), 2, 0) + t2(i - 1)(0)).toShort
    t5(i)(0) = (factorN(m(i)(0), 5, 0) + t5(i - 1)(0)).toShort
    d2(i)(0) = 'D'
    d5(i)(0) = 'D'

    t2(0)(i) = (factorN(m(0)(i), 2, 0) + t2(0)(i - 1)).toShort
    t5(0)(i) = (factorN(m(0)(i), 5, 0) + t5(0)(i - 1)).toShort
    d2(0)(i) = 'R'
    d5(0)(i) = 'R'
  }

  @tailrec
  def factorN(x: Int, N: Int, m: Short): Short = {
    if (x == 0) m
    else {
      if (x % N == 0) factorN(x / N, N, (1 + m).toShort)
      else m
    }
  }

  (1 until n).foreach { x =>
    (1 until n).foreach { y =>
      val f2 = factorN(m(y)(x), 2, 0)
      val f5 = factorN(m(y)(x), 5, 0)

      if (t2(y - 1)(x) < t2(y)(x - 1)) {
        t2(y)(x) = (t2(y - 1)(x) + f2).toShort
        d2(y)(x) = 'D'
      } else {
        t2(y)(x) = (t2(y)(x - 1) + f2).toShort
        d2(y)(x) = 'R'
      }

      if (t5(y - 1)(x) < t5(y)(x - 1)) {
        t5(y)(x) = (t5(y - 1)(x) + f5).toShort
        d5(y)(x) = 'D'
      } else {
        t5(y)(x) = (t5(y)(x - 1) + f5).toShort
        d5(y)(x) = 'R'
      }
    }
  }

  var zx = -1
  var zy = -1
  (0 until n).foreach { x =>
    (0 until n).foreach { y =>
      if (m(y)(x) == 0) {
        zx = x
        zy = y
      }
    }
  }

  val dir = new Array[Char](2 * n - 2)

  @tailrec
  def buildDir(arr: Array[Array[Char]], x: Int, y: Int, n: Int): Unit = {
    val d = arr(y)(x)
    if (d == 'D') {
      dir(n) = 'D'
      buildDir(arr, x, y - 1, n - 1)
    } else if (d == 'R') {
      dir(n) = 'R'
      buildDir(arr, x - 1, y, n - 1)
    }
  }

  val (min, dirArr) = if (t2(n - 1)(n - 1) > t5(n - 1)(n - 1)) {
    (t5(n - 1)(n - 1), d5)
  } else (t2(n - 1)(n - 1), d2)

  if (min != 0 && zx != -1) {
    println(1)
    val dir = new Array[Char](2 * n - 2)
    (0 until zx).foreach(i => dir(i) = 'R')
    (0 until (n - 1)).foreach(i => dir(zx + i) = 'D')
    (0 until (n - 1 - zx)).foreach(i => dir(zx + n - 1 + i) = 'D')
    println(new String(dir))
  } else {
    println(min)
    buildDir(dirArr, n - 1, n - 1, 2 * n - 3)
    println(new String(dir))
  }
}

object P2B {
    import io.StdIn._

    def main(args:Array[String]) {
        val n = readInt
        val a = Array.fill(n){readLine.split(' ').map{_.toInt}}
        val answers = for (d <- Array(2, 5)) yield {
            def factors(x:Int, s:Int = 0):Int = x match {
                case 0 => 1
                case _ if x % d != 0 => s
                case _ => factors(x / d, s + 1)
            }
            val s = Array.ofDim[Int](n, n)
            s(0)(0) = factors(a(0)(0))
            for (i <- 1 until n) s(0)(i) = s(0)(i - 1) + factors(a(0)(i))
            for (i <- 1 until n) s(i)(0) = s(i - 1)(0) + factors(a(i)(0))
            for (i <- 1 until n; j <- 1 until n) {
                s(i)(j) = s(i - 1)(j).min(s(i)(j - 1)) + factors(a(i)(j))
            }
            def route(x:Int, y:Int, b:StringBuilder):StringBuilder = {
                def goD = route(x - 1, y, b.+=('D'))
                def goR = route(x, y - 1, b.+=('R'))
                if (x == 0 && y == 0) return b
                if (y == 0) return goD
                if (x == 0) return goR
                if (s(x - 1)(y) < s(x)(y - 1)) goD else goR
            }
            (s(n - 1)(n - 1), route(n - 1, n - 1, new StringBuilder).reverse)
        }
        val a0 = a.map{_.indexOf(0)}.zipWithIndex.find{_._1 != -1}
        val answer = (answers ++ a0.map{case (y, x) =>
            (1, "D" * x + "R" * y + "D" * (n - 1 - x) + "R" * (n - 1 - y))
        }).minBy{_._1}
        println(answer._1)
        println(answer._2)
    }
}

object P2B {
    def main(args : Array[String]) {
        val n = readLine.toInt
        val a = Array.fill(n){
            readLine split " " map {_.toInt}
        }
        val answers = for (d <- Array(2, 5)) yield {
            def factors(x : Int, s : Int = 0) : Int = x match {
                case 0 => 1
                case _ if x % d != 0 => s
                case _ => factors(x / d, s + 1)
            }
            val s = Array.ofDim[Int](n, n)
            s(0)(0) = factors(a(0)(0))
            for (i <- 1 until n) s(0)(i) = s(0)(i - 1) + factors(a(0)(i))
            for (i <- 1 until n) s(i)(0) = s(i - 1)(0) + factors(a(i)(0))
            for {
                i <- 1 until n
                j <- 1 until n
            } s(i)(j) = (s(i - 1)(j) min s(i)(j - 1)) + factors(a(i)(j))
            val route = new Iterator[Char]{
                var (x, y) = (n - 1, n - 1)
                def hasNext = (x, y) != (0, 0)
                def next = {
                    val ret = () match {
                        case _ if y == 0 => 'D'
                        case _ if x == 0 => 'R'
                        case _ if s(x - 1)(y) < s(x)(y - 1) => 'D'
                        case _ => 'R'
                    }
                    ret match {
                        case 'D' => x = x - 1
                        case 'R' => y = y - 1
                    }
                    ret
                }
            }.mkString.reverse
            (s(n - 1)(n - 1), route)
        }
        val a0 = a.map{_ indexOf 0}.zipWithIndex find {_._1 != -1} map {
            case (y, x) =>
                (1, "D" * x + "R" * y + "D" * (n - 1 - x) + "R" * (n - 1 - y))
        }
        val answer = (answers ++ a0).minBy{_._1}
        println(answer._1)
        println(answer._2)
    }
}

import java.util._
import java.io._
import scala.annotation.tailrec

object P2B extends App {
  object ReaderWriter {
    val reader = new BufferedReader(new InputStreamReader(System.in))
    val writer = new PrintWriter(System.out)
    var tok: StringTokenizer = null

    @tailrec
    def readToken(): String = {
      if (tok != null && tok.hasMoreTokens()) {
        tok.nextToken()
      } else {
        val line = reader.readLine()
        tok = null
        if (line == null) {
          null
        } else {
          tok = new StringTokenizer(line)
          readToken()
        }
      }
    }
  }

  import ReaderWriter._

  def readInt(): Int = readToken().toInt

  def log(value: Int, base: Int): Int = {
    @tailrec
    def rec(value: Int, acc: Int): Int = {
      if (value == 0) {
        1
      } else if (value % base == 0) {
        rec(value / base, acc + 1)
      } else {
        acc
      }
    }
    rec(value, 0)
  }

  val n = readInt()
  var cur = 0
  var next = 1 - cur
  val m = Array.ofDim[Int](n, n)
  for {
    row <- 0 until n
    column <- 0 until n
  } {
    m(row)(column) = readInt()
  }

  object Direction {
    sealed trait Type
    case object No extends Type
    case object Up extends Type
    case object Left extends Type
  }

  def minSumAndPath(functor: Int => Int): (Int, Seq[Char]) = {
    val d = Array.ofDim[Int](n, n)
    val prev = Array.fill[Direction.Type](n, n)(Direction.No)
    for {
      row <- 0 until n
      column <- 0 until n
    } {
      val value = functor(m(row)(column))
      val dUpOpt: Option[Int] = if (row > 0) Some(d(row - 1)(column)) else None
      val dLeftOpt: Option[Int] = if (column > 0) Some(d(row)(column - 1)) else None
      val dUp = dUpOpt.getOrElse(Integer.MAX_VALUE)
      val dLeft = dLeftOpt.getOrElse(Integer.MAX_VALUE)
      if (!dUpOpt.isDefined && !dLeftOpt.isDefined) {
        d(row)(column) = value
        prev(row)(column) = Direction.No
      } else {
        if (dUp < dLeft) {
          d(row)(column) = dUp + value
          prev(row)(column) = Direction.Up
        } else {
          d(row)(column) = dLeft + value
          prev(row)(column) = Direction.Left
        }
      }
    }

    var row = n - 1
    var column = n - 1
    var path = Seq.empty[Char]
    while (!(row == 0 && column == 0)) {
      prev(row)(column) match {
        case Direction.Up =>
          path :+= 'D'
          row -= 1
        case Direction.Left =>
          path :+= 'R'
          column -= 1
        case _ =>
          row = 0
          column = 0
      }
    }

    (d(n - 1)(n - 1), path.reverse)
  }

  val (zeroSum, zeroPath) = minSumAndPath({ value => if (value == 0) 1 else 0 })
  val (twoSum, twoPath) = minSumAndPath({ value => log(value, 2) })
  val (fiveSum, fivePath) = minSumAndPath({ value => log(value, 5) })

  if (zeroSum > 0) {
    writer.println("1")
    writer.println(zeroPath.mkString(""))
  } else {
    val bestSum = if (twoSum < fiveSum) twoSum else fiveSum
    val bestPath = if (twoSum < fiveSum) twoPath else fivePath
    writer.println(bestSum)
    writer.println(bestPath.mkString(""))
  }

  writer.flush()
}

import io.Source
import annotation.tailrec
// Minimize # of zeroes on product of numbers on path
// relevant stuff - does the cell contain a 0? question states non-negative
// what seems to be tricky here is that the best way to get to a cell is not necessarily a subpath
// of the best way to get to a neighbour
// so, what's the best way to get to the last cell?
//
// suppose the last cell has (numTwos, 0) as its factorization
// the best path P to this cell is the one that minimizes
// tens(P) + min(uncoupled-fives(P), numTwos)
// if the last cell doesn't look like that, since we're going to pick up the
// additional 10s no matter what, just take abs(numTwos - numFives)

// now THAT is an expression I can put in my pipe and compute!

// there is also this issue with zeros... if a zero appears in the matrix, then any path that goes through that is just as good
// the only reason to avoid the 0 is if you can get no tens. does the answer need to be unique?

object LeastRound {

    def main(args: Array[String]) = {
        val lines = Source.stdin.getLines()
        val size = lines.next().toInt

        val rawNumMatrix = readMatrix(lines, size)

        val pathMatrix = calculatePathCost(rawNumMatrix)
        // cost of path found:
        println(pathMatrix(size - 1)(size - 1).cost)
        println(getBestPath(pathMatrix))
    }

    def getBestPath(pathMatrix: Array[Array[Path]]) = {
        // use a stringbuilder
        val backwardsPath = new StringBuilder()

        var row = pathMatrix.length - 1
        var col = pathMatrix.length - 1
        while (!(row == 0 && col == 0)) {
            //println("row is: " + row + ", col: " + col)
            pathMatrix(row)(col).step match {
                case Direction.Down => {backwardsPath += 'D'; row -= 1}
                case Direction.Right => {backwardsPath += 'R'; col -= 1}
                case Direction.Blank => { row = 0; col = 0}
            }
        }

        backwardsPath.reverseContents()
    }

    def readMatrix(lines: Iterator[String], matrixSize: Int) = {
        val matrix = new Array[Array[Int]](matrixSize)

        for (row <- 0 until matrixSize) {
            matrix(row) = lines.next().split(" ").map(_.toInt)
        }
        matrix
    }

    def calculatePathCost(numMatrix: Array[Array[Int]]) = {

        val size = numMatrix.length
        val pathMatrix = new Array[Array[Path]](size)
        val finalFact = TFFactorization(numMatrix(size - 1)(size - 1))

        pathMatrix(0) = new Array[Path](size)
        pathMatrix(0)(0) = Path.singleStep(numMatrix(0)(0))

        for (row <- 0 until size) {
            if (row != 0)
                pathMatrix(row) = new Array[Path](size)

            for (column <- 0 until size) {
                val currFact = TFFactorization(numMatrix(row)(column))

                if (row == 0 && column != 0)
                    pathMatrix(row)(column) = pathMatrix(row)(column - 1).augmentPath(currFact, Direction.Right)
                else if (row != 0 && column == 0)
                    pathMatrix(row)(column) = pathMatrix(row - 1)(column).augmentPath(currFact, Direction.Down)
                else if (row != 0 && column != 0)
                    pathMatrix(row)(column) = Path.getBestPath(pathMatrix(row)(column -1), pathMatrix(row - 1)(column), finalFact, currFact)
            }
        }
        //println(pathMatrix(size - 1)(size - 1).cost)
        //pathMatrix.foreach( row => {row.foreach(path => {print(path.toString); print(" ")}); println()})
        pathMatrix
    }
}

object Direction extends Enumeration {
    type Direction = Value
    val Down, Right, Blank = Value
}

sealed abstract class TFFactorization {
    def *(other: TFFactorization): TFFactorization
    def tailZeros(): Int
}

case class ProperFact(numTwos: Int, numFives: Int) extends TFFactorization {

    def *(other: TFFactorization) =
        other match {
            case ProperFact(otherTwos, otherFives) => ProperFact(numTwos + otherTwos, numFives + otherFives)
            case ZeroFact()                          => other
        }

    def tailZeros() = numTwos min numFives

    override def toString() = "(" + numTwos + ", " + numFives + ")"
}

case class ZeroFact() extends TFFactorization {
    def tailZeros() = 1
    def *(other: TFFactorization) = this

    override def toString() = "zero"
}

object TFFactorization {
    def extractExponent(divisor: Int) (toFactor: Int) = {
        @tailrec
        def runningExponentCount(currExp: Int, currN: Int): Int =
            if (currN % divisor == 0) runningExponentCount(currExp + 1, currN / divisor) else currExp
        runningExponentCount(0, toFactor)
    }
    def extractTwos = extractExponent(2) _
    def extractFives = extractExponent(5) _

    def apply(num: Int): TFFactorization =
        if (num == 0)
            ZeroFact()
        else
            new ProperFact(extractTwos(num), extractFives(num))
}

class Path(fact25: TFFactorization, lastStep: Direction.Direction) {

    def evaluate(finalCellFact: TFFactorization) =
        finalCellFact match {
            case ZeroFact() => 1
            case ProperFact(_, _) => (fact25 * finalCellFact).tailZeros
        }

    def augmentPath(currCellFact: TFFactorization, nextStep: Direction.Direction) = {
        new Path(currCellFact * fact25, nextStep)
    }

    def isBetter(other: Path, finalCellFact: TFFactorization) =
        (evaluate(finalCellFact) <= other.evaluate(finalCellFact))

    def cost() = fact25.tailZeros

    override def toString() = fact25.toString + " " + lastStep

    def step() = lastStep
}

object Path {
    def singleStep(num: Int) = new Path(TFFactorization(num), Direction.Blank)

    def getBestPath(leftNeighbour: Path, topNeighbour: Path, finalFact: TFFactorization, currFact: TFFactorization): Path =
        if (leftNeighbour.isBetter(topNeighbour, finalFact))
            leftNeighbour.augmentPath(currFact, Direction.Right)
        else
            topNeighbour.augmentPath(currFact, Direction.Down)
}

object solution {
  def solve(n: Int, cost: Array[Array[Int]]): (Int, String) = {
    val INF = 10000
    val rv = Array.fill[Int](n, n)(0)
    val rp = Array.fill[Char](n, n)(' ')
    rv(0)(0) = cost(0)(0)
    for (y <- 0 until n; x <- 0 until n if x + y > 0) {
      var res = INF
      var resp = ' '
      if (y > 0) {
        res = rv(y - 1)(x)
        resp = 'D'
      }
      if (x > 0 && res > rv(y)(x-1)) {
        res = rv(y)(x - 1)
        resp = 'L'
      }
      rv(y)(x) = res + cost(y)(x)
      rp(y)(x) = resp
    }
    var (y, x) = (n-1, n-1)
    var path = ""
    while (y + x > 0) {
      if (rp(y)(x) == 'L') {
        path = "L" + path
        x -= 1
      } else {
        path = "D" + path
        y -= 1
      }
    }
    (rv(n-1)(n-1), path)
  }

  def main(args: Array[String]) = {
    val n = io.StdIn.readInt()
    val twos = Array.fill[Int](n, n)(0)
    val fives = Array.fill[Int](n, n)(0)

    def power_of(x: Int, p: Int): Int = {
      var result = 0
      var left = x
      while (left % p == 0) {
        result += 1
        left /= p
      }
      result
    }

    for (y <- 0 until n) {
      val line = io.StdIn.readLine().split(" ").map(_.toInt)
      for (x <- 0 until n) {
        twos(y)(x) = power_of(line(x), 2)
        fives(y)(x) = power_of(line(x), 5)
      }
    }

    val s2 = solve(n, twos)
    val s5 = solve(n, fives)
    if (s2._1 <= s5._1)
      printf("%d\n%s\n", s2._1, s2._2)
    else
      printf("%d\n%s\n", s5._1, s5._2)
  }
}

object solution {
  def solve(n: Int, cost: Array[Array[Int]]): (Int, String) = {
    val INF = 100000
    val rv = Array.fill[Int](n, n)(0)
    val rp = Array.fill[Char](n, n)(' ')
    rv(0)(0) = cost(0)(0)
    for (y <- 0 until n; x <- 0 until n if x + y > 0) {
      var res = INF
      var resp = ' '
      if (y > 0) {
        res = rv(y - 1)(x)
        resp = 'D'
      }
      if (x > 0 && res > rv(y)(x-1)) {
        res = rv(y)(x - 1)
        resp = 'R'
      }
      rv(y)(x) = res + cost(y)(x)
      rp(y)(x) = resp
    }
    var (y, x) = (n-1, n-1)
    var path = new StringBuilder()
    while (y + x > 0) {
      if (rp(y)(x) == 'R') {
        path += 'R'
        x -= 1
      } else {
        path += 'D'
        y -= 1
      }
    }
    (rv(n-1)(n-1), path.reverse.toString())
  }

  def main(args: Array[String]) = {
    val n = io.StdIn.readInt()
    val twos = Array.fill[Int](n, n)(0)
    val fives = Array.fill[Int](n, n)(0)

    def power_of(x: Int, p: Int): Int = {
      var result = 0
      var left = x
      while (left % p == 0) {
        result += 1
        left /= p
      }
      result
    }
    var zero_point: Option[(Int, Int)] = None
    for (y <- 0 until n) {
      val line = io.StdIn.readLine().split(" ").map(_.toInt)
      for (x <- 0 until n) {
        if (line(x) > 0) {
          twos(y)(x) = power_of(line(x), 2)
          fives(y)(x) = power_of(line(x), 5)
        } else {
          zero_point = Some((x, y))
        }
      }
    }
    if (zero_point.isDefined) {
      val (x, y) = zero_point.get
      printf("0\n")
      println(("R" * x) + ("D" * y) + ("R" * (n-x - 1)) + ("D" * (n-y - 1)))

    } else {
      val s2 = solve(n, twos)
      val s5 = solve(n, fives)
      if (s2._1 <= s5._1)
        printf("%d\n%s\n", s2._1, s2._2)
      else
        printf("%d\n%s\n", s5._1, s5._2)
    }
  }

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val n = in.next().toInt

  def toPair(a: Int): (Long, Long) = {
    var fives = 0
    var twos = 0
    var c = a
    while (c % 2 == 0 || c % 5 == 0) {
      if (c % 2 == 0) {
        c /= 2
        twos += 1
      }
      else {
        c /= 5
        fives += 1
      }
    }
    (twos, fives)
  }

  def join(a: List[(Long, Long)], b: List[(Long, Long)]): List[(Long, Long)] = {
    val candidates = (a ::: b).sorted
    candidates.foldLeft(List.empty[(Long, Long)]) {
      case(Nil, el) => List(el)
      case(list@((a2, a5) :: xs), (b2, b5)) if b2 >= a2 && b5 >= a5 => list
      case(list, el) => el :: list
    }
  }

  val pairs = in.take(n).map(_.split(' ').map(_.toInt).map(toPair)).toArray
  val dp = Array.ofDim[List[(Long, Long)]](n, n)
  (0 until n).foreach { i =>
    (0 until n).foreach { j =>
      val pair = pairs(i)(j)
      if (i == 0 && j == 0)
        dp(i)(j) = List(pair)
      else if (i == 0)
        dp(i)(j) = dp(i)(j - 1).map(x => (x._1 + pair._1, x._2 + pair._2))
      else if (j == 0)
        dp(i)(j) = dp(i - 1)(j).map(x => (x._1 + pair._1, x._2 + pair._2))
      else
        dp(i)(j) = join(dp(i)(j - 1).map(x => (x._1 + pair._1, x._2 + pair._2)),
                        dp(i - 1)(j).map(x => (x._1 + pair._1, x._2 + pair._2)))
    }
  }
  var x = n - 1
  var y = n - 1
  var answer = List.empty[Char]

  while (x != 0 || y != 0) {
    val pair = pairs(y)(x)
    val last = dp(y)(x).minBy(i => Math.min(i._1, i._2))
    val previous = (last._1 - pair._1, last._2 - pair._2)
    val upCandidate = y != 0 && dp(y - 1)(x).contains(previous)
    if (upCandidate) {
      answer ::= 'D'
      y -= 1
    } else {
      answer ::= 'R'
      x -= 1
    }
  }

  println(dp(n - 1)(n - 1).map(i => Math.min(i._1, i._2)).min)
  println(answer.mkString)

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val n = in.next().toInt

  def toPair(a: Int): (Int, Int) = {
    var fives = 0
    var twos = 0
    var c = a
    while (c % 2 == 0 || c % 5 == 0) {
      if (c % 2 == 0) {
        c /= 2
        twos += 1
      }
      else {
        c /= 5
        fives += 1
      }
    }
    (twos, fives)
  }

  def join(a: List[(Int, Int)], b: List[(Int, Int)]): List[(Int, Int)] = {
    val candidates = (a ::: b).sorted
    candidates.foldLeft(List.empty[(Int, Int)]) {
      case(Nil, el) => List(el)
      case(list@((a2, a5) :: xs), (b2, b5)) if b2 >= a2 && b5 >= a5 => list
      case(list, el) => el :: list
    }
  }

  val line = in.take(n).map(_.split(' ').map{i =>
    val t = i.toInt
    if (t == 0) 10 else t
  }).toArray
  val pairs = line.map(_.map(toPair))
  val dp2 = Array.ofDim[Int](n, n)
  val dp5 = Array.ofDim[Int](n, n)
  (0 until n).foreach { i =>
    (0 until n).foreach { j =>
      val pair = pairs(i)(j)
      if (i == 0 && j == 0) {
        dp2(i)(j) = pair._1
        dp5(i)(j) = pair._2
      }
      else if (i == 0) {
        dp2(i)(j) = dp2(i)(j - 1) + pairs(i)(j)._1
        dp5(i)(j) = dp5(i)(j - 1) + pairs(i)(j)._2
      }
      else if (j == 0) {
        dp2(i)(j) = dp2(i - 1)(j) + pairs(i)(j)._1
        dp5(i)(j) = dp5(i - 1)(j) + pairs(i)(j)._2
      }
      else {
        dp2(i)(j) = Math.min(dp2(i - 1)(j), dp2(i)(j - 1)) + pairs(i)(j)._1
        dp5(i)(j) =  Math.min(dp5(i - 1)(j), dp5(i)(j - 1)) + pairs(i)(j)._2
      }
    }
  }
  var x = n - 1
  var y = n - 1
  var answer = List.empty[Char]

  while (x != 0 || y != 0) {
    val pair = pairs(y)(x)
    val upCandidate = y != 0 && (x == 0 || Math.min(dp2(y - 1)(x), dp5(y - 1)(x)) <= Math.min(dp2(y)(x - 1), dp5(y)(x - 1)))
    if (upCandidate) {
      answer ::= 'D'
      y -= 1
    } else {
      answer ::= 'R'
      x -= 1
    }
  }

  println(Math.min(dp2(n - 1)(n - 1), dp5(n - 1)(n - 1)))
  println(answer.mkString)

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val n = in.next().toInt

  def toPair(a: Int): (Int, Int) = {
    var fives = 0
    var twos = 0
    var c = a
    while (c % 2 == 0 || c % 5 == 0) {
      if (c % 2 == 0) {
        c /= 2
        twos += 1
      }
      else {
        c /= 5
        fives += 1
      }
    }
    (twos, fives)
  }

  def join(a: List[(Int, Int)], b: List[(Int, Int)]): List[(Int, Int)] = {
    a ::: b
  }

  val pairs = in.take(n).map(_.split(' ').map(_.toInt).map(toPair)).toArray
  val dp = Array.ofDim[List[(Int, Int)]](n, n)
  (0 until n).foreach { i =>
    (0 until n).foreach { j =>
      val pair = pairs(i)(j)
      if (i == 0 && j == 0)
        dp(i)(j) = List(pair)
      else if (i == 0)
        dp(i)(j) = dp(i)(j - 1).map(x => (x._1 + pair._1, x._2 + pair._2))
      else if (j == 0)
        dp(i)(j) = dp(i - 1)(j).map(x => (x._1 + pair._1, x._2 + pair._2))
      else
        dp(i)(j) = join(dp(i)(j - 1).map(x => (x._1 + pair._1, x._2 + pair._2)),
          dp(i - 1)(j).map(x => (x._1 + pair._1, x._2 + pair._2)))
    }
  }
  var x = n - 1
  var y = n - 1
  var answer = List.empty[Char]

  while (x != 0 || y != 0) {
    val pair = pairs(y)(x)
    val last = dp(y)(x).minBy(i => Math.min(i._1, i._2))
    val previous = (last._1 - pair._1, last._2 - pair._2)
    val upCandidate = y != 0 && dp(y - 1)(x).contains(previous)
    if (upCandidate) {
      answer ::= 'D'
      y -= 1
    } else {
      answer ::= 'R'
      x -= 1
    }
  }

  println(dp(n - 1)(n - 1).map(i => Math.min(i._1, i._2)).min)
  println(answer.mkString)

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val n = in.next().toInt

  val line = in.take(n).map(_.split(' ').map(_.toInt)).toArray

  def f(a: Int, k: Int) = {
    var r = 0
    var m = a

    while (m != 0 && m % k == 0) {
      m /= k
      r += 1
    }
    r
  }

  def dp(k: Int) = {
    val dp = line.map(_.map(i => f(i, k)))

    (1 until n).foreach { i =>
      dp(i)(0) += dp(i - 1)(0)
      dp(0)(i) += dp(0)(i - 1)
    }

    (1 until n).foreach { i =>
      (1 until n).foreach { j =>
        dp(i)(j) += Math.min(dp(i - 1)(j), dp(i)(j - 1))
      }
    }

    dp
  }

  val dpr = List(2, 5).map(dp).minBy(d => d(n - 1)(n - 1))

  var min = dpr(n - 1)(n - 1)
  var x = n - 1
  var y = n - 1
  var answer = List.empty[Char]

  while (x != 0 || y != 0) {
    val upCandidate = y != 0 && (x == 0 || dpr(y - 1)(x) <= dpr(y)(x - 1))
    if (upCandidate) {
      answer ::= 'D'
      y -= 1
    } else {
      answer ::= 'R'
      x -= 1
    }
  }

  println(min)
  println(answer.mkString)

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val n = in.next().toInt

  def toPair(a: Int): (Int, Int) = {
    var fives = 0
    var twos = 0
    var c = a
    while (c % 2 == 0 || c % 5 == 0) {
      if (c % 2 == 0) {
        c /= 2
        twos += 1
      }
      else {
        c /= 5
        fives += 1
      }
    }
    (twos, fives)
  }

  def join(a: List[(Int, Int)], b: List[(Int, Int)]): List[(Int, Int)] = {
    val candidates = (a ::: b).sorted
    candidates.foldLeft(List.empty[(Int, Int)]) {
      case(Nil, el) => List(el)
      case(list@((a2, a5) :: xs), (b2, b5)) if b2 >= a2 && b5 >= a5 => list
      case(list, el) => el :: list
    }
  }

  val pairs = in.take(n).map(_.split(' ').map(_.toInt).map(toPair)).toArray
  val dp = Array.ofDim[List[(Int, Int)]](n, n)
  (0 until n).foreach { i =>
    (0 until n).foreach { j =>
      val pair = pairs(i)(j)
      if (i == 0 && j == 0)
        dp(i)(j) = List(pair)
      else if (i == 0)
        dp(i)(j) = dp(i)(j - 1).map(x => (x._1 + pair._1, x._2 + pair._2))
      else if (j == 0)
        dp(i)(j) = dp(i - 1)(j).map(x => (x._1 + pair._1, x._2 + pair._2))
      else
        dp(i)(j) = join(dp(i)(j - 1).map(x => (x._1 + pair._1, x._2 + pair._2)),
                        dp(i - 1)(j).map(x => (x._1 + pair._1, x._2 + pair._2)))
    }
  }
  var x = n - 1
  var y = n - 1
  var answer = List.empty[Char]

  while (x != 0 || y != 0) {
    val pair = pairs(y)(x)
    val last = dp(y)(x).minBy(i => Math.min(i._1, i._2))
    val previous = (last._1 - pair._1, last._2 - pair._2)
    val upCandidate = y != 0 && dp(y - 1)(x).contains(previous)
    if (upCandidate) {
      answer ::= 'D'
      y -= 1
    } else {
      answer ::= 'R'
      x -= 1
    }
  }

  println(dp(n - 1)(n - 1).map(i => Math.min(i._1, i._2)).min)
  println(answer.mkString)

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val n = in.next().toInt

  def toPair(a: Int): (Int, Int) = {
    var fives = 0
    var twos = 0
    var c = a
    while (c % 2 == 0 || c % 5 == 0) {
      if (c % 2 == 0) {
        c /= 2
        twos += 1
      }
      else {
        c /= 5
        fives += 1
      }
    }
    (twos, fives)
  }

  def join(a: List[(Int, Int)], b: List[(Int, Int)]): List[(Int, Int)] = {
    val candidates = (a ::: b).sorted
    candidates.foldLeft(List.empty[(Int, Int)]) {
      case(Nil, el) => List(el)
      case(list@((a2, a5) :: xs), (b2, b5)) if b2 >= a2 && b5 >= a5 => list
      case(list, el) => el :: list
    }
  }

  val pairs = in.take(n).map(_.split(' ').map(_.toInt).map(toPair)).toArray
  val dp = Array.ofDim[List[(Int, Int)]](n, n)
  (0 until n).foreach { i =>
    (0 until n).foreach { j =>
      val pair = pairs(i)(j)
      if (i == 0 && j == 0)
        dp(i)(j) = List(pair)
      else if (i == 0)
        dp(i)(j) = dp(i)(j - 1).map(x => (x._1 + pair._1, x._2 + pair._2))
      else if (j == 0)
        dp(i)(j) = dp(i - 1)(j).map(x => (x._1 + pair._1, x._2 + pair._2))
      else
        dp(i)(j) = join(dp(i)(j - 1).map(x => (x._1 + pair._1, x._2 + pair._2)),
                        dp(i - 1)(j).map(x => (x._1 + pair._1, x._2 + pair._2)))
    }
  }
  var x = n - 1
  var y = n - 1
  var answer = List.empty[Char]

  while (x != 0 || y != 0) {
    val pair = pairs(y)(x)
    val last = dp(y)(x).minBy(i => Math.min(i._1, i._2))
    val previous = (last._1 - pair._1, last._2 - pair._2)
    val upCandidate = y != 0 && dp(y - 1)(x).contains(previous)
    if (upCandidate) {
      answer ::= 'D'
      y -= 1
    } else {
      answer ::= 'R'
      x -= 1
    }
  }

  println(dp(n - 1)(n - 1).map(i => Math.min(i._1, i._2)).min)
  println(answer.reverse.mkString)

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val n = in.next().toInt

  def toPair(a: Int): (Int, Int) = {
    var fives = 0
    var twos = 0
    var c = a
    while (c % 2 == 0 || c % 5 == 0) {
      if (c % 2 == 0) {
        c /= 2
        twos += 1
      }
      else {
        c /= 5
        fives += 1
      }
    }
    (twos, fives)
  }

  def join(a: List[(Int, Int)], b: List[(Int, Int)]): List[(Int, Int)] = {
    val candidates = (a ::: b).sorted
    candidates.foldLeft(List.empty[(Int, Int)]) {
      case(Nil, el) => List(el)
      case(list@((a2, a5) :: xs), (b2, b5)) if b2 >= a2 && b5 >= a5 => list
      case(list, el) => el :: list
    }
  }

  val pairs = in.take(n).map(_.split(' ').map(_.toInt).map(toPair)).toArray
  val dp = Array.ofDim[List[(Int, Int)]](n, n)
  (0 until n).foreach { i =>
    (0 until n).foreach { j =>
      val pair = pairs(i)(j)
      if (i == 0 && j == 0)
        dp(i)(j) = List(pair)
      else if (i == 0)
        dp(i)(j) = dp(i)(j - 1).map(x => (x._1 + pair._1, x._2 + pair._2))
      else if (j == 0)
        dp(i)(j) = dp(i - 1)(j).map(x => (x._1 + pair._1, x._2 + pair._2))
      else
        dp(i)(j) = join(dp(i)(j - 1).map(x => (x._1 + pair._1, x._2 + pair._2)),
          dp(i - 1)(j).map(x => (x._1 + pair._1, x._2 + pair._2)))
    }
  }
  var x = n - 1
  var y = n - 1
  var answer = List.empty[Char]

  while (x != 0 || y != 0) {
    val pair = pairs(y)(x)
    val last = dp(y)(x).minBy(i => Math.min(i._1, i._2))
    val previous = (last._1 - pair._1, last._2 - pair._2)
    val upCandidate = y != 0 && dp(y - 1)(x).contains(previous)
    if (upCandidate) {
      answer ::= 'R'
      y -= 1
    } else {
      answer ::= 'D'
      x -= 1
    }
  }

  println(dp(n - 1)(n - 1).map(i => Math.min(i._1, i._2)).min)
  println(answer.mkString)

}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val n = in.next().toInt

  def toPair(a: Int): (Int, Int) = {
    var fives = 0
    var twos = 0
    var c = a
    while (c % 2 == 0 || c % 5 == 0) {
      if (c % 2 == 0) {
        c /= 2
        twos += 1
      }
      else {
        c /= 5
        fives += 1
      }
    }
    (twos, fives)
  }

  def join(a: List[(Int, Int)], b: List[(Int, Int)]): List[(Int, Int)] = {
    val candidates = (a ::: b).sorted
    candidates.foldLeft(List.empty[(Int, Int)]) {
      case(Nil, el) => List(el)
      case(list@((a2, a5) :: xs), (b2, b5)) if b2 >= a2 && b5 >= a5 => list
      case(list, el) => el :: list
    }
  }

  val pairs = in.take(n).map(_.split(' ').map(_.toInt).map(toPair)).toArray
  val dp2 = Array.ofDim[Int](n, n)
  val dp5 = Array.ofDim[Int](n, n)
  (0 until n).foreach { i =>
    (0 until n).foreach { j =>
      val pair = pairs(i)(j)
      if (i == 0 && j == 0) {
        dp2(i)(j) = pair._1
        dp5(i)(j) = pair._2
      }
      else if (i == 0) {
        dp2(i)(j) = dp2(i)(j - 1) + pairs(i)(j)._1
        dp5(i)(j) = dp5(i)(j - 1) + pairs(i)(j)._2
      }
      else if (j == 0) {
        dp2(i)(j) = dp2(i - 1)(j) + pairs(i)(j)._1
        dp5(i)(j) = dp5(i - 1)(j) + pairs(i)(j)._2
      }
      else {
        dp2(i)(j) = Math.min(dp2(i - 1)(j), dp2(i)(j - 1)) + pairs(i)(j)._1
        dp5(i)(j) =  Math.min(dp5(i - 1)(j), dp5(i)(j - 1)) + pairs(i)(j)._2
      }
    }
  }
  var x = n - 1
  var y = n - 1
  var answer = List.empty[Char]

  while (x != 0 || y != 0) {
    val pair = pairs(y)(x)
    val upCandidate = y != 0 && (x == 0 || Math.min(dp2(y - 1)(x), dp5(y - 1)(x)) <= Math.min(dp2(y)(x - 1), dp5(y)(x - 1)))
    if (upCandidate) {
      answer ::= 'D'
      y -= 1
    } else {
      answer ::= 'R'
      x -= 1
    }
  }

  println(Math.min(dp2(n - 1)(n - 1), dp5(n - 1)(n - 1)))
  println(answer.mkString)

}

import scala.collection.mutable.HashMap
import scala.math.min

object testing {

    def findPower5(input : Int) : Int = {
        if (input == 0) {
            return 50000
        }
        var temp = input
        var returnValue = 0
        while (temp % 5 == 0) {
            returnValue += 1
            temp /= 5
        }
        return returnValue
    }

    def findPower2(input : Int) : Int = {
        if (input == 0) {
            return 50000
        }
        var temp = input
        var returnValue = 0
        while (temp % 2 == 0) {
            returnValue += 1
            temp /= 2
        }
        return returnValue
    }

    def main(args: Array[String]) : Unit = {
        var matrixSize: Int = scala.io.StdIn.readInt()
        var inputMatrix = Array.ofDim[Int](matrixSize,matrixSize)
        var fiveMatrix = Array.ofDim[Int](matrixSize,matrixSize)
        var twoMatrix = Array.ofDim[Int](matrixSize,matrixSize)
        var existsZero = false
        var zeroX = -1
        var zeroY = -1
        for (i <- 0 until matrixSize) {
            var inputLine = scala.io.StdIn.readLine()
            var inputSplit = inputLine.split(" ")
            for (j <- 0 until matrixSize) {
                inputMatrix(i)(j) = inputSplit(j).toInt
                if (inputMatrix(i)(j) == 0) {
                    existsZero = true
                    zeroY = i
                    zeroX = j
                }
                fiveMatrix(i)(j) = 0
                twoMatrix(i)(j) = 0
            }
        }
        fiveMatrix(0)(0) = findPower5(inputMatrix(0)(0))
        for (i <- 1 until matrixSize) {
            fiveMatrix(0)(i) = fiveMatrix(0)(i-1) + findPower5(inputMatrix(0)(i))
        }
        for (i <- 1 until matrixSize) {
            fiveMatrix(i)(0) = fiveMatrix(i-1)(0) + findPower5(inputMatrix(i)(0))
        }
        for (i <- 1 until matrixSize;
            j <- 1 until matrixSize) {
            fiveMatrix(i)(j) = min(fiveMatrix(i)(j-1) + findPower5(inputMatrix(i)(j)),
                fiveMatrix(i-1)(j) + findPower5(inputMatrix(i)(j)))
        }

        twoMatrix(0)(0) = findPower2(inputMatrix(0)(0))
        for (i <- 1 until matrixSize) {
            twoMatrix(0)(i) = twoMatrix(0)(i-1) + findPower2(inputMatrix(0)(i))
        }
        for (i <- 1 until matrixSize) {
            twoMatrix(i)(0) = twoMatrix(i-1)(0) + findPower2(inputMatrix(i)(0))
        }
        for (i <- 1 until matrixSize;
            j <- 1 until matrixSize) {
            twoMatrix(i)(j) = min(twoMatrix(i)(j-1) + findPower2(inputMatrix(i)(j)),
                twoMatrix(i-1)(j) + findPower2(inputMatrix(i)(j)))
        }

        var output : String = ""
        if (min(twoMatrix(matrixSize - 1)(matrixSize - 1),
            fiveMatrix(matrixSize - 1)(matrixSize - 1)) > 1 && existsZero) {
            // find zero path
            for (i <- 0 until zeroX) {
                output = output + "R"
            }
            for (i <- 0 until matrixSize - 1) {
                output = output + "D"
            }
            for (i <- zeroX until matrixSize - 1) {
                output = output + "R"
            }
            println(1)
            println(output)
            return;
        }

        if (twoMatrix(matrixSize - 1)(matrixSize - 1) < fiveMatrix(matrixSize - 1)(matrixSize - 1)) {
            var currX = matrixSize - 1
            var currY = matrixSize - 1
            while (currX != 0 || currY != 0) {
                if (currX != 0 && twoMatrix(currY)(currX - 1) <= twoMatrix(currY)(currX)) {
                    output = "R" + output
                    currX = currX - 1
                } else {
                    output = "D" + output
                    currY = currY - 1
                }
            }
            println(twoMatrix(matrixSize - 1)(matrixSize - 1))
            println(output)
            return
        } else {
            var currX = matrixSize - 1
            var currY = matrixSize - 1
            while (currX != 0 || currY != 0) {
                if (currX != 0 && fiveMatrix(currY)(currX - 1) <= fiveMatrix(currY)(currX)) {
                    output = "R" + output
                    currX = currX - 1
                } else {
                    output = "D" + output
                    currY = currY - 1
                }
            }
            println(fiveMatrix(matrixSize - 1)(matrixSize - 1))
            println(output)
            return
        }
    }
}

import scala.collection.mutable
import java.util.Scanner
import scala.util.Random

object Path extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  solve(Edge(0, 0, findTwoCount(0, 0), findFiveCount(0, 0), None, direction = false), Set())

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  case class Point(x: Int, y: Int)

  def solve(curEdge: Edge, visited: Set[Point]): Unit = {
    if (curEdge.last) {
      println(curEdge.weight.toInt)
      println(traceBack(Some(curEdge)).reverse.tail.mkString)
    } else {
      curEdge.neighbours.filterNot(it => visited.contains(Point(it.x, it.y))).foreach(queue += _)
      solve(queue.dequeue(), visited + Point(curEdge.x, curEdge.y))
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, twoCount: Int, fiveCount: Int, prev: Option[Edge], direction: Boolean) extends Ordered[Edge] {

    def weight:Double = {
      val common = Math.min(twoCount, fiveCount)
      if (scala.math.abs(twoCount - fiveCount) > 0) common + 0.5 else common
    }

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x, y + 1)
      val downTwos = twoCount + findTwoCount(x, y + 1)
      Edge(x, y + 1, downTwos, downFives, Some(this), true)
    }

    private def createRightEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x + 1, y)
      val downTwos = twoCount + findTwoCount(x + 1, y)
      Edge(x + 1, y, downTwos, downFives, Some(this), false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import scala.collection.mutable
import java.util.Scanner

object Path extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  var zeroPoint: Option[Point] = None

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
          if (matrix(x)(y) == 0) {
            zeroPoint = Some(Point(x, y))
            matrix(x)(y) == 10
          }
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  solve(Edge(0, 0, findTwoCount(0, 0), findFiveCount(0, 0), None, direction = false), Set())

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  case class Point(x: Int, y: Int)

  def printZeroPath(p: Point): Unit = {
    println(1)
    (0 until p.x).foreach(t => print("R"))
    (0 until dim).foreach(t => print("D"))
    (p.x until dim).foreach(t => print("R"))
  }

  def printResult(edge: Edge): Unit = {
    zeroPoint match {
      case None =>
        println(edge.pureWeight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) if edge.pureWeight == 0 =>
        println(edge.pureWeight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) => printZeroPath(v)
    }

  }

  def solve(curEdge: Edge, visited: Set[Point]): Unit = {
    if (curEdge.last) {
      printResult(curEdge)
    } else {
      curEdge.neighbours.filterNot(it => visited.contains(Point(it.x, it.y))).foreach(queue += _)
      solve(queue.dequeue(), visited + Point(curEdge.x, curEdge.y))
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, twoCount: Int, fiveCount: Int, prev: Option[Edge], direction: Boolean) extends Ordered[Edge] {

    def weight = {
      Math.min(twoCount, fiveCount) * 100 + twoCount * 2 + fiveCount
    }

    def pureWeight = {
      Math.min(twoCount, fiveCount)
    }

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x, y + 1)
      val downTwos = twoCount + findTwoCount(x, y + 1)
      Edge(x, y + 1, downTwos, downFives, Some(this), true)
    }

    private def createRightEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x + 1, y)
      val downTwos = twoCount + findTwoCount(x + 1, y)
      Edge(x + 1, y, downTwos, downFives, Some(this), false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import scala.collection.mutable
import java.util.Scanner
import scala.util.Random

object Path extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  var zeroPoint: Option[Point] = None

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
          if (matrix(x)(y) == 0) {
            zeroPoint = Some(Point(x, y))
            matrix(x)(y) == 10
          }
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  solve(Edge(0, 0, findTwoCount(0, 0), findFiveCount(0, 0), None, direction = false), Set())

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  case class Point(x: Int, y: Int)

  def printZeroPath(p: Point): Unit = {
    println(1)
    (0 until p.x).foreach(t => print("R"))
    (0 until dim).foreach(t => print("D"))
    (p.x until dim).foreach(t => print("R"))
  }

  def printResult(edge: Edge): Unit = {
    zeroPoint match {
      case None =>
        println(edge.weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) if edge.weight == 0 =>
        println(edge.weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) => printZeroPath(v)
    }

  }

  def solve(curEdge: Edge, visited: Set[Point]): Unit = {
    if (curEdge.last) {
      printResult(curEdge)
    } else {
      curEdge.neighbours.filterNot(it => visited.contains(Point(it.x, it.y))).foreach(queue += _)
      solve(queue.dequeue(), visited + Point(curEdge.x, curEdge.y))
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, twoCount: Int, fiveCount: Int, prev: Option[Edge], direction: Boolean) extends Ordered[Edge] {

    def weight = {
      Math.min(twoCount, fiveCount) * 100 + twoCount*2 + fiveCount
    }

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x, y + 1)
      val downTwos = twoCount + findTwoCount(x, y + 1)
      Edge(x, y + 1, downTwos, downFives, Some(this), true)
    }

    private def createRightEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x + 1, y)
      val downTwos = twoCount + findTwoCount(x + 1, y)
      Edge(x + 1, y, downTwos, downFives, Some(this), false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import scala.collection.mutable
import java.util.Scanner
import scala.util.Random

object Path extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  var zeroPoint: Option[Point] = None

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
          if (matrix(x)(y) == 0) {
            zeroPoint = Some(Point(x,y))
            matrix(x)(y) == 10
          }
      }
  }

  zeroPoint = Some(Point(3,3))

  val queue = new mutable.PriorityQueue[Edge]()

  solve(Edge(0, 0, findTwoCount(0, 0), findFiveCount(0, 0), None, direction = false), Set())

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  case class Point(x: Int, y: Int)

  def printZeroPath(p: Point): Unit = {
    println(1)
    (0 until p.x).foreach(t => print("R"))
    (0 until dim).foreach(t => print("D"))
    (p.x until dim).foreach(t => print("R"))
  }

  def printResult(edge: Edge): Unit = {
    zeroPoint match {
      case None =>
        println(edge.weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) if edge.weight == 0 =>
        println(edge.weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) => printZeroPath(v)
    }

  }

  def solve(curEdge: Edge, visited: Set[Point]): Unit = {
    if (curEdge.last) {
      printResult(curEdge)
    } else {
      curEdge.neighbours.filterNot(it => visited.contains(Point(it.x, it.y))).foreach(queue += _)
      solve(queue.dequeue(), visited + Point(curEdge.x, curEdge.y))
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, twoCount: Int, fiveCount: Int, prev: Option[Edge], direction: Boolean) extends Ordered[Edge] {

    def weight = {
      Math.min(twoCount, fiveCount)
    }

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x, y + 1)
      val downTwos = twoCount + findTwoCount(x, y + 1)
      Edge(x, y + 1, downTwos, downFives, Some(this), true)
    }

    private def createRightEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x + 1, y)
      val downTwos = twoCount + findTwoCount(x + 1, y)
      Edge(x + 1, y, downTwos, downFives, Some(this), false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import java.util.Scanner
import scala.util.Random

object BLessRoundTripDynamic extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  var zeroPoint: Option[(Int, Int)] = None

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
          if (matrix(x)(y) == 0) {
            zeroPoint = Some((x, y))
            matrix(x)(y) == 10
          }
      }
  }

  def printZeroPath(p: (Int, Int)): Unit = {
    println(1)
    (0 until p._1).foreach(t => print("R"))
    (0 until dim).foreach(t => print("D"))
    (p._1 until dim).foreach(t => print("R"))
  }

  case class Direction(value: Int, dir: Boolean)

  val divs = Array.ofDim[Direction](dim, dim)
  forEach(matrix, (x, y, v: Long) => divs(x)(y) = Direction(findDivNum(v, 5), false))
  val fiveWeight = countWeights(divs)
  val fivePath = getPath(divs)
  forEach(matrix, (x, y, v: Long) => divs(x)(y) = Direction(findDivNum(v, 2), false))
  val twoWeight = countWeights(divs)
  val twoPath = getPath(divs)

  if (math.min(twoWeight, fiveWeight) > 0 && zeroPoint.isDefined) {
    printZeroPath(zeroPoint.get)
  } else if (twoWeight < fiveWeight) {
    println(twoWeight)
    println(twoPath)
  } else {
    println(fiveWeight)
    println(fivePath)
  }

  def getPath(divs: Array[Array[Direction]]): String = {
    def traceBack(x: Int, y: Int): List[Char] = {
      if (x == 0 && y == 0) Nil
      else if (divs(x)(y).dir) 'R' :: traceBack(x - 1, y)
      else 'D' :: traceBack(x, y - 1)
    }
    traceBack(dim - 1, dim - 1).reverse.mkString
  }

  def countWeights(divs: Array[Array[Direction]]): Long = {
    forEach(divs, (x, y, value: Direction) => {
      if (y == 0 && x == 0) {
        divs(x)(y) = Direction(divs(x)(y).value, false)
      } else if (y == 0) {
        divs(x)(y) = Direction(divs(x)(y).value + divs(x - 1)(y).value, true)
      } else if (x == 0) {
        divs(x)(y) = Direction(divs(x)(y).value + divs(x)(y - 1).value, false)
      } else {
        if (divs(x)(y - 1).value < divs(x - 1)(y).value) {
          divs(x)(y) = Direction(divs(x)(y).value + divs(x)(y - 1).value, false)
        } else {
          divs(x)(y) = Direction(divs(x)(y).value + divs(x - 1)(y).value, true)
        }
      }
    })
    divs(dim - 1)(dim - 1).value
  }

  def findDivNum(item: Long, num: Int): Int = {
    var it = item
    while (it % num == 0) {
      it = it / num
    }
    it.toInt
  }

  def forEach[T](arr: Array[Array[T]], func: (Int, Int, T) => Unit): Unit = {
    (0 until dim) foreach {
      y =>
        (0 until dim) foreach {
          x =>
            func(x, y, arr(x)(y))
        }
    }
  }

}

import scala.collection.mutable
import java.util.Scanner

object Path extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  var zeroPoint: Option[Point] = None

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
          if (matrix(x)(y) == 0) {
            zeroPoint = Some(Point(x, y))
            matrix(x)(y) == 10
          }
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  solve(Edge(0, 0, findTwoCount(0, 0), findFiveCount(0, 0), None, direction = false), Set())

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  case class Point(x: Int, y: Int)

  def printZeroPath(p: Point): Unit = {
    println(1)
    (0 until p.x).foreach(t => print("R"))
    (0 until dim).foreach(t => print("D"))
    (p.x until dim).foreach(t => print("R"))
  }

  def printResult(edge: Edge): Unit = {
    zeroPoint match {
      case None =>
        println(edge.weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) if edge.weight == 0 =>
        println(edge.weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) => printZeroPath(v)
    }

  }

  def solve(curEdge: Edge, visited: Set[Point]): Unit = {
    if (curEdge.last) {
      printResult(curEdge)
    } else {
      curEdge.neighbours.filterNot(it => visited.contains(Point(it.x, it.y))).foreach(queue += _)
      solve(queue.dequeue(), visited + Point(curEdge.x, curEdge.y))
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, twoCount: Int, fiveCount: Int, prev: Option[Edge], direction: Boolean) extends Ordered[Edge] {

    def weight = {
      Math.min(twoCount, fiveCount) * 100 + twoCount * 2 + fiveCount
    }

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x, y + 1)
      val downTwos = twoCount + findTwoCount(x, y + 1)
      Edge(x, y + 1, downTwos, downFives, Some(this), true)
    }

    private def createRightEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x + 1, y)
      val downTwos = twoCount + findTwoCount(x + 1, y)
      Edge(x + 1, y, downTwos, downFives, Some(this), false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import scala.collection.mutable
import java.util.Scanner
import scala.util.Random

object Path extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  var zeroPoint: Option[Point] = None

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
          if (matrix(x)(y) == 0) {
            zeroPoint = Some(Point(x,y))
            matrix(x)(y) == 10
          }
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  solve(Edge(0, 0, findTwoCount(0, 0), findFiveCount(0, 0), None, direction = false), Set())

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  case class Point(x: Int, y: Int)

  def printZeroPath(p: Point): Unit = {
    println(1)
    (0 until p.x).foreach(t => print("R"))
    (0 until dim).foreach(t => print("D"))
    (p.x until dim).foreach(t => print("R"))
  }

  def printResult(edge: Edge): Unit = {
    zeroPoint match {
      case None =>
        println(edge.weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) if edge.weight == 0 =>
        println(edge.weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) => printZeroPath(v)
    }

  }

  def solve(curEdge: Edge, visited: Set[Point]): Unit = {
    if (curEdge.last) {
      printResult(curEdge)
    } else {
      curEdge.neighbours.filterNot(it => visited.contains(Point(it.x, it.y))).foreach(queue += _)
      solve(queue.dequeue(), visited + Point(curEdge.x, curEdge.y))
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, twoCount: Int, fiveCount: Int, prev: Option[Edge], direction: Boolean) extends Ordered[Edge] {

    def weight = {
      Math.min(twoCount, fiveCount)
    }

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x, y + 1)
      val downTwos = twoCount + findTwoCount(x, y + 1)
      Edge(x, y + 1, downTwos, downFives, Some(this), true)
    }

    private def createRightEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x + 1, y)
      val downTwos = twoCount + findTwoCount(x + 1, y)
      Edge(x + 1, y, downTwos, downFives, Some(this), false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import scala.collection.mutable
import java.util.Scanner
import scala.util.Random

object Path extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  solve(Edge(0, 0, findTwoCount(0, 0), findFiveCount(0, 0), None, direction = false), Set())

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  case class Point(x: Int, y: Int)

  def solve(curEdge: Edge, visited: Set[Point]): Unit = {
    if (curEdge.last) {
      println(curEdge.weight)
      println(traceBack(Some(curEdge)).reverse.tail.mkString)
    } else {
      curEdge.neighbours.filterNot(it => visited.contains(Point(it.x, it.y))).foreach(queue += _)
      solve(queue.dequeue(), visited + Point(curEdge.x, curEdge.y))
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, twoCount: Int, fiveCount: Int, prev: Option[Edge], direction: Boolean) extends Ordered[Edge] {

    def weight:Double = {
      val common = Math.min(twoCount, fiveCount)
      if (scala.math.abs(twoCount - fiveCount) > 0) common + 0.5 else common
    }

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x, y + 1)
      val downTwos = twoCount + findTwoCount(x, y + 1)
      Edge(x, y + 1, downTwos, downFives, Some(this), true)
    }

    private def createRightEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x + 1, y)
      val downTwos = twoCount + findTwoCount(x + 1, y)
      Edge(x + 1, y, downTwos, downFives, Some(this), false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import scala.collection.mutable
import java.util.Scanner

object Path extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  solve(Edge(0, 0, findTwoCount(0, 0), findFiveCount(0, 0), None, direction = false), Set())

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  case class Point(x: Int, y: Int)

  def solve(curEdge: Edge, visited: Set[Point]): Unit = {
    if (curEdge.last) {
      println(curEdge.weight)
      println(traceBack(Some(curEdge)).reverse.tail.mkString)
    } else {
      curEdge.neighbours.filterNot(it => visited.contains(Point(it.x, it.y))).foreach(queue += _)
      solve(queue.dequeue(), visited + Point(curEdge.x, curEdge.y))
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, twoCount: Int, fiveCount: Int, prev: Option[Edge], direction: Boolean) extends Ordered[Edge] {

    def weight = Math.min(twoCount, fiveCount)

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x, y + 1)
      val downTwos = twoCount + findTwoCount(x, y + 1)
      Edge(x, y + 1, downTwos, downFives, Some(this), true)
    }

    private def createRightEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x + 1, y)
      val downTwos = twoCount + findTwoCount(x + 1, y)
      Edge(x + 1, y, downTwos, downFives, Some(this), false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import scala.collection.mutable
import java.util.Scanner

object LessRoundTrip extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  var zeroPoint: Option[Point] = None

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
          if (matrix(x)(y) == 0) {
            zeroPoint = Some(Point(x, y))
            matrix(x)(y) == 10
          }
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  val twoEdge = solve(Edge(0, 0, findTwoCount(0, 0), None, 2, direction = false), Set())
  val fiveEdge = solve(Edge(0, 0, findTwoCount(0, 0), None, 2, direction = false), Set())
  val weight = math.min(twoEdge.weight, fiveEdge.weight)
  if (twoEdge.weight < fiveEdge.weight) {
    printResult(twoEdge, weight)
  } else {
    printResult(fiveEdge, weight)
  }

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  case class Point(x: Int, y: Int)

  def printZeroPath(p: Point): Unit = {
    println(1)
    (0 until p.x).foreach(t => print("R"))
    (0 until dim).foreach(t => print("D"))
    (p.x until dim).foreach(t => print("R"))
  }

  def printResult(edge: Edge, weight: Int): Unit = {
    zeroPoint match {
      case None =>
        println(weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) if weight == 0 =>
        println(weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) => printZeroPath(v)
    }

  }

  def solve(curEdge: Edge, visited: Set[Point]): Edge = {
    if (curEdge.last) {
      curEdge
    } else {
      curEdge.neighbours.filterNot(it => visited.contains(Point(it.x, it.y))).foreach(queue += _)
      solve(queue.dequeue(), visited + Point(curEdge.x, curEdge.y))
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, numCount: Int, prev: Option[Edge], num: Int, direction: Boolean) extends Ordered[Edge] {

    def weight = {
      numCount
    }

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downNum = numCount + findDivNum(matrix(x)(y + 1), num)
      Edge(x, y + 1, downNum, Some(this), num, true)
    }

    private def createRightEdge(): Edge = {
      val rightNum = numCount + findDivNum(matrix(x + 1)(y), num)
      Edge(x + 1, y, rightNum, Some(this), num, false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import scala.collection.mutable
import java.util.Scanner

object Path extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  (0 until dim) foreach {
    x =>
      (0 until dim) foreach {
        y =>
          matrix(x)(y) = scanner.nextLong()
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  solve(Edge(0, 0, findTwoCount(0, 0), findFiveCount(0, 0), None, direction = false))

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  def solve(curEdge: Edge): Unit = {
    if (curEdge.last) {
      println(curEdge.weight)
      println(traceBack(Some(curEdge)).reverse.tail)
    } else {
      curEdge.neighbours.foreach(queue += _)
      solve(queue.dequeue())
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, twoCount: Int, fiveCount: Int, prev: Option[Edge], direction: Boolean) extends Ordered[Edge] {

    def weight = Math.min(twoCount, fiveCount)

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x, y + 1)
      val downTwos = twoCount + findTwoCount(x, y + 1)
      Edge(x, y + 1, downTwos, downFives, Some(this), true)
    }

    private def createRightEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x + 1, y)
      val downTwos = twoCount + findTwoCount(x + 1, y)
      Edge(x + 1, y, downTwos, downFives, Some(this), false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import scala.collection.mutable
import java.util.Scanner

object Path extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  solve(Edge(0, 0, findTwoCount(0, 0), findFiveCount(0, 0), None, direction = false), Set())

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  case class Point(x: Int, y: Int)

  def solve(curEdge: Edge, visited: Set[Point]): Unit = {
    if (curEdge.last) {
      println(curEdge.weight)
      println(traceBack(Some(curEdge)).reverse.tail.mkString)
    } else if (visited.contains(Point(curEdge.x, curEdge.y))) {
      solve(queue.dequeue(), visited)
    } else {
      curEdge.neighbours.filterNot(it => visited.contains(Point(it.x, it.y))).foreach(queue += _)
      solve(queue.dequeue(), visited + Point(curEdge.x, curEdge.y))
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, twoCount: Int, fiveCount: Int, prev: Option[Edge], direction: Boolean) extends Ordered[Edge] {

    def weight = Math.min(twoCount, fiveCount)

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x, y + 1)
      val downTwos = twoCount + findTwoCount(x, y + 1)
      Edge(x, y + 1, downTwos, downFives, Some(this), true)
    }

    private def createRightEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x + 1, y)
      val downTwos = twoCount + findTwoCount(x + 1, y)
      Edge(x + 1, y, downTwos, downFives, Some(this), false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import scala.collection.mutable
import java.util.Scanner

object Path extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  (0 until dim) foreach {
    x =>
      (0 until dim) foreach {
        y =>
          matrix(x)(y) = scanner.nextLong()
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  solve(Edge(0, 0, findTwoCount(0, 0), findFiveCount(0, 0), None, direction = false))

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  def solve(curEdge: Edge): Unit = {
    if (curEdge.last) {
      println(curEdge.weight)
      println(traceBack(Some(curEdge)).reverse.tail.mkString)
    } else {
      curEdge.neighbours.foreach(queue += _)
      solve(queue.dequeue())
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, twoCount: Int, fiveCount: Int, prev: Option[Edge], direction: Boolean) extends Ordered[Edge] {

    def weight = Math.min(twoCount, fiveCount)

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x, y + 1)
      val downTwos = twoCount + findTwoCount(x, y + 1)
      Edge(x, y + 1, downTwos, downFives, Some(this), true)
    }

    private def createRightEdge(): Edge = {
      val downFives = fiveCount + findFiveCount(x + 1, y)
      val downTwos = twoCount + findTwoCount(x + 1, y)
      Edge(x + 1, y, downTwos, downFives, Some(this), false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

import scala.collection.mutable
import java.util.Scanner

object LessRoundTrip extends App {

  val scanner = new Scanner(System.in)

  val dim = scanner.nextInt()

  val matrix = Array.ofDim[Long](dim, dim)

  var zeroPoint: Option[Point] = None

  (0 until dim) foreach {
    y =>
      (0 until dim) foreach {
        x =>
          matrix(x)(y) = scanner.nextLong()
          if (matrix(x)(y) == 0) {
            zeroPoint = Some(Point(x, y))
            matrix(x)(y) == 10
          }
      }
  }

  val queue = new mutable.PriorityQueue[Edge]()

  val twoEdge = solve(Edge(0, 0, findTwoCount(0, 0), None, 2, direction = false), Set())
  val fiveEdge = solve(Edge(0, 0, findTwoCount(0, 0), None, 5, direction = false), Set())
  val weight = math.min(twoEdge.weight, fiveEdge.weight)
  if (twoEdge.weight < fiveEdge.weight) {
    printResult(twoEdge, weight)
  } else {
    printResult(fiveEdge, weight)
  }

  def traceBack(edge: Option[Edge]): List[Char] = {
    edge match {
      case Some(v) => if (v.direction) 'D' :: traceBack(v.prev) else 'R' :: traceBack(v.prev)
      case None => Nil
    }
  }

  case class Point(x: Int, y: Int)

  def printZeroPath(p: Point): Unit = {
    println(1)
    (0 until p.x).foreach(t => print("R"))
    (0 until dim).foreach(t => print("D"))
    (p.x until dim).foreach(t => print("R"))
  }

  def printResult(edge: Edge, weight: Int): Unit = {
    zeroPoint match {
      case None =>
        println(weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) if weight == 0 =>
        println(weight)
        println(traceBack(Some(edge)).reverse.tail.mkString)
      case Some(v) => printZeroPath(v)
    }

  }

  def solve(curEdge: Edge, visited: Set[Point]): Edge = {
    if (curEdge.last) {
      curEdge
    } else {
      curEdge.neighbours.filterNot(it => visited.contains(Point(it.x, it.y))).foreach(queue += _)
      solve(queue.dequeue(), visited + Point(curEdge.x, curEdge.y))
    }

  }

  def findTwoCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 2)

  def findFiveCount(x: Int, y: Int): Int = findDivNum(matrix(x)(y), 5)

  def findDivNum(item: Long, num: Int): Int = {
    def find(curItem: Long, acc: Int): Int = {
      if (curItem % num == 0)
        find(curItem / num, acc + 1)
      else
        acc
    }
    find(item, 0)
  }

  case class Edge(x: Int, y: Int, numCount: Int, prev: Option[Edge], num: Int, direction: Boolean) extends Ordered[Edge] {

    def weight = {
      numCount
    }

    override def compare(that: Edge): Int = {
      that.weight.compareTo(this.weight)
    }

    private def createDownEdge(): Edge = {
      val downNum = numCount + findDivNum(matrix(x)(y + 1), num)
      Edge(x, y + 1, downNum, Some(this), num, true)
    }

    private def createRightEdge(): Edge = {
      val rightNum = numCount + findDivNum(matrix(x + 1)(y), num)
      Edge(x + 1, y, rightNum, Some(this), num, false)
    }

    def neighbours: List[Edge] = {
      if (x == matrix.length - 1) {
        List(createDownEdge())
      } else if (y == matrix.length - 1) {
        List(createRightEdge())
      } else {
        List(createRightEdge(), createDownEdge())
      }
    }

    def last: Boolean = x == matrix.length - 1 && y == matrix.length - 1

  }

}

object B2 {

  import IO._
  import collection.{mutable => cu}

  def main(args: Array[String]): Unit = {
    val Array(n) = readInts(1)
    val in = Array.fill(n)(readInts(n))
    for(i <- 0 until n; j <- 0 until n if in(i)(j) == 0)
      in(i)(j) = 10
    val two = Array.ofDim[Int](n, n)
    val five = Array.ofDim[Int](n, n)
    for(i <- 0 until n; j <- 0 until n) {
      var num = in(i)(j)
      var t, f = 0
      while(num%2 == 0) {
        num /= 2
        t += 1
      }
      while(num%5 == 0) {
        num /= 5
        f += 1
      }
      if(i == 0 && j == 0) {
        two(i)(j) = t
        five(i)(j) = f
      } else if(i == 0) {
        two(i)(j) = two(i)(j-1) + t
        five(i)(j) = five(i)(j-1) + f
      } else if(j == 0) {
        two(i)(j) = two(i-1)(j) + t
        five(i)(j) = five(i-1)(j) + f
      } else {
        two(i)(j) = math.min(two(i-1)(j), two(i)(j-1)) + t
        five(i)(j) = math.min(five(i-1)(j), five(i)(j-1)) + f
      }
    }
    val dp = if(two(n-1)(n-1) < five(n-1)(n-1)) two else five
    println(dp(n-1)(n-1))
    val res = cu.ArrayBuffer.empty[Char]
    var i = n-1
    var j = n-1
    while(i != 0 || j != 0) {
      if(i > 0 && (j==0 || dp(i)(j-1) >= dp(i-1)(j))) {
        res.append('D')
        i -= 1
      } else {
        res.append('R')
        j -= 1
      }
    }
    println(res.reverse.mkString(""))
  }

  object IO {
    private val input = new java.io.BufferedReader(new java.io.InputStreamReader(System.in))

    @inline def read: String = input.readLine()

    @inline def tokenizeLine = new java.util.StringTokenizer(read)

    def readInt: Int = tokenizeLine.nextToken.toInt

    def readInts(n: Int): Array[Int] = {
      val tl = tokenizeLine
      Array.fill(n)(tl.nextToken.toInt)
    }

    def readLongs(n: Int): Array[Long] = {
      val tl = tokenizeLine
      Array.fill(n)(tl.nextToken.toLong)
    }

    def readBigs(n: Int): Array[BigInt] = {
      val tl = tokenizeLine
      Array.fill(n)(BigInt(tl.nextToken))
    }
  }

}

object B2 {

  import IO._
  import collection.{mutable => cu}

  def main(args: Array[String]): Unit = {
    val Array(n) = readInts(1)
    val in = Array.fill(n)(readInts(n))
    val two = Array.ofDim[Int](n, n)
    val five = Array.ofDim[Int](n, n)
    for(i <- 0 until n; j <- 0 until n) {
      var num = in(i)(j)
      var t, f = 0
      while(num%2 == 0) {
        num /= 2
        t += 1
      }
      while(num%5 == 0) {
        num /= 5
        f += 1
      }
      if(i == 0 && j == 0) {
        two(i)(j) = t
        five(i)(j) = f
      } else if(i == 0) {
        two(i)(j) = two(i)(j-1) + t
        five(i)(j) = five(i)(j-1) + f
      } else if(j == 0) {
        two(i)(j) = two(i-1)(j) + t
        five(i)(j) = five(i-1)(j) + f
      } else {
        two(i)(j) = math.min(two(i-1)(j), two(i)(j-1)) + t
        five(i)(j) = math.min(five(i-1)(j), five(i)(j-1)) + f
      }
    }
    println(math.min(two(n-1)(n-1), five(n-1)(n-1)))
    val res = cu.ArrayBuffer.empty[Char]
    var i, j = n-1
    while(i > 0 && j > 0) {
      if(math.min(two(i-1)(j), five(i-1)(j)) < math.min(two(i)(j-1), five(i)(j-1))) {
        res.append('D')
        i -= 1
      } else {
        res.append('R')
        j -= 1
      }
    }
    while(i > 0) {
      res.append('D')
      i -= 1
    }
    while(j > 0) {
      res.append('R')
      j -= 1
    }
    println(res.reverse.mkString(""))
  }

  object IO {
    private val input = new java.io.BufferedReader(new java.io.InputStreamReader(System.in))

    @inline def read: String = input.readLine()

    @inline def tokenizeLine = new java.util.StringTokenizer(read)

    def readInt: Int = tokenizeLine.nextToken.toInt

    def readInts(n: Int): Array[Int] = {
      val tl = tokenizeLine
      Array.fill(n)(tl.nextToken.toInt)
    }

    def readLongs(n: Int): Array[Long] = {
      val tl = tokenizeLine
      Array.fill(n)(tl.nextToken.toLong)
    }

    def readBigs(n: Int): Array[BigInt] = {
      val tl = tokenizeLine
      Array.fill(n)(BigInt(tl.nextToken))
    }
  }

}

import scala.io.StdIn
import scala.annotation.tailrec
import scala.collection

object X extends App {

  case class MyVertex[T, U](id: T, edges: Map[T, U])

  case class ScoreAndPrev[T, V](id: T, score: V)

  class MyGraph[T, U](vertices: Map[T, MyVertex[T, U]]) {

    def doDjikstra[V](start: T, initialValue: V)(combiner: (U, V) => V)(
        implicit ord: Ordering[V]
    ): Map[T, ScoreAndPrev[T, V]] = {

      var m = new collection.mutable.HashMap[T, ScoreAndPrev[T, V]]();

      var visited = new collection.mutable.HashSet[T]();

      m.update(start, ScoreAndPrev(start, initialValue))

      implicit val tOrdering = new Ordering[T] {
        def compare(x: T, y: T): Int = {
          ord.compare(m(y).score, m(x).score)
        }
      }

      var q = new collection.mutable.PriorityQueue[T]();

      q.enqueue(start)

      while (q.nonEmpty) {
        val next = q.dequeue()

        if (!visited.contains(next)) {
          val neighbours = vertices(next).edges
          val score = m(next).score

          val unvisitedNeighbours = neighbours.keySet.diff(visited)

          unvisitedNeighbours.foreach(n => {
            val neighbourWeight = neighbours(n)

            val oldScore = m.get(n).map(s => s.score)

            val potScore = combiner(neighbourWeight, score)

            val nextScore = oldScore match {
              case None => potScore
              case Some(value) =>
                if (ord.lt(potScore, value)) potScore else value
            }

            m.update(n, ScoreAndPrev(next, nextScore))

          })

          q.enqueue(unvisitedNeighbours.toSeq: _*)

          visited.add(next)
        }

      }

      m.toMap
    }
  }

  object MyGraph {
    def apply[T, U](vertices: Map[T, MyVertex[T, U]]) =
      new MyGraph[T, U](vertices)
  }

  object Y {

    @tailrec
    def largestDividingPower(n: Int, m: Int, c: Int = 0): Int = {
      if (n % m == 0 && n != 0) largestDividingPower(n / m, m, c + 1) else c
    }

    def getAnswer(graph: MyGraph[(Int, Int), Int], end: (Int, Int)) = {

      val endModTwo =
        graph.doDjikstra((-1, -1), 0)((s, w) => w + largestDividingPower(s, 2))

      val endModFive =
        graph.doDjikstra((-1, -1), 0)((s, w) => w + largestDividingPower(s, 5))

      val smallestEnd = List(endModTwo, endModFive).minBy(s => s(end).score)

      def determinePath[T, V](
          start: T,
          end: T,
          djikstrad: Map[T, ScoreAndPrev[T, V]],
          path: List[T] = Nil
      ): List[T] = {
        if (start == end) path
        else determinePath(djikstrad(start).id, end, djikstrad, start +: path)
      }

      val thePath = determinePath(end, (0, 0), smallestEnd)

      val stringedPath = thePath
        .foldLeft("", (0, 0))((path, e) => {
          val prev = path._2
          if (e._1 == prev._1) (path._1 + "R", e) else (path._1 + "D", e)
        })
        ._1

      (smallestEnd(end).score, stringedPath)
    }

    val vertices = Map(
      (2, 2) -> MyVertex((2, 2), Map[(Int, Int), Int]()),
      (2, 1) -> MyVertex((2, 1), Map((2, 2) -> 9)),
      (2, 0) -> MyVertex((2, 0), Map((2, 1) -> 8)),
      (1, 2) -> MyVertex((1, 2), Map((2, 2) -> 9)),
      (-1, -1) -> MyVertex((-1, -1), Map((0, 0) -> 1)),
      (1, 0) -> MyVertex((1, 0), Map((2, 0) -> 7, (1, 1) -> 5)),
      (0, 0) -> MyVertex((0, 0), Map((1, 0) -> 4, (0, 1) -> 2)),
      (0, 2) -> MyVertex((0, 2), Map((1, 2) -> 6)),
      (0, 1) -> MyVertex((0, 1), Map((1, 1) -> 5, (0, 2) -> 3)),
      (1, 1) -> MyVertex((1, 1), Map((2, 1) -> 8, (1, 2) -> 6))
    )

    val graph = new MyGraph(vertices)

    val res = getAnswer(graph, (2, 2))

    println(res)
  }

  val lineCount = StdIn.readInt()

  val matrix =
    (0 until lineCount).foldLeft(Map[(Int, Int), Int]())((accMap, currLine) => {
      val line = StdIn.readLine().split(" ").map(_.toInt)

      val lineMap = line.zipWithIndex.foldLeft(Map[(Int, Int), Int]())(
        (accLineMap, curr) => {
          accLineMap + ((currLine, curr._2) -> curr._1)
        }
      )

      accMap ++ lineMap
    })

  val vertexStart = MyVertex((-1, -1), Map((0, 0) -> matrix(0, 0)))

  val vertices = matrix.foldLeft(Map[(Int, Int), MyVertex[(Int, Int), Int]]())(
    (accMap, currVert) => {
      val thisVert = currVert._1

      val downNeighbour = matrix.get((thisVert._1 + 1, thisVert._2)) match {
        case None        => None
        case Some(value) => Some((thisVert._1 + 1, thisVert._2), value)
      }
      val rightNeighbour = matrix.get(thisVert._1, thisVert._2 + 1) match {
        case None        => None
        case Some(value) => Some((thisVert._1, thisVert._2 + 1), value)
      }

      val neighbours = List(downNeighbour, rightNeighbour).flatten.toMap

      val vert = MyVertex((currVert._1), neighbours)

      accMap + (currVert._1 -> vert)
    }
  ) + ((-1, -1) -> vertexStart)

  val graph = MyGraph(vertices)

  val answer = Y.getAnswer(graph, (lineCount - 1, lineCount - 1))

  println(answer._1)
  println(answer._2)

}

import scala.reflect.ClassTag
object X extends App {
  def dynamicSolveMatrixRightDown[T, U: ClassTag](
      matrix: Array[Array[T]],
      initialValue: U
  )(
      combiner: (U, T) => U
  )(implicit ord: Ordering[U]) = {

    val len = matrix.length

    val solutionMatrix = Array.ofDim[(String, U)](len, len)

    solutionMatrix(0)(0) = ("", combiner(initialValue, matrix(0)(0)))

    (0 until len).foreach(b => {
      (0 to b).foreach(i => {
        if (b != 0 && i == b) {
          val leftWeight = combiner(solutionMatrix(b - 1)(b)._2, matrix(b)(b))
          val upWeight = combiner(solutionMatrix(b)(b - 1)._2, matrix(b)(b))

          solutionMatrix(b)(b) =
            if (ord.lt(leftWeight, upWeight)) ("D", leftWeight)
            else ("R", upWeight)
        }
        // row
        val rowWeight = solutionMatrix(i)(b)._2

        if (!(b + 1 > len - 1)) {
          solutionMatrix(i)(b + 1) =
            ("R", combiner(rowWeight, matrix(i)(b + 1)))
        }

        if (!(i + 1 > len - 1)) {
          val rightWeight = matrix(i + 1)(b)

          val candidateWeight = combiner(rowWeight, rightWeight)

          if (solutionMatrix(i + 1)(b) == null) {
            solutionMatrix(i + 1)(b) = ("D", candidateWeight)
          } else {
            val currentRightWeight = solutionMatrix(i + 1)(b)._2

            if (ord.lt(candidateWeight, currentRightWeight)) {
              solutionMatrix(i + 1)(b) = ("D", candidateWeight)
            }
          }

        }

        //col
        val colWeight = solutionMatrix(b)(i)._2

        if (!(b + 1 > len - 1)) {
          solutionMatrix(b + 1)(i) =
            ("D", combiner(colWeight, matrix(b + 1)(i)))
        }

        if (!(i + 1 > len - 1)) {
          val downWeight = matrix(b)(i + 1)

          val otherCandidateWeight = combiner(colWeight, downWeight)

          if (solutionMatrix(b)(i + 1) == null) {
            solutionMatrix(b)(i + 1) = ("R", otherCandidateWeight)
          } else {
            val currentDownWeight = solutionMatrix(b)(i + 1)._2

            if (ord.lt(otherCandidateWeight, currentDownWeight)) {
              solutionMatrix(b)(i + 1) = ("R", otherCandidateWeight)
            }
          }

        }

      })

    })

    solutionMatrix
  }

  def highestFactor(f: Int, n: Int) = {
    var m = n
    var c = 0
    while (m % f == 0) {
      c = c + 1
      m = m / f
    }
    c
  }

  def getPath[U](
      solnMatrix: Array[Array[(String, U)]],
      start: (Int, Int),
      path: String = "",
      end: (Int, Int) = (0, 0)
  ): String = {
    if (start == end) {
      path
    } else {
      val dir = solnMatrix(start._1)(start._2)._1
      if (dir == "R") {
        getPath(solnMatrix, (start._1, start._2 - 1), "R" + path)
      } else getPath(solnMatrix, (start._1 - 1, start._2), "D" + path)
    }
  }

  val lineCount = scala.io.StdIn.readInt()

  val inpMatrix = Array.ofDim[Int](lineCount, lineCount)

  (0 until lineCount).foreach(r => {
    val line = scala.io.StdIn
      .readLine()
      .split(" ")
      .zipWithIndex
      .foreach(w => {
        inpMatrix(r)(w._2) = w._1.toInt
      })
  })

  val powerOfTwo = ((x: Int, y: Int) => x + (y & ~(y - 1)))
  val powerOfFive = ((x: Int, y: Int) => x + highestFactor(5, y))

  val solutionMatrixTwo = dynamicSolveMatrixRightDown(
    inpMatrix,
    0
  )(powerOfTwo)

  val resultsTwo =
    solutionMatrixTwo(inpMatrix.length - 1)(inpMatrix.length - 1)._2

  val betterWay = if (resultsTwo == 0) {
    solutionMatrixTwo
  } else {
    val solutionMatrixFive = dynamicSolveMatrixRightDown(
      inpMatrix,
      0
    )(powerOfFive)

    val resultsFive =
      solutionMatrixFive(inpMatrix.length - 1)(inpMatrix.length - 1)._2

    if (resultsTwo < resultsFive) solutionMatrixTwo else solutionMatrixFive
  }

  val path =
    getPath(betterWay, (inpMatrix.length - 1, inpMatrix.length - 1))

  println(betterWay(inpMatrix.length - 1)(inpMatrix.length - 1)._2)
  println(path)

}

import scala.reflect.ClassTag
import scala.annotation.tailrec
object X extends App {
  def dynamicSolveMatrixRightDown[T, U: ClassTag](
      matrix: Array[Array[T]],
      initialValue: U
  )(
      combiner: (U, U, T) => U
  ) = {

    val len = matrix.length

    val solutionMatrix = Array.ofDim[U](len, len)

    solutionMatrix(0)(0) = combiner(initialValue, initialValue, matrix(0)(0))

    (0 until len).foreach(b => {
      (0 to b).foreach(i => {
        // row
        val rowWeight = solutionMatrix(i)(b)
        val colWeight = solutionMatrix(b)(i)

        if (!(b + 1 > len - 1)) {
          solutionMatrix(i)(b + 1) =
            combiner(rowWeight, solutionMatrix(i)(b + 1), matrix(i)(b + 1))
          solutionMatrix(b + 1)(i) =
            combiner(colWeight, solutionMatrix(b + 1)(i), matrix(b + 1)(i))
        }

        if (!(i + 1 > len - 1)) {
          val rightWeight = matrix(i + 1)(b)

          val candidateWeight =
            combiner(rowWeight, solutionMatrix(i + 1)(b), rightWeight)

          solutionMatrix(i + 1)(b) = candidateWeight

          val downWeight = matrix(b)(i + 1)

          val otherCandidateWeight =
            combiner(colWeight, solutionMatrix(b)(i + 1), downWeight)

          solutionMatrix(b)(i + 1) = otherCandidateWeight

        }

        if (b < len - 1 && i == b) {
          val leftWeight =
            combiner(
              solutionMatrix(b)(b + 1),
              solutionMatrix(b + 1)(b + 1),
              matrix(b + 1)(b + 1)
            )

          solutionMatrix(b + 1)(b + 1) = leftWeight

          val upWeight =
            combiner(
              solutionMatrix(b + 1)(b),
              solutionMatrix(b + 1)(b + 1),
              matrix(b + 1)(b + 1)
            )

          solutionMatrix(b + 1)(b + 1) = upWeight
        }

      })

    })

    solutionMatrix
  }

  def dynamicSolveMatrixRightDownInPlace[T](
      matrix: Array[Array[T]],
      initialValue: T
  )(
      combiner: (T, T, T) => T
  ): Array[Array[T]] = {

    val len = matrix.length

    matrix(0)(0) = initialValue

    (1 until len).foreach(i => {
      matrix(0)(i) = combiner(matrix(0)(i - 1), matrix(0)(i - 1), matrix(0)(i))
      matrix(i)(0) = combiner(matrix(i - 1)(0), matrix(i - 1)(0), matrix(i)(0))
    })

    (1 until len).foreach(i => {
      (1 until len).foreach(j => {
        matrix(i)(j) =
          combiner(matrix(i - 1)(j), matrix(i)(j - 1), matrix(i)(j))
      })
    })

    matrix
  }

  def highestFactor(f: Int, n: Int) = {
    var m = n
    var c = 0
    while (m % f == 0) {
      c = c + 1
      m = m / f
    }
    (c, m)
  }

  @tailrec
  def getPath[U](
      solnMatrix: Array[Array[U]],
      start: (Int, Int),
      path: List[String] = List(),
      end: (Int, Int) = (0, 0)
  )(implicit ord: Ordering[U]): String = {
    if (start == end) {
      path.mkString("")
    } else {
      start match {
        case (0, s) =>
          getPath(solnMatrix, (start._1, start._2 - 1), "R" +: path)
        case (s, 0) =>
          getPath(solnMatrix, (start._1 - 1, start._2), "D" +: path)
        case (u, v) => {
          if (ord.lt(solnMatrix(u - 1)(v), solnMatrix(u)(v - 1)))
            getPath(solnMatrix, (start._1 - 1, start._2), "D" +: path)
          else getPath(solnMatrix, (start._1, start._2 - 1), "R" +: path)
        }
      }
    }
  }

  val lineCount = scala.io.StdIn.readInt()

  val inpMatrix = Array.ofDim[(Int, Int)](lineCount, lineCount)

  var hasZero = Option.empty[(Int, Int)]

  (0 until lineCount).foreach(r => {
    var i = 0
    val line = scala.io.StdIn
      .readLine()
      .split(" ")
      .foreach(w => {
        val cell = w.toInt
        if (cell == 0) {
          hasZero = Some((r, i))
          inpMatrix(r)(i) = (1, 1)
        } else {
          val (p10, t) = highestFactor(10, cell)

          val (p2, k) = highestFactor(2, t)
          val p5 = highestFactor(5, k)._1
          inpMatrix(r)(i) = (p2 + p10, p5 + p10)

        }
        i = i + 1
      })
  })

//   println(inpMatrix.map(_.mkString("\t")).mkString("\n"))
//   println()

  val smaller = (x: Int, y: Int) => if (x < y) x else y

  val solutionMatrix = dynamicSolveMatrixRightDownInPlace(
    inpMatrix,
    inpMatrix(0)(0)
  )((left, up, y) => {
    val fstCont = smaller(left._1, up._1)
    val sndCont = smaller(left._2, up._2)
    (
      fstCont + y._1,
      sndCont + y._2
    )

  })

  val ending = solutionMatrix(lineCount - 1)(lineCount - 1)
  val smallest = smaller(ending._1, ending._2)

  val bestPath = if (ending._1 < ending._2) {
    getPath(solutionMatrix, (lineCount - 1, lineCount - 1))(
      new Ordering[(Int, Int)] {
        def compare(x: (Int, Int), y: (Int, Int)): Int = x._1.compare(y._1)
      }
    )
  } else {
    getPath(solutionMatrix, (lineCount - 1, lineCount - 1))(
      new Ordering[(Int, Int)] {
        def compare(x: (Int, Int), y: (Int, Int)): Int = x._2.compare(y._2)
      }
    )
  }

  val (p, s) = hasZero match {
    case None => (bestPath, smallest)
    case Some(value) =>
      if (smallest == 0) {
        (bestPath, smallest)
      } else {
        val x = value._1

        val s = (0 until x - 1).map(_ => "R").mkString("")
        val d = (0 until lineCount - 1).map(_ => "D").mkString("")
        val r = (0 until lineCount - x).map(_ => "R").mkString("")

        (s + d + r, 1)
      }
  }

//   println(solutionMatrix.map(_.mkString("\t")).mkString("\n"))

  println(s)
  println(p)
}

import scala.reflect.ClassTag
import scala.annotation.tailrec
object X extends App {
  def dynamicSolveMatrixRightDown[T, U: ClassTag](
      matrix: Array[Array[T]],
      initialValue: U
  )(
      combiner: (U, T) => U
  )(implicit ord: Ordering[U]) = {

    val len = matrix.length

    val solutionMatrix = Array.ofDim[U](len, len)

    solutionMatrix(0)(0) = combiner(initialValue, matrix(0)(0))

    (0 until len).foreach(b => {
      (0 to b).foreach(i => {
        if (b != 0 && i == b) {
          val leftWeight = combiner(solutionMatrix(b - 1)(b), matrix(b)(b))
          val upWeight = combiner(solutionMatrix(b)(b - 1), matrix(b)(b))

          solutionMatrix(b)(b) =
            if (ord.lt(leftWeight, upWeight)) leftWeight
            else upWeight
        }
        // row
        val rowWeight = solutionMatrix(i)(b)
        val colWeight = solutionMatrix(b)(i)

        if (!(b + 1 > len - 1)) {
          solutionMatrix(i)(b + 1) = combiner(rowWeight, matrix(i)(b + 1))
          solutionMatrix(b + 1)(i) = combiner(colWeight, matrix(b + 1)(i))

        }

        if (!(i + 1 > len - 1)) {
          val rightWeight = matrix(i + 1)(b)

          val candidateWeight = combiner(rowWeight, rightWeight)

          val currentRightWeight = solutionMatrix(i + 1)(b)

          if (ord.lt(candidateWeight, currentRightWeight)) {
            solutionMatrix(i + 1)(b) = candidateWeight
          }

          val downWeight = matrix(b)(i + 1)

          val otherCandidateWeight = combiner(colWeight, downWeight)

          val currentDownWeight = solutionMatrix(b)(i + 1)

          if (ord.lt(otherCandidateWeight, currentDownWeight)) {
            solutionMatrix(b)(i + 1) = otherCandidateWeight
          }

        }

      })

    })

    solutionMatrix
  }

  def highestFactor(f: Int, n: Int) = {
    var m = n
    var c = 0
    while (m % f == 0) {
      c = c + 1
      m = m / f
    }
    (c, m)
  }

  @tailrec
  def getPath[U](
      solnMatrix: Array[Array[U]],
      start: (Int, Int),
      path: List[String] = List(),
      end: (Int, Int) = (0, 0)
  )(implicit ord: Ordering[U]): String = {
    if (start == end) {
      path.mkString("")
    } else {
      start match {
        case (0, s) =>
          getPath(solnMatrix, (start._1, start._2 - 1), "R" +: path)
        case (s, 0) =>
          getPath(solnMatrix, (start._1 - 1, start._2), "D" +: path)
        case (u, v) => {
          if (ord.lt(solnMatrix(u - 1)(v), solnMatrix(u)(v - 1)))
            getPath(solnMatrix, (start._1 - 1, start._2), "D" +: path)
          else getPath(solnMatrix, (start._1, start._2 - 1), "R" +: path)
        }
      }
    }
  }

  val lineCount = scala.io.StdIn.readInt()

  val inpMatrix = Array.ofDim[(Int, Int)](lineCount, lineCount)

  (0 until lineCount).foreach(r => {
    var i = 0
    val line = scala.io.StdIn
      .readLine()
      .split(" ")
      .foreach(w => {
        if (w.last != '0') {
          inpMatrix(r)(i) = (0, 0)
        } else {
          val cell = w.toInt
          val (p10, t) = highestFactor(10, cell)

          val (p2, k) = highestFactor(2, t)
          val p5 = highestFactor(5, k)._1
          inpMatrix(r)(i) = (p2 + p10, p5 + p10)
        }
        i = i + 1

      })
  })

  val solutionMatrixTwo = dynamicSolveMatrixRightDown(
    inpMatrix,
    0
  )(((x: Int, y: (Int, Int)) => x + y._1))

  val resultsTwo =
    solutionMatrixTwo(lineCount - 1)(lineCount - 1)

  val (path, score) = if (resultsTwo == 0) {
    (getPath(solutionMatrixTwo, (lineCount - 1, lineCount - 1)), resultsTwo)
  } else {
    val solutionMatrixFive = dynamicSolveMatrixRightDown(
      inpMatrix,
      0
    )(((x: Int, y: (Int, Int)) => x + y._2))

    val resultsFive =
      solutionMatrixFive(lineCount - 1)(lineCount - 1)

    if (resultsTwo < resultsFive)
      (getPath(solutionMatrixTwo, (lineCount - 1, lineCount - 1)), resultsTwo)
    else
      (getPath(solutionMatrixFive, (lineCount - 1, lineCount - 1)), resultsFive)
  }

  println(score)
  println(path)

}

import scala.reflect.ClassTag
import scala.annotation.tailrec
object X extends App {
  def dynamicSolveMatrixRightDown[T, U: ClassTag](
      matrix: Array[Array[T]],
      initialValue: U
  )(
      combiner: (U, U, T) => U
  ) = {

    val len = matrix.length

    val solutionMatrix = Array.ofDim[U](len, len)

    solutionMatrix(0)(0) = combiner(initialValue, initialValue, matrix(0)(0))

    (0 until len).foreach(b => {
      (0 to b).foreach(i => {
        // row
        val rowWeight = solutionMatrix(i)(b)
        val colWeight = solutionMatrix(b)(i)

        if (!(b + 1 > len - 1)) {
          solutionMatrix(i)(b + 1) =
            combiner(rowWeight, solutionMatrix(i)(b + 1), matrix(i)(b + 1))
          solutionMatrix(b + 1)(i) =
            combiner(colWeight, solutionMatrix(b + 1)(i), matrix(b + 1)(i))
        }

        if (!(i + 1 > len - 1)) {
          val rightWeight = matrix(i + 1)(b)

          val candidateWeight =
            combiner(rowWeight, solutionMatrix(i + 1)(b), rightWeight)

          solutionMatrix(i + 1)(b) = candidateWeight

          val downWeight = matrix(b)(i + 1)

          val otherCandidateWeight =
            combiner(colWeight, solutionMatrix(b)(i + 1), downWeight)

          solutionMatrix(b)(i + 1) = otherCandidateWeight

        }

        if (b < len - 1 && i == b) {
          val leftWeight =
            combiner(
              solutionMatrix(b)(b + 1),
              solutionMatrix(b + 1)(b + 1),
              matrix(b + 1)(b + 1)
            )

          solutionMatrix(b + 1)(b + 1) = leftWeight

          val upWeight =
            combiner(
              solutionMatrix(b + 1)(b),
              solutionMatrix(b + 1)(b + 1),
              matrix(b + 1)(b + 1)
            )

          solutionMatrix(b + 1)(b + 1) = upWeight
        }

      })

    })

    solutionMatrix
  }

  def highestFactor(f: Int, n: Int) = {
    var m = n
    var c: Byte = 0
    while (m % f == 0) {
      c = c.+(1).asInstanceOf[Byte]
      m = m / f
    }
    (c, m)
  }

  @tailrec
  def getPath[U](
      solnMatrix: Array[Array[U]],
      start: (Int, Int),
      path: List[String] = List(),
      end: (Int, Int) = (0, 0)
  )(implicit ord: Ordering[U]): String = {
    if (start == end) {
      path.mkString("")
    } else {
      start match {
        case (0, s) =>
          getPath(solnMatrix, (start._1, start._2 - 1), "R" +: path)
        case (s, 0) =>
          getPath(solnMatrix, (start._1 - 1, start._2), "D" +: path)
        case (u, v) => {
          if (ord.lt(solnMatrix(u - 1)(v), solnMatrix(u)(v - 1)))
            getPath(solnMatrix, (start._1 - 1, start._2), "D" +: path)
          else getPath(solnMatrix, (start._1, start._2 - 1), "R" +: path)
        }
      }
    }
  }

  val lineCount = scala.io.StdIn.readInt()

  val inpMatrix = Array.ofDim[(Byte, Byte)](lineCount, lineCount)

  (0 until lineCount).foreach(r => {
    var i = 0
    val line = scala.io.StdIn
      .readLine()
      .split(" ")
      .foreach(w => {
        val cell = w.toInt
        val (p10, t) = highestFactor(10, cell)

        val (p2, k) = highestFactor(2, t)
        val p5 = highestFactor(5, k)._1
        inpMatrix(r)(i) =
          (p2.+(p10).asInstanceOf[Byte], p5.+(p10).asInstanceOf[Byte])
        i = i + 1
      })
  })

//   println(inpMatrix.map(_.mkString("\t")).mkString("\n"))
//   println()

  val smaller = (x: Byte, y: Byte) => if (x < y) x else y

  val solutionMatrix = dynamicSolveMatrixRightDown(
    inpMatrix,
    inpMatrix(0)(0)
  )((x, currScore, y) => {
    val candidateNextFst = x._1.+(y._1).asInstanceOf[Byte]
    val candidateNextSnd = x._2.+(y._2).asInstanceOf[Byte]
    if (currScore == null) {
      (candidateNextFst, candidateNextSnd)
    } else {
      (
        smaller(candidateNextFst, currScore._1),
        smaller(candidateNextSnd, currScore._2)
      )
    }
  })

  val ending = solutionMatrix(lineCount - 1)(lineCount - 1)
  val smallest = smaller(ending._1, ending._2)

  val p = if (ending._1 < ending._2) {
    getPath(solutionMatrix, (lineCount - 1, lineCount - 1))(
      new Ordering[(Byte, Byte)] {
        def compare(x: (Byte, Byte), y: (Byte, Byte)): Int =
          x._1.compare(y._1)
      }
    )
  } else {
    getPath(solutionMatrix, (lineCount - 1, lineCount - 1))(
      new Ordering[(Byte, Byte)] {
        def compare(x: (Byte, Byte), y: (Byte, Byte)): Int =
          x._2.compare(y._2)
      }
    )
  }

//   println(solutionMatrix.map(_.mkString("\t")).mkString("\n"))

  println(smallest)
  println(p)
}

import scala.io.StdIn
import scala.annotation.tailrec

object X extends App {
  case class MyVertex[T, U](id: T, edges: Map[T, U])

  case class ScoreAndPrev[T, V](id: T, score: V)

  class MyGraph[T, U](vertices: Map[T, MyVertex[T, U]]) {

    def doDjikstra[V](start: T, initialValue: V)(combiner: (U, V) => V)(
        implicit ord: Ordering[V]
    ): Map[T, ScoreAndPrev[T, V]] = {
      val nextVertex = (
          visited: Set[T],
          scores: Map[T, ScoreAndPrev[T, V]]
      ) => {
        scores.filterNot(p => visited.contains(p._1)).minBy(w => w._2.score)._1
      }

      case class RunningScore(
          scores: Map[T, ScoreAndPrev[T, V]] = Map(
            start -> ScoreAndPrev(start, initialValue)
          ),
          visitedVertices: Set[T] = Set(),
          currVert: T = start
      )

      val scoreMap = vertices
        .foldLeft(RunningScore())((runningScore, _) => {
          val RunningScore(scores, visitedVertices, currVert) = runningScore
          val currVertEdges = vertices(currVert).edges

          val newScores =
            currVertEdges.foldLeft(scores)((currScores, currEdge) => {
              val neighbour = currEdge._1
              val edgeWeight = currEdge._2

              val scoreForCurrVert = currScores(currVert)

              val scoreForNeighbour = currScores.get(neighbour)

              val potentialScore = combiner(
                edgeWeight,
                scoreForCurrVert.score
              )

              val updatedScores = scoreForNeighbour match {
                case Some(s) if (ord.lt(potentialScore, s.score)) =>
                  currScores + (neighbour -> ScoreAndPrev(
                    currVert,
                    potentialScore
                  ))
                case None =>
                  currScores + (neighbour -> ScoreAndPrev(
                    currVert,
                    potentialScore
                  ))
                case _ => currScores
              }

              updatedScores
            })

          val updatedSet = visitedVertices + currVert
          val nextVert =
            if (updatedSet.size == vertices.size) currVert
            else nextVertex(updatedSet, newScores)

          RunningScore(newScores, updatedSet, nextVert)
        })
        .scores

      scoreMap
    }
  }

  object MyGraph {
    def apply[T, U](vertices: Map[T, MyVertex[T, U]]) =
      new MyGraph[T, U](vertices)
  }

  @tailrec
  def largestDividingPower(n: Int, m: Int, c: Int = 0): Int = {
    if (n % m == 0 && n != 0) largestDividingPower(n / m, m, c + 1) else c
  }

  def getAnswer(graph: MyGraph[(Int, Int), Int], end: (Int, Int)) = {
    val endModTwo =
      graph.doDjikstra((-1, -1), 0)((s, w) => w + largestDividingPower(s, 2))

    val endModFive =
      graph.doDjikstra((-1, -1), 0)((s, w) => w + largestDividingPower(s, 5))

    val smallestEnd = List(endModTwo, endModFive).minBy(s => s(end).score)

    def determinePath[T, V](
        start: T,
        end: T,
        djikstrad: Map[T, ScoreAndPrev[T, V]],
        path: List[T] = Nil
    ): List[T] = {
      if (start == end) path
      else determinePath(djikstrad(start).id, end, djikstrad, start +: path)
    }

    val thePath = determinePath(end, (0, 0), smallestEnd)

    val stringedPath = thePath
      .foldLeft("", (0, 0))((path, e) => {
        val prev = path._2
        if (e._1 == prev._1) (path._1 + "R", e) else (path._1 + "D", e)
      })
      ._1

    (smallestEnd(end).score, stringedPath)
  }

  val lineCount = StdIn.readInt()

  val matrix =
    (0 until lineCount).foldLeft(Map[(Int, Int), Int]())((accMap, currLine) => {
      val line = StdIn.readLine().split(" ").map(_.toInt)

      val lineMap = line.zipWithIndex.foldLeft(Map[(Int, Int), Int]())(
        (accLineMap, curr) => {
          accLineMap + ((currLine, curr._2) -> curr._1)
        }
      )

      accMap ++ lineMap
    })

  val vertexStart = MyVertex((-1, -1), Map((0, 0) -> 1))

  val vertices = matrix.foldLeft(Map[(Int, Int), MyVertex[(Int, Int), Int]]())(
    (accMap, currVert) => {
      val thisVert = currVert._1

      val downNeighbour = matrix.get((thisVert._1 + 1, thisVert._2)) match {
        case None        => None
        case Some(value) => Some((thisVert._1 + 1, thisVert._2), value)
      }
      val rightNeighbour = matrix.get(thisVert._1, thisVert._2 + 1) match {
        case None        => None
        case Some(value) => Some((thisVert._1, thisVert._2 + 1), value)
      }

      val neighbours = List(downNeighbour, rightNeighbour).flatten.toMap

      val vert = MyVertex((currVert._1), neighbours)

      accMap + (currVert._1 -> vert)
    }
  ) + ((-1, -1) -> vertexStart)

  val graph = MyGraph(vertices)

  val answer = getAnswer(graph, (lineCount - 1, lineCount - 1))

  println(answer._1)
  println(answer._2)

}

import scala.reflect.ClassTag
import scala.annotation.tailrec
object X extends App {
  def dynamicSolveMatrixRightDown[T, U: ClassTag](
      matrix: Array[Array[T]],
      initialValue: U
  )(
      combiner: (U, U, T) => U
  ) = {

    val len = matrix.length

    val solutionMatrix = Array.ofDim[U](len, len)

    solutionMatrix(0)(0) = combiner(initialValue, initialValue, matrix(0)(0))

    (0 until len).foreach(b => {
      (0 to b).foreach(i => {
        // row
        val rowWeight = solutionMatrix(i)(b)
        val colWeight = solutionMatrix(b)(i)

        if (!(b + 1 > len - 1)) {
          solutionMatrix(i)(b + 1) =
            combiner(rowWeight, solutionMatrix(i)(b + 1), matrix(i)(b + 1))
          solutionMatrix(b + 1)(i) =
            combiner(colWeight, solutionMatrix(b + 1)(i), matrix(b + 1)(i))
        }

        if (!(i + 1 > len - 1)) {
          val rightWeight = matrix(i + 1)(b)

          val candidateWeight =
            combiner(rowWeight, solutionMatrix(i + 1)(b), rightWeight)

          solutionMatrix(i + 1)(b) = candidateWeight

          val downWeight = matrix(b)(i + 1)

          val otherCandidateWeight =
            combiner(colWeight, solutionMatrix(b)(i + 1), downWeight)

          solutionMatrix(b)(i + 1) = otherCandidateWeight

        }

        if (b < len - 1 && i == b) {
          val leftWeight =
            combiner(
              solutionMatrix(b)(b + 1),
              solutionMatrix(b + 1)(b + 1),
              matrix(b + 1)(b + 1)
            )

          solutionMatrix(b + 1)(b + 1) = leftWeight

          val upWeight =
            combiner(
              solutionMatrix(b + 1)(b),
              solutionMatrix(b + 1)(b + 1),
              matrix(b + 1)(b + 1)
            )

          solutionMatrix(b + 1)(b + 1) = upWeight
        }

      })

    })

    solutionMatrix
  }

  def highestFactor(f: Int, n: Int) = {
    var m = n
    var c = 0
    while (m % f == 0) {
      c = c + 1
      m = m / f
    }
    (c, m)
  }

  @tailrec
  def getPath[U](
      solnMatrix: Array[Array[U]],
      start: (Int, Int),
      path: List[String] = List(),
      end: (Int, Int) = (0, 0)
  )(implicit ord: Ordering[U]): String = {
    if (start == end) {
      path.mkString("")
    } else {
      start match {
        case (0, s) =>
          getPath(solnMatrix, (start._1, start._2 - 1), "R" +: path)
        case (s, 0) =>
          getPath(solnMatrix, (start._1 - 1, start._2), "D" +: path)
        case (u, v) => {
          if (ord.lt(solnMatrix(u - 1)(v), solnMatrix(u)(v - 1)))
            getPath(solnMatrix, (start._1 - 1, start._2), "D" +: path)
          else getPath(solnMatrix, (start._1, start._2 - 1), "R" +: path)
        }
      }
    }
  }

  val lineCount = scala.io.StdIn.readInt()

  val inpMatrix = Array.ofDim[(Int, Int)](lineCount, lineCount)

  (0 until lineCount).foreach(r => {
    var i = 0
    val line = scala.io.StdIn
      .readLine()
      .split(" ")
      .foreach(w => {
        val cell = w.toInt
        val (p10, t) = highestFactor(10, cell)

        val (p2, k) = highestFactor(2, t)
        val p5 = highestFactor(5, k)._1
        inpMatrix(r)(i) = (p2, p5)
        i = i + 1
      })
  })

  val smaller = (x: Int, y: Int) => if (x < y) x else y

  val solutionMatrix = dynamicSolveMatrixRightDown(
    inpMatrix,
    (0, 0)
  )((x, currScore, y) => {
    val candidateNextFst = x._1 + y._1
    val candidateNextSnd = x._2 + y._2
    if (currScore == null) {
      (candidateNextFst, candidateNextSnd)
    } else {
      (
        smaller(candidateNextFst, currScore._1),
        smaller(candidateNextSnd, currScore._2)
      )
    }
  })

  val ending = solutionMatrix(lineCount - 1)(lineCount - 1)
  val smallest = smaller(ending._1, ending._2)

  val p = if (ending._1 < ending._2) {
    getPath(solutionMatrix, (lineCount - 1, lineCount - 1))(
      new Ordering[(Int, Int)] {
        def compare(x: (Int, Int), y: (Int, Int)): Int = x._1.compare(y._1)
      }
    )
  } else {
    getPath(solutionMatrix, (lineCount - 1, lineCount - 1))(
      new Ordering[(Int, Int)] {
        def compare(x: (Int, Int), y: (Int, Int)): Int = x._2.compare(y._2)
      }
    )
  }

  println(smallest)
  println(p)
}

import scala.annotation.tailrec
import scala.io.StdIn

object Main extends App {
  val n = StdIn.readInt()
  val m = Array.ofDim[Int](n, n)
  (0 until n).foreach{i =>
    m(i) = StdIn.readLine().split(" ").map(_.toInt)
  }

  val t2 = Array.ofDim[Short](n, n)
  val t5 = Array.ofDim[Short](n, n)
  val d2 = Array.ofDim[Char](n, n)
  val d5 = Array.ofDim[Char](n, n)

  val corner = m(0)(0)
  t2(0)(0) = factorN(corner, 2, 0)
  t5(0)(0) = factorN(corner, 5, 0)
  d2(0)(0) = ' '
  d5(0)(0) = ' '

  (1 until n).foreach{i =>
    t2(i)(0) = (factorN(m(i)(0), 2, 0) + t2(i-1)(0)).toShort
    t5(i)(0) = (factorN(m(i)(0), 5, 0) + t5(i-1)(0)).toShort
    d2(i)(0) = 'D'
    d5(i)(0) = 'D'

    t2(0)(i) = (factorN(m(0)(i), 2, 0) + t2(0)(i-1)).toShort
    t5(0)(i) = (factorN(m(0)(i), 5, 0) + t5(0)(i-1)).toShort
    d2(0)(i) = 'R'
    d5(0)(i) = 'R'
  }

  @tailrec
  def factorN(x: Int, N: Int, m: Short): Short = {
    if(x == 0) m
    else {
      if (x % N == 0) factorN(x / N, N, (1 + m).toShort)
      else m
    }
  }

  (1 until n).foreach{x =>
    (1 until n).foreach{y =>
      val f2 = factorN(m(y)(x), 2, 0)
      val f5 = factorN(m(y)(x), 5, 0)

      if(t2(y-1)(x) < t2(y)(x-1)) {
        t2(y)(x) = (t2(y-1)(x) + f2).toShort
        d2(y)(x) = 'D'
      } else {
        t2(y)(x) = (t2(y)(x-1) + f2).toShort
        d2(y)(x) = 'R'
      }

      if(t5(y-1)(x) < t5(y)(x-1)) {
        t5(y)(x) = (t5(y-1)(x) + f5).toShort
        d5(y)(x) = 'D'
      } else {
        t5(y)(x) = (t5(y)(x-1) + f5).toShort
        d5(y)(x) = 'R'
      }
    }
  }

  var zx = -1
  var zy = -1
  (0 until n).foreach{x =>
    (0 until n).foreach{y =>
      if(m(y)(x) == 0) {
        zx = x
        zy = y
      }
    }
  }

  if(zx != -1) {
    println(0)
//    println("R" * zx + "D" * (n-1) + "R" * (n-1-zx))
  } else {
    val dir = new Array[Char](2*n - 2)
    @tailrec
    def buildDir(arr: Array[Array[Char]], x: Int, y: Int, n: Int): Unit = {
      val d = arr(y)(x)
      if(d == 'D') {
        dir(n) = 'D'
        buildDir(arr, x, y - 1, n - 1)
      } else if (d == 'R') {
        dir(n) = 'R'
        buildDir(arr, x - 1, y, n - 1)
      }
    }
    if(t2(n-1)(n-1) > t5(n-1)(n-1)) {
      println(t5(n-1)(n-1))
      buildDir(d5, n-1, n-1, 2*n-3)
      println(new String(dir))
    } else {
      println(t2(n-1)(n-1))
      buildDir(d2, n-1, n-1, 2*n-3)
      println(new String(dir))
    }
  }
}

import scala.io.StdIn

object Main extends App {
  val n = StdIn.readInt()
  val m = Array.ofDim[Int](n, n)
  (0 until n).foreach{i =>
    m(i) = StdIn.readLine().split(" ").map(_.toInt)
  }

  val table = Array.ofDim[(Int, Int, String)](n, n)
  val last = m(n-1)(n-1)
  if(last % 2 == 0) table(n-1)(n-1) = (1, 0, "")
  else if(last % 5 == 0) table(n-1)(n-1) = (0, 1, "")
  else table(n-1)(n-1) = (0, 0, "")

  def recursive(x: Int, y: Int): (Int, Int, String) = {
    val tv = table(x-1)(y-1)
    val cell = m(x-1)(y-1)
    val (t, f) =
      if(cell % 2 == 0) (1, 0)
      else if(cell % 5 == 0) (0, 1)
      else (0, 0)

    if(tv != null) tv else {
      (x, y) match {
        case _ if x == n =>
          val d = recursive(x, y + 1)
          val v = (d._1 + t, d._2 + f, "D" + d._3)
          table(x-1)(y-1) = v
          v
        case _ if y == n =>
          val r = recursive(x + 1, y)
          val v = (r._1 + t, r._2 + f, "R" + r._3)
          table(x-1)(y-1) = v
          v
        case _ =>
          val d = recursive(x, y + 1)
          val r = recursive(x + 1, y)

          val select = if(d._1 == 0 && d._2 == 0) (d, "D")
          else if (r._1 == 0 && r._2 == 0) (r, "R")
          else {
            val dt = (d._1 + t).min(d._2 + f)
            val rt = (r._1 + t).min(r._2 + f)
            val dr = (d._1 + t).max(d._2 + f)
            val rr = (r._1 + t).max(r._2 + f)
            if(dt > rt) {
              (r, "R")
            } else if(rt > dt ){
              (d, "D")
            } else if(dr > rr) {
              (r, "R")
            } else {
              (d, "D")
            }
          }

          val v = (select._1._1 + t, select._1._2 + f, select._2 + select._1._3)
          table(x-1)(y-1) = v
          v
      }
    }
  }

  val ret = recursive(1, 1)
  println(ret._1 min ret._2)
  println(ret._3)
}

import scala.annotation.tailrec
import scala.io.StdIn

object Main extends App {
  val n = StdIn.readInt()
  val m = Array.ofDim[Int](n, n)
  (0 until n).foreach{i =>
    m(i) = StdIn.readLine().split(" ").map(_.toInt)
  }

  val t2 = Array.ofDim[Short](n, n)
  val t5 = Array.ofDim[Short](n, n)
  val d2 = Array.ofDim[Char](n, n)
  val d5 = Array.ofDim[Char](n, n)

  val corner = m(0)(0)
  t2(0)(0) = factorN(corner, 2, 0)
  t5(0)(0) = factorN(corner, 5, 0)
  d2(0)(0) = ' '
  d5(0)(0) = ' '

  (1 until n).foreach{i =>
    t2(i)(0) = (factorN(m(i)(0), 2, 0) + t2(i-1)(0)).toShort
    t5(i)(0) = (factorN(m(i)(0), 5, 0) + t5(i-1)(0)).toShort
    d2(i)(0) = 'D'
    d5(i)(0) = 'D'

    t2(0)(i) = (factorN(m(0)(i), 2, 0) + t2(0)(i-1)).toShort
    t5(0)(i) = (factorN(m(0)(i), 5, 0) + t5(0)(i-1)).toShort
    d2(0)(i) = 'R'
    d5(0)(i) = 'R'
  }

  @tailrec
  def factorN(x: Int, N: Int, m: Short): Short = {
    if(x == 0) m
    else {
      if (x % N == 0) factorN(x / N, N, (1 + m).toShort)
      else m
    }
  }

  (1 until n).foreach{x =>
    (1 until n).foreach{y =>
      val f2 = factorN(m(y)(x), 2, 0)
      val f5 = factorN(m(y)(x), 5, 0)

      if(t2(y-1)(x) < t2(y)(x-1)) {
        t2(y)(x) = (t2(y-1)(x) + f2).toShort
        d2(y)(x) = 'D'
      } else {
        t2(y)(x) = (t2(y)(x-1) + f2).toShort
        d2(y)(x) = 'R'
      }

      if(t5(y-1)(x) < t5(y)(x-1)) {
        t5(y)(x) = (t5(y-1)(x) + f5).toShort
        d5(y)(x) = 'D'
      } else {
        t5(y)(x) = (t5(y)(x-1) + f5).toShort
        d5(y)(x) = 'R'
      }
    }
  }

  var zx = -1
  var zy = -1
  (0 until n).foreach{x =>
    (0 until n).foreach{y =>
      if(m(y)(x) == 0) {
        zx = x
        zy = y
      }
    }
  }

  if(zx != -1) {
    println(1)
    val dir = new Array[Char](2*n - 2)
    (0 until zx).foreach(i => dir(i) = 'R')
    (0 until (n-1)).foreach(i => dir(zx + i) = 'D')
    (0 until (n-1-zx)).foreach(i => dir(zx + n - 1 + i) = 'D')
    println(new String(dir))
  } else {
    val dir = new Array[Char](2*n - 2)
    @tailrec
    def buildDir(arr: Array[Array[Char]], x: Int, y: Int, n: Int): Unit = {
      val d = arr(y)(x)
      if(d == 'D') {
        dir(n) = 'D'
        buildDir(arr, x, y - 1, n - 1)
      } else if (d == 'R') {
        dir(n) = 'R'
        buildDir(arr, x - 1, y, n - 1)
      }
    }
    if(t2(n-1)(n-1) > t5(n-1)(n-1)) {
      println(t5(n-1)(n-1))
      buildDir(d5, n-1, n-1, 2*n-3)
      println(new String(dir))
    } else {
      println(t2(n-1)(n-1))
      buildDir(d2, n-1, n-1, 2*n-3)
      println(new String(dir))
    }
  }
}

import scala.io.StdIn

object Main extends App {
  val n = StdIn.readInt()
  val m = Array.ofDim[Int](n, n)
  (0 until n).foreach{i =>
    m(i) = StdIn.readLine().split(" ").map(_.toInt)
  }

  val table = Array.ofDim[(Int, Int, String, String)](n, n)

  val corner = m(0)(0)
  table(0)(0) = (factorN(corner, 2), factorN(corner, 5), "", "")
  (1 until n).foreach{i =>
    val (d2, d5, dd2, dd5) = table(i-1)(0)
    table(i)(0) = (factorN(m(i)(0), 2) + d2, factorN(m(i)(0), 5) + d5, dd2 + "D", dd5 + "D")
    val (r2, r5, rd2, rd5) = table(0)(i-1)
    table(0)(i) = (factorN(m(0)(i), 2) + r2, factorN(m(0)(i), 5) + r5, rd2 + "R", rd5 + "R")
  }

  def factorN(x: Int, N: Int): Int = {
    if(x % N == 0) factorN(x/N, N) + 1
    else 0
  }

  (1 until n).foreach{x =>
    (1 until n).foreach{y =>
      val f2 = factorN(m(y)(x), 2)
      val f5 = factorN(m(y)(x), 5)

      val dt = table(y-1)(x)
      val rt = table(y)(x-1)

      val r2 = if(dt._1 < rt._1) (dt._1 + f2, dt._3 + "D")
      else (rt._1 + f2, rt._3 + "R")

      val r5 = if(dt._2 < rt._2) (dt._2 + f5, dt._4 + "D")
      else (rt._2 + f5, rt._4 + "R")

      table(y)(x) = (r2._1, r5._1, r2._2, r5._2)
    }
  }

  var zx = -1
  var zy = -1
  (0 until n).foreach{x =>
    (0 until n).foreach{y =>
      if(m(y)(x) == 0) {
        zx = x
        zy = y
      }
      println(table(y)(x))
    }
  }

  if(zx != -1) {
    println(0)
    println("R" * zx + "D" * (n-1) + "R" * (n-1-zx))
  } else {
    val f = table(n-1)(n-1)
    if(f._1 > f._2) {
      println(f._2)
      println(f._4)
    } else {
      println(f._1)
      println(f._3)
    }
  }
}

import scala.annotation.tailrec
import scala.io.StdIn

object Main extends App {
  val n = StdIn.readInt()
  val m = Array.ofDim[Int](n, n)
  (0 until n).foreach{i =>
    m(i) = StdIn.readLine().split(" ").map(_.toInt)
  }

  val t2 = Array.ofDim[Short](n, n)
  val t5 = Array.ofDim[Short](n, n)
  val d2 = Array.ofDim[Char](n, n)
  val d5 = Array.ofDim[Char](n, n)

  val corner = m(0)(0)
  t2(0)(0) = factorN(corner, 2, 0)
  t5(0)(0) = factorN(corner, 5, 0)
  d2(0)(0) = ' '
  d5(0)(0) = ' '

  (1 until n).foreach{i =>
    t2(i)(0) = (factorN(m(i)(0), 2, 0) + t2(i-1)(0)).toShort
    t5(i)(0) = (factorN(m(i)(0), 5, 0) + t5(i-1)(0)).toShort
    d2(i)(0) = 'D'
    d5(i)(0) = 'D'

    t2(0)(i) = (factorN(m(0)(i), 2, 0) + t2(0)(i-1)).toShort
    t5(0)(i) = (factorN(m(0)(i), 5, 0) + t5(0)(i-1)).toShort
    d2(0)(i) = 'R'
    d5(0)(i) = 'R'
  }

  @tailrec
  def factorN(x: Int, N: Int, m: Short): Short = {
    if(x == 0) m
    else {
      if (x % N == 0) factorN(x / N, N, (1 + m).toShort)
      else m
    }
  }

  (1 until n).foreach{x =>
    (1 until n).foreach{y =>
      val f2 = factorN(m(y)(x), 2, 0)
      val f5 = factorN(m(y)(x), 5, 0)

      if(t2(y-1)(x) < t2(y)(x-1)) {
        t2(y)(x) = (t2(y-1)(x) + f2).toShort
        d2(y)(x) = 'D'
      } else {
        t2(y)(x) = (t2(y)(x-1) + f2).toShort
        d2(y)(x) = 'R'
      }

      if(t5(y-1)(x) < t5(y)(x-1)) {
        t5(y)(x) = (t5(y-1)(x) + f5).toShort
        d5(y)(x) = 'D'
      } else {
        t5(y)(x) = (t5(y)(x-1) + f5).toShort
        d5(y)(x) = 'R'
      }
    }
  }

  var zx = -1
  var zy = -1
  (0 until n).foreach{x =>
    (0 until n).foreach{y =>
      if(m(y)(x) == 0) {
        zx = x
        zy = y
      }
    }
  }

  if(zx != -1) {
    println(1)
    val dir = new Array[Char](2*n - 2)
    (0 until zx).foreach(i => dir(i) = 'R')
    (0 until (n-1)).foreach(i => dir(zx + i) = 'D')
    (0 until (n-1-zx)).foreach(i => dir(zx + n - 1 + i) = 'D')
    println(new String(dir))
  } else {
    val dir = new Array[Char](2*n - 2)
    @tailrec
    def buildDir(arr: Array[Array[Char]], x: Int, y: Int, n: Int): Unit = {
      val d = arr(y)(x)
      if(d == 'D') {
        dir(n) = 'D'
        buildDir(arr, x, y - 1, n - 1)
      } else if (d == 'R') {
        dir(n) = 'R'
        buildDir(arr, x - 1, y, n - 1)
      }
    }

    val (min, dirArr) = if(t2(n-1)(n-1) > t5(n-1)(n-1)){
      (t5(n-1)(n-1), d5)
    } else (t2(n-1)(n-1), d2)

    if(min != 0 && zx != -1) {
      println(1)
      val dir = new Array[Char](2*n - 2)
      (0 until zx).foreach(i => dir(i) = 'R')
      (0 until (n-1)).foreach(i => dir(zx + i) = 'D')
      (0 until (n-1-zx)).foreach(i => dir(zx + n - 1 + i) = 'D')
      println(new String(dir))
    } else {
      println(min)
      buildDir(dirArr, n-1, n-1, 2*n-3)
      println(new String(dir))
    }
  }
}