package main

import "fmt"

const maxCost = 401

func dfs(i, j, gi, gj int, m [][]byte, c [][]int) {
	if i == gi && j == gj {
		return
	}

	next := [][]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
	for _, p := range next {
		ni, nj := i+p[0], j+p[1]
		if ni < 0 || ni >= len(m) || nj < 0 || nj >= len(m[0]) {
			continue
		}
		if m[ni][nj] == '#' || c[ni][nj] <= c[i][j] {
			continue
		}
		c[ni][nj] = c[i][j] + 1
		dfs(ni, nj, gi, gj, m, c)
	}
}

func initCost(c [][]int) {
	for i := 0; i < len(c); i++ {
		for j := 0; j < len(c[0]); j++ {
			c[i][j] = maxCost
		}
	}
}

func main() {
	var h, w int
	fmt.Scan(&h, &w)

	m := make([][]byte, h)
	c := make([][]int, h)
	for i := 0; i < h; i++ {
		var s string
		fmt.Scan(&s)
		m[i] = make([]byte, w)
		c[i] = make([]int, w)
		for j := 0; j < w; j++ {
			m[i][j] = s[j]
			c[i][j] = maxCost
		}
	}

	ans := 0
	for i := 0; i < h; i++ {
		for j := 0; j < w; j++ {
			for gi := 0; gi < h; gi++ {
				for gj := 0; gj < w; gj++ {
					initCost(c)
					c[i][j] = 0
					dfs(i, j, gi, gj, m, c)
					if c[gi][gj] != maxCost && ans < c[gi][gj] {
						ans = c[gi][gj]
					}
				}
			}
		}
	}
	fmt.Println(ans)
}
