#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <bitset>
#include <map>
#include <set>
#include <algorithm>
#include <cmath>
#include <vector>
#define fir first
#define sec second
using ll = long long;
using uint = unsigned int;
constexpr int INF = 2e9;

template<typename T>
bool rMin(T& a, const T& b){
    if(b < a){
        a = b;
        return true;
    }
    return false;
}

template<typename T>
bool rMax(T& a, const T& b){
    if(a < b){
        a = b;
        return true;
    }
    return false;
}


using namespace std;

vector<vector<uint>> mind;
vector<string> table;
vector<vector<bool>> can;

struct Dot{
    int l;
    int u;
    bool operator<(const Dot& a) const{
        if(mind[l][u] != mind[a.l][a.u]) return mind[l][u] < mind[a.l][a.u];
        if(l != a.l) return l < a.l;
        return u < a.u;
    }
    Dot operator+(const Dot & a) const{
        return {l + a.l, u + a.u};
    }
    Dot(int l, int u): l(l), u(u) {;}
};

pair<Dot, int> moves[8] = {
        {{0, 1}, 4},
        {{1, 0}, 4},
        {{0, -1}, 4},
        {{-1, 0}, 4},
        {{1, 1}, 5},
        {{-1, 1}, 5},
        {{1, -1}, 5},
        {{-1, -1}, 5},
};

void solve(){

    int ql, qu;
    cin >> ql >> qu;
    for(int i = 0; i < ql; ++i){
        table.emplace_back();
        cin >> table.back();
    }
    mind.assign(ql + 1, vector<uint>(qu + 1, INF));
    can.assign(ql + 1, vector<bool>(qu + 1, INF));
    for(int i = 0; i <= ql; ++i){
        for(int t = 0; t <= qu; ++t){
            can[i][t] = i != 0 && i != ql && t != 0 && t != qu && table[i][t] == '.'  && table[i-1][t] == '.' && table[i][t-1] == '.' && table[i-1][t-1] == '.';
        }
    }
    mind[1][1] = 0;

    set<Dot> nxt;
    nxt.emplace(1, 1);
    while(!nxt.empty()){
        Dot a = *nxt.begin();
        nxt.erase(nxt.begin());
        for(auto &i : moves){
            Dot b = a + i.fir;
            if(can[b.l][b.u] && mind[b.l][b.u] > mind[a.l][a.u] + i.sec){
                nxt.erase(b);
                mind[b.l][b.u] = mind[a.l][a.u] + i.sec;
                nxt.insert(b);
            }
        }
    }

    if(mind[ql - 1][qu - 1] == INF){
        cout << "-1\n";
    }
    else{
        cout << mind[ql - 1][qu - 1] << '\n';
    }
}

int main(){
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    int t = 1;

    //cin >> t;

    for(int i = 0; i < t; ++i){
        solve();
    }
}