Problem:
Score : 400 points

Problem Statement

Takahashi has a maze, which is a grid of H \times W squares with H horizontal rows and W vertical columns.

The square at the i-th row from the top and the j-th column is a "wall" square if S_{ij} is #, and a "road" square if S_{ij} is ..

From a road square, you can move to a horizontally or vertically adjacent road square.

You cannot move out of the maze, move to a wall square, or move diagonally.

Takahashi will choose a starting square and a goal square, which can be any road squares, and give the maze to Aoki.

Aoki will then travel from the starting square to the goal square, in the minimum number of moves required.

In this situation, find the maximum possible number of moves Aoki has to make.

Constraints

1 \leq H,W \leq 20

S_{ij} is . or #.

S contains at least two occurrences of ..

Any road square can be reached from any road square in zero or more moves.

Input

Input is given from Standard Input in the following format:

H W
S_{11}...S_{1W}
:
S_{H1}...S_{HW}

Output

Print the maximum possible number of moves Aoki has to make.

Sample Input 1

3 3
...
...
...

Sample Output 1

4

If Takahashi chooses the top-left square as the starting square and the bottom-right square as the goal square, Aoki has to make four moves.

Sample Input 2

3 5
...#.
.#.#.
.#...

Sample Output 2

10

If Takahashi chooses the bottom-left square as the starting square and the top-right square as the goal square, Aoki has to make ten moves.

Solution in Rust (1.15.1) (judge verdict: Accepted)

#![allow(unused_macros, deprecated)]

#[allow(dead_code)]
mod utils {
    use std::io::{
        self, BufRead, BufReader, BufWriter, Seek, SeekFrom, Stdin, StdinLock, Stdout, StdoutLock,
        Write,
    };
    use std::mem;
    use std::ops::{Deref, DerefMut};
    use std::ptr;
    use std::slice;
    use std::str::{self, FromStr};

    #[inline]
    fn is_space_or_line_break(b: &u8) -> bool {
        *b == b' ' || *b == b'\n'
    }

    pub struct Scanner<R: BufRead> {
        reader: R,
        buf: Vec<u8>,
    }

    impl<R: BufRead> Scanner<R> {
        #[inline]
        pub fn new(reader: R) -> Scanner<R> {
            Scanner {
                reader: reader,
                buf: Vec::with_capacity(100),
            }
        }

        pub fn read<T: FromStr>(&mut self) -> T {
            self.read_until(is_space_or_line_break);
            self.parse()
        }

        pub fn read2<T1: FromStr, T2: FromStr>(&mut self) -> (T1, T2) {
            (self.read(), self.read())
        }

        pub fn read3<T1: FromStr, T2: FromStr, T3: FromStr>(&mut self) -> (T1, T2, T3) {
            (self.read(), self.read(), self.read())
        }

        pub fn read4<T1: FromStr, T2: FromStr, T3: FromStr, T4: FromStr>(
            &mut self,
        ) -> (T1, T2, T3, T4) {
            (self.read(), self.read(), self.read(), self.read())
        }

        pub fn reads(&mut self) -> &str {
            self.read_until(is_space_or_line_break);
            unsafe { str::from_utf8_unchecked(&self.buf) }
        }

        pub fn readl(&mut self) -> &str {
            self.buf.clear();
            self.reader.read_until(b'\n', &mut self.buf).unwrap();
            let bytes = if self.buf.last() == Some(&b'\n') {
                &self.buf[..self.buf.len() - 1]
            } else {
                &self.buf
            };
            unsafe { str::from_utf8_unchecked(&bytes) }
        }

        pub fn read_vec<T: FromStr>(&mut self, count: usize) -> Vec<T> {
            (0..count).map(|_| self.read()).collect()
        }

        fn read_until<P: FnMut(&u8) -> bool>(&mut self, mut predicate: P) {
            self.buf.clear();
            let mut first = true;

            // https://doc.rust-lang.org/src/std/io/mod.rs.html#1623-1649
            loop {
                let (done, used) = {
                    let available = self.reader.fill_buf().unwrap();
                    if first && available.len() == 0 {
                        panic!("Scan Error (EOF reached)");
                    }

                    match available.iter().position(&mut predicate) {
                        Some(0) if first => (false, 1),
                        Some(i) => {
                            self.buf.extend_from_slice(&available[..i]);
                            (true, i + 1)
                        }
                        None => {
                            self.buf.extend_from_slice(available);
                            (false, available.len())
                        }
                    }
                };

                self.reader.consume(used);
                if done || used == 0 {
                    return;
                }

                first = false;
            }
        }

        #[inline]
        fn parse<T: FromStr>(&mut self) -> T {
            // 文字列をT型へパースする
            let elem = unsafe { str::from_utf8_unchecked(&self.buf) };
            elem.parse()
                .unwrap_or_else(|_| panic!(format!("failed parsing: {}", elem)))
        }
    }

    impl<R: BufRead + Seek> Seek for Scanner<R> {
        #[inline]
        fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
            self.reader.seek(pos)
        }
    }

    pub struct StdinScanner {
        stdin: Stdin,
        scanner: Scanner<BufReader<StdinLock<'static>>>,
    }

    impl StdinScanner {
        #[inline]
        pub fn new() -> StdinScanner {
            let stdin = io::stdin();
            let stdinlock = unsafe { mem::transmute(stdin.lock()) };
            let reader = BufReader::with_capacity(4096, stdinlock);
            let scanner = Scanner::new(reader);
            StdinScanner {
                stdin: stdin,
                scanner: scanner,
            }
        }
    }

    impl Deref for StdinScanner {
        type Target = Scanner<BufReader<StdinLock<'static>>>;

        #[inline]
        fn deref(&self) -> &Self::Target {
            &self.scanner
        }
    }

    impl DerefMut for StdinScanner {
        #[inline]
        fn deref_mut(&mut self) -> &mut Self::Target {
            &mut self.scanner
        }
    }

    pub struct StdoutWriter {
        stdout: Stdout,
        writer: BufWriter<StdoutLock<'static>>,
    }

    impl StdoutWriter {
        #[inline]
        pub fn new() -> StdoutWriter {
            let stdout = io::stdout();
            let stdoutlock = unsafe { mem::transmute(stdout.lock()) };
            let writer = BufWriter::with_capacity(4096, stdoutlock);
            StdoutWriter {
                stdout: stdout,
                writer: writer,
            }
        }

        pub fn write<T: Writable>(&mut self, v: T) {
            v.display(&mut self.writer);
        }

        pub fn writeln<T: Writable>(&mut self, v: T) {
            v.display(&mut self.writer);
            self.writer.write_all(b"\n").unwrap();
        }

        pub fn write_horizontal<I>(&mut self, iter: I)
        where
            I: IntoIterator,
            I::Item: Writable,
        {
            let mut it = iter.into_iter();
            if let Some(elem) = it.next() {
                elem.display(&mut self.writer);
            } else {
                return;
            }

            for elem in it {
                elem.display(&mut self.writer);
                self.writer.write_all(b" ").unwrap();
            }
        }

        pub fn write_vertical<I>(&mut self, iter: I)
        where
            I: IntoIterator,
            I::Item: Writable,
        {
            let mut it = iter.into_iter();
            if let Some(elem) = it.next() {
                elem.display(&mut self.writer);
            } else {
                return;
            }

            for elem in it {
                elem.display(&mut self.writer);
                self.writer.write_all(b"\n").unwrap();
            }
        }
    }

    impl Write for StdoutWriter {
        #[inline]
        fn flush(&mut self) -> io::Result<()> {
            self.writer.flush()
        }

        #[inline]
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            self.writer.write(buf)
        }
    }

    static DEC_DIGITS_LUT: &'static [u8; 200] = b"0001020304050607080910111213141516171819\
            2021222324252627282930313233343536373839\
            4041424344454647484950515253545556575859\
            6061626364656667686970717273747576777879\
            8081828384858687888990919293949596979899";

    fn write_int<W: Write>(mut writer: W, mut n: u64, is_negative: bool) {
        unsafe {
            let mut buf: [u8; 39] = mem::uninitialized();
            let buf_ptr_start = buf.as_mut_ptr().offset(39);
            let mut buf_ptr = buf_ptr_start;
            let lut_ptr = DEC_DIGITS_LUT.as_ptr();

            while n >= 10000 {
                let rem = (n % 10000) as isize;
                n /= 10000;

                let d1 = (rem / 100) << 1;
                let d2 = (rem % 100) << 1;
                buf_ptr = buf_ptr.offset(-4);
                ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr, 2);
                ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(2), 2);
            }

            let mut n = n as isize; // possibly reduce 64bit math

            // decode 2 more chars, if > 2 chars
            if n >= 100 {
                let d1 = (n % 100) << 1;
                n /= 100;
                buf_ptr = buf_ptr.offset(-2);
                ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr, 2);
            }

            // decode last 1 or 2 chars
            if n < 10 {
                buf_ptr = buf_ptr.offset(-1);
                *buf_ptr = (n as u8) + b'0';
            } else {
                let d1 = n << 1;
                buf_ptr = buf_ptr.offset(-2);
                ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr, 2);
            }

            if is_negative {
                buf_ptr = buf_ptr.offset(-1);
                *buf_ptr = b'-';
            }

            let buf_slice =
                slice::from_raw_parts(buf_ptr, buf_ptr_start as usize - buf_ptr as usize);

            writer.write_all(buf_slice).unwrap();
        }
    }

    pub trait Writable {
        fn display<W: Write>(&self, writer: &mut W);
    }

    impl Writable for str {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            writer.write_all(self.as_bytes()).unwrap()
        }
    }

    impl<'a> Writable for &'a str {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            writer.write_all(self.as_bytes()).unwrap()
        }
    }

    impl Writable for String {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            writer.write_all(self.as_bytes()).unwrap()
        }
    }

    impl Writable for bool {
        #[inline]
        fn display<W: Write>(&self, writer: &mut W) {
            let s: &'static [u8] = if *self { b"Yes" } else { b"No" };
            writer.write_all(s).unwrap();
        }
    }

    macro_rules! impl_writable_int {
        ($($int:ty)*) => {
            $(
                impl Writable for $int {
                    #[allow(unused_comparisons)]
                    fn display<W: Write>(&self, writer: &mut W) {
                        let is_negative = !(*self >= 0);
                        let abs = if is_negative {
                            (!*self as u64).wrapping_add(1)
                        } else {
                            *self as u64
                        };
                        write_int(writer, abs, is_negative);
                    }
                }
            )*
        };
    }

    macro_rules! impl_writable_float {
        ($($float:ty)*) => {
            $(
                impl Writable for $float {
                    #[inline]
                    fn display<W: Write>(&self, writer: &mut W) {
                        write!(writer, "{}", *self).unwrap();
                    }
                }
            )*
        }
    }

    impl_writable_int!(u8 u16 u32 u64 usize i8 i16 i32 i64 isize);
    impl_writable_float!(f32 f64);

    pub static mut SCANNER: *mut StdinScanner = 0 as *mut StdinScanner;
    pub static mut WRITER: *mut StdoutWriter = 0 as *mut StdoutWriter;

    #[inline]
    pub fn atcoder_initialize() {
        unsafe {
            SCANNER = mem::transmute(Box::new(StdinScanner::new()));
            WRITER = mem::transmute(Box::new(StdoutWriter::new()));
        }
    }

    #[inline]
    pub fn atcoder_finish() {
        unsafe {
            (*WRITER).flush().unwrap();
        }
    }
}

macro_rules! input {
    () => {};
    (@scanner $scanner:ident, @pred [ $($pred:tt)* ], ($var1:tt, $var2:tt) : [($t1:tt, $t2:tt) ; $len:expr]) => {
        let mut $var1 = Vec::with_capacity($len as usize);
        let mut $var2 = Vec::with_capacity($len as usize);

        for _ in 0..$len {
            $var1.push(scan!($scanner, $t1));
            $var2.push(scan!($scanner, $t2));
        }
    };
    (@scanner $scanner:ident, @pred [ $($pred:tt)* ], $var:tt : $t:tt) => {
        let $($pred)* $var = scan!($scanner, $t);
    };
    (@scanner $scanner:ident,) => {};
    (@scanner $scanner:ident, $var:tt : $t:tt) => {
        input!(@scanner $scanner, @pred [], $var : $t);
    };
    (@scanner $scanner:ident, mut $var:tt : $t:tt) => {
        input!(@scanner $scanner, @pred [mut], $var : $t);
    };
    (@scanner $scanner:ident, $var:tt : $t:tt, $($r:tt)*) => {
        input!(@scanner $scanner, $var : $t);
        input!(@scanner $scanner, $($r)*);
    };
    (@scanner $scanner:ident, mut $var:tt : $t:tt, $($r:tt)*) => {
        input!(@scanner $scanner, mut $var : $t);
        input!(@scanner $scanner, $($r)*);
    };
    ($($r:tt)*) => {
        let scanner_ref = unsafe { &mut *$crate::utils::SCANNER };
        input!(@scanner scanner_ref, $($r)*);
    }
}

macro_rules! scan {
    ($scanner:ident, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| scan!($scanner, $t)).collect::<Vec<_>>()
    };
    ($scanner:ident, usize1) => {
        scan!($scanner, usize) - 1
    };
    ($scanner:ident, line) => {
        $scanner.readl().to_string()
    };
    ($scanner:ident, $t:ty) => {
        $scanner.read::<$t>()
    };
}

macro_rules! pprint {
    ($value:expr) => {
        unsafe {
            (*$crate::utils::WRITER).write($value);
        }
    };
    ($value:expr, $($r:tt)*) => {
        let writer = unsafe { &*$crate::utils::WRITER };
        writer.write($value);
        writer.write(" ");
        pprint!($($r)*);
    };
}

macro_rules! pprintln {
    ($value:expr) => {
        unsafe {
            (*$crate::utils::WRITER).writeln($value);
        }
    };
    ($value:expr, $($r:tt)*) => {
        let writer = unsafe { &*$crate::utils::WRITER };
        writer.write($value);
        writer.write(" ");
        pprintln!($($r)*);
    };
}

macro_rules! atcoder_main {
    ($func:ident) => {
        fn main() {
            $crate::utils::atcoder_initialize();
            $func();
            $crate::utils::atcoder_finish();
        }
    };
}

use std::collections::VecDeque;

struct Maze {
    height: usize,
    width: usize,
    map: Vec<bool>,
}

impl Maze {
    pub fn solve(&self, s: (usize, usize), e: (usize, usize)) -> usize {
        if s == e {
            return 0;
        }

        let mut queue = VecDeque::with_capacity(self.width + self.height);
        let mut visited = self.map.clone();
        visited[s.0 * self.width + s.1] = true;
        queue.push_back(s);
        let mut count = 0;

        while !queue.is_empty() {
            count += 1;
            let queue_size = queue.len();

            for _ in 0..queue_size {
                let current = queue.pop_front().unwrap();
                let nexts = [
                    (current.0, current.1 + 1),
                    (current.0, current.1 - 1),
                    (current.0 + 1, current.1),
                    (current.0 - 1, current.1),
                ];

                for next in &nexts {
                    if *next == e {
                        return count;
                    }

                    if !visited[next.0 * self.width + next.1] {
                        visited[next.0 * self.width + next.1] = true;
                        queue.push_back(next.clone());
                    }
                }
            }
        }

        panic!("Failed to solve maze");
    }
}

fn run() {
    input! {
        h: usize,
        w: usize,
        s: [line; h]
    }

    let mut map: Vec<bool> = vec![true; (h + 2) * (w + 2)];
    let h = h + 2;
    let w = w + 2;

    for (i, l) in s.iter().enumerate() {
        for (j, c) in l.bytes().enumerate() {
            if c == b'.' {
                map[(i + 1) * w + (j + 1)] = false;
            }
        }
    }
    
    let maze = Maze {
        width: w,
        height: h,
        map: map.clone(),
    };

    let mut max = 0;

    for si in 1..h - 1 {
        for sj in 1..w - 1 {
            if map[si * w + sj] {
                continue;
            }

            for ei in 1..h - 1 {
                for ej in 1..w - 1 {
                    if map[ei * w + ej] {
                        continue;
                    }
                    let s = (si, sj);
                    let e = (ei, ej);

                    let result = maze.solve(s, e);
                    if result > max {
                        max = result;
                    }
                }
            }
        }
    }

    pprintln!(max);
}

atcoder_main!(run);