use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char) 
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn readc() -> char {
    let s: String = read();
    return s.chars().nth(0).unwrap();
}

fn read_vec<T: FromStr>(n: usize) -> Vec<T> {
    return (0..n).map(|_| read()).collect();
}

fn solve(map: Vec<Vec<char>>) -> usize {
    

    fn _solve(i: i32, j: i32, map: &Vec<Vec<char>>) -> usize {
        let v_vec: Vec<(i32, i32)> = vec![(1, 0), (-1, 0), (0, 1), (0, -1)];
        let mut next_pos: Vec<(i32, i32)> = Vec::new();

        let mut visited: Vec<Vec<bool>> = (0..map.len()).map(|_| (0..map[0].len()).map(|_| false).collect()).collect();
        visited[i as usize][j as usize] = true;
        let mut cnt = 0;
        loop {
            let tmp_next_pos = next_pos.clone();
            next_pos = Vec::new();
            for pos in tmp_next_pos.iter() {
                let i = pos.0;
                let j = pos.1;
                if i < 0 || i >= map.len() as i32 {
                    continue;
                }
                if j < 0 || j >= map[0].len() as i32 {
                    continue;
                }

                let i = i as usize;
                let j = j as usize;
                if visited[i][j] {
                    continue;
                }
                visited[i][j] = true;


                if map[i][j] == 'g' {
                    return cnt;
                }
                if map[i][j] == '#' {
                    continue;
                }

                let i = i as i32;
                let j = j as i32;
                for v in v_vec.iter() {
                    next_pos.push((i+v.0, j+v.1));
                }
            }

            for v in v_vec.iter() {
                next_pos.push((i+v.0, j+v.1));
            }

            cnt += 1;
        }

        return 0;
    }

    let mut ans = 0;
    for i in 0..map.len() {
        for j in 0..map[0].len() {
            let mut base_map = map.clone();
            base_map[i][j] = 's';
            for n in 0..map.len() {
                for m in 0..map[0].len() {
                    if base_map[n][m] == 's' {
                        continue;
                    }
                    let mut tmp_map = base_map.clone();
                    tmp_map[n][m] = 'g';
                    let i = i as i32;
                    let j = j as i32;
                    let cnt = _solve(i, j, &tmp_map);
                    if cnt > ans {
                        ans = cnt;
                    }
                }
            }
        }
    }

    return ans;
}

fn main() {
    let h: usize = read();
    let w: usize = read();
    let c_ij: Vec<Vec<char>> = (0..h).map(|_| read::<String>().chars().collect()).collect();

    println!("{}", solve(c_ij));
}
