use std::io;
use std::str::FromStr;
use std::collections::VecDeque;

type Point = (usize, usize);

fn input_tuple() -> (usize, usize) {
    let mut line: String = String::new();
    io::stdin().read_line(&mut line);
    let vec: Vec<usize> = line.split_whitespace().map(|s| s.parse().unwrap()).collect();
    (vec[0], vec[1])
}

fn input<T:FromStr>() -> T {
    let mut line: String = String::new();
    io::stdin().read_line(&mut line);
    line.trim().parse().ok().unwrap()
}

fn push_queue(x: usize, y: usize, queue: &mut VecDeque<Point>, count: &mut Vec<Vec<usize>>, field: &mut Vec<Vec<char>>) {
    if field[y][x-1] == '.' {        
        queue.push_back((y, x-1));
        count[y][x-1] = count[y][x] + 1;
        field[y][x-1] = '#';
    }
    if field[y][x+1] == '.' {
        queue.push_back((y, x+1));
        count[y][x+1] = count[y][x] + 1;
        field[y][x+1] = '#';
    }
    if field[y-1][x] == '.' {
        queue.push_back((y - 1, x));
        count[y-1][x] = count[y][x] + 1;
        field[y-1][x] = '#';
    }
    if field[y+1][x] == '.' {
        queue.push_back((y + 1, x));
        count[y+1][x] = count[y][x] + 1;
        field[y+1][x] = '#';
    }
}

fn bfs(goal: Point, grid: &Vec<Vec<char>>, count: &mut Vec<Vec<usize>>) {
    let mut queue: VecDeque<Point> = VecDeque::new();
    let mut grid_buf: Vec<Vec<char>> = grid.to_vec();
    grid_buf[goal.0][goal.1] = '#';
    queue.push_back(goal);
    while (queue.len() > 0) {
        let point = queue.pop_front().unwrap();
        push_queue(point.1, point.0, &mut queue, count, &mut grid_buf);
    }
}

fn main() {
    let (h, w) = input_tuple();
    let mut grid: Vec<Vec<char>> = Vec::new();
    grid.push(vec!['#'; (w+2)]);
    for _ in 0..h {
        let s: String = input();
        let mut s: Vec<char> = s.chars().collect();
        s.insert(0, '#');
        s.push('#');
        grid.push(s);
    }
    grid.push(vec!['#'; (w+2)]);
    // println!("{:?}", grid);

    let mut max = 0;
    for i_g in 1..(h+1) {
        for j_g in 1..(w+1) {
            // println!("{}, {}", i_g, j_g);
            let mut count: Vec<Vec<usize>> = vec![vec![0; grid[0].len()]; grid.len()];
            bfs((i_g, j_g), &grid, &mut count);        
            // println!("{:?}", count);
            for i in count {
                for j in i {
                    if j > max {
                        max = j;
                    }
                }
            }
        }
    }
    println!("{}", max);    
}
