#![allow(unused_imports)]

use proconio::{input, fastout};
use proconio::marker::*;
use std::cmp::{min, max};
use smallvec::alloc::collections::VecDeque;

#[fastout]
fn main() {
    input! {
    h: usize,
    w: usize,
    s: [Chars; h]
    }
    let mut ans = 0;
    let dx = [0, -1, 0, 1];
    let dy = [1, 0, -1, 0];
    let mut q = VecDeque::new();
    for si in 0..h {
        for sj in 0..w {
            let mut map = vec![vec![0; w]; h];
            if s[si][sj] == '#' {continue}
            q.push_back((si, sj));
            while !q.is_empty() {
                let (x, y) = q.pop_front().unwrap();
                for i in 0..4 {
                    let (nx, ny) = (x as i64 + dx[i], y as i64 + dy[i]);
                    if nx >= 0 && nx < h as i64 && ny >= 0 && ny < w as i64 {
                        let (nx, ny) = (nx as usize, ny as usize);
                        if s[nx][ny] == '#' || map[nx][ny] > 0 {continue}
                        map[nx][ny] = map[x][y] + 1;
                        ans = max(map[nx][ny], ans);
                        q.push_back((nx, ny))
                    }
                }
            }
        }
    }
    println!("{}", ans);
}
