#include<bits/stdc++.h>
using namespace std;
int Kralj=0;
int Lovac= 1;
int Top= 2;
int Konj= 3;
int Kraljica= 4;
int n,m;
const int KingX[8]={1,1,1,-1,-1,-1,0,0};
const int KingY[8]={0,1,-1,0,1,-1,1,-1};
const int HorseX[8]={-1,-1,1,1,-2,-2,2,2};
const int HorseY[8]={2,-2,2,-2,1,-1,1,-1};

const int QueenX[8]={1,1,1,-1,-1,-1,0,0};
const int QueenY[8]={0,1,-1,0,1,-1,1,-1};
const int CannonX[4]={0,0,-1,1};
const int CannonY[4]={1,-1,0,0};
const int BishopX[4]={1,1,-1,-1};
const int BishopY[4]={-1,1,-1,1};
void Check(vector <string> &a,int x=0,int y=0){
    if(x<0||y<0||x>=a.size()||y>a[0].size())return;
    if(a[x][y]!='.')return;
    a[x][y]='Z';
    for(int i=0;i<8;i++){
        Check(a,x+KingX[i],y+KingY[i]);
        Check(a,x+HorseX[i],y+HorseY[i]);
    }

}
void Die(int code){
    cout <<code<<endl;
    exit(0);
}
struct Move{
int x,y,Cena,Figure;
};
struct CompareMoves{
    bool operator()(Move const& A,Move  const&B){
        return A.Cena>B.Cena;
    }
};

vector <vector<int> > DP[5];
vector <vector<bool> > Bio[5];
Move MakeMove(int xx,int yy,int f,int c){
Move m;
m.x=xx;
m.y=yy;
m.Cena=c;
m.Figure=f;
return m;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cerr.tie(0);
cin >>n>>m;

vector <string> a(n);
string s;

for(int i=0;i<n;i++)cin >>a[i];
 vector <string> cpy(n);
    cpy=a;
    Check(cpy);
    if(cpy[n-1][m-1]!='Z')Die(-1);

for(int i=0;i<5;i++)DP[i].resize(n,vector <int> (m,10000000));
for(int i=0;i<5;i++)Bio[i].resize(n,vector <bool> (m));

priority_queue<Move,vector <Move>,CompareMoves > pq;
    for(int i=0;i<5;i++){
        pq.push(MakeMove(0,0,i,i+1-(i==Kralj)));
    }
    int solved=0;

    while(pq.size()&&solved<=n*m*5){
        Move Current=pq.top();
        ///cout <<Current.Figure<<" "<<Current.x<<" "<<Current.y<<endl;


        pq.pop();
        if(Current.x<0||Current.y<0||Current.x>=n||Current.y>=m)continue;
        if(Bio[Current.Figure][Current.x][Current.y])continue;
        if(a[Current.x][Current.y]=='#')continue;
        Bio[Current.Figure][Current.x][Current.y]=true;
        DP[Current.Figure][Current.x][Current.y]=Current.Cena;
solved++;
        for(int i=0;i<5;i++){
            if(Current.Figure==i)continue;
           if(DP[i][Current.x][Current.y]>Current.Cena+i+1){
            DP[i][Current.x][Current.y]=Current.Cena+i+1;
            pq.push(MakeMove(Current.x,Current.y,i,Current.Cena+i+1));
           }

        }

        if(Current.Figure==Kralj){
            for(int i=0;i<8;i++){
                    if(Current.x+KingX[i]<0||Current.y+KingY[i]<0||Current.x+KingX[i]>=n||Current.y+KingY[i]>=m)break;
             if(DP[Kralj][Current.x+KingX[i]][Current.y+KingY[i]]>Current.Cena+1){
                 DP[Kralj][Current.x+KingX[i]][Current.y+KingY[i]]=Current.Cena+1;
                pq.push(MakeMove(Current.x+KingX[i],Current.y+KingY[i],Kralj,Current.Cena+1));
             }
            }
        }

        if(Current.Figure==Konj){
             for(int i=0;i<8;i++){
            if(Current.x+HorseX[i]<0||Current.y+HorseY[i]<0||Current.x+HorseX[i]>=n||Current.y+HorseY[i]>=m)break;
             if(DP[Konj][Current.x+HorseX[i]][Current.y+HorseY[i]]>Current.Cena+1){
                 DP[Konj][Current.x+HorseX[i]][Current.y+HorseY[i]]=Current.Cena+1;
                pq.push(MakeMove(Current.x+HorseX[i],Current.y+HorseY[i],Konj,Current.Cena+1));
             }
            }
        }

        if(Current.Figure==Kraljica){
            for(int i=0;i<8;i++){
                int X=Current.x+QueenX[i];
                int Y=Current.y+QueenY[i];
                while(X>=0&&X<n&&Y>=0&&Y<m&&a[X][Y]!='#'){
                    if(DP[Kraljica][X][Y]>Current.Cena+1){
                            DP[Kraljica][X][Y]=Current.Cena+1;
                       pq.push(MakeMove(X,Y,Kraljica,Current.Cena+1));
                    }


                    X+=QueenX[i];
                    Y+=QueenY[i];


                }
            }
        }

        if(Current.Figure==Lovac){
            for(int i=0;i<4;i++){
               int X=Current.x+BishopX[i];
                int Y=Current.y+BishopY[i];
                while(X>=0&&X<n&&Y>=0&&Y<m&&a[X][Y]!='#'){
                    if(DP[Lovac][X][Y]>Current.Cena+1){
                            DP[Lovac][X][Y]=Current.Cena+1;
                       pq.push(MakeMove(X,Y,Lovac,Current.Cena+1));
                    }


                    X+=BishopX[i];
                    Y+=BishopY[i];

            }
        }
        }

        if(Current.Figure==Top){
            for(int i=0;i<4;i++){
                int X=Current.x+CannonX[i];
                int Y=Current.y+CannonY[i];
                while(X>=0&&X<n&&Y>=0&&Y<m&&a[X][Y]!='#'){
                    if(DP[Top][X][Y]>Current.Cena+1){
                            DP[Top][X][Y]=Current.Cena+1;
                       pq.push(MakeMove(X,Y,Top,Current.Cena+1));
                    }


                    X+=CannonX[i];
                    Y+=CannonY[i];
                }
            }
        }


    }

        int rez=DP[0][n-1][m-1];
    int fig=0;
    for(int i=0;i<5;i++){
        if(rez>DP[i][n-1][m-1])fig=i;
    rez=min(rez,DP[i][n-1][m-1]);
    }
   /// cout <<"FIG: "<<fig<<endl;
    cout <<rez<<endl;

}