#include <bits/stdc++.h>

#define y1 plz

#define mp make_pair

#define fi first
#define se second

#define pw(x) (1LL << x)
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define sz(x) (int)(x).size()

using namespace std;

template < typename T >
bool umn (T& a, T  b) {return a > b ? a = b, 1 : 0;}
template < typename T >
bool umx (T& a, T  b) {return a < b ? a = b, 1 : 0;}

using ll = long long;
using ld = long double;

const int N = 1e6 + 5;

queue < pair <   < pair < int, int >, 4 > , int > > q;
map < array < pair < int , int > , 4 >, int > dp;

int n, m;
vector < vector < char > > c;

array < pair < int , int >, 4 > vertex (pair < int , int > a, pair < int , int > b, pair < int , int > c,
                                      pair < int , int > d) {
    vector < pair < int , int > > v;
    v.pb (a);
    v.pb (b);
    v.pb (c);
    v.pb (d);

    array < pair < int , int > , 4 > A;

    sort (all (v));
    for (int j = 0; j < sz(v); ++ j) A[j] = v[j];
    return A;
}

bool possible (array < pair < int , int > , 4 > a, int d) {
    vector < pair < int , int > > v;
    for (int i = 0; i < 4; ++ i) {
        v.pb (a[i]);
        if (a[i].fi <= 0 || a[i].se <= 0 || a[i].fi > n || a[i].se > m) return false;
        for (int j = 0; j < i; ++ j) if (a[i] == a[j]) return false;
        if (c[a[i].fi][a[i].se] == '#') return false;
    }

    sort (all (v));
    for (int i = 0; i < 4; ++ i) a[i] = v[i];

    queue < pair < int, int > > Q;
    Q.push({a[0].fi, a[0].se});
    int f[5];
    f[0] = f[1] = f[2] = f[3] = 0;
    f[0] = 1;
    while (!Q.empty ()) {
        int x = Q.front().fi, y = Q.front().se;
        Q.pop();
        for (int i = 0; i < 4; ++ i) {
            if (f[i]) continue;
            if (a[i].fi == x && abs(a[i].se - y) == 1) {
                Q.push(a[i]);
                f[i] = true;
            }

            if (a[i].se == y && abs(a[i].fi - x) == 1) {
                Q.push(a[i]);
                f[i] = true;
            }
        }

    }

    if ((f[0] + f[1] + f[2] + f[3]) != 4) return false;

    if (dp.find (a) == dp.end()) {
        q.push({a, d + 1});
        dp[a] = d + 1;
        return true;
    }

    if (dp[a] > d + 1) {
        dp[a] = d + 1;
        q.push ({a, d + 1});
        return true;
    }

    return false;
}

vector < int > add (array < pair < int, int >, 4 > a, int d) {
    for (int i = 0; i < 4; ++ i) {
        array < pair < int , int > , 4 > b = a;

        ++ b[i].fi;
        possible (b, d);
        -- b[i].fi;

        ++ b[i].se;
        possible (b, d);
        -- b[i].se;

        ++ b[i].se;
        ++ b[i].fi;
        possible (b, d);
        -- b[i].se;
        -- b[i].fi;
    }
}



int main() {
#ifdef localy
    freopen ("input.txt", "r", stdin);
    freopen ("output.txt", "w", stdout);
#endif // localy
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> m;


    c.resize (n + 4);
    for (int i = 1; i <= n; ++ i) {
        c[i].resize (m + 4);
        for (int j = 1; j <= m; ++ j) cin >> c[i][j];
    }


    array < pair < int , int > , 4 > s = vertex (mp(1, 1), mp(2, 1), mp(1, 2), mp(2, 2));

    dp[s] = 0;
    q.push({s, 0});

    while (!q.empty ()) {
        pair < array < pair < int, int > , 4 > , int > v = q.front();
        q.pop();

        add (v.fi, v.se);
    }

    s = vertex ({n - 1, m - 1}, {n - 1, m}, {n, m - 1}, {n, m});

    if (dp.find (s) == dp.end()) cout << -1 << "\n";
    else cout << dp[s] << "\n";

    return 0;
}
