Main(myin());
function myin(){return require("fs").readFileSync("/dev/stdin", "utf8").trim();}
function myout(t){console.log(t);}//standard output
function myerr(t){console.error(t);}//standard error
//[no]param
//不明値:何もしない  1:数値へ変換  2:半角SPで分割  3:改行で分割  4:半角SPで分割し、数値配列へ
//5:改行で分割し、数値配列へ  6:1文字に分割  7:1文字に分割し、数値配列へ
//8:半角SPで結合　9:改行で結合　0:文字なしで結合
function myconv(i,no){switch(no){case 1:return parseInt(i);case 2:return i.split(" ");case 3:return i.split("\n");case 4:return i.split(" ").map((a)=>Number(a));case 5:return i.split("\n").map((a)=>Number(a));case 6:return i.split("");case 7:return i.split("").map((a)=>Number(a));case 8:return i.join(" ");case 9:return i.join("\n");case 0:return i.join("");default:return i;}}
function Main(input) {
  input = myconv(input,3);
  var H = myconv(input[0],4)[0];
  var W = myconv(input[0],4)[1];
  input.shift();
  var output = 0;
  for(var i = 0; i < H; i++){
    for(var j = 0; j < W; j++){
      var tmp = myconv(input[i],6);
      if(tmp[j] == "."){
         for(var k = 0; k < H; k++){
           for(var l = 0; l < W; l++){
             var tmp2 = myconv(input[k],6);
             if(i == k && j == l){
                continue;
             }
             if(tmp2[l] == "."){
                //ここでij地をスタート、kl地をゴールとしてtestに放り込む。
               //その時の距離をoutputに投げる
               //myout(test(i+1,j+1,k+1,l+1));
               output = Math.max(output,test(i,j,k,l));
             }
           }
         }
      }
    }
  }
  //test(1,1,3,4)
  myout(output);
  
  function test(sy, sx, gy, gx) {
    var count = 0;
    var r, c, sy, sx, gy, gx,q;
    r = H;
    c = W;
    var maze = input;
    var ds = [0, 1, 0, -1, 0];
    var queue = [[0, sy, sx]];
    var visited = new Array(r * c); // 
    for(var i=0;i<r*c;++i){
      visited[i] = false;
    }
		//console.error(r + " " + c);
  	//console.error(sy + " " + sx);
  //console.error(gy + " " + gx);
    while (queue) {
      //myerr(queue);
        //q = queue.shift();
      	q = queue[count];
      	count++;
        if (q[1] === gy && q[2] === gx) {
            //console.log("%d", q[0]);
            return q[0];
        }
        for (var i = 0; i < 4; ++i) {
            var ny = q[1] + ds[i];
            var nx = q[2] + ds[i + 1];
            if (visited[ny * c + nx] === false && maze[ny][nx] === ".") {
                queue.push([q[0] + 1, ny, nx]);
                visited[ny * c + nx] = true;
            }
        }
    }
}


}

