import java.io.{BufferedReader, InputStreamReader}

import scala.collection.mutable.ListBuffer

object Main {
  def main(args: Array[String]): Unit = {
    val in = new BufferedReader(new InputStreamReader(System.in))
    val Array(h, w) = in.readLine().split("\\s+").map(_.toInt)

    val maze = (1 to h).map { _ =>
      in.readLine().toCharArray
    }

    def max(x: Int, y: Int): Int = {
      val log = Array.ofDim[Int](h, w)

      def update(step: Int, startPoints: List[(Int, Int)]): Int = {
        if (startPoints.isEmpty) {
          step - 1
        } else {
          val nexts = new ListBuffer[(Int, Int)]
          for {
            (y, x) <- startPoints
            (dx, dy) <- List((-1, 0), (1, 0), (0, -1), (0, 1))
            if x + dx != w
            if x + dx != -1
            if y + dy != h
            if y + dy != -1
            if log(y + dy)(x + dx) == 0
            if maze(y + dy)(x + dx) == '.'
          } {
            log(y + dy)(x + dx) = step + 1
            nexts.append((y + dy, x + dx))
          }
          update(step + 1, nexts.toList)
        }
      }

      log(y)(x) = -1
      update(0, List((y, x)))
    }

    System.out.println(
      (for {
        x <- (0 until w)
        y <- (0 until h)
        if maze(y)(x) == '.'
      } yield {
        max(x, y)
      }).max
    )
  }
}
