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

class Program
{
    #region library
    static int n = 0;
    static int m = 0;
    static int r = 0;
    static int c = 0;
    static int x = 0;
    static int y = 0;
    static string s = "";
    static string[] ss;
    static long sum = 0;
    static long cnt = 0;
    static long max = -1;
    static long min = 2147483647;
    static bool flg = false;
    static bool flg2 = false;
    static string alpha = "abcdefghijklmnopqrstuvwxyz";
    static int mod = 1000000007;
    static long[] arr;
    static char[,] map;
    static long[,] imap;
    public class Input
    {
        static readonly char[] separator = { ' ', '\r', '\n' };
        readonly StreamReader sr;
        readonly Queue<string> queue;

        public Input(string path = "")
        {
            queue = new Queue<string>();

            if (string.IsNullOrEmpty(path))
            {
                sr = new StreamReader(Console.OpenStandardInput());
            }
            else
            {
                sr = new StreamReader(path);
            }
        }

        public void SetText(IEnumerable<string> items)
        {
            foreach (var item in items)
            {
                SetText(item);
            }
        }

        public bool SetText(string s)
        {
            if (s == null) return false;

            foreach (var elem in s.Trim()
                .Split(separator, StringSplitOptions.RemoveEmptyEntries))
            {
                queue.Enqueue(elem);
            }

            return true;
        }

        public bool Any()
        {
            return queue.Any() || Read();
        }

        bool Read()
        {
            if (!SetText(sr.ReadLine())) return false;

            if (!queue.Any()) return Read();

            return queue.Any();
        }

        public string Next()
        {
            if (!queue.Any() && !Read())
            {
                return "";
            }

            return queue.Dequeue();
        }

        bool Accumulate(int n)
        {
            while (queue.Count() < n)
            {
                if (!Read()) return false;
            }

            return true;
        }

        public int NextInt()
        {
            return int.Parse(Next());
        }
        public long NextLong()
        {
            return long.Parse(Next());
        }
        public double NextDouble()
        {
            return double.Parse(Next());
        }

        T[] NextT<T>(int n, T offset, Func<string, T> parse, Func<T, T, T> add)
        {
            if (!Accumulate(n)) return null;

            var a = new T[n];

            for (int i = 0; i < n; i++)
                a[i] = add(parse(queue.Dequeue()), offset);

            return a;
        }

        public string[] Next(int n)
        {
            return NextT(n, "", x => x, (x, y) => x);
        }
        public int[] NextInt(int n, int offset = 0)
        {
            return NextT(n, offset, int.Parse, (x, y) => x + y);
        }
        public long[] NextLong(int n, long offset = 0)
        {
            return NextT(n, offset, long.Parse, (x, y) => x + y);
        }
        public double[] NextDouble(int n, double offset = 0.0)
        {
            return NextT(n, offset, double.Parse, (x, y) => x + y);
        }
    }
    static Input input;
    static int Int()
    {
        return input.NextInt();
    }
    static long Long()
    {
        return input.NextLong();
    }
    static double Double()
    {
        return input.NextDouble();
    }
    static string Text()
    {
        return input.Next();
    }
    static void wl(object obj = null)
    {
        Console.WriteLine(obj);
    }
    static void w(object obj)
    {
        Console.Write(obj);
    }
    static void Yes()
    {
        wl("YES");
    }
    static void No()
    {
        wl("NO");
    }
    static void Sum()
    {
        wl(sum);
    }
    static void Cnt()
    {
        wl(cnt);
    }
    static void SetArray(long num = -1)
    {
        if (n == 0)
        {
            n = Int();
        }
        arr = new long[n];
        for (int i = 0; i < n; i++)
        {
            if (num == -1)
                arr[i] = Int();
            else
                arr[i] = num;
        }
    }
    static void SetMap(char def = '@')
    {
        if (r == 0 && c == 0)
        {
            r = Int();
            c = Int();
        }
        map = new char[r, c];
        for (int i = 0; i < r; i++)
        {
            if (def == '@') s = Text();
            for (int j = 0; j < c; j++)
            {
                map[i, j] = (def == '@') ? s[j] : def;
            }
        }
    }
    static void SetIMap(long def = -1)
    {
        if (r == 0 && c == 0)
        {
            r = Int();
            c = Int();
        }
        imap = new long[r, c];
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                imap[i, j] = (def == -1) ? Int() : def;
            }
        }
    }
    #endregion

    #region main
    static void Main(string[] args)
    {
        var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
        Console.SetOut(sw);
        input = new Input();
        Solve();
        Console.Out.Flush();
    }

    static Queue<int>  qx;
    static Queue<int> qy;
    public static void Solve()
    {
        r = Int();
        c = Int();
        imap = new long[r,c];
        qx = new Queue<int>();
        qy = new Queue<int>();
        for (int i = 0; i < r; i++)
        {
            s = Text();
            for (int j = 0; j < c; j++)
            {
                if (s[j] == '.')
                {
                    imap[i, j] = 0;
                    cnt++;
                }
                else
                {
                    imap[i, j] = -1;
                }
            }
        }

        qx.Enqueue(0);
        qy.Enqueue(0);
        imap[0, 0] = 1;

        while (qx.Count > 0)
        {
            x = qx.Dequeue();
            y = qy.Dequeue();
            f(x, y);
        }

        if (imap[r - 1, c - 1] == 0)
            wl(-1);
        else
            wl(cnt - imap[r - 1,c - 1]);
            
    }

    static void f(int x, int y)
    {
        long cnt = imap[y, x];
        if(x + 1 < c && imap[y, x + 1] != -1 && (imap[y, x + 1] == 0  || imap[y, x + 1] > cnt + 1))
        {
            imap[y, x + 1] = cnt + 1;
            qx.Enqueue(x + 1);
            qy.Enqueue(y);
        }
        if (y + 1 < r && imap[y + 1, x] != -1 && (imap[y + 1, x] == 0 || imap[y + 1, x] > cnt + 1))
        {
            imap[y + 1, x] = cnt + 1;
            qx.Enqueue(x);
            qy.Enqueue(y + 1);
        }
        if (x - 1 >= 0 && imap[y, x - 1] != -1 && (imap[y, x - 1] == 0 || imap[y, x - 1] > cnt + 1))
        {
            imap[y, x - 1] = cnt + 1;
            qx.Enqueue(x - 1);
            qy.Enqueue(y);
        }
        if (y - 1 >= 0 && imap[y - 1, x] != -1 && (imap[y - 1, x] == 0 || imap[y - 1, x] > cnt + 1))
        {
            imap[y - 1, x] = cnt + 1;
            qx.Enqueue(x);
            qy.Enqueue(y - 1);
        }
    }

    #endregion
}

Measured memory_bytes: 13524