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()
    (w, h, a)
  }


  def solve(w: Int, h: Int, a: IndexedSeq[String]): Int = {
    var open = mutable.Set.empty[(Int, Int)]
    var numBlack = 0
    var numOpe = 0

    for (y <- 0 until h; x <- 0 until w if a(y)(x) == '#') {
      numBlack += 1
      open.add((x, y))
    }
    val mutA = a.map(_.toArray).toArray



    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)}
    }

    while (true) {

      val next = mutable.Set.empty[(Int, Int)]
      for ((x, y) <- open) {
        mutA(y)(x) = '#'
        nextList(x,y).filter{case (x0, y0)=> mutA(y0)(x0) == '.'}.foreach{case (x0, y0) => next.add((x0, y0))}
      }
      if(next.isEmpty) return numOpe
      numOpe += 1

      open = next
    }

    -1
  }

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