macro_rules! scan_sub {
    ( $itr:ident, $t:ty ) => {
        let mut buf = String::new();
        let $itr = {
            while buf.trim().len() == 0 {
                buf = String::new();
                std::io::stdin().read_line(&mut buf).unwrap();
            }
            buf.split_whitespace().map(|n| n.parse::<$t>().unwrap())
        };
    };
}

macro_rules! scan {
    ( $x:ident; Vec<$t:ty> ) => {
        scan_sub!(itr, $t);
        let $x = itr.collect::<Vec<_>>();
    };
    ( $( $x:ident ),*; $t:ty ) => {
        scan_sub!(itr, $t);
        let mut itr = itr;
        $(
            let $x = itr.next().unwrap();
        )*
    };
}

use std::collections::VecDeque;

fn main() {
    scan!(h, w; usize);
    let mut maze = vec![vec![false; w]; h];
    for i in 0..h {
        scan!(line; String);
        for (j, c) in line.chars().enumerate() {
            if c == '.' { maze[i][j] = true; }
        }
    }

    let mut start;
    let mut max_depth = 0;
    for (i, j) in (0..h)
        .map(|&i| (0..w).map(|&j| (i, j)).collect())
        .collect()
    {
        let mut que = VecDeque::new();
        let mut visited = vec![vec![false; w]; h];
        que.push_front((0, (i, j)));
        let mut md = 0;

        while let Some(t) = que.pop_back() {
            let d = t.0;
            if md < d { md = d; }
            let p = t.1;
            visited[p.0][p.1] = true;

            let four = vec![
                          (-1,  0),
                ( 0, -1),           ( 0,  1),
                          ( 1,  0),
            ];

            for (dx, dy) in four {
                let (a, b) = (p.0 as i64 + dx, p.1 as i64 + dy);
                if a < 0 || h as i64 <= a || b < 0 || w as i64 <= b {
                    continue;
                }
                let (a, b) = (a as usize, b as uzie);
                if maze[a][b] && !visited[a][b] {
                    que.push_front((d, (a, b)));
                }
            }
        }
        if max_depth < md {
            max_depth = md;
        }
    }

    println!("{}", max_depth);
}
