package main

import (
	"fmt"
	"io"
	"os"
	"strconv"
)

var pri = fmt.Println
var scan = fmt.Fscanln
var scanone = fmt.Fscan

func main() {
	solve(os.Stdin)
}

func min(a ...int) int {
	res := a[0]
	for i := 1; i < len(a); i++ {
		if res > a[i] {
			res = a[i]
		}
	}
	return res
}

func max(a ...int) int {
	res := a[0]
	for i := 1; i < len(a); i++ {
		if res < a[i] {
			res = a[i]
		}
	}
	return res
}

func mustint(a string) int {
	i, _ := strconv.Atoi(a)
	return int(i)
}

type P struct {
	x, y int
}

func (p *P) add(q *P) *P {
	return &P{p.x + q.x, p.y + q.y}
}

const huge = 1e10

func get_around(i, j, h, w int) []P {
	res := make([]P, 0, 4)
	if i > 0 {
		res = append(res, P{i - 1, j})
	}
	if i < h-1 {
		res = append(res, P{i + 1, j})
	}
	if j > 0 {
		res = append(res, P{i, j - 1})
	}
	if j < w-1 {
		res = append(res, P{i, j + 1})
	}
	return res
}

func solve(rd io.Reader) {
	var h, w int
	scan(rd, &h, &w)
	board := make([][]int, h)
	for i := 0; i < h; i++ {
		board[i] = make([]int, w)
	}
	for i := 0; i < h; i++ {
		var s string
		scan(rd, &s)
		for j, ss := range s {
			if ss == '.' {
				board[i][j] = 1
			}
		}
	}

	all_pos := make([]P, 0, h*w)
	for i := 0; i < h; i++ {
		for j := 0; j < w; j++ {
			if board[i][j] == 1 {
				all_pos = append(all_pos, P{i, j})
			}
		}
	}
	const MAX = 10000000000
	d := make([][][][]int, h)
	for i := 0; i < h; i++ {
		d[i] = make([][][]int, w)
		for j := 0; j < w; j++ {
			d[i][j] = make([][]int, h)
			for k := 0; k < h; k++ {
				d[i][j][k] = make([]int, w)
				for kl := 0; kl < w; kl++ {
					d[i][j][k][kl] = MAX
				}
			}
		}
	}
	for _, p := range all_pos {
		for _, q := range get_around(p.x, p.y, h, w) {
			d[p.x][p.y][q.x][q.y] = 1
		}
	}
	for _, k := range all_pos {
		for _, i := range all_pos {
			for _, j := range all_pos {
				if d[i.x][i.y][j.x][j.y] > d[i.x][i.y][k.x][k.y]+d[j.x][j.y][k.x][k.y] {
					d[i.x][i.y][j.x][j.y] = d[i.x][i.y][k.x][k.y] + d[j.x][j.y][k.x][k.y]
				}
			}
		}
	}
	res := 0

	for i := 0; i < h; i++ {
		for j := 0; j < w; j++ {
			for k := 0; k < h; k++ {
				for kl := 0; kl < w; kl++ {
					dd := d[i][j][k][kl]
					if dd != MAX && res < dd {
						res = dd
					}
				}
			}
		}
	}
	pri(res)
}
