#include <iostream>
#include <bits/stdc++.h>

using namespace std;

int n, m;

bool obstacle[501][501];
int costmat[501][501];
int piecestate[501][501];

void makemove(int x, int y, int piece, bool s, int totalcost);

void comparestates(int x, int y, int piece, int totalcost){
	//cout << "trazimo kod " << x << ", " << y << "(kosta " << totalcost << "-" << piece << " vs " << costmat[x][y] << " - " << piecestate[x][y] << " trenutno) " << endl;
	if(totalcost - piece <= costmat[x][y] - piecestate[x][y]){
		costmat[x][y] = totalcost;
		piecestate[x][y] = piece;
		//cout << "tu smo" << endl;
		makemove(x, y, piece, false, totalcost);
	}
}

void makemove(int x, int y, int piece, bool s, int totalcost){
	
	//cout << "ali da li smo zaista tu?" << endl;
	for (int g = 1; g <= 5 && !s; g++){
		if (g != piece){
			makemove(x,y,g,true,totalcost+g);
		}
	}
	int i;
	int j;
	bool stop = false;
	switch(piece){
		case 1:
			//gore levo
			i = x-1;
			j = y-1;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
					j--;
				}
			}
			//gore desno
			i = x-1;
			j = y+1;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
					j++;
				}
			}
			//dole levo
			i = x+1;
			j = y-1;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
					j--;
				}
			}
			//dole desno
			i = x+1;
			j = y+1;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
					j++;
				}
			}
			//gore
			i = x-1;
			j = y;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
				}
			}
			//levo
			i = x;
			j = y-1;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					j--;
				}
			}
			//dole
			i = x+1;
			j = y;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
				}
			}
			//desno
			i = x;
			j = y+1;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					j++;
				}
			}
			break;
		case 2:
			//gore levo
			i = x-1;
			j = y-1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
					j--;
				}
			}
			//gore desno
			i = x-1;
			j = y+1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
					j++;
				}
			}
			//dole levo
			i = x+1;
			j = y-1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
					j--;
				}
			}
			//dole desno
			i = x+1;
			j = y+1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
					j++;
				}
			}
			break;
		case 3:
			//gore
			i = x-1;
			j = y;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
				}
			}
			//levo
			i = x;
			j = y-1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					j--;
				}
			}
			//dole
			i = x+1;
			j = y;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
				}
			}
			//desno
			i = x;
			j = y+1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					j++;
				}
			}
			break;
		case 4:
			//gore levo
			i = x-1;
			j = y-2;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
					j--;
				}
			}
			//gore desno
			i = x-1;
			j = y+2;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
					j++;
				}
			}
			//dole levo
			i = x+1;
			j = y-2;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
					j--;
				}
			}
			//dole desno
			i = x+1;
			j = y+2;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
					j++;
				}
			}
			//gore levo
			i = x-2;
			j = y-1;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
					j--;
				}
			}
			//gore desno
			i = x-2;
			j = y+1;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
					j++;
				}
			}
			//dole levo
			i = x+2;
			j = y-1;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
					j--;
				}
			}
			//dole desno
			i = x+2;
			j = y+1;
			stop = false;
			if (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
					j++;
				}
			}
			break;
		case 5:
			//gore levo
			i = x-1;
			j = y-1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
					j--;
				}
			}
			//gore desno
			i = x-1;
			j = y+1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
					j++;
				}
			}
			//dole levo
			i = x+1;
			j = y-1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
					j--;
				}
			}
			//dole desno
			i = x+1;
			j = y+1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
					j++;
				}
			}
			//gore
			i = x-1;
			j = y;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i--;
				}
			}
			//levo
			i = x;
			j = y-1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					j--;
				}
			}
			//dole
			i = x+1;
			j = y;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					i++;
				}
			}
			//desno
			i = x;
			j = y+1;
			stop = false;
			while (i >= 0 && j >= 0 && i < n && j < m && !stop){
				if(obstacle[i][j]){
					stop = true;
				}
				else {
					comparestates(i,j,piece,totalcost+1);
					j++;
				}
			}
			break;
	}
	
}



int main(int argc, char** argv) {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cerr.tie(0);
	
	cin >> n >> m;
	
	string input;
	
	for (int i = 0; i < n; i++){
		cin >> input;
		for (int j = 0; j < m; j++){
			if(input[j] == '#'){
				obstacle[i][j] = true;
			}
			else {
				obstacle[i][j] = false;
			}
		}
	}
	
	for (int i = 0; i < n; i++){
		for (int j = 0; j < m; j++){
			costmat[i][j] = 999999999;
			piecestate[i][j] = 0;
		}
	}
	
	costmat[0][0] = 0;
	piecestate[0][0] = 1;
	
	
	makemove(0,0,1,false,0);
	
	if(costmat[n-1][m-1] == 999999999){
		cout << -1 << endl;
	}
	else {
		cout << costmat[n-1][m-1] << endl;
	}
	
	
	
	return 0;
}