#include <bits/stdc++.h>

#define MAXN 505
#define INF 100000000
#define mt make_tuple

using namespace std;

char matrix[MAXN][MAXN];

int weight(int x) {

    if(x == 0)
        return 1;
    if(x == 1)
        return 2;
    if(x == 2)
        return 3;
    if(x == 3)
        return 4;
    return 5;
}

void dijkstra(int h, int w) {

    int dist[h][w][5];
    bool processed[h][w][5];
    for(int i = 0; i < h; i++)
        for(int j = 0; j < w; j++)
            for(int k = 0; k < 5; k++)
                dist[i][j][k] = INF, processed[i][j][k] = false;
    dist[0][0][0] = 0;

    priority_queue< pair<int, tuple<int, int, int> > > pq;
    pq.push({0, mt(0, 0, 0)});
    while(!pq.empty()) {
        int i, j, f;
        tie(i, j, f) = pq.top().second;
        pq.pop();

        processed[i][j][f] = true;
        for(int k = 0; k < 5; k++) {
            if(k == f)
                continue;
            
            if(dist[i][j][k] > dist[i][j][f] + weight(k)) {
                dist[i][j][k] = dist[i][j][f] + weight(k);

                if(!processed[i][j][k])
                    pq.push({-dist[i][j][k], mt(i, j, k)});
            }
        }

        if(f == 0) {
            for(int p1 = -1; p1 <= 1; p1++) {
                for(int p2 = -1; p2 <= 1; p2++) {
                    if((p1 == 0 && p2 == 0)
                        || i + p1 < 0 || h <= i + p1 || j + p2 < 0 || w <= j + p2
                            || matrix[i + p1][j + p2] == '#')
                        continue;
                    
                    if(dist[i + p1][j + p2][f] > dist[i][j][f] + 1) {
                        dist[i + p1][j + p2][f] = dist[i][j][f] + 1;

                        if(!processed[i + p1][j + p2][f])
                            pq.push({-dist[i + p1][j + p2][f], mt(i + p1, j + p2, f)});
                    }
                }
            }
            continue;
        }

        if(f == 1 || f == 4) {
            for(int p = 1; ; p++) {
                if(i + p >= h || j + p >= w || matrix[i + p][j + p] == '#')
                    break;
                
                if(dist[i + p][j + p][f] > dist[i][j][f] + 1) {
                    dist[i + p][j + p][f] = dist[i][j][f] + 1;

                    if(!processed[i + p][j + p][f])
                        pq.push({-dist[i + p][j + p][f], mt(i + p, j + p, f)});
                }
            }
            for(int p = 1; ; p++) {
                if(i - p < 0 || j - p < 0 || matrix[i - p][j - p] == '#')
                    break;
                
                if(dist[i - p][j - p][f] > dist[i][j][f] + 1) {
                    dist[i - p][j - p][f] = dist[i][j][f] + 1;

                    if(!processed[i - p][j - p][f])
                        pq.push({-dist[i - p][j - p][f], mt(i - p, j - p, f)});
                }
            }
            for(int p = 1; ; p++) {
                if(i - p < 0 || j + p >= w || matrix[i - p][j + p] == '#')
                    break;
                
                if(dist[i - p][j + p][f] > dist[i][j][f] + 1) {
                    dist[i - p][j + p][f] = dist[i][j][f] + 1;

                    if(!processed[i - p][j + p][f])
                        pq.push({-dist[i - p][j + p][f], mt(i - p, j + p, f)});
                }
            }
            for(int p = 1; ; p++) {
                if(i + p >= h || j - p < 0 || matrix[i + p][j - p] == '#')
                    break;
                
                if(dist[i + p][j - p][f] > dist[i][j][f] + 1) {
                    dist[i + p][j - p][f] = dist[i][j][f] + 1;

                    if(!processed[i + p][j - p][f])
                        pq.push({-dist[i + p][j - p][f], mt(i + p, j - p, f)});
                }
            }
        }

        if(f == 2 || f == 4) {
            for(int p = 1; ; p++) {
                if(i + p >= h || matrix[i + p][j] == '#')
                    break;
                
                if(dist[i + p][j][f] > dist[i][j][f] + 1) {
                    dist[i + p][j][f] = dist[i][j][f] + 1;

                    if(!processed[i + p][j][f])
                        pq.push({-dist[i + p][j][f], mt(i + p, j, f)});
                }
            }
            for(int p = 1; ; p++) {
                if(i - p < 0 || matrix[i - p][j] == '#')
                    break;
                
                if(dist[i - p][j][f] > dist[i][j][f] + 1) {
                    dist[i - p][j][f] = dist[i][j][f] + 1;

                    if(!processed[i - p][j][f])
                        pq.push({-dist[i - p][j][f], mt(i - p, j, f)});
                }
            }
            for(int p = 1; ; p++) {
                if(j + p >= w || matrix[i][j + p] == '#')
                    break;
                
                if(dist[i][j + p][f] > dist[i][j][f] + 1) {
                    dist[i][j + p][f] = dist[i][j][f] + 1;

                    if(!processed[i][j + p][f])
                        pq.push({-dist[i][j + p][f], mt(i, j + p, f)});
                }
            }
            for(int p = 1; ; p++) {
                if(j - p < 0 || matrix[i][j - p] == '#')
                    break;
                
                if(dist[i][j - p][f] > dist[i][j][f] + 1) {
                    dist[i][j - p][f] = dist[i][j][f] + 1;

                    if(!processed[i][j - p][f])
                        pq.push({-dist[i][j - p][f], mt(i, j - p, f)});
                }
            }
        }

        if(f == 3) {
            for(int p1 = -2; p1 <= 2; p1++) {
                for(int p2 = -2; p2 <= 2; p2++) {
                    int x = i + p1, y = i + p2;
                    
                    if(p1 != p2 && p1 != 0 && p2 != 0 && 0 <= x < h && 0 <= y < w && matrix[x][y] != '#') {
                        if(dist[x][y][f] > dist[i][j][f] + 1) {
                            dist[x][y][f] = dist[i][j][f] + 1;

                        if(!processed[x][y][f])
                            pq.push({-dist[x][y][f], mt(x, y, f)});
                        }
                    }
                }
            }
        }
    }

    int sol = INF;
    for(int i = 0; i < 5; i++)
        sol = min(sol, dist[h - 1][w - 1][i]);
    
    if(sol == INF)
        cout << -1 << endl;
    else
        cout << sol << endl;
}

int main() {

    int h, w;
    cin >> h >> w;

    for(int i = 0; i < h; i++)
        for(int j = 0; j < w; j++)
            cin >> matrix[i][j];
    
    dijkstra(h, w);
    return 0;
}