package main

import "fmt"

const road = '.'
const wall = '#'

type stage []string

type point struct {
	x int
	y int
}

func main() {
	s := input()
	f := initStage(len(s), len(s[0]))
	max := -1
	for i := range s {
		for k := range s[i] {
			// for l := range s {
			for l := i; l < len(s); l++ {
				for m := range s[l] {
					if i == l && k == m {
						continue
					}
					tmp := s.dis(point{k, i}, point{m, l}, 0, f)
					// fmt.Println(point{k, i}, point{m, l}, ": ", tmp)
					if max < tmp {
						max = tmp
					}
				}
			}
		}
	}
	fmt.Println(max)
}

func initStage(h, w int) [][]bool {
	f := make([][]bool, h, h)
	for i := range f {
		f[i] = make([]bool, w, w)
	}
	return f
}

func (s stage) dis(p, e point, d int, passed [][]bool) int {
	if !s.isRoad(p) {
		return -1
	}
	if passed[p.y][p.x] {
		return -1
	}
	if p == e {
		return d
	}
	passed[p.y][p.x] = true
	min := s.dis(p.up(), e, d+1, passed)
	tmp := s.dis(p.left(), e, d+1, passed)
	if min < 0 {
		min = tmp
	} else if tmp >= 0 && tmp < min {
		min = tmp
	}
	tmp = s.dis(p.down(), e, d+1, passed)
	if min < 0 {
		min = tmp
	} else if tmp >= 0 && tmp < min {
		min = tmp
	}
	tmp = s.dis(p.right(), e, d+1, passed)
	if min < 0 {
		min = tmp
	} else if tmp >= 0 && tmp < min {
		min = tmp
	}
	passed[p.y][p.x] = false
	return min
}

func (s stage) isRoad(p point) bool {
	if p.x < 0 || len(s[0]) <= p.x {
		return false
	}
	if p.y < 0 || len(s) <= p.y {
		return false
	}
	if s[p.y][p.x] == wall {
		return false
	}
	return true
}

func (p point) up() point {
	return point{p.x, p.y - 1}
}

func (p point) down() point {
	return point{p.x, p.y + 1}
}
func (p point) left() point {
	return point{p.x - 1, p.y}
}

func (p point) right() point {
	return point{p.x + 1, p.y}
}

func input() stage {
	var h, w int
	fmt.Scan(&h, &w)
	s := make([]string, h, h)
	for i := range s {
		fmt.Scan(&s[i])
	}
	return s
}
