using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace abc151_d
{
  class Program
  {
    static void Main(string[] args)
    {
      var H = CIn.ReadInt();
      var W = CIn.ReadInt();
      var S = CIn.ReadCharMatrix(H, W);

      var ans = 0;

      for (var i = 0; i < H; i++)
      {
        for (var j = 0; j < W; j++)
        {
          if (S[i, j] == '.')
          {

            var searched = new bool[H, W];
            var queue = new Queue<SearchPath>();
            queue.Enqueue(new SearchPath(i, j, 0));

            while (queue.Count > 0)
            {
              var sp = queue.Dequeue();
              if (!searched[sp.Y, sp.X])
              {
                searched[sp.Y, sp.X] = true;
                ans = Math.Max(ans, sp.Depth);

                if (sp.Y > 0 && S[sp.Y - 1, sp.X] == '.' && !searched[sp.Y - 1, sp.X]) queue.Enqueue(new SearchPath(sp.Y - 1, sp.X, sp.Depth + 1));
                if (sp.Y < H - 1 && S[sp.Y + 1, sp.X] == '.' && !searched[sp.Y + 1, sp.X]) queue.Enqueue(new SearchPath(sp.Y + 1, sp.X, sp.Depth + 1));
                if (sp.X > 0 && S[sp.Y, sp.X - 1] == '.' && !searched[sp.Y, sp.X - 1]) queue.Enqueue(new SearchPath(sp.Y, sp.X - 1, sp.Depth + 1));
                if (sp.X < W - 1 && S[sp.Y, sp.X + 1] == '.' && !searched[sp.Y, sp.X + 1]) queue.Enqueue(new SearchPath(sp.Y, sp.X + 1, sp.Depth + 1));
              }
            }
          }
        }
      }

      Console.WriteLine(ans);
    }
  }

  class SearchPath
  {
    public int Y { get; }
    public int X { get; }
    public int Depth { get; }

    public SearchPath(int y, int x, int d)
    {
      Y = y;
      X = x;
      Depth = d;
    }
  }

  static class CIn
  {
    private static readonly Queue<string> fieldBuffer = new Queue<string>();

    public static string Read()
    {
      if (fieldBuffer.Count == 0)
      {
        foreach (var field in Console.ReadLine().Split())
        {
          fieldBuffer.Enqueue(field);
        }
      }
      return fieldBuffer.Dequeue();
    }

    public static int ReadInt() => int.Parse(Read());
    public static long ReadLong() => long.Parse(Read());
    public static double ReadDouble() => double.Parse(Read());

    public static string[] ReadStringArray(long n)
    {
      var array = new string[n];
      for (var i = 0L; i < n; i++)
      {
        array[i] = Read();
      }
      return array;
    }

    public static int[] ReadIntArray(long n)
    {
      var array = new int[n];
      for (var i = 0L; i < n; i++)
      {
        array[i] = ReadInt();
      }
      return array;
    }

    public static long[] ReadLongArray(long n)
    {
      var array = new long[n];
      for (var i = 0L; i < n; i++)
      {
        array[i] = ReadLong();
      }
      return array;
    }

    public static double[] ReadDoubleArray(long n)
    {
      var array = new double[n];
      for (var i = 0L; i < n; i++)
      {
        array[i] = ReadDouble();
      }
      return array;
    }

    public static char[,] ReadCharMatrix(long h, long w)
    {
      var array = new char[h, w];
      for (var i = 0L; i < h; i++)
      {
        var l = Console.ReadLine().ToCharArray();
        for (var j = 0L; j < w; j++)
        {
          array[i, j] = l[j];
        }
      }
      return array;
    }
  }
}


Measured memory_bytes: 15436