object Main {
  import java.io.{BufferedReader, InputStream, InputStreamReader}
  import java.util.StringTokenizer
  import scala.reflect.ClassTag

  def main(args: Array[String]): Unit = {
    val out = new java.io.PrintWriter(System.out)
    new Main(out, new InputReader(System.in)).solve()
    out.flush()
  }

  private val oj = System.getenv("ATCODER_DEBUG") == null
  def DEBUG(f: => Unit): Unit = {
    if (!oj){ f }
  }
  def debug(as: Array[Boolean]): Unit = if (!oj){ debug(as.map(x => if(x) "1" else "0").mkString) }
  def debug(as: Array[Int]): Unit = if (!oj){ debug(as.mkString(" ")) }
  def debug(as: Array[Long]): Unit =if (!oj){ debug(as.mkString(" ")) }
  def debugDim(m: Array[Array[Long]]): Unit = if (!oj){
    REP(m.length) { i =>
      debug(m(i))
    }
  }
  def debugDimFlip(m: Array[Array[Long]]): Unit = if (!oj){
    REP(m(0).length) { j =>
      REP(m.length) { i =>
        System.err.print(m(i)(j))
        System.err.print(" ")
      }
      System.err.println()
    }
  }
  def debug(s: => String): Unit = DEBUG {
    System.err.println(s)
  }
  def debugL(num: => Long): Unit = DEBUG {
    System.err.println(num)
  }

  class InputReader(val stream: InputStream) {
    private val reader = new BufferedReader(new InputStreamReader(stream), 32768)
    private var tokenizer: StringTokenizer = _

    def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = Integer.parseInt(next())
    def nextLong(): Long = java.lang.Long.parseLong(next())
    def nextChar(): Char = next().charAt(0)

    def ni(): Int = nextInt()
    def nl(): Long = nextLong()
    def nc(): Char = nextChar()
    def ns(): String = next()
    def ns(n: Int): Array[Char] = ns().toCharArray
    def na(n: Int, offset: Int = 0): Array[Int] = map(n)(_ => ni() + offset)
    def na2(n: Int, offset: Int = 0): (Array[Int], Array[Int]) = {
      val A1, A2 = Array.ofDim[Int](n)
      REP(n) { i =>
        A1(i) = ni() + offset
        A2(i) = ni() + offset
      }
      (A1, A2)
    }
    def nm(n: Int, m: Int): Array[Array[Int]] = {
      val A = Array.ofDim[Int](n, m)
      REP(n) { i =>
        REP(m) { j =>
          A(i)(j) = ni()
        }
      }
      A
    }
    def nal(n: Int): Array[Long] = map(n)(_ => nl())
    def nm_c(n: Int, m: Int): Array[Array[Char]] = map(n) (_ => ns(m))
  }

  def REP(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = offset
    val N = n + offset
    while(i < N) { f(i); i += 1 }
  }
  def REP_r(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = n - 1 + offset
    while(i >= offset) { f(i); i -= 1 }
  }
  def TO(from: Int, to: Int)(f: Int => Unit): Unit = {
    REP(to - from + 1, from) { i =>
      f(i)
    }
  }
  def map[@specialized A: ClassTag](n: Int, offset: Int = 0)(f: Int => A): Array[A] = {
    val res = Array.ofDim[A](n)
    REP(n)(i => res(i) = f(i + offset))
    res
  }

  def sumL(as: Array[Int]): Long = {
    var s = 0L
    REP(as.length)(i => s += as(i))
    s
  }
  def cumSum(as: Array[Int]): Array[Long] = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}

class Main(out: java.io.PrintWriter, sc: Main.InputReader) {
  import sc._
  import Main._
  import java.util.Arrays.sort

  import scala.collection.mutable
  import math.{abs, max, min}
  import mutable.ArrayBuffer

  // toIntとか+7とかするならvalにしろ
  @inline private def MOD = 1000000007

  case class Entry(v: Int, c: Int)
  type G = Array[ArrayBuffer[Entry]]

  def solve(): Unit = {
    val N, M, P = ni()
    val g1, revG = Array.fill[ArrayBuffer[Entry]](N)(ArrayBuffer())
    REP(M) { _ =>
      val a, b = ni() - 1
      val c = ni()
      revG(b) += Entry(a, c)
      g1(a) += Entry(b, c)
    }

    val (_, _, q1, _) = traceBfs(g1, 0)
    val (_, _, qRev, _) = traceBfs(revG, N - 1)
    val r1, rn = Array.ofDim[Boolean](N)
    r1(0) = true
    rn(N - 1) = true
    REP(N) { i =>
      val v = q1(i)
      r1(v) = true
    }
    REP(N) { i =>
      val v = qRev(i)
      rn(v) = true
    }

    val reahable = Array.ofDim[Boolean](N)
    REP(N) { i =>
      reahable(i) = r1(i) && rn(i)
    }

    debug(reahable)

    val g = Array.fill[ArrayBuffer[Entry]](N)(ArrayBuffer())
    REP(N) { v =>
      if (reahable(v)) {
        REP(revG(v).length) { i =>
          val e = revG(v)(i)
          g(e.v) += Entry(v, e.c)
        }
      }
    }

    if (topologicalSort(g) == null) {
      out.println(-1)
      return
    }

    val INF = -1e18.toLong
    val dp = Array.fill[Long](N)(INF)
    dp(0) = 0
    REP(N) { _ =>
      REP(N) { v =>
        REP(g(v).length) { j =>
          if (dp(v) != INF) {
            val u = g(v)(j)
            if (dp(u.v) < dp(v) + u.c - P) {
              dp(u.v) = dp(v) + u.c - P
            }
          }
        }
      }
    }
    out.println(max(0, dp(N - 1)))
  }

  /**
    * @return 閉路の場合はnull
    */
  def topologicalSort(g: G): Array[Int] = {
    val n = g.length
    val L = Array.ofDim[Int](n)
    var ptr = 0
    val S = Array.ofDim[Int](n)
    var last, cur = 0
    val deg = Array.ofDim[Int](n)
    REP(n) { i =>
      REP(g(i).length) { j =>
        deg(g(i)(j).v) += 1
      }
    }

    REP(n) { i =>
      if (deg(i) == 0) {
        S(last) = i
        last += 1
      }
    }

    while(cur < last) {
      val v = S(cur)
      cur += 1
      L(ptr) = v
      ptr += 1

      REP(g(v).length) { i =>
        val u = g(v)(i).v
        deg(u) -= 1
        if (deg(u) == 0) {
          S(last) = u
          last += 1
        }
      }
    }

    // 閉路チェック
    REP(n) { i =>
      if (deg(i) > 0) return null
    }
    L
  }

  /**
    * @return (depth, parent, queue, length)
    */
  def traceBfs(g: G, rt: Int = 0): (Array[Int], Array[Int], Array[Int], Int) = {
    val n = g.length
    val INF = 1e9.toInt + 10
    val q, p = Array.ofDim[Int](n)
    q(0) = rt
    p(rt) = -1
    val d = Array.fill[Int](n)(INF)
    d(rt) = 0
    var cur = 0
    var last = 1
    while (cur < last) {
      val v = q(cur)
      REP(g(v).length) { i =>
        val u = g(v)(i).v
        if (d(u) == INF) {
          d(u) = d(v) + 1
          p(u) = v
          q(last) = u
          last += 1
        }
      }
      cur += 1
    }
    (d, p, q, cur)
  }
}


object Main extends App {
  import scala.io.StdIn._
  val n = readInt()
  val h = readLine().split(" ").map(_.toInt)
  var c = 0
  for(i <- (0 until(n-1))){
    if(h(i) > h(i+1)){
      c += 1
    }
    if(h(i) > h(i+1) + 1){
      c += 1
    }
  }
  println(if(c > 1) "No" else "Yes")
}

Global OOD problem IDs are disjoint from train, validation, and in-distribution test problem IDs.

Score : 300 points

Problem Statement

There are N squares arranged in a row from left to right. The height of the i-th square from the left is H_i.

For each square, you will perform either of the following operations once:

Decrease the height of the square by 1.

Do nothing.

Determine if it is possible to perform the operations so that the heights of the squares are non-decreasing from left to right.

Constraints

All values in input are integers.

1 \leq N \leq 10^5

1 \leq H_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N
H_1 H_2 ... H_N

Output

If it is possible to perform the operations so that the heights of the squares are non-decreasing from left to right, print Yes; otherwise, print No.

Sample Input 1

5
1 2 1 1 3

Sample Output 1

Yes

You can achieve the objective by decreasing the height of only the second square from the left by 1.

Sample Input 2

4
1 3 2 1

Sample Output 2

No

Sample Input 3

5
1 2 3 4 5

Sample Output 3

Yes

Sample Input 4

1
1000000000

Sample Output 4

Yes

Submitted source-code file size, in bytes.

Execution CPU time reported by official Project CodeNet metadata, in milliseconds.

Peak memory usage reported by official Project CodeNet metadata, in kilobytes.


object Main extends App {
  @scala.annotation.tailrec
  def loop(i: Int, ints: Seq[Int]): String = ints match {
    case _ :: Seq() => "Yes"
    case x :: xs if x - 1 == i => loop(x - 1, xs)
    case x :: xs if x <= i => loop(x, xs)
    case _ => "No"
  }

  val sc = new java.util.Scanner(System.in)
  val i :: ints = Seq.fill(sc.nextInt())(sc.nextInt()).reverse
  println(loop(i, ints))
}


object Main extends App {
  @scala.annotation.tailrec
  def loop(i: Int, ints: Seq[Int]): String = ints match {
    case _ :: Seq() => "Yes"
    case x :: xs if x < i => loop(x, xs)
    case x :: xs if x - 1 == i => loop(x - 1, xs)
    case x :: xs if x == i => loop(x, xs)
    case _ => "No"
  }

  val sc = new java.util.Scanner(System.in)
  val i :: ints = Seq.fill(sc.nextInt())(sc.nextInt()).reverse
  println(loop(i, ints))
}


import java.util.Scanner

import IsLowerd._

import scala.annotation.tailrec

object Main extends App {

  val sc = new Scanner(System.in)

  val n = sc.nextInt
  val hs = Seq.fill(n)(sc.nextInt)

  @tailrec
  def loop(list: Seq[Int], pre: Int, canLower: IsLowerd = CanLower): Boolean = {
    if(list.isEmpty) true
    else {
      (pre - list.head, canLower) match {
        case (d, _) if d >= 2 => false
        case (1, HaveLowerd)  => false
        case (1, CanLower)    => loop(list.tail, list.head, HaveLowerd)
        case (_, state)       => loop(list.tail, list.head, state)
      }
    }
  }

  val res = if(loop(hs, hs.head)) "Yes" else "No"

  println(res)

}

sealed trait IsLowerd

object IsLowerd {
  case object CanLower extends IsLowerd
  case object HaveLowerd extends IsLowerd
}


import scala.io.StdIn._
object Main extends App {
  val n = readInt
  val hs = readLine.split(" ").map(_.toInt)

  def check(i: Int, pre: Int): Boolean = {
    if (i == n) true
    else {
      if (hs(i) < pre) false
      else if (hs(i) == pre) check(i + 1, pre)
      else check(i + 1, hs(i) - 1)
    }
  }

  println(if (check(0, 0)) "Yes" else "No")
}


object Main extends App {
  val sc = new java.util.Scanner(System.in)
  val stairCount: Int = sc.nextInt
  val stairs = List.fill(stairCount)(sc.nextInt).reverse

  def go(n: Int)(l: List[Int]): Boolean = l match {
    case Nil => true
    case _ if (l.exists(x => x > n + 1)) => false
    case _ => go(l.head)(l.tail)
  }

  if (go(stairs.head)(stairs.tail)) println("Yes") else println("No")
}


object Main extends App {

  var n = scala.io.StdIn.readLine.toInt
  val hArr = scala.io.StdIn.readLine.split(" ").map(_.toLong)

  def solve(): String = {
    for(i <- 0 until n-1) {
      val diff = hArr(i+1) - hArr(i)
      diff match {
        case x if x >= 1 => hArr(i+1) -= 1
        case 0 => hArr(i+1)
        case _ => return "No"
      }
    }
    "Yes"
  }
  println(solve)
}


object Main extends App {

  var n = scala.io.StdIn.readLine.toInt
  val hArr = scala.io.StdIn.readLine.split(" ").map(_.toLong)

  def solve(): String = {
    var max = 0L
    for(i <- 0 until n-1) {
      if(hArr(i+1) > hArr(i)) max = Math.max(max, hArr(i)-1)
      else if(hArr(i+1) == hArr(i)) max = Math.max(max, hArr(i))
      else return "No"
    }
    "Yes"
  }
  println(solve)
}


object Main extends App {

  var n = scala.io.StdIn.readLine.toInt
  val hArr = scala.io.StdIn.readLine.split(" ").map(_.toLong)

  def solve(): String = {
    var max = 0L
    for(i <- 0 until n-1) {
      max = Math.max(hArr(i), max)
      if(max-1 >= hArr(i)) return "No"
    }
    "Yes"
  }
  println(solve)
}


import scala.io.StdIn._

object Main extends App {
  val N = readInt()
  val stairs = readLine(" ").split(" ").map(_.toInt).toSeq

  val res = for (e <- 0 until N - 1) yield {
    if (stairs(e + 1) - stairs(e) >= -1 && stairs(e + 1) + 1 >= stairs(e)) true else false
  }

  if (res.contains(false)) println("No") else println("Yes")

}


object Main {
  def main(args:Array[String]) {
    val N = readLine().toInt
    var H = readLine().split(' ').map(_.toLong)

    var flag = true
    for(i <- (N - 1) until 0 by -1) if(H(i - 1) > H(i)) H(i - 1) -= 1
    for(i <- (N - 1) until 0 by -1) if(H(i - 1) > H(i)) flag = false
    if(flag) println("Yes")
    else println("No")
  }
}


object Main {
  def main(args:Array[String]) {
    val N = readLine().toInt
    var H = readLine().split(' ').map(_.toLong)

    var flag = true
    for(i <- (N - 1) until 0 by -1) if(H(i - 1) > H(i)) H(i) -= 1
    for(i <- (N - 1) until 0 by -1) if(H(i - 1) > H(i)) flag = false
    if(flag) println("Yes")
    else println("No")
  }
}


object Main {
  def main(args:Array[String]) {
    val N = readLine().toInt
    var H = readLine().split(' ').map(_.toLong)
    println(H.toList)

    var flag = true
    for(i <- (N - 1) until 0 by -1) if(H(i - 1) > H(i)) H(i) -= 1
    for(i <- (N - 1) until 0 by -1) if(H(i - 1) > H(i)) flag = false
    if(flag) println("Yes")
    else println("No")
  }
}


object Main {
  def main(args:Array[String]) {
    val N = readLine().toInt
    var H = readLine().split(' ').map(_.toLong)

    var flag = true
    for(i <- 0 until N - 1) if(H(i) > H(i + 1)) H(i) -= 1
    for(i <- 0 until N - 1) if(H(i) > H(i + 1)) flag = false
    if(flag) println("Yes")
    else println("No")
  }
}


object Main {
  def main(args:Array[String]) {
    val N = readLine().toInt
    var H = readLine().split(' ').map(_.toInt)

    var flag = true
    for(i <- 0 until N - 1) if(H(i) > H(i + 1)) H(i) -= 1
    for(i <- 0 until N - 1) if(H(i) > H(i + 1)) flag = false
    if(flag) println("Yes")
    else println("No")
  }
}


//import java.util.Scanner

import java.io._
import java.nio.file.Files._
import java.nio.file.Path
import java.util.StringTokenizer

import scala.collection.immutable._
import scala.io.Codec

/**
  * Scala implementation of a faster java.util.Scanner
  * See: http://codeforces.com/blog/entry/7018
  */

class Scanner(reader: LineNumberReader) extends Iterable[String] with AutoCloseable {
  def this(reader: BufferedReader) = this(new LineNumberReader(reader))

  def this(reader: Reader) = this(new BufferedReader(reader))

  def this(inputStream: InputStream)(implicit codec: Codec) = this(new InputStreamReader(inputStream, codec.charSet))

  def this(path: Path)(implicit codec: Codec) = this(newBufferedReader(path, codec.charSet))

  def this(file: File)(implicit codec: Codec) = this(file.toPath)(codec)

  def this(str: String) = this(new StringReader(str))

  override def iterator: Iterator[String] = for {
    line <- Iterator.continually(reader.readLine()).takeWhile(_ != null)
    tokenizer = new StringTokenizer(line)
    tokens <- Iterator.continually(tokenizer).takeWhile(_.hasMoreTokens)
  } yield tokens.nextToken()

  private[this] var current = iterator

  def hasNext: Boolean = current.hasNext

  @inline def next(): String = current.next()

  /**
    * This is different from Java's scanner.nextLine
    * The Java one is a misnomer since it actually travel to end of current line
    * This one actually does fetch the next line
    */
  def nextLine(): String = {
    val line = reader.readLine()
    current = iterator
    line
  }

  def lineNumber: Int = reader.getLineNumber

  def nextString(): String = next()

  def nextBoolean(): Boolean = next().toBoolean

  def nextByte(radix: Int = 10): Byte = java.lang.Byte.parseByte(next(), radix)

  def nextShort(radix: Int = 10): Short = java.lang.Short.parseShort(next(), radix)

  def nextInt(radix: Int = 10): Int = java.lang.Integer.parseInt(next(), radix)

  def nextLong(radix: Int = 10): Long = java.lang.Long.parseLong(next(), radix)

  def nextBigInt(radix: Int = 10): BigInt = BigInt(next(), radix)

  def nextFloat(): Float = next().toFloat

  def nextDouble(): Double = next().toDouble

  def nextBigDecimal(): BigDecimal = BigDecimal(next())

  override def close(): Unit = reader.close()
}

class IUnionFind(val size: Int) {

  private case class Node(var parent: Option[Int], var treeSize: Int)

  private val nodes = Array.fill[Node](size)(Node(None, treeSize = 1))

  def union(t1: Int, t2: Int): IUnionFind = {
    if (t1 == t2) return this

    val root1 = root(t1)
    val root2 = root(t2)
    if (root1 == root2) return this

    val node1 = nodes(root1)
    val node2 = nodes(root2)

    if (node1.treeSize < node2.treeSize) {
      node1.parent = Some(t2)
      node2.treeSize += node1.treeSize
    } else {
      node2.parent = Some(t1)
      node1.treeSize += node2.treeSize
    }
    this
  }

  def connected(t1: Int, t2: Int): Boolean = t1 == t2 || root(t1) == root(t2)

  def root(t: Int): Int = nodes(t).parent match {
    case None => t
    case Some(p) =>
      nodes(t).parent = Some(root(p))
      nodes(t).parent.get
  }
}

object Main {
  def solve(sc: => Scanner): Unit = {
    println(if (Array.fill(sc.nextInt())(sc.nextLong())
      .foldLeft(-1L)((a, b) => if (a > b) Long.MaxValue else Math.max(a, b - 1)) == Long.MaxValue)"No" else "Yes")
  }

  def getPermutation(begin: Long = 0): Stream[Long] =
    Stream.cons(begin, getPermutation(begin + 1))

  def calc(A: Array[Long]): Array[String] = {
    if (A.length == 0) Array.fill(0)("")
    else {
      val last = A.zipWithIndex.map(x => (x._1 - x._2, x._1)).takeWhile(x => x._1 == A.head).last._2
      if (last == A.head) "%d".format(A.head) +: calc(A.zipWithIndex.map(x => (x._1 - x._2, x._1)).dropWhile(x => x._1 == A.head).map(x => x._2))
      else "%d-%d".format(A.head, last) +: calc(A.zipWithIndex.map(x => (x._1 - x._2, x._1)).dropWhile(x => x._1 == A.head).map(x => x._2))
    }
  }

  var memo: Map[(Long, Long), Long] = Map[(Long, Long), Long]()

  def recursive(N: Long, now: Array[Long], limit: Array[Long], sc: => Scanner): Long = {
    if (N == 0) 0 else {
      val a, b, c = sc.nextInt()
      if (a == 1) now(b - 1) += c
      else now(b - 1) -= c
      if (now(b - 1) < 0 || limit(b - 1) < now(b - 1)) b
      else recursive(N - 1, now, limit, sc)
    }
  }

  def recursive2(X: Set[Long], Y: Stream[Long]): Long = if (X.contains(Y.head)) X.size else recursive2(X + Y.head, Y.tail)

  def check(i: Int, X: String): Long = {
    if (X == "") 0 else check(i, X.tail) * i + X.head.toString.toLong
  }

  def shift(n: Long): Long = {
    if (n == 0) 0
    else if (n == 1) 1
    else shift(n - 1) << 1
  }

  def unShift(n: Long): Long = {
    if (n == 0) 0
    else unShift(n >> 1) + 1
  }

  def gcd(i: Long, j: Long): Long = {
    if (i < j) gcd(j, i)
    else if (j == 0) i
    else gcd(j, i % j)
  }

  def primeFactors(i: Long): List[Long] = primeFactors_(i, 1).sorted

  def primeFactors_(i: Long, j: Long): List[Long] = {
    if (j * j > i) List.empty else if (i % j == 0) primeFactors_(i, j + 1) ++ List[Long](j, i / j) else primeFactors_(i, j + 1)
  }

  def main(args: Array[String]): Unit = {
    val sc: Scanner = new Scanner(System.in)
    solve(sc)
  }
}

object Util {
  def getPermutation(begin: Long = 0): Stream[Long] =
    Stream.cons(begin, getPermutation(begin + 1))

  def getPrimeList: Stream[Long] =
    getPrimeListRecursive(getPermutation(begin = 2))

  private def getPrimeListRecursive(A: Stream[Long]): Stream[Long] =
    Stream.cons(A.head, getPrimeListRecursive(A.tail.filter(_ % A.head != 0)))

  def fib(a: Long = 0, b: Long = 1, mod: Long = Long.MaxValue): Stream[Long] = a #:: fib(b % mod, (a + b) % mod, mod)
}

object ArabicRoman {

  type =?>[A, B] = PartialFunction[A, B]

  val codeTable = List(
    (1000, "M"), (900, "CM"), (500, "D"), (400, "CD"), (100, "C"),
    (90, "XC"), (50, "L"), (40, "XL"), (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I"))

  val arabicToRoman: Int =?> String = {
    case src if src >= 1 && src <= 3999 =>

      def convert(left: Int, cont: String = "", code: List[(Int, String)] = codeTable): String = {
        val (unitVal, unitChar) = code.head
        left - unitVal match {
          case n if n == 0 => cont + unitChar
          case n if n > 0 => convert(n, cont + unitChar, code)
          case _ => convert(left, cont, code.tail)
        }
      }

      convert(src)
  }

  val romanToArabic: String =?> Int = {
    case src if Option(src).exists { s => {
      s.nonEmpty && """[^MDCLXVI]""".r.findFirstMatchIn(s.toUpperCase).isEmpty
    }
    } =>

      def convert(left: String, cont: Int = 0, code: List[(Int, String)] = codeTable): Int = {
        val (unitVal, unitChar) = code.head
        left.splitAt(unitChar.length) match {
          case ("", _) => cont
          case (`unitChar`, tail) => convert(tail, cont + unitVal, code)
          case _ => convert(left, cont, code.tail)
        }
      }

      convert(src.toUpperCase())
  }
}


object Main extends App {
  val input = io.StdIn.readLine().split(' ').toVector.map(_.toInt)
  val getResult: Seq[Int] => Boolean = list => list.foldLeft((1, true)) { case (acc, current) =>
    val prevMax = acc._1
    val judge = current >= prevMax - 1
    (math.max(prevMax, current),  acc._2 && judge)
  }._2

  if (getResult(input)) println("Yes") else println("No")
}


object Main extends App {
  val input = io.StdIn.readLine().split(' ').toList.map(_.toInt)
  val result: Boolean = input.foldLeft((1, 1, true)) { case (acc, current) =>
    val prev2 = acc._1
    val prev1 = acc._2
    val reducedPrev = if (prev1 > current) prev1 - 1 else prev1
    val judge = prev2 <= reducedPrev && reducedPrev <= current
    (reducedPrev, current, acc._3 && judge)
  }._3
  if (result) println("Yes") else println("No")
}


object Main extends App {
  def isNoDown(hs: List[Int]): String = {
    @annotation.tailrec
    def f(l: List[(Int, Int)], before: Int): String = {
      l match {
        case h :: t =>
          val diff = h._2 - h._1
          if (diff < -1 || (before < 0 && diff < 0)) "No"
          //          if (before < 0 && diff < 0) "No"
          else f(t, diff)
        case _ => "Yes"
      }
    }

    //    def g(l: List[(Int)], before: Int, isDown: Boolean): String = {
    //      l match {
    //        case h :: t =>
    //          val diff = h - before
    //          if (diff < 0) {
    //            if (isDown) "No"
    //            else g(t, h, true)
    //          }
    //          else g(t, h, false)
    //        case _ => "Yes"
    //      }
    //    }

    f(hs.zip(hs.tail), 0)
    //    g(hs, 0, false)
  }
  val sc = new java.util.Scanner(System.in)
  val n = sc.nextInt
  val hs = List.fill(n)(sc.nextInt)

  println(isNoDown(hs))
}


object Main extends App {
  def isNoDown(hs: List[Int]): String = {
    @annotation.tailrec
    def f(l: List[(Int, Int)], before: Int): String = {
      l match {
        case h :: t =>
          val diff = h._2 - h._1
          if (before < 0 && diff < 0) "No"
          else f(t, diff)
        case _ => "Yes"
      }
    }

    def g(l: List[(Int)], before: Int, isDown: Boolean): String = {
      l match {
        case h :: t =>
          val diff = h - before
          if (diff < 0) {
            if (isDown) "No"
            else g(t, h, true)
          }
          else g(t, h, false)
        case _ => "Yes"
      }
    }

    //    f(hs.zip(hs.tail), 0)
    g(hs, 0, false)
  }
  val sc = new java.util.Scanner(System.in)
  val n = sc.nextInt
  val hs = List.fill(n)(sc.nextInt)

  println(isNoDown(hs))
}


object Main extends App {
  def isNoDown(hs: List[Int]): String = {
    @annotation.tailrec
    def f(l: List[(Int, Int)], before: Int): String = {
      l match {
        case h :: t =>
          val diff = h._2 - h._1
          if (before < 0 && diff < 0) "No"
          else f(t, diff)
        case _ => "Yes"
      }
    }

    val zip = hs.zip(hs.tail)
    f(zip, 0)
  }
  val sc = new java.util.Scanner(System.in)
  val n = sc.nextInt
  val hs = List.fill(n)(sc.nextInt)

  println(isNoDown(hs))
}


import scala.util.control.Breaks

object Main extends App {
  val n = scala.io.StdIn.readInt()
  val read = scala.io.StdIn.readLine()
  val array =  read.split(" ").map(_.toInt).toVector

  var result = "Yes"
  val b = new Breaks
  val lastIndex = n - 1

  var beforeTempH = 0
  var beforeDiff = 0
  var afterDiff = 0

  b.breakable{
    array.zipWithIndex.foreach { case(h, i) =>
      var tempH = h
      var minusflg = false
      if( i != 0) {
        beforeDiff = h - beforeTempH
        if (beforeDiff > 2 || beforeDiff < 0) {
          result = "No"
          b.break()
        } else if(beforeDiff == 2) {
          tempH = h - 1
          minusflg = true
        }
      }
      if(i != lastIndex) {
        afterDiff = array(i + 1) - tempH
        if(afterDiff > 2 || afterDiff < -1) {
          result = "No"
          b.break()
        } else if(afterDiff == -1) {
          if(minusflg || (i !=0 && beforeDiff < 1)) {
            result = "No"
            b.break()
          } else {
            tempH = h - 1
          }
        }
      }
      beforeTempH = tempH
    }
  }
  println(result)

}


object Main{

def main(args: Array[String]): Unit = {

    val arr1 = io.StdIn.readLine().split(' ')
    val n = arr1(0).toInt
    val arr2 = io.StdIn.readLine().split(' ')
    val h = arr2.map(_.toInt)

    var yes = true

    var base = -2
    h.indices.map{
      i =>
        if(i != n - 1){
        val res = h(i + 1) - h(i)

        if(res > 0) {
          base = -2
        }else if(res <= base){
          yes = false
        }else{
          base = base - res
        }

    }
    }

    if(n == 1) {
      yes = true
    }

    if(yes) println("Yes") else println("No")

}
}


object Main extends App {
  var a = readInt
  var b = readLine.split(" ").map(_.toInt)
  var sum = "Yes"
  for(i <- 0 until a - 1){
    if(b(i)<b(i+1) - 1) {
      sum = "No"
    }
  }
  print(sum)
}


import scala.io.StdIn

object Main {

  def main(args: Array[String]): Unit = {
    val n = StdIn.readLine().toInt
    val hs = StdIn.readLine().split(' ').toList.map(_.toInt)
    val ans = hs.foldLeft(Some(0): Option[Int]){ (acc, h) =>
      acc.flatMap{ pre =>
        if (h - 1 >= pre) Some(h - 1)
        else if (h >= pre) Some(h)
        else None
      }
    }.isDefined
    println(if(ans) "Yes" else "No")
  }

}


import scala.io.StdIn

object Main extends App {
  val n  = StdIn.readLine().toInt
  val a: Array[Int]  = StdIn.readLine().split(" ").map(_.toInt)

  def solve(a: Array[Int]): String = {

    a.foldLeft(0) { (acc, i) =>
      if (acc < i) i - 1 else if (acc == i) i else return "No"
    }
    "Yes"
  }

  println(solve(a))
}


object Main {

  def main(args: Array[String]): Unit = {
    val sc = new java.util.Scanner(System.in)

    val N = sc.nextInt()
    val H = Array.fill(N)(sc.nextInt())

    def solve(): Boolean = {
      var i = 0
      while (i < N - 1) {
        if (H(i+1) < H(i))
          if (H(i+1) + 1 >= H(i)) {
            H(i+1) += 1
          } else {
            return false
          }
        i += 1
      }
      true
    }

    println(if (solve()) "Yes" else "No")
  }

}


import java.io._
import java.util.StringTokenizer

import scala.reflect.ClassTag

class Remainder(fScanner: Main.FastScanner, out: java.io.PrintWriter) {

  import Main._
  import fScanner._

  def solve(): Unit = {
    val L = nl()
    val R = nl()

    val r1 = L % 2019
    val r2 = R % 2019

    if(R - L >= 2019) {
      out.println(0)
    } else {
      var l = L
      var mn = 2020L
      while (l < R) {
        val x = (l * (l+1)) % 2019
        mn = Math.min(x, mn)
        l = l + 1
      }
      out.println(mn)
    }
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    try {
      val (in, out) =
        if (isOnlineJudge) {
          (
            new FastScanner(new InputStreamReader(System.in)),
            new PrintWriter(System.out)
          )
        } else {
          (
            new FastScanner(new FileReader(new File("src/resource/problem.in"))),
            new PrintWriter(new File("src/resource/problem.out"))
          )
        }
      new Remainder(in, out).solve()
      out.flush()
      out.close()
    } catch {
      case e: IOException => e.printStackTrace()
    }
  }

  private[this] val isOnlineJudge = true

  class FastScanner(val streamReader: InputStreamReader) {
    private[this] val reader = new BufferedReader(streamReader, 32768)
    private[this] var tokenizer: StringTokenizer = _

    @inline private[this] final def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = Integer.parseInt(next())

    def nextLong(): Long = java.lang.Long.parseLong(next())

    def nextChar(): Char = next().charAt(0)

    def ni(): Int = nextInt()

    def nl(): Long = nextLong()

    def nc(): Char = nextChar()

    def ns(): String = next()

    def ns(n: Int): Array[Char] = ns().toCharArray

    def na(n: Int, offset: Int = 0): Array[Int] = map(n)(_ => ni() + offset)

    def na2(n: Int, offset: Int = 0): (Array[Int], Array[Int]) = {
      val A1, A2 = Array.ofDim[Int](n)
      REP(n) { i =>
        A1(i) = ni() + offset
        A2(i) = ni() + offset
      }
      (A1, A2)
    }

    def nm(n: Int, m: Int): Array[Array[Int]] = {
      val A = Array.ofDim[Int](n, m)
      REP(n) { i =>
        REP(m) { j =>
          A(i)(j) = ni()
        }
      }
      A
    }

    def nal(n: Int): Array[Long] = map(n)(_ => nl())

    def nm_c(n: Int, m: Int): Array[Array[Char]] = map(n)(_ => ns(m))
  }

  def REP(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = offset
    val N = n + offset
    while (i < N) {
      f(i);
      i += 1
    }
  }

  def REP_r(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = n - 1 + offset
    while (i >= offset) {
      f(i);
      i -= 1
    }
  }

  def TO(from: Int, to: Int)(f: Int => Unit): Unit = {
    REP(to - from + 1, from)(f)
  }

  def map[@specialized A: ClassTag](n: Int, offset: Int = 0)(f: Int => A): Array[A] = {
    val res = Array.ofDim[A](n)
    REP(n)(i => res(i) = f(i + offset))
    res
  }

  def sumL(as: Array[Int]): Long = {
    var s = 0L
    REP(as.length)(i => s += as(i))
    s
  }

  def cumSum(as: Array[Int]): Array[Long] = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}

Score : 300 points

Problem Statement

You are given two non-negative integers L and R.
We will choose two integers i and j such that L \leq i < j \leq R.
Find the minimum possible value of (i \times j) \mbox{ mod } 2019.

Constraints

All values in input are integers.

0 \leq L < R \leq 2 \times 10^9

Input

Input is given from Standard Input in the following format:

L R

Output

Print the minimum possible value of (i \times j) \mbox{ mod } 2019 when i and j are chosen under the given condition.

Sample Input 1

2020 2040

Sample Output 1

2

When (i, j) = (2020, 2021), (i \times j) \mbox{ mod } 2019 = 2.

Sample Input 2

4 5

Sample Output 2

20

We have only one choice: (i, j) = (4, 5).


import java.io._
import java.util.StringTokenizer

import scala.reflect.ClassTag

class Remainder(fScanner: Main.FastScanner, out: java.io.PrintWriter) {

  import Main._
  import fScanner._

  def solve(): Unit = {
    val L = nl()
    val R = nl()

    val r1 = L % 2019
    val r2 = R % 2019

    if(R - L >= 2019) {
      out.println(0)
    } else {
      val v1 = (r1 * (r1 + 1)) % 2019
      val v2 = (r2 * (r2 - 1) + 2019) % 2019
      out.println(Math.min(v1, v2))
    }
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    try {
      val (in, out) =
        if (isOnlineJudge) {
          (
            new FastScanner(new InputStreamReader(System.in)),
            new PrintWriter(System.out)
          )
        } else {
          (
            new FastScanner(new FileReader(new File("src/resource/problem.in"))),
            new PrintWriter(new File("src/resource/problem.out"))
          )
        }
      new Remainder(in, out).solve()
      out.flush()
      out.close()
    } catch {
      case e: IOException => e.printStackTrace()
    }
  }

  private[this] val isOnlineJudge = true

  class FastScanner(val streamReader: InputStreamReader) {
    private[this] val reader = new BufferedReader(streamReader, 32768)
    private[this] var tokenizer: StringTokenizer = _

    @inline private[this] final def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = Integer.parseInt(next())

    def nextLong(): Long = java.lang.Long.parseLong(next())

    def nextChar(): Char = next().charAt(0)

    def ni(): Int = nextInt()

    def nl(): Long = nextLong()

    def nc(): Char = nextChar()

    def ns(): String = next()

    def ns(n: Int): Array[Char] = ns().toCharArray

    def na(n: Int, offset: Int = 0): Array[Int] = map(n)(_ => ni() + offset)

    def na2(n: Int, offset: Int = 0): (Array[Int], Array[Int]) = {
      val A1, A2 = Array.ofDim[Int](n)
      REP(n) { i =>
        A1(i) = ni() + offset
        A2(i) = ni() + offset
      }
      (A1, A2)
    }

    def nm(n: Int, m: Int): Array[Array[Int]] = {
      val A = Array.ofDim[Int](n, m)
      REP(n) { i =>
        REP(m) { j =>
          A(i)(j) = ni()
        }
      }
      A
    }

    def nal(n: Int): Array[Long] = map(n)(_ => nl())

    def nm_c(n: Int, m: Int): Array[Array[Char]] = map(n)(_ => ns(m))
  }

  def REP(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = offset
    val N = n + offset
    while (i < N) {
      f(i);
      i += 1
    }
  }

  def REP_r(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = n - 1 + offset
    while (i >= offset) {
      f(i);
      i -= 1
    }
  }

  def TO(from: Int, to: Int)(f: Int => Unit): Unit = {
    REP(to - from + 1, from)(f)
  }

  def map[@specialized A: ClassTag](n: Int, offset: Int = 0)(f: Int => A): Array[A] = {
    val res = Array.ofDim[A](n)
    REP(n)(i => res(i) = f(i + offset))
    res
  }

  def sumL(as: Array[Int]): Long = {
    var s = 0L
    REP(as.length)(i => s += as(i))
    s
  }

  def cumSum(as: Array[Int]): Array[Long] = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}


object Main {
  def main(args: Array[String]): Unit = {
    solve
  }

  def solve(): Unit = {
    val sc = new java.util.Scanner(System.in)
    val l, r = sc.nextLong

    val lMod = l % 2019
    val rMod = r % 2019

    if (r - l + 1 >= 2019) {
      println(0)
    } else {
      if (lMod <= rMod) println(lMod * (lMod + 1))
      else {
        if (rMod == 0) println(0)
        else println(rMod * lMod)
      }

    }
  }
}


object Main {
  def main(args: Array[String]): Unit = {
    solve
  }

  def solve(): Unit = {
    val sc = new java.util.Scanner(System.in)
    val l, r = sc.nextLong

    val lMod = l % 2019
    val rMod = r % 2019

    if (r - l >= 2019) {
      println(0)
    } else {
      if (lMod <= rMod) println(lMod * (lMod + 1))
      else {
        if (rMod == 0) println(0)
        else println(rMod * lMod)
      }

    }
  }
}


import scala.io.StdIn._
object Main extends App {
  val Array(l, r) = readLine.split(" ").map(_.toLong)
  val is = l to Math.min(r - 1, l + 2019)
  val js = l + 1 to Math.min(r, l + 2020)

  println(is.foldLeft(Long.MaxValue){(min, i) =>
    js.foldLeft(min){(minmin, j) =>
      Math.min(minmin, j * j % 2019)
    }
  })
}


import scala.io.StdIn._
object Main extends App {
  val Array(l, r) = readLine.split(" ").map(_.toLong)
  var min = Long.MaxValue
  for {
    i <- l to Math.min(r - 1, l + 2019)
    j <- l + 1 to Math.min(r, l + 2020)
  } min = Math.min(min, i * j % 2019)
  println(min)
}


object Main extends App {
  val Array(l,r) = readLine.split(" ").map(_.toInt)
  val lm = l % 2019
  val rm = r - (l-lm)
  if(rm>=2019){
    println(0)
  }else{
    println((lm to rm).map{i =>
      (i+1 to rm).map{j => (i*j)%2019}.foldLeft(2019)(math.min(_,_))
    }.min)
  }
}


object Main{

def main(args: Array[String]): Unit = {
  val arr1 = io.StdIn.readLine().split(' ')
  val L = arr1(0).toInt
  val R = arr1(1).toInt

  val given = 2019 // = 1 x 3 x 673
  val pf1 = 3
  val pf2 = 673
  val res = R - L

  if(res >= pf2 - 1){
    println("0")
  }else{
    var min = 2018
    (L until R).foreach{
      i =>
      (i + 1 to R).foreach{
        j =>
      val k = (i % 2019) * (j % 2019)
      if(min > k) min = k
      }
    }
    println(min)
  }
}
}


object Main extends App {
  val sc = new java.util.Scanner(System.in)
  val l, r = sc.nextLong

  def remainderMinimization2019(min: Long, max: Long): Long = {
    val divisor = 2019
    val startBlock = min / divisor
    val endBlock = max / divisor
    val (i, j) =
      if (startBlock == endBlock) {
        (min, min + 1)
      } else {
        //startBlock < endBlock
        (min, endBlock * divisor)
      }
    ((i % divisor) * (j % divisor)) % divisor
  }

  println(remainderMinimization2019(l, r))
}


object Main extends App {
  val sc = new java.util.Scanner(System.in)
  val l, r = sc.nextLong

  def remainderMinimization2019(min: Long, max: Long): Long = {
    val divisor = 2019
    val startBlock = min / divisor
    val endBlock = max / divisor
    val (i, j) = if (startBlock == endBlock) {
      (min, min + 1)
    } else {
      //startBlock < endBlock
      (min, endBlock * divisor)
    }

    (i * j) % divisor
  }

  println(remainderMinimization2019(l, r))
}


object Main extends App {
  val sc = new java.util.Scanner(System.in)
  val l, r = sc.nextInt

  def remainderMinimization2019(min: Int, max: Int): Int = {
    val divisor = 2019
    val startBlock = min / divisor
    val endBlock = max / divisor
    val (i, j) = if (startBlock == endBlock) {
      (min, min + 1)
    } else {
      //startBlock < endBlock
      (min, endBlock * divisor)
    }

    (i * j) % divisor
  }

  println(remainderMinimization2019(l, r))
}


object Main extends App {
  val sc = new java.util.Scanner(System.in)
  val l :Int = sc.nextInt()
  val r :Int = sc.nextInt()

  val combinationList: List[Seq[Int]] = (l to r).combinations(2).toList
  val multiList = combinationList.map(x => (x(0) * x(1)) % 2019)
  println(multiList.min)
}


//import java.util.Scanner

import java.io._
import java.nio.file.Files._
import java.nio.file.Path
import java.util.StringTokenizer

import scala.collection.immutable._
import scala.io.Codec

/**
  * Scala implementation of a faster java.util.Scanner
  * See: http://codeforces.com/blog/entry/7018
  */

class Scanner(reader: LineNumberReader) extends Iterable[String] with AutoCloseable {
  def this(reader: BufferedReader) = this(new LineNumberReader(reader))

  def this(reader: Reader) = this(new BufferedReader(reader))

  def this(inputStream: InputStream)(implicit codec: Codec) = this(new InputStreamReader(inputStream, codec.charSet))

  def this(path: Path)(implicit codec: Codec) = this(newBufferedReader(path, codec.charSet))

  def this(file: File)(implicit codec: Codec) = this(file.toPath)(codec)

  def this(str: String) = this(new StringReader(str))

  override def iterator: Iterator[String] = for {
    line <- Iterator.continually(reader.readLine()).takeWhile(_ != null)
    tokenizer = new StringTokenizer(line)
    tokens <- Iterator.continually(tokenizer).takeWhile(_.hasMoreTokens)
  } yield tokens.nextToken()

  private[this] var current = iterator

  def hasNext: Boolean = current.hasNext

  @inline def next(): String = current.next()

  /**
    * This is different from Java's scanner.nextLine
    * The Java one is a misnomer since it actually travel to end of current line
    * This one actually does fetch the next line
    */
  def nextLine(): String = {
    val line = reader.readLine()
    current = iterator
    line
  }

  def lineNumber: Int = reader.getLineNumber

  def nextString(): String = next()

  def nextBoolean(): Boolean = next().toBoolean

  def nextByte(radix: Int = 10): Byte = java.lang.Byte.parseByte(next(), radix)

  def nextShort(radix: Int = 10): Short = java.lang.Short.parseShort(next(), radix)

  def nextInt(radix: Int = 10): Int = java.lang.Integer.parseInt(next(), radix)

  def nextLong(radix: Int = 10): Long = java.lang.Long.parseLong(next(), radix)

  def nextBigInt(radix: Int = 10): BigInt = BigInt(next(), radix)

  def nextFloat(): Float = next().toFloat

  def nextDouble(): Double = next().toDouble

  def nextBigDecimal(): BigDecimal = BigDecimal(next())

  override def close(): Unit = reader.close()
}

class IUnionFind(val size: Int) {

  private case class Node(var parent: Option[Int], var treeSize: Int)

  private val nodes = Array.fill[Node](size)(Node(None, treeSize = 1))

  def union(t1: Int, t2: Int): IUnionFind = {
    if (t1 == t2) return this

    val root1 = root(t1)
    val root2 = root(t2)
    if (root1 == root2) return this

    val node1 = nodes(root1)
    val node2 = nodes(root2)

    if (node1.treeSize < node2.treeSize) {
      node1.parent = Some(t2)
      node2.treeSize += node1.treeSize
    } else {
      node2.parent = Some(t1)
      node1.treeSize += node2.treeSize
    }
    this
  }

  def connected(t1: Int, t2: Int): Boolean = t1 == t2 || root(t1) == root(t2)

  def root(t: Int): Int = nodes(t).parent match {
    case None => t
    case Some(p) =>
      nodes(t).parent = Some(root(p))
      nodes(t).parent.get
  }
}

object Main {
  def solve(sc: => Scanner): Unit = {
    val L, R = sc.nextLong()
    println(if (L + 2019 <= R) 0 else (L until R).map(i => (i + 1 to R).map(j => (i * j) % 2019).min).min)
  }

  def getPermutation(begin: Long = 0): Stream[Long] =
    Stream.cons(begin, getPermutation(begin + 1))

  def calc(S: Int, T: Int): Boolean = {
    1 <= S && S <= 12
  }

  var memo: Map[(Long, Long), Long] = Map[(Long, Long), Long]()

  def recursive(n: Long, k: Long): Long = {

    if (n == 1) k else recursive(n - 1, k) * k % 1000000007L
  }

  def recursive2(X: Set[Long], Y: Stream[Long]): Long = if (X.contains(Y.head)) X.size else recursive2(X + Y.head, Y.tail)

  def check(s: String): Boolean = {
    s.isEmpty ||
      s.startsWith("dream") && check(s.drop(5)) ||
      s.startsWith("dreamer") && check(s.drop(7)) ||
      s.startsWith("erase") && check(s.drop(5)) ||
      s.startsWith("eraser") && check(s.drop(6))
  }

  def shift(n: Long): Long = {
    if (n == 0) 0
    else if (n == 1) 1
    else shift(n - 1) << 1
  }

  def unShift(n: Long): Long = {
    if (n == 0) 0
    else unShift(n >> 1) + 1
  }

  def gcd(i: Long, j: Long): Long = {
    if (i < j) gcd(j, i)
    else if (j == 0) i
    else gcd(j, i % j)
  }

  def primeFactors(i: Long): List[Long] = primeFactors_(i, 1).sorted

  def primeFactors_(i: Long, j: Long): List[Long] = {
    if (j * j > i) List.empty else if (i % j == 0) primeFactors_(i, j + 1) ++ List[Long](j, i / j) else primeFactors_(i, j + 1)
  }

  def main(args: Array[String]): Unit = {
    val sc: Scanner = new Scanner(System.in)
    solve(sc)
  }
}

object Util {
  def getPermutation(begin: Long = 0): Stream[Long] =
    Stream.cons(begin, getPermutation(begin + 1))

  def getPrimeList: Stream[Long] =
    getPrimeListRecursive(getPermutation(begin = 2))

  private def getPrimeListRecursive(A: Stream[Long]): Stream[Long] =
    Stream.cons(A.head, getPrimeListRecursive(A.tail.filter(_ % A.head != 0)))

  def fib(a: Long = 0, b: Long = 1, mod: Long = Long.MaxValue): Stream[Long] = a #:: fib(b % mod, (a + b) % mod, mod)
}

object ArabicRoman {

  type =?>[A, B] = PartialFunction[A, B]

  val codeTable = List(
    (1000, "M"), (900, "CM"), (500, "D"), (400, "CD"), (100, "C"),
    (90, "XC"), (50, "L"), (40, "XL"), (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I"))

  val arabicToRoman: Int =?> String = {
    case src if src >= 1 && src <= 3999 =>

      def convert(left: Int, cont: String = "", code: List[(Int, String)] = codeTable): String = {
        val (unitVal, unitChar) = code.head
        left - unitVal match {
          case n if n == 0 => cont + unitChar
          case n if n > 0 => convert(n, cont + unitChar, code)
          case _ => convert(left, cont, code.tail)
        }
      }

      convert(src)
  }

  val romanToArabic: String =?> Int = {
    case src if Option(src).exists { s => {
      s.nonEmpty && """[^MDCLXVI]""".r.findFirstMatchIn(s.toUpperCase).isEmpty
    }
    } =>

      def convert(left: String, cont: Int = 0, code: List[(Int, String)] = codeTable): Int = {
        val (unitVal, unitChar) = code.head
        left.splitAt(unitChar.length) match {
          case ("", _) => cont
          case (`unitChar`, tail) => convert(tail, cont + unitVal, code)
          case _ => convert(left, cont, code.tail)
        }
      }

      convert(src.toUpperCase())
  }
}


import scala.io.{StdIn => in}

object Main extends App {
  val mod = 2019
  val Array(l, r) = in.readLine.split(" ").map(_.toLong)

  val res = for(i <- 1 until mod if l + i <= r) yield {
    (l % mod) * ((l+i) % mod) % mod
  }

  val ans = res.min
  println(ans)
}


import scala.io.{StdIn => in}

object Main extends App {
  val mod = 2019L
  val Array(l, r) = in.readLine.split(" ").map(_.toLong)

  var res = Int.MaxValue + 1L
  for{
    i <- 0L until mod
    if l + i < r
    j <- (i + 1L) until (i + 1L + mod)
    if l + j <= r
  } {
    val v = ((l+i) % mod) * ((l+j) % mod) % mod
    if(res > v) res = v
  }

  val ans = res
  println(ans)
}


object Main extends App {
  var a = readLine.split(" ").map(_.toInt)
  var sum = 2020L
    if(a(1)-a(0)<2019){
      for(i<-a(0) until a(1); j<-i+1 to a(1)) {
            sum = Math.min(sum,((i%2019) * (j%2019))%2019)
      }
    } else {
      sum = 0
    }
  print(sum)
}


object Main extends App {
  var a = readLine.split(" ").map(_.toInt)
  var sum = 2020L
    if(a(1)-a(0)<2019){
      for(i<-a(0) until a(1); j<-i+1 to a(1)) {
            sum = Math.min(sum,(i * j)%2019)
      }
    } else {
      sum = 0
    }
  print(sum)
}


object Main extends App {
  val Array(l, r) = scala.io.StdIn.readLine.split(" ").map(_.toLong)

  var min = 2020
  val rr = List(r, l + 4040).min
  (l until rr).foreach { i =>
    (l + 1 to rr).foreach { j =>
      val aa = (i * j) % 2019
      if (aa < min) {
        min = aa.toInt
      }
    }

  }
  println(min)
}


import scala.io.{StdIn => in}

object Main extends App {
  val mod = 2019L
  val Array(l, r) = in.readLine.split(" ").map(_.toLong)

  var res = Int.MaxValue + 1L
  for{
    i <- 0L until mod
    if l + i < r
    j <- (i + 1L) until (i + 1L + mod * 2)
    if l + j <= r
  } {
    val v = ((l+i) % mod) * ((l+j) % mod)
    if(res > v) res = v
  }

  val ans = res
  println(ans)
}


import scala.math._

// longでrangeの作り方

object Main extends App {

  val YES = "YES"
  val Yes = "Yes"
  val NO = "NO"
  val No = "No"
  ///////////////////////////////////////////

  val sc = new java.util.Scanner(System.in)
  val l, r = sc.nextLong
//  val list = List.fill(n, d)(sc.nextInt)

//  val sorted = (l to r).map(p => (p, p % 2019)).sortBy(_._2)
//  val ans = (sorted.head._1 * sorted(1)._1) % 2019

  val ans = (l to r).take(2019).combinations(2).foldLeft(2019L)((acc, f) => {
    val tmp = (f.head * f.last) % 2019
    if (tmp <= acc) tmp else acc
  })
  println(ans)

  ///////////////////////////////////////////

  def bigIterator(start: BigInt, end: BigInt, step: BigInt = 1) =
    Iterator.iterate(start)(_ + step).takeWhile(_ <= end)

  def lcm(a :Int, b :Int): Int =
    a / gcd(a, b) * b

  def lcm(a :Long, b :Long): Long =
    a / gcd(a, b) * b

  def gcd(a: Int, b: Int): Int =
    if (b == 0) a else gcd(b, a % b)

  def gcd(a: Long, b: Long): Long =
    if (b == 0) a else gcd(b, a % b)

  def setOrUpdated[A, B](a: Map[A, B], key: A, value: B, f: (B, B) => B) =
    a.get(key) match {
      case Some(v) => a.updated(key, f(value, v))
      case _ => a + (key -> value)
    }
}


object Main extends App {
  val Array(l, r) = scala.io.StdIn.readLine.split(" ").map(_.toInt)

  var min = 2020
  (l until r).foreach { i =>
    val end = List(r, i + 2020).min
    (l + 1 to end).foreach { j =>
      val aa = (i * j) % 2019
      if (aa < min) {
        min = aa
      }

    }

  }
  println(min)
}


object Main extends App {
  val read = scala.io.StdIn.readLine()
  val arrayIJ =  read.split(" ").map(_.toLong).toVector
  if(arrayIJ(1) - arrayIJ(0) >= 2019) {
    println(0)
  } else {
    val modList = (arrayIJ(0) to arrayIJ(1)).map(_ % 2019L).sorted
    println(modList(0) * modList(1))
  }
}


import scala.math._

// longでrangeの作り方

object Main extends App {

  val YES = "YES"
  val Yes = "Yes"
  val NO = "NO"
  val No = "No"
  ///////////////////////////////////////////

  val sc = new java.util.Scanner(System.in)
  val l, r = sc.nextLong
//  val list = List.fill(n, d)(sc.nextInt)

//  val sorted = (l to r).map(p => (p, p % 2019)).sortBy(_._2)
//  val ans = (sorted.head._1 * sorted(1)._1) % 2019

  val ans = (l to r).take(2019).combinations(2).map(f => (f, (f.head * f.last) % 2019)).minBy(_._2)._2
  println(ans)

  ///////////////////////////////////////////

  def bigIterator(start: BigInt, end: BigInt, step: BigInt = 1) =
    Iterator.iterate(start)(_ + step).takeWhile(_ <= end)

  def lcm(a :Int, b :Int): Int =
    a / gcd(a, b) * b

  def lcm(a :Long, b :Long): Long =
    a / gcd(a, b) * b

  def gcd(a: Int, b: Int): Int =
    if (b == 0) a else gcd(b, a % b)

  def gcd(a: Long, b: Long): Long =
    if (b == 0) a else gcd(b, a % b)

  def setOrUpdated[A, B](a: Map[A, B], key: A, value: B, f: (B, B) => B) =
    a.get(key) match {
      case Some(v) => a.updated(key, f(value, v))
      case _ => a + (key -> value)
    }
}


object Main extends App {

  var a = readLine.split(" ").map(_.toInt)
  def b(c:Long,d:Long,e:Long,f:Long):Long = {
    if(d-c>2019){
      return 0
    }
    if(c+1>d) {
      return f
    } else {
      var g=if((c*(c+1))%2019<f)(c*(c+1))%2019 else f
      b(c+1,d,c*d%2019,g)
    }
  }
  print(b(a(0),a(1),2020,2020))
}


object Main extends App {

  val arr: Array[Int] = scala.io.StdIn.readLine().split(" ").map(_.toInt)
  val l = arr(0)
  val r = arr(1)

  val list = for {
    i <- l to r
    j <- l to r
  } yield if(i < j || i != j) i * j else 0

  val list2 = list.toSet.filter(_ != 0)

  val ans = list2.map(v => v % 2019).min

  println(ans)

}


import scala.io.{StdIn => in}

object Main extends App {
  val mod = 2019L
  val Array(l, r) = in.readLine.split(" ").map(_.toLong)

  var res = Int.MaxValue + 1L
  for{
    i <- 0L until mod
    if l + i < r
    j <- (i + 1L) until (i + 1L + mod)
    if l + j <= r
  } {
    val v = ((l+i) % mod) * ((l+j) % mod)
    if(res > v) res = v
  }

  val ans = res
  println(ans)
}


object Main {
  def main(args: Array[String]): Unit = {
    val sc = new java.util.Scanner(System.in)
    val l, r = sc.nextInt
    sc.close

    val j = 2019 < r match {
      case true => 2020
      case _    => r
    }
    val i = 2019 < l match {
      case true => j + 1
      case _ => {
        if (j > 2019) 2019
        else if (2019 < l && l < j - 1) l + 1
        else l
      }
    }

    val ij = i * j
    println(i, j)
    println((math.floor(ij % 2019)).toInt)
  }
}


object Main {
  def main(args: Array[String]): Unit = {
    val sc = new java.util.Scanner(System.in)
    val l, r = sc.nextInt
    sc.close

    val j = 2019 < r match {
      case true => 2020
      case _    => r
    }
    val i = 2019 < l match {
      case true => j + 1
      case _ => {
        if (j > 2019) l
        else if (2019 < l && l < j - 1) l + 1
        else l
      }
    }

    val ij = i * j
    println((math.floor(ij % 2019)).toInt)
  }
}


object Main {
  def main(args: Array[String]): Unit = {
    val sc = new java.util.Scanner(System.in)
    val l, r = sc.nextInt
    sc.close

    val j = 2019 < r match {
      case true => 2020
      case _    => r
    }
    val i = 2019 < l match {
      case true => j + 1
      case _ => {
        if (j > 2019) l
        else if (l < j - 1) l + 1
        else l
      }
    }

    val ij = i * j
    println((math.floor(ij % 2019)).toInt)
  }
}


import scala.io.StdIn

object Main extends App {
  val Array(l, r)  = StdIn.readLine().split(" ").map(_.toInt)

  val lr = (l / 2019).floor
  val rr = (r / 2019).floor

  if (lr != rr) {
    println(0)
  } else {

    val lm = l % 2019
    val rm = r % 2019

    if (lm == 0 || rm == 0)
      println(0)
    else
      println((lm * (lm + 1)) % 2019)
  }
}


object Main {
  def main(args: Array[String]): Unit = {
    val sc = new java.util.Scanner(System.in)
    val l, r = sc.nextInt
    sc.close

    val j = 2019 < r match {
      case true => 2020
      case _    => r
    }
    val i = 2019 < l match {
      case true => j + 1
      case _ => {
        if (l < j - 1) l + 1
        else l
      }
    }

    val ij = i * j
    println((math.floor(ij % 2019)).toInt)
  }
}


import java.util.Scanner

import scala.annotation.tailrec
import scala.collection.mutable.ArrayBuffer
import scala.util.Random

object Main {
  def read() = {
    val sc = new Scanner(System.in)
    val l, r = sc.nextInt()
    (l, r)
  }

  def solve(l: Int, r: Int): Long = {
    val mod = 2019
    // 0~2018が必要条件
    val ml = l % mod
    val mr = r % mod
    // ml <= mr の場合: [ml, mr]の範囲
    // ml > mrの場合: [0, mr], [ml, 2018]

    if (mr < ml) return 0
    val dl = l / mod
    val dr = r / mod

    val range: IndexedSeq[Int] = ml to mr
    if (dl == dr) {
      (for (i <- range; j <- range; if i < j) yield {
        i * j % mod
      }).min
    } else {
      (for (i <- range; j <- range) yield {
        i * j % mod
      }).min
    }
  }

  def solve2(l: Int, r: Int): Long = {
    (for (i1 <- l until r; i2 <- l + 1 to r if i1 < i2) yield {
      i1 * i2 % 2019
    }).min
  }

  def solve3(l: Int, r: Int): Long = {
    val mod = 2019
    // 0~2018が必要条件
    val ml = l % mod
    val mr = r % mod
    // ml <= mr の場合: [ml, mr]の範囲
    // ml > mrの場合: [0, mr], [ml, 2018]

    val dl = l / mod
    val dr = r / mod
    if (dl < dr) return 0

    val range: IndexedSeq[Int] = ml to mr
    (for (i <- range; j <- range; if i < j) yield {
      i * j % mod
    }).min
  }

def readRand () = {
  val l = 1000
  val r = Random.nextInt (4000) + l + 1
  (l, r)
}

  def test (): Unit = {
  val (l, r) = readRand ()
  println (l, r)
  println (solve (l, r) == solve2 (l, r) )
}

  def main (args: Array[String] ): Unit = {
  //test()
  val (l, r) = read ()
  println (solve3 (l, r) )
}
}


import scala.io.StdIn

object Main extends App {
  val Array(l, r)  = StdIn.readLine().split(" ").map(_.toInt)

  val lm = l % 2019
  val lr = (l / 2019).floor
  val rr = (r / 2019).floor

  if (r % 2019 < lm) {
    println(0)
  } else if (lr != rr) {
    println(0)
  } else {
    val rm = r % 2019
    if (lm == 0 || rm == 0)
      println(0)
    else
      println((lm to rm).combinations(2).map{ i => (i(0) * i(1)) % 2019 }.min)
  }
}


import scala.io.{StdIn => in}

object Main extends App {
  val mod = 2019
  val Array(l, r) = in.readLine.split(" ").map(_.toLong)

  var res = Long.MaxValue
  for{
    i <- 0 to 2019
    if l + i < r
    j <- i + 1 to i + 1 + 2019
    if l + j <= r
  } {
    val v = ((l+i) % mod ) * ((l+j) % mod)
    if(res > v) res = v
  }

  val ans = res
  println(ans)
}


import scala.io.StdIn

object Main extends App {
  val Array(l, r)  = StdIn.readLine().split(" ").map(_.toInt)

  val lm = l % 2019

  if (r % 2019 < lm) {
    println(0)
  } else {
    val rm = r % 2019
    if (lm == 0 || rm == 0)
      println(0)
    else
      println((lm to rm).combinations(2).map{ i => (i(0) * i(1)) % 2019 }.min)
  }
}


import java.util.Scanner

import scala.annotation.tailrec
import scala.collection.mutable.ArrayBuffer

object Main {
  def read() = {
    val sc = new Scanner(System.in)
    val l, r = sc.nextInt()
    (l, r)
  }

  def solve(l: Int, r: Int): Long = {
    val mod = 2019
    // 0~2018が必要条件
    val ml = l % mod
    val mr = r % mod
    // ml <= mr の場合: [ml, mr]の範囲
    // ml > mrの場合: [0, mr], [ml, 2018]

    if(mr < ml) return 0
    var dl = l / mod
    var dr = r / mod

    val range: IndexedSeq[Int] = ml to mr
    if(dl == dr) {
      (for (i <- range; j <- range; if i < j) yield {
        i * j % mod
      }).min
    }else{
      (for (i <- range; j <- range; if i <= j) yield {
        i * j % mod
      }).min
    }
  }

  def main(args: Array[String]): Unit = {
    val (l, r) = read()
    println(solve(l, r))
  }
}


import java.util.Scanner

object Main {

  def read() = {
    val sc = new Scanner(System.in)
    val s = sc.next()
    s
  }

  def solve(s: String): Long = {
    val ps = s.replace("BC", "K").replace("B", "X").replace("C", "X")
    val n = ps.length

    // sは使わない
    //i=>(i含めて)iより右で一番左のもの

    def makeRightX() = {
      val rightX = Array.fill(n)(-123)
      var idx = n - 1
      var currentRX = n
      while (idx >= 0) {
        if (ps(idx) == 'X') {
          currentRX = idx
        }
        rightX(idx) = currentRX

        idx -= 1
      }
      rightX
    }

    val rightX = makeRightX()

    val cumSumK = ps.map(c => if (c == 'K') 1 else 0).scanLeft(0)(_ + _)

    def countK(begin: Int, end: Int) = cumSumK(end) - cumSumK(begin)

    val hoge = ps.zipWithIndex.map {
      case (c, i) => if (c == 'A') countK(i, rightX(i)) else 0
    }
    hoge.sum
  }

  def main(args: Array[String]): Unit = {
    val s = read()
    println(solve(s))
  }
}

Score : 600 points

Problem Statement

You are given a string s consisting of A, B and C.

Snuke wants to perform the following operation on s as many times as possible:

Choose a contiguous substring of s that reads ABC and replace it with BCA.

Find the maximum possible number of operations.

Constraints

1 \leq |s| \leq 200000

Each character of s is A, B and C.

Input

Input is given from Standard Input in the following format:

s

Output

Find the maximum possible number of operations.

Sample Input 1

ABCABC

Sample Output 1

3

You can perform the operations three times as follows: ABCABC → BCAABC → BCABCA → BCBCAA. This is the maximum result.

Sample Input 2

C

Sample Output 2

0

Sample Input 3

ABCACCBABCBCAABCB

Sample Output 3

6


import scala.math.BigInt
import scala.io.StdIn

object Main {

  type BI = BigInt

  def main(args: Array[String]): Unit = {
    val s: List[Char] = StdIn.readLine().toList
    println(s"${solve(s, 0, 0)}")
  }

  def solve(s: List[Char], aAlive: BI, ans: BI): BI = {
    s match {
      case Nil => ans
      case 'A' :: t => solve(t, aAlive + 1, ans)
      case 'B' :: 'C' :: t => solve(t, aAlive, ans + aAlive)
      case _ :: t => solve(t, 0, ans)
    }
  }

}


import scala.math.BigInt
import scala.io.StdIn

object Main {

  type BI = BigInt
  val s: List[Char] = StdIn.readLine().toList
  println(s"${solve(s, 0, 0)}")

  def solve(s: List[Char], aAlive: BI, ans: BI): BI = {
    s match {
      case Nil => ans
      case 'A' :: t => solve(t, aAlive + 1, ans)
      case 'B' :: 'C' :: t => solve(t, aAlive, ans + aAlive)
      case _ :: t => solve(t, 0, ans)
    }
  }

}


import java.io._
import java.util.StringTokenizer
import scala.util.control.Breaks.{breakable,break}
import java.util.Scanner

object Main extends App {
  val in = new InputReader(System.in)
  val pw = new PrintWriter(System.out)

  //val sc = new Scanner(System.in)

  val s = in.next()
  //val s = sc.nextLine()

  var ans = 0L
  var cnt = 0L
  var i = 0
  while (i < s.length - 1) {
    val now = s(i)
    if (now == 'A') {
      cnt += 1
      i += 1
    }
    else if (now == 'C') {
      cnt = 0
      i += 1
    }
    else if (now == 'B') {
      if (s(i+1) == 'C') {
        ans += cnt
        i += 2
      }
      else {
        cnt = 0
        i += 1
      }
    }
  }
  println(ans)
}

class InputReader(stream: InputStream) {
  private val reader = new BufferedReader(new InputStreamReader(stream))
  private var tokenizer: StringTokenizer = new StringTokenizer(reader.readLine())
  def next(): String = {
    while (!tokenizer.hasMoreTokens()) {
      tokenizer = new StringTokenizer(reader.readLine())
    }
    tokenizer.nextToken()
  }
}


import java.io._
import java.util.StringTokenizer
import scala.util.control.Breaks.{breakable,break}
import java.util.Scanner

object Main extends App {
  val in = new InputReader(System.in)
  val pw = new PrintWriter(System.out)

  //val sc = new Scanner(System.in)

  val s = in.next()
  //val s = sc.nextLine()

  var ans = 0
  var cnt = 0
  var i = 0
  while (i < s.length - 1) {
    val now = s(i)
    if (now == 'A') {
      cnt += 1
      i += 1
    }
    else if (now == 'C') {
      cnt = 0
      i += 1
    }
    else if (now == 'B') {
      if (s(i+1) == 'C') {
        ans += cnt
        i += 2
      }
      else {
        cnt = 0
        i += 1
      }
    }
  }
  println(ans)
}

class InputReader(stream: InputStream) {
  private val reader = new BufferedReader(new InputStreamReader(stream))
  private var tokenizer: StringTokenizer = new StringTokenizer(reader.readLine())
  def next(): String = {
    while (!tokenizer.hasMoreTokens()) {
      tokenizer = new StringTokenizer(reader.readLine())
    }
    tokenizer.nextToken()
  }
}


object Main extends App {
  val stdin = new MyStdIn
  val Array(h, w) = stdin.readNums()
  val field = Array.fill(h)(stdin.readLine())
  val queue = new java.util.ArrayDeque[((Int, Int), Int)]()
  for (j <- 0 until h; i <- 0 until w; if field(j)(i) == '#') queue.offer(((i, j), 0))
  var times = 0
  while(!queue.isEmpty) {
    val ((x, y), count) = queue.poll()
    for {
      p <- Seq((x,y-1), (x,y+1), (x-1,y), (x+1,y))
      if p._1 >= 0 && p._1 < w && p._2 >= 0 && p._2 < h
      if field(p._2)(p._1) == '.'
    } {
      field(p._2)(p._1) = '#'
      queue.offer((p, count+1))
    }
    if (times < count) times = count
  }
  println(times)
}

class MyStdIn {
  val in: java.io.InputStream = System.in
  var head = 0
  var last = 0
  val bufSize = 1024
  val buf = new Array[Byte](bufSize)
  private def empty: Boolean = head >= last
  private def read(): Unit = {
    val len = in.read(buf)
    head = 0
    last = len - 1
  }
  def readLine(): Array[Byte] = {
    if (empty) read()
    val ret = collection.mutable.ArrayBuffer.empty[Byte]
    while (buf(head) != '\n' && head <= last) {
      ret += buf(head)
      if (head + 1 >= bufSize) read()
      else head += 1
    }
    head += 1
    ret.toArray
  }
  def readNums(): Array[Int] = {
    def isNumber(b: Byte): Boolean = '0' <= b && b <= '9'
    val bytes = readLine()
    val ret = collection.mutable.ArrayBuffer.empty[Int]
    var x = 0
    for (i <- bytes.indices)
      if (isNumber(buf(i))) {
        x = x * 10 + (buf(i) - '0')
        if (i+1 == bytes.length || !isNumber(buf(i + 1))) {
          ret += x
          x = 0
        }
      }
    ret.toArray
  }
}

Score : 300 points

Problem Statement

You are given a grid of squares with H horizontal rows and W vertical columns, where each square is painted white or black.
HW characters from A_{11} to A_{HW} represent the colors of the squares.
A_{ij} is # if the square at the i-th row from the top and the j-th column from the left is black, and A_{ij} is . if that square is white.

We will repeatedly perform the following operation until all the squares are black:

Every white square that shares a side with a black square, becomes black.

Find the number of operations that will be performed.
The initial grid has at least one black square.

Constraints

1 \leq H,W \leq 1000

A_{ij} is # or ..

The given grid has at least one black square.

Input

Input is given from Standard Input in the following format:

H W
A_{11}A_{12}...A_{1W}
:
A_{H1}A_{H2}...A_{HW}

Output

Print the number of operations that will be performed.

Sample Input 1

3 3
...
.#.
...

Sample Output 1

2

After one operation, all but the corners of the grid will be black. After one more operation, all the squares will be black.

Sample Input 2

6 6
..#..#
......
#..#..
......
.#....
....#.

Sample Output 2

3


import java.io.{BufferedReader, InputStreamReader}

object Main extends App {
  val in = new BufferedReader(new InputStreamReader(System.in))
  val Array(h, w) = in.readLine().split(' ').map(_.toInt)
  val field = Array.fill(h)(in.readLine().toCharArray)
  val queue = new java.util.ArrayDeque[((Int, Int), Int)]()
  for (j <- 0 until h; i <- 0 until w; if field(j)(i) == '#') queue.offer(((i, j), 0))
  var times = 0
  while(!queue.isEmpty) {
    val ((x, y), count) = queue.poll()
    for {
      p <- Seq((x,y-1), (x,y+1), (x-1,y), (x+1,y))
      if p._1 >= 0 && p._1 < w && p._2 >= 0 && p._2 < h
      if field(p._2)(p._1) == '.'
    } {
      field(p._2)(p._1) = '#'
      queue.offer((p, count+1))
    }
    if (times < count) times = count
  }
  println(times)
}


import scala.reflect.ClassTag

object Main extends App {
  val Array(h, w) = io.StdIn.readLine().split(' ').map(_.toInt)
  val field = Array.fill(h)(io.StdIn.readLine().toCharArray)
  val queue = new MyQueue[((Int, Int), Int)](h*w)
  for (j <- 0 until h; i <- 0 until w; if field(j)(i) == '#') queue.enqueue(((i, j), 0))
  var times = 0
  while(queue.nonEmpty) {
    val ((x, y), count) = queue.dequeue()
    for {
      p <- Seq((x,y-1), (x,y+1), (x-1,y), (x+1,y))
      if p._1 >= 0 && p._1 < w && p._2 >= 0 && p._2 < h
      if field(p._2)(p._1) == '.'
    } {
      field(p._2)(p._1) = '#'
      queue.enqueue((p, count+1))
    }
    if (times < count) times = count
  }
  println(times)
}

class MyQueue[T: ClassTag](size: Int) {
  var head = 0
  var tail = 0
  val data: Array[T] = new Array[T](size)
  def enqueue(e: T): Unit = {
    data(tail) = e
    tail += 1
  }
  def dequeue(): T = {
    val e = data(head)
    head += 1
    e
  }
  def isEmpty: Boolean = head >= tail
  def nonEmpty: Boolean = !isEmpty
}


import java.io.{BufferedReader, InputStreamReader}

object Main extends App {
  val in = new BufferedReader(new InputStreamReader(System.in))
  val Array(h, w) = in.readLine().split(' ').map(_.toInt)
  val field = Array.fill(h)(in.readLine().toCharArray)
  val queue = collection.mutable.Queue.empty[((Int, Int), Int)]
  for (j <- 0 until h; i <- 0 until w; if field(j)(i) == '#') queue.enqueue(((i, j), 0))
  var times = 0
  while(queue.nonEmpty) {
    val ((x, y), count) = queue.dequeue()
    for {
      p <- Seq((x,y-1), (x,y+1), (x-1,y), (x+1,y))
      if p._1 >= 0 && p._1 < w && p._2 >= 0 && p._2 < h
      if field(p._2)(p._1) == '.'
    } {
      field(p._2)(p._1) = '#'
      queue.enqueue((p, count+1))
    }
    times = count
  }
  println(times)
}


import scala.collection.mutable

object Main extends App {
  val in   = new java.util.Scanner(System.in)
  val h, w = in.nextInt
  val t    = List.fill(h)(in.next)

  // 幅優先探索を行う

  val queue   = mutable.Queue[(Int, Int)]()
  val visited = mutable.Map.empty[(Int, Int), Int]

  // 最初に与えられている黒マスをキューに追加する
  t.zipWithIndex.foreach(r => r._1.zipWithIndex.filter(_._1 == '#').foreach(v => queue += ((r._2, v._2))))

  // 黒マスは訪問済みの印を付ける
  queue.foreach(v => visited((v._1, v._2)) = 0)

  // 塗りつぶすまでの回数を数える
  while (queue.nonEmpty) {
    val v = queue.dequeue()
    val nextTo = Seq((v._1 - 1, v._2), (v._1, v._2 + 1), (v._1 + 1, v._2), (v._1, v._2 - 1))
      .filter(v => v._1 >= 0 && v._1 < h && v._2 >= 0 && v._2 < w)
      .filterNot(visited.contains)
    queue ++= nextTo
    nextTo.foreach(nv => visited((nv._1, nv._2)) = visited((v._1, v._2)) + 1)
  }
  println(visited.maxBy(_._2)._2)
}


import java.io.{BufferedReader, InputStreamReader}
import java.util
import java.util.Scanner

import scala.collection.mutable

object Main {

  def read() = {
    val sc = new Scanner(System.in)

    val h, w = sc.nextInt()
    val a = for (i <- 0 until h) yield sc.next()
    //val a = IndexedSeq.fill(h)(sc.next())
    //IndexedSeq.fill(w,h)(sc.nextInt())
    (w, h, a)
  }

  def read2() = {
    val input = io.Source.stdin.getLines()
    val (h, w) = {
      val strs = input.next().split(" ")
      (strs(0).toInt, strs(1).toInt)
    }
    val a = for (i <- 0 until h) yield input.next()
    (w, h, a)
  }

  def read3() = {
    val in = new BufferedReader(new InputStreamReader(System.in))
    val Array(h, w) = in.readLine().split(" ").map(_.toInt)
    val a = for (i <- 0 until h) yield in.readLine()
    (w, h, a)
  }

  def solve(w: Int, h: Int, a: IndexedSeq[String]): Int = {
    def isWithin(x: Int, y: Int): Boolean = 0 <= x && x < w && 0 <= y && y < h

    def bfs(): Int = {
      val open: java.util.Queue[(Int, Int)] = new java.util.ArrayDeque[(Int, Int)]()
      val dist = Array.fill(h, w)(h + w)
      // h + w: enough large
      val visited = Array.fill(h, w)(false)

      for (y <- 0 until h; x <- 0 until w if a(y)(x) == '#') {
        open.add((x, y))
        dist(y)(x) = 0
        visited(y)(x) = true
      }
      var maxDist = 0

      def update(x: Int, y: Int, xNext: Int, yNext: Int) = {
        if (isWithin(xNext, yNext) && !visited(yNext)(xNext)) {
          open.add((xNext, yNext))
          dist(yNext)(xNext) = dist(y)(x) + 1
          maxDist = math.max(maxDist, dist(yNext)(xNext))
          visited(yNext)(xNext) = true
        }
      }

      while (!open.isEmpty) {
        val (x, y) = open.remove()
        update(x, y, x + 1, y)
        update(x, y, x - 1, y)
        update(x, y, x, y + 1)
        update(x, y, x, y - 1)
      }
      maxDist
    }

    bfs()
  }

  //719ms
  def bench(): Unit = {
    val w = 1000
    val h = 1000
    val open = Array.fill[(Int, Int)](w * h)((0, 0))
    var openLen = 0
    val next = Array.fill[(Int, Int)](w * h)((0, 0))
    var nextLen = 0
  }

  //527ms
  def bench2(): Unit = {
    val w = 1000
    val h = 1000
    val openX = Array.fill[Int](w * h)(0)
    val openY = Array.fill[Int](w * h)(0)
    var openLen = 0
    val nextX = Array.fill[Int](w * h)(0)
    val nextY = Array.fill[Int](w * h)(0)
    var nextLen = 0
  }

  // 1524ms (solve実行時間)
  def makeTestCase() = {
    val w = 1000
    val h = 1000
    val a = (for (y <- 0 until h) yield {
      for (x <- 0 until w) yield {
        if (y == 500 && x == 500) '#' else '.'
      }
    }).map(_.mkString)
    (w, h, a)
  }

  // 1524ms (solve実行時間)
  def makeTestCase2() = {
    val w = 1000
    val h = 1000
    val a = (for (y <- 0 until h) yield {
      for (x <- 0 until w) yield {
        if (y == 0 && x == 0) '#' else '.'
      }
    }).map(_.mkString)
    (w, h, a)
  }

  def printExecutionTime(proc: => Unit): Unit = {
    val start = System.currentTimeMillis
    proc
    val duration = System.currentTimeMillis - start
    println(s"$duration ms")
  }

  def main(args: Array[String]): Unit = {
    val (w, h, a) = read()
    //val (w, h, a) = makeTestCase2()
    //printExecutionTime({
    println(solve(w, h, a))
    //bench2()
    //})
  }
}


import java.io.{BufferedReader, InputStreamReader}
import java.util
import java.util.Scanner

import scala.collection.mutable

object Main {

  def read() = {
    val sc = new Scanner(System.in)

    val h, w = sc.nextInt()
    val a = for (i <- 0 until h) yield sc.next()
    //val a = IndexedSeq.fill(h)(sc.next())
    //IndexedSeq.fill(w,h)(sc.nextInt())
    (w, h, a)
  }

  def read2() = {
    val input = io.Source.stdin.getLines()
    val (h, w) = {
      val strs = input.next().split(" ")
      (strs(0).toInt, strs(1).toInt)
    }
    val a = for (i <- 0 until h) yield input.next()
    (w, h, a)
  }

  def read3() = {
    val in = new BufferedReader(new InputStreamReader(System.in))
    val Array(h, w) = in.readLine().split(" ").map(_.toInt)
    val a = for (i <- 0 until h) yield in.readLine()
    (w, h, a)
  }

  def solve(w: Int, h: Int, a: IndexedSeq[String]): Int = {
    def isWithin(x: Int, y: Int): Boolean = 0 <= x && x < w && 0 <= y && y < h

    def bfs(): Int = {
      val open: java.util.Queue[(Int, Int)] = new java.util.ArrayDeque[(Int, Int)]()
      val dist = Array.fill(h, w)(h + w)
      // h + w: enough large
      val visited = Array.fill(h, w)(false)

      for (y <- 0 until h; x <- 0 until w if a(y)(x) == '#') {
        open.add((x, y))
        dist(y)(x) = 0
        visited(y)(x) = true
      }
      var maxDist = 0

      def update(x: Int, y: Int, xNext: Int, yNext: Int) = {
        if (isWithin(xNext, yNext) && !visited(yNext)(xNext)) {
          open.add((xNext, yNext))
          dist(yNext)(xNext) = dist(y)(x) + 1
          maxDist = math.max(maxDist, dist(yNext)(xNext))
          visited(yNext)(xNext) = true
        }
      }

      while (!open.isEmpty) {
        val (x, y) = open.remove()
        update(x, y, x + 1, y)
        update(x, y, x - 1, y)
        update(x, y, x, y + 1)
        update(x, y, x, y - 1)
      }
      maxDist
    }

    bfs()
  }

  //719ms
  def bench(): Unit = {
    val w = 1000
    val h = 1000
    val open = Array.fill[(Int, Int)](w * h)((0, 0))
    var openLen = 0
    val next = Array.fill[(Int, Int)](w * h)((0, 0))
    var nextLen = 0
  }

  //527ms
  def bench2(): Unit = {
    val w = 1000
    val h = 1000
    val openX = Array.fill[Int](w * h)(0)
    val openY = Array.fill[Int](w * h)(0)
    var openLen = 0
    val nextX = Array.fill[Int](w * h)(0)
    val nextY = Array.fill[Int](w * h)(0)
    var nextLen = 0
  }

  // 1524ms (solve実行時間)
  def makeTestCase() = {
    val w = 1000
    val h = 1000
    val a = (for (y <- 0 until h) yield {
      for (x <- 0 until w) yield {
        if (y == 500 && x == 500) '#' else '.'
      }
    }).map(_.mkString)
    (w, h, a)
  }

  // 1524ms (solve実行時間)
  def makeTestCase2() = {
    val w = 1000
    val h = 1000
    val a = (for (y <- 0 until h) yield {
      for (x <- 0 until w) yield {
        if (y == 0 && x == 0) '#' else '.'
      }
    }).map(_.mkString)
    (w, h, a)
  }

  def printExecutionTime(proc: => Unit): Unit = {
    val start = System.currentTimeMillis
    proc
    val duration = System.currentTimeMillis - start
    println(s"$duration ms")
  }

  def main(args: Array[String]): Unit = {
    val (w, h, a) = read2()
    //val (w, h, a) = makeTestCase2()
    //printExecutionTime({
    println(solve(w, h, a))
    //bench2()
    //})
  }
}


import java.io.{BufferedReader, InputStreamReader}
import java.util.Scanner

import scala.collection.mutable

object Main {

  def read() = {
    val sc = new Scanner(System.in)

    val h, w = sc.nextInt()
    val a = for (i <- 0 until h) yield sc.next()
    //val a = IndexedSeq.fill(h)(sc.next())
    //IndexedSeq.fill(w,h)(sc.nextInt())
    (w, h, a)
  }

  def read2() = {
    val input = io.Source.stdin.getLines()
    val (h, w) = {
      val strs = input.next().split(" ")
      (strs(0).toInt, strs(1).toInt)
    }
    val a = for (i <- 0 until h) yield input.next()
    (w, h, a)
  }

  def read3() = {
    val in = new BufferedReader(new InputStreamReader(System.in))
    val Array(h, w) = in.readLine().split(" ").map(_.toInt)
    val a = for (i <- 0 until h) yield in.readLine()
    (w, h, a)
  }

  def solve(w: Int, h: Int, a: IndexedSeq[String]): Int = {
    def isWithin(x: Int, y: Int): Boolean = 0 <= x && x < w && 0 <= y && y < h

    def bfs(): Int = {
      val openX = mutable.Queue.empty[Int]
      val openY = mutable.Queue.empty[Int]
      val dist = Array.fill(h, w)(h + w)
      // h + w: enough large
      val visited = Array.fill(h, w)(false)

      for (y <- 0 until h; x <- 0 until w if a(y)(x) == '#') {
        openX.enqueue(x)
        openY.enqueue(y)
        dist(y)(x) = 0
        visited(y)(x) = true
      }
      var maxDist = 0

      def update(x: Int, y: Int, xNext: Int, yNext: Int) = {
        if (isWithin(xNext, yNext) && !visited(yNext)(xNext)) {
          openX.enqueue(xNext)
          openY.enqueue(yNext)
          dist(yNext)(xNext) = dist(y)(x) + 1
          maxDist = math.max(maxDist, dist(yNext)(xNext))
          visited(yNext)(xNext) = true
        }
      }

      while (openX.nonEmpty) {
        val x = openX.dequeue()
        val y = openY.dequeue()
        update(x, y, x + 1, y)
        update(x, y, x - 1, y)
        update(x, y, x, y + 1)
        update(x, y, x, y - 1)
      }
      maxDist
    }

    bfs()
  }

  //719ms
  def bench(): Unit = {
    val w = 1000
    val h = 1000
    val open = Array.fill[(Int, Int)](w * h)((0, 0))
    var openLen = 0
    val next = Array.fill[(Int, Int)](w * h)((0, 0))
    var nextLen = 0
  }

  //527ms
  def bench2(): Unit = {
    val w = 1000
    val h = 1000
    val openX = Array.fill[Int](w * h)(0)
    val openY = Array.fill[Int](w * h)(0)
    var openLen = 0
    val nextX = Array.fill[Int](w * h)(0)
    val nextY = Array.fill[Int](w * h)(0)
    var nextLen = 0
  }

  // 1524ms (solve実行時間)
  def makeTestCase() = {
    val w = 1000
    val h = 1000
    val a = (for (y <- 0 until h) yield {
      for (x <- 0 until w) yield {
        if (y == 500 && x == 500) '#' else '.'
      }
    }).map(_.mkString)
    (w, h, a)
  }

  // 1524ms (solve実行時間)
  def makeTestCase2() = {
    val w = 1000
    val h = 1000
    val a = (for (y <- 0 until h) yield {
      for (x <- 0 until w) yield {
        if (y == 0 && x == 0) '#' else '.'
      }
    }).map(_.mkString)
    (w, h, a)
  }

  def printExecutionTime(proc: => Unit): Unit = {
    val start = System.currentTimeMillis
    proc
    val duration = System.currentTimeMillis - start
    println(s"$duration ms")
  }

  def main(args: Array[String]): Unit = {
    val (w, h, a) = read2()
    //val (w, h, a) = makeTestCase2()
    //printExecutionTime({
      println(solve(w, h, a))
      //bench2()
    //})
  }
}


import java.io.{BufferedReader, InputStreamReader}
import java.util.Scanner

import scala.collection.mutable

object Main {

  def read() = {
    val sc = new Scanner(System.in)

    val h, w = sc.nextInt()
    val a = for (i <- 0 until h) yield sc.next()
    //val a = IndexedSeq.fill(h)(sc.next())
    //IndexedSeq.fill(w,h)(sc.nextInt())
    (w, h, a)
  }

  def read2() = {
    val input = io.Source.stdin.getLines()
    val (h, w) = {
      val strs = input.next().split(" ")
      (strs(0).toInt, strs(1).toInt)
    }
    val a = for (i <- 0 until h) yield input.next()
    (w, h, a)
  }

  def read3() = {
    val in = new BufferedReader(new InputStreamReader(System.in))
    val Array(h, w) = in.readLine().split(" ").map(_.toInt)
    val a = for (i <- 0 until h) yield in.readLine()
    (w, h, a)
  }

  def solve(w: Int, h: Int, a: IndexedSeq[String]): Int = {
    def isWithin(x: Int, y: Int): Boolean = 0 <= x && x < w && 0 <= y && y < h

    def nextList(x: Int, y: Int): IndexedSeq[(Int, Int)] = {
      IndexedSeq((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)).filter { case (x0, y0) => isWithin(x0, y0) }
    }

    def printArray2D(arr: Array[Array[Char]]): Unit = {
      arr.foreach { row =>
        row.foreach(print)
        println()
      }
      println()
    }

    def bfs(): Int = {
      val open = mutable.Queue.empty[(Int, Int)]
      val dist = Array.fill(h, w)(h + w)
      // h + w: enough large
      val visited = Array.fill(h, w)(false)

      for (y <- 0 until h; x <- 0 until w if a(y)(x) == '#') {
        open.enqueue((x, y))
        dist(y)(x) = 0
        visited(y)(x) = true
      }
      var maxDist = 0

      def update(x: Int, y: Int, xNext: Int, yNext: Int) = {
        if (isWithin(xNext, yNext) && !visited(yNext)(xNext)) {
          open.enqueue((xNext, yNext))
          dist(yNext)(xNext) = dist(y)(x) + 1
          maxDist = math.max(maxDist, dist(yNext)(xNext))
          visited(yNext)(xNext) = true
        }
      }

      while (open.nonEmpty) {
        val (x, y) = open.dequeue()
        update(x, y, x + 1, y)
        update(x, y, x - 1, y)
        update(x, y, x, y + 1)
        update(x, y, x, y - 1)
      }
      maxDist
    }

    bfs()
  }

  //719ms
  def bench(): Unit = {
    val w = 1000
    val h = 1000
    val open = Array.fill[(Int, Int)](w * h)((0, 0))
    var openLen = 0
    val next = Array.fill[(Int, Int)](w * h)((0, 0))
    var nextLen = 0
  }

  //527ms
  def bench2(): Unit = {
    val w = 1000
    val h = 1000
    val openX = Array.fill[Int](w * h)(0)
    val openY = Array.fill[Int](w * h)(0)
    var openLen = 0
    val nextX = Array.fill[Int](w * h)(0)
    val nextY = Array.fill[Int](w * h)(0)
    var nextLen = 0
  }

  // 1524ms (solve実行時間)
  def makeTestCase() = {
    val w = 1000
    val h = 1000
    val a = (for (y <- 0 until h) yield {
      for (x <- 0 until w) yield {
        if (y == 500 && x == 500) '#' else '.'
      }
    }).map(_.mkString)
    (w, h, a)
  }

  // 1524ms (solve実行時間)
  def makeTestCase2() = {
    val w = 1000
    val h = 1000
    val a = (for (y <- 0 until h) yield {
      for (x <- 0 until w) yield {
        if (y == 0 && x == 0) '#' else '.'
      }
    }).map(_.mkString)
    (w, h, a)
  }

  def printExecutionTime(proc: => Unit): Unit = {
    val start = System.currentTimeMillis
    proc
    val duration = System.currentTimeMillis - start
    println(s"$duration ms")
  }

  def main(args: Array[String]): Unit = {
    val (w, h, a) = read2()
    //val (w, h, a) = makeTestCase2()
    //printExecutionTime({
      println(solve(w, h, a))
      //bench2()
    //})
  }
}


import java.io.{BufferedReader, InputStreamReader}
import java.util.Scanner

import scala.collection.mutable

object Main {

  def read() = {
    val sc = new Scanner(System.in)

    val h, w = sc.nextInt()
    val a = for (i <- 0 until h) yield sc.next()
    //val a = IndexedSeq.fill(h)(sc.next())
    //IndexedSeq.fill(w,h)(sc.nextInt())
    (w, h, a)
  }

  def read2() = {
    val input = io.Source.stdin.getLines()
    val (h, w) = {
      val strs = input.next().split(" ")
      (strs(0).toInt, strs(1).toInt)
    }
    val a = for (i <- 0 until h) yield input.next()
    (w, h, a)
  }

  def read3() = {
    val in = new BufferedReader(new InputStreamReader(System.in))
    val Array(h, w) = in.readLine().split(" ").map(_.toInt)
    val a = for (i <- 0 until h) yield in.readLine()
    (w, h, a)
  }

  def solve(w: Int, h: Int, a: IndexedSeq[String]): Int = {
    def isWithin(x: Int, y: Int): Boolean = 0 <= x && x < w && 0 <= y && y < h

    def nextList(x: Int, y: Int): IndexedSeq[(Int, Int)] = {
      IndexedSeq((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)).filter { case (x0, y0) => isWithin(x0, y0) }
    }

    def printArray2D(arr: Array[Array[Char]]): Unit = {
      arr.foreach { row =>
        row.foreach(print)
        println()
      }
      println()
    }

    def bfs(): Int = {
      val open = mutable.Queue.empty[(Int, Int)]
      val dist = Array.fill(h, w)(h + w)
      // h + w: enough large
      val visited = Array.fill(h, w)(false)

      for (y <- 0 until h; x <- 0 until w if a(y)(x) == '#') {
        open.enqueue((x, y))
        dist(y)(x) = 0
        visited(y)(x) = true
      }
      var maxDist = 0

      def update(x: Int, y: Int, xNext: Int, yNext: Int) = {
        if (isWithin(xNext, yNext) && !visited(yNext)(xNext)) {
          open.enqueue((xNext, yNext))
          dist(yNext)(xNext) = dist(y)(x) + 1
          maxDist = math.max(maxDist, dist(yNext)(xNext))
          visited(yNext)(xNext) = true
        }
      }

      while (open.nonEmpty) {
        val (x, y) = open.dequeue()
        var xNext = x + 1
        var yNext = y
        if (isWithin(xNext, yNext) && !visited(yNext)(xNext)) {
          open.enqueue((xNext, yNext))
          dist(yNext)(xNext) = dist(y)(x) + 1
          maxDist = math.max(maxDist, dist(yNext)(xNext))
          visited(yNext)(xNext) = true
        }

        xNext = x - 1
        yNext = y
        if (isWithin(xNext, yNext) && !visited(yNext)(xNext)) {
          open.enqueue((xNext, yNext))
          dist(yNext)(xNext) = dist(y)(x) + 1
          maxDist = math.max(maxDist, dist(yNext)(xNext))
          visited(yNext)(xNext) = true
        }

        xNext = x
        yNext = y + 1
        if (isWithin(xNext, yNext) && !visited(yNext)(xNext)) {
          open.enqueue((xNext, yNext))
          dist(yNext)(xNext) = dist(y)(x) + 1
          maxDist = math.max(maxDist, dist(yNext)(xNext))
          visited(yNext)(xNext) = true
        }

        xNext = x
        yNext = y - 1
        if (isWithin(xNext, yNext) && !visited(yNext)(xNext)) {
          open.enqueue((xNext, yNext))
          dist(yNext)(xNext) = dist(y)(x) + 1
          maxDist = math.max(maxDist, dist(yNext)(xNext))
          visited(yNext)(xNext) = true
        }

      }
      maxDist
    }

    bfs()
  }

  //719ms
  def bench(): Unit = {
    val w = 1000
    val h = 1000
    val open = Array.fill[(Int, Int)](w * h)((0, 0))
    var openLen = 0
    val next = Array.fill[(Int, Int)](w * h)((0, 0))
    var nextLen = 0
  }

  //527ms
  def bench2(): Unit = {
    val w = 1000
    val h = 1000
    val openX = Array.fill[Int](w * h)(0)
    val openY = Array.fill[Int](w * h)(0)
    var openLen = 0
    val nextX = Array.fill[Int](w * h)(0)
    val nextY = Array.fill[Int](w * h)(0)
    var nextLen = 0
  }

  // 1524ms (solve実行時間)
  def makeTestCase() = {
    val w = 1000
    val h = 1000
    val a = (for (y <- 0 until h) yield {
      for (x <- 0 until w) yield {
        if (y == 500 && x == 500) '#' else '.'
      }
    }).map(_.mkString)
    (w, h, a)
  }

  // 1524ms (solve実行時間)
  def makeTestCase2() = {
    val w = 1000
    val h = 1000
    val a = (for (y <- 0 until h) yield {
      for (x <- 0 until w) yield {
        if (y == 0 && x == 0) '#' else '.'
      }
    }).map(_.mkString)
    (w, h, a)
  }

  def printExecutionTime(proc: => Unit): Unit = {
    val start = System.currentTimeMillis
    proc
    val duration = System.currentTimeMillis - start
    println(s"$duration ms")
  }

  def main(args: Array[String]): Unit = {
    val (w, h, a) = read2()
    //val (w, h, a) = makeTestCase2()
    //printExecutionTime({
    println(solve(w, h, a))
    //bench2()
    //})
  }
}


object Main {
  def main(args: Array[String]): Unit = {
    val s = new Main()
    s.solve()
    s.out.flush()
  }
}

class Main {
  import java.io._
  import java.util.StringTokenizer
  import java.util.Arrays.sort

  import scala.collection.mutable
  import math.{abs, max, min}
  import mutable.ArrayBuffer
  import scala.reflect.ClassTag

  val MOD = 1000000007
  val out = new PrintWriter(System.out)

  def solve(): Unit = {
    val H, W = ni()
    val g = nm_c(H, W)

    val q = new Queue[Int](W * H)
    REP(H) { h =>
      REP(W) { w =>
        if (g(h)(w) == '#') {
          q += h * W + w
        }
      }
    }

    val D = Array(
      Array(-1, 0), Array(1, 0), Array(0, -1), Array(0, 1)
    )
    val V = Array.ofDim[Int](H, W)

    while(q.nonEmpty) {
      val p = q.dequeue()
      REP(4) { i =>
        val h = p / W
        val w = p % W
        val hh = h + D(i)(0)
        val ww = w + D(i)(1)
        if (0 <= hh && hh < H && 0 <= ww && ww < W && g(hh)(ww) == '.') {
          g(hh)(ww) = '#'
          V(hh)(ww) = V(h)(w) + 1
          q += hh * W + ww
        }
      }
    }

    val ans = V.map(_.max).max
    out.println(ans)
  }

  class Queue[A: ClassTag](n: Int) {
    private val as = Array.ofDim[A](n)
    var p = 0
    var cur = 0

    def +=(a: A): Unit = {
      as(p) = a
      p += 1
    }

    def dequeue(): A = {
      val a = as(cur)
      cur += 1
      a
    }

    def head: A = as(cur)

    def apply(i: Int): A = as(cur + i)

    def length: Int = p - cur
    def isEmpty: Boolean = length == 0
    def nonEmpty: Boolean = !isEmpty

    def mkString(delimiter: String = ""): String = as.slice(cur, cur + length).mkString(delimiter)
  }

  private val oj = System.getenv("ATCODER_DEBUG") == null

  def DEBUG(f: => Unit): Unit = {
    if (!oj){ f }
  }

  def debug(as: Array[Boolean]): Unit = DEBUG {
    debug(as.map(x => if(x) "1" else "0").mkString)
  }

  def debug(as: Array[Int]): Unit = DEBUG {
    debug(as.mkString(" "))
  }

  def debug(as: Array[Long]): Unit = DEBUG {
    debug(as.mkString(" "))
  }

  def debugDim(m: Array[Array[Long]]): Unit = DEBUG {
    REP(m.length) { i =>
      debug(m(i))
    }
  }

  def debugDimFlip(m: Array[Array[Long]]): Unit = DEBUG {
    REP(m(0).length) { j =>
      REP(m.length) { i =>
        System.err.print(m(i)(j))
        System.err.print(" ")
      }
      System.err.println()
    }
  }

  def debug(s: => String): Unit = DEBUG {
    System.err.println(s)
  }

  def debugL(num: => Long): Unit = DEBUG {
    System.err.println(num)
  }

  class InputReader(val stream: InputStream) {
    private val reader = new BufferedReader(new InputStreamReader(stream), 32768)
    private var tokenizer: StringTokenizer = _

    def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = next().toInt
    def nextLong(): Long = next().toLong
    def nextChar(): Char = next().charAt(0)
  }
  val sc = new InputReader(System.in)
  def ni(): Int = sc.nextInt()
  def nl(): Long = sc.nextLong()
  def nc(): Char = sc.nextChar()
  def ns(): String = sc.next()
  def ns(n: Int): Array[Char] = ns().toCharArray
  def na(n: Int, offset: Int = 0): Array[Int] = map(n)(_ => ni() + offset)
  def na2(n: Int, offset: Int = 0): (Array[Int], Array[Int]) = {
    val A1, A2 = Array.ofDim[Int](n)
    REP(n) { i =>
      A1(i) = ni() + offset
      A2(i) = ni() + offset
    }
    (A1, A2)
  }
  def nm(n: Int, m: Int): Array[Array[Int]] = {
    val A = Array.ofDim[Int](n, m)
    REP(n) { i =>
      REP(m) { j =>
        A(i)(j) = ni()
      }
    }
    A
  }
  def nal(n: Int): Array[Long] = map(n)(_ => nl())
  def nm_c(n: Int, m: Int): Array[Array[Char]] = map(n) (_ => ns(m))
  def REP(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = offset
    val N = n + offset
    while(i < N) { f(i); i += 1 }
  }
  def REP_r(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = n - 1 + offset
    while(i >= offset) { f(i); i -= 1 }
  }
  def TO(from: Int, to: Int)(f: Int => Unit): Unit = {
    REP(to - from + 1, from) { i =>
      f(i)
    }
  }

  def map[@specialized A: ClassTag](n: Int, offset: Int = 0)(f: Int => A): Array[A] = {
    val res = Array.ofDim[A](n)
    REP(n)(i => res(i) = f(i + offset))
    res
  }

  def sumL(as: Array[Int]): Long = {
    var s = 0L
    REP(as.length)(i => s += as(i))
    s
  }

  def cumSum(as: Array[Int]): Array[Long] = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}


object Main {
  def main(args: Array[String]): Unit = {
    val s = new Main()
    s.solve()
    s.out.flush()
  }
}

class Main {
  import java.io._
  import java.util.StringTokenizer
  import java.util.Arrays.sort

  import scala.collection.mutable
  import math.{abs, max, min}
  import mutable.ArrayBuffer
  import scala.reflect.ClassTag

  val MOD = 1000000007
  val out = new PrintWriter(System.out)

  def solve(): Unit = {
    val H, W = ni()
    val g = nm_c(H, W)

    case class P(h: Int, w: Int)
    val q = new Queue[P](W * H)
    REP(H) { h =>
      REP(W) { w =>
        if (g(h)(w) == '#') {
          q += P(h, w)
        }
      }
    }

    val D = Array(
      P(-1, 0), P(1, 0), P(0, -1), P(0, 1)
    )
    val V = Array.ofDim[Int](H, W)

    while(q.nonEmpty) {
      val p = q.dequeue()
      REP(4) { i =>
        val hh = D(i).h + p.h
        val ww = D(i).w + p.w
        if (0 <= hh && hh < H && 0 <= ww && ww < W && g(hh)(ww) == '.') {
          g(hh)(ww) = '#'
          V(hh)(ww) = V(p.h)(p.w) + 1
          q += P(hh, ww)
        }
      }
    }

    var ans = 0
    REP(H) { h =>
      ans = max(ans, V(h).max)
    }
    out.println(ans)
  }

  class Queue[A: ClassTag](n: Int) {
    private val as = Array.ofDim[A](n)
    var p = 0
    var cur = 0

    def +=(a: A): Unit = {
      as(p) = a
      p += 1
    }

    def dequeue(): A = {
      val a = as(cur)
      cur += 1
      a
    }

    def head: A = as(cur)

    def apply(i: Int): A = as(cur + i)

    def length: Int = p - cur
    def isEmpty: Boolean = length == 0
    def nonEmpty: Boolean = !isEmpty

    def mkString(delimiter: String = ""): String = as.slice(cur, cur + length).mkString(delimiter)
  }

  private val oj = System.getenv("ATCODER_DEBUG") == null

  def DEBUG(f: => Unit): Unit = {
    if (!oj){ f }
  }

  def debug(as: Array[Boolean]): Unit = DEBUG {
    debug(as.map(x => if(x) "1" else "0").mkString)
  }

  def debug(as: Array[Int]): Unit = DEBUG {
    debug(as.mkString(" "))
  }

  def debug(as: Array[Long]): Unit = DEBUG {
    debug(as.mkString(" "))
  }

  def debugDim(m: Array[Array[Long]]): Unit = DEBUG {
    REP(m.length) { i =>
      debug(m(i))
    }
  }

  def debugDimFlip(m: Array[Array[Long]]): Unit = DEBUG {
    REP(m(0).length) { j =>
      REP(m.length) { i =>
        System.err.print(m(i)(j))
        System.err.print(" ")
      }
      System.err.println()
    }
  }

  def debug(s: => String): Unit = DEBUG {
    System.err.println(s)
  }

  def debugL(num: => Long): Unit = DEBUG {
    System.err.println(num)
  }

  class InputReader(val stream: InputStream) {
    private val reader = new BufferedReader(new InputStreamReader(stream), 32768)
    private var tokenizer: StringTokenizer = _

    def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = next().toInt
    def nextLong(): Long = next().toLong
    def nextChar(): Char = next().charAt(0)
  }
  val sc = new InputReader(System.in)
  def ni(): Int = sc.nextInt()
  def nl(): Long = sc.nextLong()
  def nc(): Char = sc.nextChar()
  def ns(): String = sc.next()
  def ns(n: Int): Array[Char] = ns().toCharArray
  def na(n: Int, offset: Int = 0): Array[Int] = map(n)(_ => ni() + offset)
  def na2(n: Int, offset: Int = 0): (Array[Int], Array[Int]) = {
    val A1, A2 = Array.ofDim[Int](n)
    REP(n) { i =>
      A1(i) = ni() + offset
      A2(i) = ni() + offset
    }
    (A1, A2)
  }
  def nm(n: Int, m: Int): Array[Array[Int]] = {
    val A = Array.ofDim[Int](n, m)
    REP(n) { i =>
      REP(m) { j =>
        A(i)(j) = ni()
      }
    }
    A
  }
  def nal(n: Int): Array[Long] = map(n)(_ => nl())
  def nm_c(n: Int, m: Int): Array[Array[Char]] = map(n) (_ => ns(m))
  def REP(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = offset
    val N = n + offset
    while(i < N) { f(i); i += 1 }
  }
  def REP_r(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = n - 1 + offset
    while(i >= offset) { f(i); i -= 1 }
  }
  def TO(from: Int, to: Int)(f: Int => Unit): Unit = {
    REP(to - from + 1, from) { i =>
      f(i)
    }
  }

  def map[@specialized A: ClassTag](n: Int, offset: Int = 0)(f: Int => A): Array[A] = {
    val res = Array.ofDim[A](n)
    REP(n)(i => res(i) = f(i + offset))
    res
  }

  def sumL(as: Array[Int]): Long = {
    var s = 0L
    REP(as.length)(i => s += as(i))
    s
  }

  def cumSum(as: Array[Int]): Array[Long] = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}


object Main {
  def main(args: Array[String]): Unit = {
    val s = new Main()
    s.solve()
    s.out.flush()
  }
}

class Main {
  import java.io._
  import java.util.StringTokenizer
  import java.util.Arrays.sort

  import scala.collection.mutable
  import math.{abs, max, min}
  import mutable.ArrayBuffer
  import scala.reflect.ClassTag

  val MOD = 1000000007
  val out = new PrintWriter(System.out)

  def solve(): Unit = {
    val H, W = ni()
    val g = nm_c(H, W)

    case class P(h: Int, w: Int)
    val q = new Queue[P](W * H)
    REP(H) { h =>
      REP(W) { w =>
        if (g(h)(w) == '#') {
          q += P(h, w)
        }
      }
    }

    val D = Array(
      P(-1, 0), P(1, 0), P(0, -1), P(0, 1)
    )
    val V = Array.ofDim[Int](H, W)

    while(q.nonEmpty) {
      val p = q.dequeue()
      REP(4) { i =>
        val hh = D(i).h + p.h
        val ww = D(i).w + p.w
        if (0 <= hh && hh < H && 0 <= ww && ww < W && g(hh)(ww) == '.') {
          g(hh)(ww) = '#'
          V(hh)(ww) = V(p.h)(p.w) + 1
          q += P(hh, ww)
        }
      }
    }

    val ans = V.map(_.max).max
    out.println(ans)
  }

  class Queue[A: ClassTag](n: Int) {
    private val as = Array.ofDim[A](n)
    var p = 0
    var cur = 0

    def +=(a: A): Unit = {
      as(p) = a
      p += 1
    }

    def dequeue(): A = {
      val a = as(cur)
      cur += 1
      a
    }

    def head: A = as(cur)

    def apply(i: Int): A = as(cur + i)

    def length: Int = p - cur
    def isEmpty: Boolean = length == 0
    def nonEmpty: Boolean = !isEmpty

    def mkString(delimiter: String = ""): String = as.slice(cur, cur + length).mkString(delimiter)
  }

  private val oj = System.getenv("ATCODER_DEBUG") == null

  def DEBUG(f: => Unit): Unit = {
    if (!oj){ f }
  }

  def debug(as: Array[Boolean]): Unit = DEBUG {
    debug(as.map(x => if(x) "1" else "0").mkString)
  }

  def debug(as: Array[Int]): Unit = DEBUG {
    debug(as.mkString(" "))
  }

  def debug(as: Array[Long]): Unit = DEBUG {
    debug(as.mkString(" "))
  }

  def debugDim(m: Array[Array[Long]]): Unit = DEBUG {
    REP(m.length) { i =>
      debug(m(i))
    }
  }

  def debugDimFlip(m: Array[Array[Long]]): Unit = DEBUG {
    REP(m(0).length) { j =>
      REP(m.length) { i =>
        System.err.print(m(i)(j))
        System.err.print(" ")
      }
      System.err.println()
    }
  }

  def debug(s: => String): Unit = DEBUG {
    System.err.println(s)
  }

  def debugL(num: => Long): Unit = DEBUG {
    System.err.println(num)
  }

  class InputReader(val stream: InputStream) {
    private val reader = new BufferedReader(new InputStreamReader(stream), 32768)
    private var tokenizer: StringTokenizer = _

    def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = next().toInt
    def nextLong(): Long = next().toLong
    def nextChar(): Char = next().charAt(0)
  }
  val sc = new InputReader(System.in)
  def ni(): Int = sc.nextInt()
  def nl(): Long = sc.nextLong()
  def nc(): Char = sc.nextChar()
  def ns(): String = sc.next()
  def ns(n: Int): Array[Char] = ns().toCharArray
  def na(n: Int, offset: Int = 0): Array[Int] = map(n)(_ => ni() + offset)
  def na2(n: Int, offset: Int = 0): (Array[Int], Array[Int]) = {
    val A1, A2 = Array.ofDim[Int](n)
    REP(n) { i =>
      A1(i) = ni() + offset
      A2(i) = ni() + offset
    }
    (A1, A2)
  }
  def nm(n: Int, m: Int): Array[Array[Int]] = {
    val A = Array.ofDim[Int](n, m)
    REP(n) { i =>
      REP(m) { j =>
        A(i)(j) = ni()
      }
    }
    A
  }
  def nal(n: Int): Array[Long] = map(n)(_ => nl())
  def nm_c(n: Int, m: Int): Array[Array[Char]] = map(n) (_ => ns(m))
  def REP(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = offset
    val N = n + offset
    while(i < N) { f(i); i += 1 }
  }
  def REP_r(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = n - 1 + offset
    while(i >= offset) { f(i); i -= 1 }
  }
  def TO(from: Int, to: Int)(f: Int => Unit): Unit = {
    REP(to - from + 1, from) { i =>
      f(i)
    }
  }

  def map[@specialized A: ClassTag](n: Int, offset: Int = 0)(f: Int => A): Array[A] = {
    val res = Array.ofDim[A](n)
    REP(n)(i => res(i) = f(i + offset))
    res
  }

  def sumL(as: Array[Int]): Long = {
    var s = 0L
    REP(as.length)(i => s += as(i))
    s
  }

  def cumSum(as: Array[Int]): Array[Long] = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}