import java.util.*

fun main(args: Array<String>) {
    abc151d()
}

fun abc151d() {
    val (h, w) = readLine()!!.split(' ').map { it.toInt() }
    val isRoad = (1..h).map { readLine()!!.map { it == '.' }.toBooleanArray() }.toTypedArray()

    data class Coordinate(val y: Int, val x: Int)

    val INF = 1000000
    val direction = listOf(-1 to 0, 1 to 0, 0 to -1, 0 to 1)
    val minCosts = Array(500) { y -> IntArray(500) { x -> if (y == x) 0 else INF } }
    fun getId(y: Int, x: Int) = y * w + x

    for (y in 0 until h) {
        for (x in 0 until w) {
            if (!isRoad[y][x]) continue
            direction.map { Coordinate(y + it.first, x + it.second) }
                .filter { it.y in 0 until h && it.x in 0 until w && isRoad[it.y][it.x] }
                .forEach { minCosts[getId(y, x)][getId(it.y, it.x)] = 1 }
        }
    }

    val gridSize = h * w

    for (k in 0 until gridSize)
        for (i in 0 until gridSize)
            for (j in 0 until gridSize)
                minCosts[i][j] = Math.min(minCosts[i][j], minCosts[i][k] + minCosts[k][j])

    val answer = minCosts.map { it.filter { it < INF }.max() ?: 0 }.max() ?: 0

    println(answer)
}
