import scala.io.{StdIn => in}

object Main extends App {
  val Array(h, w) = in.readLine.split(" ").map(_.toInt)
  val n = h * w

  val arr = Iterator.continually(in.readLine)
    .take(h)
    .map(_.map(ch => if(ch == '#') 0 else n).toArray)
    .toArray

  def bfs(maze:Array[Array[Int]], sy:Int, sx:Int):Int = {
    var distMax = 0
    val dx = Array( 0, 1, 0,-1)
    val dy = Array( 1, 0,-1, 0)
    val que = collection.mutable.Queue.empty[(Int,Int)]
    que += Tuple2(sy,sx)
  
    while(que.nonEmpty) {
      val(y,x) = que.dequeue
  
      for(i <- 0 until 4) {
        val nx = x + dx(i)
        val ny = y + dy(i)
        if(0 <= ny && ny < h && 0 <= nx && nx < w && maze(ny)(nx) > maze(y)(x)) {
          maze(ny)(nx) = maze(y)(x) + 1
          distMax = distMax max maze(ny)(nx)
          que += Tuple2(ny, nx)
        }
      }
    }
    distMax
  }

  val ans = {
    for {
      i <- 0 until h
      j <- 0 until w
      if arr(i)(j) == 0
    } yield bfs(arr, i, j)
  }.min
  println(ans)
}