Imports System.Collections.Generic

Public Class Program
  Shared Sub Main()
    Dim hw As Integer() = Cin.IntArr()
    Dim h As Integer = hw(0)
    Dim w As Integer = hw(1)
    ' 迷路を格納する2次元配列 maze ... 0: 道, -1: 壁 '
    Dim maze(0 To h - 1, 0 To w - 1) As Integer
    For i As Integer = 0 To h - 1
      Dim s As String = Cin.Str()
      For j As Integer = 0 To w - 1
        maze(i, j) = If(s(j) = ".", 0, -1)
      Next
    Next
    
    Dim ans As Integer = 0
    ' 1マスずつスタート地点 (i, j) を変えながら確認する '
    For i As Integer = 0 To h - 1
      For j As Integer = 0 To w - 1
        ' maze をコピーして、通過済みを記録する配列 visited を作成する '
        Dim visited(0 To maze.GetLength(0) - 1, 0 To maze.GetLength(1) - 1) As Integer
        Array.Copy(maze, visited, maze.Length())
        ' 移動回数 cnt '
        Dim cnt As Integer = 0
        ' スタート地点 (i, j) マスが道の場合、移動回数 cnt を取得する処理を行う '
        If visited(i, j) = 0 Then
          ' 現在地点から、次に行こうと思えば行けるマス全てを格納するリスト list(Of Tuple(Of Integer, Integer)) '
          Dim list As List(Of Tuple(Of Integer, Integer)) = New List(Of Tuple(Of Integer, Integer))
          ' 最初は探索スタート地点 (i, j) を list に格納する '
          list.Add(New Tuple(Of Integer, Integer)(i, j))
          ' 配列 visited にスタート地点 (i, j) は通過済みであることを示す 1 をセットする '
          visited(i, j) = 1
          cnt = -1
          ' 移動できるマスがなくなるまで続ける '
          While list.Count > 0
            cnt += 1
            ' 現在地点から、次に行こうと思えば行けるマス全てを探索して、 list にセットする '
            list = FillAround(visited, list)
          End While
        End If
        If ans < cnt Then ans = cnt
      Next
    Next
    Console.WriteLine(ans.ToString())
  End Sub

  Shared Function FillAround(ByRef maze As Integer(,), list As List(Of Tuple(Of Integer, Integer))) As List(Of Tuple(Of Integer, Integer))
    Dim nextList As List(Of Tuple(Of Integer, Integer)) = New List(Of Tuple(Of Integer, Integer))()
    For Each s As Tuple(Of Integer, Integer) In list
      nextList.AddRange(FillAround(maze, s))
    Next
    Return nextList
  End Function
  
  Shared Function FillAround(ByRef maze As Integer(,), item As Tuple(Of Integer, Integer)) As List(Of Tuple(Of Integer, Integer))
    Dim nextList As List(Of Tuple(Of Integer, Integer)) = New List(Of Tuple(Of Integer, Integer))()
    Dim x As Integer = item.Item1
    Dim y As Integer = item.Item2
    
    Fill(maze, nextList, x - 1, y)
    Fill(maze, nextList, x + 1, y)
    Fill(maze, nextList, x, y - 1)
    Fill(maze, nextList, x, y + 1)
    
    Return nextList
  End Function
  
  Shared Sub Fill(ByRef maze As Integer(,), ByRef list As List(Of Tuple(Of Integer, Integer)), x As Integer, y As Integer)
    If x < 0 OrElse x >= maze.GetLength(0) OrElse y < 0 OrElse y >= maze.GetLength(1) Then Return
    If maze(x, y) = 0 Then
      maze(x, y) = 1
      list.Add(New Tuple(Of Integer, Integer)(x, y))
    End If
  End Sub
End Class

Public Class Cin
  Public Shared Function Str() As String
    Return Console.ReadLine().Trim()
  End Function
  Public Shared Function Int() As Integer
    Return Integer.Parse(Str())
  End Function
  Public Shared Function Lng() As Long
    Return Long.Parse(Str())
  End Function
  Public Shared Function Dbl() As Double
    Return Double.Parse(Str())
  End Function
  Public Shared Function StrArr(Optional separator As String = " ") As String()
    Return Str().Split(separator)
  End Function
  Public Shared Function IntArr(Optional separator As String = " ") As Integer()
    Return Array.ConvertAll(Of String, Integer)(StrArr(separator), AddressOf Integer.Parse)
  End Function
  Public Shared Function LngArr(Optional separator As String = " ") As Long()
    Return Array.ConvertAll(Of String, Long)(StrArr(separator), AddressOf Long.Parse)
  End Function
  Public Shared Function DblArr(Optional separator As String = " ") As Double()
    Return Array.ConvertAll(Of String, Double)(StrArr(separator), AddressOf Double.Parse)
  End Function
End Class
