import java.util.*

fun main(args: Array<String>) {
    val (MAX_Y, MAX_X) = readLine()!!.split(" ").map(String::toInt)
    val (SY, SX) = 0 to 0
    val (GY, GX) = MAX_Y - 1 to MAX_X - 1
    val array = Array(MAX_Y) {
        readLine()!!.toCharArray()
    }

    val INF = Integer.MAX_VALUE

    val dx = intArrayOf(1, 0, -1, 0)
    val dy = intArrayOf(0, 1, 0, -1)


    fun bfs(): Int {
        val d = Array(MAX_Y) {
            IntArray(MAX_X) { INF }
        }
        val queue: Queue<Pair<Int, Int>> = ArrayDeque()

        queue.add(SX to SY)
        d[SY][SX] = 0

        while (queue.isNotEmpty()) {
            val (x, y) = queue.poll()

            if (x == GX && y == GY) {
//                println("x:$x , y:$y")
                break
            }

            for (i in 0..3) {
                val nx = x + dx[i]
                val ny = y + dy[i]
//                println("nx:$nx , ny:$ny")

                if (nx in 0 until MAX_X && ny in 0 until MAX_Y && array[ny][nx] != '#' && d[ny][nx] == INF) {
                    queue.add(nx to ny)
                    d[ny][nx] = d[y][x] + 1
                }
            }
//            d.joinToString(System.lineSeparator()) {
//                it.map { if (it == INF) -1 else it }
//                    .map { "%3d".format(it) }
//                    .joinToString { it }
//            }.let(::println)

        }
        return d[GY][GX]
    }


    val moveCount = bfs()
    if (moveCount == INF) {
        println(-1)
        return
    }

    println(MAX_X * MAX_Y - array.map { it.count { it == '#' } }.sum() - (moveCount + 1))

}

