import std.stdio, std.algorithm, std.range, std.array, std.conv, std.string, std.math;

void main() {
    auto S = readln.split.to!(int[]);
    auto H = S[0], W = S[1];
    char[][] cell;
    foreach (y; 0..H) {
        cell ~= readln.split.to!(char[]);
    }
    auto white = cell.map!(c => c.count('.')).sum;
    float[][] score = new float[][](H,W);
    score.each!(s => s.fill(float.nan));
    float cost(int x, int y, char[][] cell) {
        if (x == W-1 && y == H-1) return 1;
        if (x < 0) return float.infinity;
        if (y < 0) return float.infinity;
        if (x >= W) return float.infinity;
        if (y >= H) return float.infinity;
        if (cell[y][x] == '#') return float.infinity;
        if (!score[y][x].isNaN) return score[y][x];
        cell[y][x] = '#';
        scope(exit) cell[y][x] = '.';
        float result = cost(x-1,y,cell);
        if (result == W-1-x + H-1-y) return score[y][x] = result + 1;
        result = min(result, cost(x+1,y,cell));
        if (result == W-1-x + H-1-y) return score[y][x] = result + 1;
        result = min(result, cost(x,y-1,cell));
        if (result == W-1-x + H-1-y) return score[y][x] = result + 1;
        result = min(result, cost(x,y+1,cell));
        return score[y][x] = result + 1;
    }
    auto minCost = cost(0,0,cell);
    if (minCost == float.infinity) {
        writeln(-1);
        return;
    }
    writeln(cast(int)(white - minCost));
}
