using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    static public void Main()
    {
        var s = new Sol();
        //s.Solve1();
        //s.Solve2();
        s.Solve3();
        s.Solve4();
        s.Solve5();
        s.Solve6();
    }
}
public class Sol
{
    //ABC 007 C 幅優先探索
    //https://atcoder.jp/contests/abc007/tasks/abc007_3
    //public void Solve1()
    //{
    //    int[] In = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
    //    int r = In[0];
    //    int c = In[1];
    //    int[] In2 = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
    //    int sy = In2[0];
    //    int sx = In2[1];
    //    sy--;sx--;
    //    int[] In3 = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
    //    int gy = In3[0];
    //    int gx = In3[1];
    //    gy--;gx--;
    //    var C = new char[r, c];
    //    for(int i = 0; i < r; i++)
    //    {
    //        string s = Console.ReadLine();
    //        for(int j = 0; j < c; j++)
    //        {
    //            C[i, j] = s[j];
    //        }
    //    }
    //    var que = new Queue<Pair>();
    //    que.Enqueue(new Pair(sy, sx));
    //    var dis = new int[r, c];
    //    for(int i = 0; i < r; i++)
    //    {
    //        for(int j = 0; j < c; j++)
    //        {
    //            dis[i, j] = -1;
    //        }
    //    }
    //    dis[sy, sx] = 0;
    //    while (que.Count > 0)
    //    {
    //        Pair p = que.Dequeue();
    //        //Console.WriteLine($"{p.y} {p.x}");
    //        if (p.y == gy && p.x == gx)
    //        {
    //            Console.WriteLine(dis[p.y, p.x]);
    //            break;
    //        }
    //        for (int i=0; i < 4; i++)
    //        {
    //            int ny = p.y + dy[i];
    //            int nx = p.x + dx[i];
    //            if (ny < 0 || r <= ny || nx < 0 || c <= nx || C[ny,nx]=='#' || dis[ny,nx]!=-1) continue;
    //            dis[ny, nx] = dis[p.y, p.x] + 1;
    //            que.Enqueue(new Pair(ny, nx));
    //        }
    //    }
    //}
    //public struct Pair
    //{
    //    public int y,x;
    //    public Pair(int y, int x)
    //    {
    //        this.x = x;
    //        this.y = y;
    //    }
    //}
    public static int[] dx = new int[] { 1, 0, -1, 0 };
    public static int[] dy = new int[] { 0, 1, 0, -1 };

    //JOI 2010　予選E チーズ
    //https://atcoder.jp/contests/joi2011yo/tasks/joi2011yo_e
    public void Solve2()
    {
        int[] In = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
        int h = In[0];
        int w = In[1];
        int n = In[2];
        var C = new char[h, w];
        for(int i = 0; i < h; i++)
        {
            string s = Console.ReadLine();
            for (int j = 0; j < w; j++)
            {
                C[i, j] = s[j];
            }
        }
        var dis = new int[h, w];
        for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) dis[i, j] = -1;
        var que = new Queue<Pair>();
        //Sを探す
        for (int i = 0; i < h; i++) for (int j = 0; j < w; j++)
                if (C[i, j] == 'S') { que.Enqueue(new Pair(i, j)); C[i, j] = '.'; dis[i, j] = 0; }
        int HP = 1;
        int ans = 0;
        while (que.Count > 0 && n>0)
        {
            var p = que.Dequeue();
            //Console.WriteLine($"{p.x} {p.y}");
            char m = C[p.x, p.y];
            if('1' <= m && m <= '9' && int.Parse(m.ToString()) <= HP)
            {
                //Console.WriteLine("!");
                ans += dis[p.x, p.y];
                for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) dis[i, j] = -1;
                C[p.x, p.y] = '.';
                dis[p.x, p.y] = 0;
                n--;
                HP++;
                que.Clear();
                que.Enqueue(p);
                continue;
            }
            for(int i = 0; i < 4; i++)
            {
                int nx = p.x + dx[i];
                int ny = p.y + dy[i];
                if (nx < 0 || h <= nx || ny < 0 || w <= ny || C[nx, ny] == 'X' || dis[nx, ny] != -1) continue;
                dis[nx, ny] = dis[p.x, p.y] + 1;
                que.Enqueue(new Pair(nx, ny));
            }
        }
        Console.WriteLine(ans);
    }
    public struct Pair
    {
        public int x, y;
        public Pair(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }

    //ABC 088 D grid Repainting
    //https://atcoder.jp/contests/abc088/tasks/abc088_d
    public void Solve3()
    {
        int[] In = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
        int h = In[0];
        int w = In[1];
        var C = new char[h, w];
        int wcnt = 0;
        for(int i = 0; i < h; i++)
        {
            string s = Console.ReadLine();
            for(int j = 0; j < w; j++)
            {
                C[i, j] = s[j];
                if (s[j] == '.') wcnt++;
            }
        }
        var dis = new int[h, w];
        for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) dis[i, j] = -1;
        var que = new Queue<Pair>();
        que.Enqueue(new Pair(0, 0));
        dis[0, 0] = 0;
        int INF = 1001001001;
        int min=INF;
        while (que.Count > 0)
        {
            Pair p = que.Dequeue();
            if(p.x == h - 1 && p.y == w - 1)
            {
                min = dis[p.x, p.y];
                break;
            }
            for(int i = 0; i < 4; i++)
            {
                int nx = p.x + dx[i];
                int ny = p.y + dy[i];
                if (nx < 0 || h <= nx || ny < 0 || w <= ny || C[nx, ny] == '#' || dis[nx, ny] != -1) continue;
                dis[nx, ny] = dis[p.x, p.y] + 1;
                que.Enqueue(new Pair(nx, ny));
            }
        }
        if (min == INF)
        {
            Console.WriteLine(-1);
        }else Console.WriteLine(wcnt - min - 1);
    }

    //A
    //
    public void Solve4()
    {

    }

    //
    //
    public void Solve5()
    {

    }

    //
    //
    public void Solve6()
    {

    }
}

Measured memory_bytes: 28304