#include <bits/stdc++.h>
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimization ("unroll-loops")
using namespace std;
typedef long long ll;
typedef pair <short,short> p;
const int N = 505;
const int inf = 1000000000;

struct cvor{
    short i,j,v;
};

typedef pair <int,cvor> pi;

bool a[N][N];
vector <cvor> g[N][N][5];
int n,m;
int dist[N][N][5];
p kraj1[N][N][4],kraj2[N][N][4];
bool ima[N][N];
vector <p> krajevi;
bool gotov[N][N][5];

class cmp{
public:
    bool operator ()(pi a,pi b){
        return a.first > b.first;
    }
};

int brgrana = 0;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    //freopen("test.txt","r",stdin);
    cin >> n >> m;
    string s;
    for(int i = 1; i <= n; i++){
        cin >> s;
        for(int j = 1; j <= m; j++){
            a[i][j] = (s[j-1] == '#');
        }
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(a[i][j]){
                continue;
            }
            ///zavrsi topa,lovca i kraljicu
            ///lovac
            if(!kraj1[i][j][1].first){
                int x = i,y = j;
                int poslx = 0,posly = 0;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    poslx = x,posly = y;
                    x--,y++;
                }
                x = i,y = j;
                int poslx1 = 0,posly1 = 0;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    poslx1 = x,posly1 = y;
                    x++,y--;
                }
                x = poslx1,y = posly1;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    kraj1[x][y][1] = p(poslx,posly);
                    kraj2[x][y][1] = p(poslx1,posly1);
                    x--,y++;
                }
                if(!ima[poslx][posly]){
                    krajevi.push_back(p(poslx,posly));
                    ima[poslx][posly] = 1;
                }
                if(!ima[poslx1][posly1]){
                    krajevi.push_back(p(poslx1,posly1));
                    ima[poslx1][posly1] = 1;
                }
            }
            if(!kraj1[i][j][3].first){
                int x = i,y = j;
                int poslx = 0,posly = 0;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    poslx = x,posly = y;
                    x--,y--;
                }
                x = i,y = j;
                int poslx1 = 0,posly1 = 0;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    poslx1 = x,posly1 = y;
                    x++,y++;
                }
                x = poslx1,y = posly1;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    kraj1[x][y][3] = p(poslx,posly);
                    kraj2[x][y][3] = p(poslx1,posly1);
                    x--,y--;
                }
                if(!ima[poslx][posly]){
                    krajevi.push_back(p(poslx,posly));
                    ima[poslx][posly] = 1;
                }
                if(!ima[poslx1][posly1]){
                    krajevi.push_back(p(poslx1,posly1));
                    ima[poslx1][posly1] = 1;
                }
            }
            ///top
            if(!kraj1[i][j][0].first){
                int x = i,y = j;
                int poslx = 0,posly = 0;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    poslx = x,posly = y;
                    y++;
                }
                x = i,y = j;
                int poslx1 = 0,posly1 = 0;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    poslx1 = x,posly1 = y;
                    y--;
                }
                x = poslx1,y = posly1;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    kraj1[x][y][0] = p(poslx1,posly1);
                    kraj2[x][y][0] = p(poslx,posly);
                    y++;
                }
                if(!ima[poslx][posly]){
                    krajevi.push_back(p(poslx,posly));
                    ima[poslx][posly] = 1;
                }
                if(!ima[poslx1][posly1]){
                    krajevi.push_back(p(poslx1,posly1));
                    ima[poslx1][posly1] = 1;
                }
            }
            if(!kraj1[i][j][2].first){
                int x = i,y = j;
                int poslx = 0,posly = 0;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    poslx = x,posly = y;
                    x--;
                }
                x = i,y = j;
                int poslx1 = 0,posly1 = 0;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    poslx1 = x,posly1 = y;
                    x++;
                }
                x = poslx1,y = posly1;
                while(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y]){
                    kraj1[x][y][2] = p(poslx,posly);
                    kraj2[x][y][2] = p(poslx1,posly1);
                    x--;
                }
                if(!ima[poslx][posly]){
                    krajevi.push_back(p(poslx,posly));
                    ima[poslx][posly] = 1;
                }
                if(!ima[poslx1][posly1]){
                    krajevi.push_back(p(poslx1,posly1));
                    ima[poslx1][posly1] = 1;
                }
            }
        }
    }
    for(int i = 0; i < krajevi.size(); i++){
        for(int j = 0; j < krajevi.size(); j++){
            if(i == j){
                continue;
            }
            p a = krajevi[i],b = krajevi[j];
            if(kraj1[a.first][a.second][0] == kraj1[b.first][b.second][0]){///top
                g[a.first][a.second][2].push_back({b.first,b.second,2});
                g[b.first][b.second][2].push_back({a.first,a.second,2});
                brgrana += 2;
            }
            else if(kraj1[a.first][a.second][1] == kraj1[b.first][b.second][1]){///lovac
                g[a.first][a.second][1].push_back({b.first,b.second,1});
                g[b.first][b.second][1].push_back({a.first,a.second,1});
                brgrana += 2;
            }
            else if(kraj1[a.first][a.second][2] == kraj1[b.first][b.second][2]){///top
                g[a.first][a.second][2].push_back({b.first,b.second,2});
                g[b.first][b.second][2].push_back({a.first,a.second,2});
                brgrana += 2;
            }
            else if(kraj1[a.first][a.second][3] == kraj1[b.first][b.second][3]){///lovac
                g[a.first][a.second][1].push_back({b.first,b.second,1});
                g[b.first][b.second][1].push_back({a.first,a.second,1});
                brgrana += 2;
            }
        }
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(a[i][j]){
                continue;
            }
            ///isti
            for(int k = 0; k < 5; k++){
                for(int l = 0; l < 5; l++){
                    if(k == l){
                        continue;
                    }
                    g[i][j][k].push_back({i,j,l});
                    brgrana++;
                }
            }
            ///kralj
            for(int k = -1; k <= 1; k++){
                for(int l = -1; l <= 1; l++){
                    if(l == 0 && k == 0){
                        continue;
                    }
                    if(i+k >= 1 && i+k <= n && j+l >= 1 && j+l <= m && !a[i+k][j+l]){
                        g[i][j][0].push_back({i+k,j+l,0});
                        brgrana++;
                    }
                }
            }
            ///konj
            for(int k = 1; k <= 2; k++){
                for(int z1 = -1; z1 <= 1; z1++){
                    if(z1 == 0){
                        continue;
                    }
                    for(int z2 = -1; z2 <= 1; z2++){
                        if(z2 == 0){
                            continue;
                        }
                        int nx = i+k*z1,ny = j+(3-k)*z2;
                        if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && !a[nx][ny]){
                            g[i][j][3].push_back({i+k*z1,j+(3-k)*z2,3});
                            brgrana++;
                        }
                    }
                }
            }
            //cout << i << " " << j << " " << brgrana << endl;
        }
    }
    /*for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            for(int v = 0; v < 5; v++){
                cout << "cvor " << i << " " << j << " " << v << endl;
                for(auto f : g[i][j][v]){
                    cout << f.i << " " << f.j << " " << f.v << endl;
                }
            }
        }
    }*/
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            for(int v = 0; v < 5; v++){
                dist[i][j][v] = 1000000000;
            }
        }
    }
    dist[1][1][0] = 0;
    priority_queue <pi,vector<pi>,cmp> pq;
    cvor poc = {1,1,0};
    pq.push(make_pair(0,poc));
    while(!pq.empty()){
        cvor u = pq.top().second;
        pq.pop();
        gotov[u.i][u.j][u.v] = 1;
        for(auto f : g[u.i][u.j][u.v]){
            int vi = f.i,vj = f.j,t = f.v,cost = 1;
            if(u.i == vi && u.j == vj){ /// promena figure
                cost = t+1;
            }
            if(!gotov[vi][vj][t] && dist[vi][vj][t] > dist[u.i][u.j][u.v] + cost){
                dist[vi][vj][t] = dist[u.i][u.j][u.v]+cost;
                pq.push(pi(dist[vi][vj][t],f));
            }
        }
    }
    int sol = min({dist[n][m][0],dist[n][m][1],dist[n][m][2],dist[n][m][3],dist[n][m][4]});
    if(sol == inf){
        cout << -1 << endl;
    }
    else{
        cout << sol << endl;
    }
}