<?php

list($h, $w) = explode(' ', trim(fgets(STDIN)));

$s = [];
for ($i = 0; $i < $h; ++$i) {
    $s[] = str_split(trim(fgets(STDIN)));
}

$maze_master = new MazeMaster($h, $w, $s);
echo $maze_master->getLongestDistnace();

class MazeMaster
{
    private $height;
    private $width;
    private $maze;
    private $longest_distance = 0;

    public function __construct($height, $width, $maze)
    {
        $this->height = $height;
        $this->width = $width;

        for ($i = 0; $i < $this->height; ++$i) {
            for ($j = 0; $j < $this->width; ++$j) {
                $this->maze[$this->convertXY2Index($j, $i)] = $maze[$i][$j];
            }
        }
    }

    /**
     * 各点に対して最も遠い点までの距離をBFS（幅優先探索）で求める
     *
     * @return void
     */
    public function getLongestDistnace()
    {
        foreach ($this->maze as $index => $road_or_stop) {
            $distance = $this->getLongestDistnaceWithStartPoint($index);
            if ($distance > $this->longest_distance) {
                $this->longest_distance = $distance;
            }
        }

        return $this->longest_distance;
    }

    /**
     * 各点に対して最も遠い点までの距離をBFS（幅優先探索）で求める
     *
     * @return void
     */
    protected function getLongestDistnaceWithStartPoint($start_point_index)
    {
        $que = [$start_point_index];
        $distance = [$start_point_index => 0];
        $passed = [];

        while (($current_point = array_shift($que)) !== null) {
            $passed[$current_point] = $distance[$current_point];
            foreach ($this->getNextPoints($current_point) as $next_point) {
                if ($this->maze[$next_point] === '#') {
                    continue;
                }
                if (array_key_exists($next_point, $passed)) {
                    continue;
                }
                if (in_array($next_point, $que)) {
                    continue;
                }

                $que[] = $next_point;
                $distance[$next_point] = $distance[$current_point] + 1;
            }
        }

        return max($distance);
    }

    protected function getNextPoints($current_point)
    {
        $x = $current_point % $this->width;
        $y = ($current_point - $x) / $this->width;

        $next_points = [];
        if ($y > 0) {
            $next_points[] = $this->convertXY2Index($x, $y - 1);
        }
        if ($y < $this->height - 1) {
            $next_points[] = $this->convertXY2Index($x, $y + 1);
        }
        if ($x > 0) {
            $next_points[] = $this->convertXY2Index($x - 1, $y);
        }
        if ($x < $this->width - 1) {
            $next_points[] = $this->convertXY2Index($x + 1, $y);
        }

        return $next_points;
    }

    protected function convertXY2Index($x, $y)
    {
        return $this->width * $y + $x;
    }
}
