#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll MOD = 1e9+7;
const int N = 505;
const int INF = 1e9+5;
const int dirx[]={-1,0,1};
const int diry[]={-1,0,1};

struct State{
    int x,y,type,dist;
    State(int _x,int _y,int _type,int _dist){
        x=_x;
        y=_y;
        type=_type;
        dist=_dist;
    }
};

struct cmp{
    bool operator()(const State &fi,const State &se){
        return fi.dist>se.dist;
    }
};

int n,m;
priority_queue<State,vector<State>,cmp>pq;
char c[N][N];
int d[N][N][6];

bool ok(int x,int y){
    if(x>=1&&x<=n&&y>=1&&y<=m&&c[x][y]=='.')return true;
    return false;
}

int main()
{
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>c[i][j];
        }
    }

    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int k=1;k<=5;k++){
                d[i][j][k]=INF;
            }
        }
    }

    pq.push(State(1,1,1,0));
    d[1][1][1]=0;

    while(!pq.empty()){
        auto e=pq.top();
        pq.pop();
        int x=e.x;
        int y=e.y;
        int type=e.type;
        int dist=e.dist;

        if(d[x][y][type]<dist)continue;
        if(c[x][y]=='#')continue;
        d[x][y][type]=dist;

        for(int i=1;i<=5;i++){
            if(i!=type)pq.push(State(x,y,i,dist+i));/* change type */
        }
        if(type==1){
            for(int i=0;i<=2;i++){
                for(int j=0;j<=2;j++){
                    if(i==1&&j==1)continue;
                    int newx=x+dirx[i];
                    int newy=y+diry[j];
                    if(ok(newx,newy)){
                        if(d[newx][newy][1]>=dist+1)pq.push(State(newx,newy,1,dist+1));
                    }
                }
            }
        }else if(type==2){
            for(int i=1;;i++){
                int newx=x-i;
                int newy=y-i;
                if(ok(newx,newy)){
                    if(d[newx][newy][2]>=dist+1)pq.push(State(newx,newy,2,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x-i;
                int newy=y+i;
                if(ok(newx,newy)){
                    if(d[newx][newy][2]>=dist+1)pq.push(State(newx,newy,2,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x+i;
                int newy=y-i;
                if(ok(newx,newy)){
                    if(d[newx][newy][2]>=dist+1)pq.push(State(newx,newy,2,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x+i;
                int newy=y+i;
                if(ok(newx,newy)){
                    if(d[newx][newy][2]>=dist+1)pq.push(State(newx,newy,2,dist+1));
                }else break;
            }
        }else if(type==3){
            for(int i=1;;i++){
                int newx=x-i;
                int newy=y;
                if(ok(newx,newy)){
                    if(d[newx][newy][3]>=dist+1)pq.push(State(newx,newy,3,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x+i;
                int newy=y;
                if(ok(newx,newy)){
                    if(d[newx][newy][3]>=dist+1)pq.push(State(newx,newy,3,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x;
                int newy=y-i;
                if(ok(newx,newy)){
                    if(d[newx][newy][3]>=dist+1)pq.push(State(newx,newy,3,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x;
                int newy=y+i;
                if(ok(newx,newy)){
                    if(d[newx][newy][3]>=dist+1)pq.push(State(newx,newy,3,dist+1));
                }else break;
            }
        }else if(type==4){
            int newx,newy;
            newx=x-2,newy=y-1;if(ok(newx,newy))if(d[newx][newy][4]>=dist+1)pq.push(State(newx,newy,4,dist+1));
            newx=x-2,newy=y+1;if(ok(newx,newy))if(d[newx][newy][4]>=dist+1)pq.push(State(newx,newy,4,dist+1));

            newx=x+2,newy=y-1;if(ok(newx,newy))if(d[newx][newy][4]>=dist+1)pq.push(State(newx,newy,4,dist+1));
            newx=x+2,newy=y+1;if(ok(newx,newy))if(d[newx][newy][4]>=dist+1)pq.push(State(newx,newy,4,dist+1));

            newx=x-1,newy=y-2;if(ok(newx,newy))if(d[newx][newy][4]>=dist+1)pq.push(State(newx,newy,4,dist+1));
            newx=x+1,newy=y-2;if(ok(newx,newy))if(d[newx][newy][4]>=dist+1)pq.push(State(newx,newy,4,dist+1));

            newx=x-1,newy=y+2;if(ok(newx,newy))if(d[newx][newy][4]>=dist+1)pq.push(State(newx,newy,4,dist+1));
            newx=x+1,newy=y+2;if(ok(newx,newy))if(d[newx][newy][4]>=dist+1)pq.push(State(newx,newy,4,dist+1));
        }else{
            /* parallel to x and y axis*/
            for(int i=1;;i++){
                int newx=x-i;
                int newy=y;
                if(ok(newx,newy)){
                    if(d[newx][newy][5]>=dist+1)pq.push(State(newx,newy,5,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x+i;
                int newy=y;
                if(ok(newx,newy)){
                    if(d[newx][newy][5]>=dist+1)pq.push(State(newx,newy,5,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x;
                int newy=y-i;
                if(ok(newx,newy)){
                    if(d[newx][newy][5]>=dist+1)pq.push(State(newx,newy,5,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x;
                int newy=y+i;
                if(ok(newx,newy)){
                    if(d[newx][newy][5]>=dist+1)pq.push(State(newx,newy,5,dist+1));
                }else break;
            }

            /* diagonal */
            for(int i=1;;i++){
                int newx=x-i;
                int newy=y-i;
                if(ok(newx,newy)){
                    if(d[newx][newy][5]>=dist+1)pq.push(State(newx,newy,5,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x-i;
                int newy=y+i;
                if(ok(newx,newy)){
                    if(d[newx][newy][5]>=dist+1)pq.push(State(newx,newy,5,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x+i;
                int newy=y-i;
                if(ok(newx,newy)){
                    if(d[newx][newy][5]>=dist+1)pq.push(State(newx,newy,5,dist+1));
                }else break;
            }
            for(int i=1;;i++){
                int newx=x+i;
                int newy=y+i;
                if(ok(newx,newy)){
                    if(d[newx][newy][5]>=dist+1)pq.push(State(newx,newy,5,dist+1));
                }else break;
            }
        }
    }

    int ans=min(d[n][m][1],min(d[n][m][2],min(d[n][m][3],min(d[n][m][4],d[n][m][5]))));
    if(ans==INF)ans=-1;

    cout<<ans;
    return 0;
}
/*

10 10
..#.......
..#.......
..#.......
..##...#..
..######..
..#....#..
..#....#..
..#....#..
.......#..
.......#..

*/