/**
 * @param input string[][]
 */
function Main(input) {
  const line0 = input[0].split(' ').map(Number);
  const H = line0[0];
  const W = line0[1];
  const ss = input.slice(1);

  const edges = [];

  function getMax(y, x) {
    const stepMap = createStepMap(y, x);

    var max = 0, step;
    for (var i = 0; i < edges.length; i++) {
      step = stepMap[edges[i][0]][edges[i][1]];
      if (step > max) {
        max = step;
      }
    }

    return max;
  }

  function createStepMap(y, x) {
    const stepMap = ss.map((ssi) => ssi.split(''));

    fillRoute(y, x, stepMap, 0);

    return stepMap;
  }

  function fillRoute(y, x, stepMap, step, fromDir) {
    const current = stepMap[y][x];
    if (current === '#' || current <= step) return;

    stepMap[y][x] = step;

    if (fromDir !== 1 && y > 0) {
      fillRoute(y - 1, x, stepMap, step + 1, 3);
    }
    if (fromDir !== 2 && x < W - 1) {
      fillRoute(y, x + 1, stepMap, step + 1, 4);
    }
    if (fromDir !== 3 && y < H - 1) {
      fillRoute(y + 1, x, stepMap, step + 1, 1);
    }
    if (fromDir !== 4 && x > 0) {
      fillRoute(y, x - 1, stepMap, step + 1, 2);
    }
  }

  function isEdge(y, x) {
    // 上下において端ではない
    if (0 < y && y < H - 1) {
      if (ss[y - 1][x] === '.' && ss[y + 1][x] === '.') {
        return false;
      }
    }
    if (0 < x && x < W - 1) {
      // 左右において端ではない
      if (ss[y][x - 1] === '.' && ss[y][x + 1] === '.') {
        return false;
      }
    }
    return true;
  }

  var answer = 0;

  var y, x, max;
  for (y = 0; y < H; y++) {
    for (x = 0; x < W; x++) {
      if (ss[y][x] === '#' || !isEdge(y, x)) continue;

      if (edges.length > 0) {
        max = getMax(y, x);

        if (max > answer) {
          answer = max;
        }
      }

      edges.push([y, x]);
    }
  }

  console.log(answer);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8").trim()
  .split('\n')
  // .map((v) => v.split(' '))
);
