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

#define long int64_t
#define endl '\n'

#ifdef OFFLINE
	#define logan(...) logg(#__VA_ARGS__, __VA_ARGS__)
	template<class Arg>
	void logg(const char* name, Arg&& arg){ cerr << name << ": " << arg << '\n'; }
	template<class Arg, class ... Args>
	void logg(const char* name, Arg&& arg, Args&& ... args){
		char *next = (char*)name, *cand;
		int depth = 0;
		do{
			if(depth){ next = strchr(next+1, ')'); --depth; }
			else if((cand = strchr(next+1, '('))){ next = cand; ++depth; }
			else{ next = strchr(next+1, ','); }
		}while(depth);
		cerr.write(name, next-name) << ": " << arg << ",";
		logg(next+1, args...);
	}
	#define timeme 1.0*clock()/CLOCKS_PER_SEC
#else
	#define logan(...) {}
	#define timeme {}
#endif

enum fig{
	KING = 0,
	BISHOP,
	ROOK,
	KNIGHT,
	QUEEN
};

struct pr{
	int a, b;

	bool operator< (const pr& o) const{
		return a < o.a;
	}
};

pr mov[4][8] = {
	{{1, 0}, {0, 1}, {1, -1}, {-1, 1}, {1, 1}, {-1, -1}, {-1, 0}, {0, -1}},
	{{0, 0}},
	{{0, 0}},
	{{2, 1}, {2, -1}, {1, 2}, {1, -2}, {-1, 2}, {-1, -2}, {-2, 1}, {-2, -1}},
};

int n, m;
int a[501][501];
pr dp[501][501];


int valid(int x, int y){
	return x >= 0 && x < n && y >= 0 && y < m && !a[x][y];
}

int fmt(int x, int y){
	return x*m+y;
}

pr ifmt(int f){
	return {f/m, f%m};
}

pr real(int x, int y, int f){
	return {dp[x][y].a + (f != dp[x][y].b)*(f+1), dp[x][y].b};
}

int v[501*501];

void fillK(){
	memset(v, 0, sizeof v);
	queue<pr> q;
	q.push({fmt(0, 0), -1});
	v[fmt(0, 0)] = 1;

	while(!q.empty()){
		pr c = q.front();
		q.pop();
		pr ff = ifmt(c.a);
		dp[ff.a][ff.b] = min(dp[ff.a][ff.b], {c.b+1, KING});

		for(int i = 0; i < 8; ++i){
			int dx = ff.a+mov[KING][i].a;
			int dy = ff.b+mov[KING][i].b;

			if(!valid(dx, dy)) continue;
			if(v[fmt(dx, dy)]) continue;

			q.push({fmt(dx, dy), c.b+1});
			v[fmt(dx, dy)] = 1;
		}
	}
}

void fillN(){
	memset(v, 0, sizeof v);
	queue<pr> q;
	q.push({fmt(0, 0), 3});
	v[fmt(0, 0)] = 1;

	while(!q.empty()){
		pr c = q.front();
		q.pop();
		pr ff = ifmt(c.a);
		dp[ff.a][ff.b] = min(dp[ff.a][ff.b], min(real(ff.a, ff.b, KNIGHT), {c.b+1, KNIGHT}));

		for(int i = 0; i < 8; ++i){
			int dx = ff.a+mov[KNIGHT][i].a;
			int dy = ff.b+mov[KNIGHT][i].b;

			if(!valid(dx, dy)) continue;
			if(v[fmt(dx, dy)]) continue;

			q.push({fmt(dx, dy), c.b+1});
			v[fmt(dx, dy)] = 1;
		}
	}
}

void fillR(){
	memset(v, 0, sizeof v);
	queue<pr> q;
	q.push({fmt(0, 0), 2});
	v[fmt(0, 0)] = 1;

	while(!q.empty()){
		pr c = q.front();
		q.pop();
		pr ff = ifmt(c.a);
		dp[ff.a][ff.b] = min(dp[ff.a][ff.b], min(real(ff.a, ff.b, ROOK), {c.b+1, ROOK}));

		if(ff.a == ff.b && ff.a == 9) logan('c');

		for(int i = ff.a-1; valid(i, ff.b); --i){
			if(v[fmt(i, ff.b)]) continue;

			q.push({fmt(i, ff.b), c.b+1});
			v[fmt(i, ff.b)] = 1;
		}

		for(int i = ff.a+1; valid(i, ff.b); ++i){
			if(v[fmt(i, ff.b)]) continue;

			q.push({fmt(i, ff.b), c.b+1});
			v[fmt(i, ff.b)] = 1;
		}

		for(int i = ff.b-1; valid(ff.a, i); --i){
			if(v[fmt(ff.a, i)]) continue;

			q.push({fmt(ff.a, i), c.b+1});
			v[fmt(ff.a, i)] = 1;
		}

		for(int i = ff.b+1; valid(ff.a, i); ++i){
			if(v[fmt(ff.a, i)]) continue;

			q.push({fmt(ff.a, i), c.b+1});
			v[fmt(ff.a, i)] = 1;
		}
	}
}

void fillB(){
	memset(v, 0, sizeof v);
	queue<pr> q;
	q.push({fmt(0, 0), 1});
	v[fmt(0, 0)] = 1;

	while(!q.empty()){
		pr c = q.front();
		q.pop();
		pr ff = ifmt(c.a);
		dp[ff.a][ff.b] = min(dp[ff.a][ff.b], min(real(ff.a, ff.b, BISHOP), {c.b+1, BISHOP}));

		for(int dx = ff.a-1, dy = ff.b+1; valid(dx, dy); --dx, ++dy){
			if(v[fmt(dx, dy)]) continue;

			q.push({fmt(dx, dy), c.b+1});
			v[fmt(dx, dy)] = 1;
		}
		for(int dx = ff.a-1, dy = ff.b-1; valid(dx, dy); --dx, --dy){
			if(v[fmt(dx, dy)]) continue;

			q.push({fmt(dx, dy), c.b+1});
			v[fmt(dx, dy)] = 1;
		}
		for(int dx = ff.a+1, dy = ff.b-1; valid(dx, dy); ++dx, --dy){
			if(v[fmt(dx, dy)]) continue;

			q.push({fmt(dx, dy), c.b+1});
			v[fmt(dx, dy)] = 1;
		}
		for(int dx = ff.a+1, dy = ff.b+1; valid(dx, dy); ++dx, ++dy){
			if(v[fmt(dx, dy)]) continue;

			q.push({fmt(dx, dy), c.b+1});
			v[fmt(dx, dy)] = 1;
		}
	}
}

void fillQ(){
	memset(v, 0, sizeof v);
	queue<pr> q;
	q.push({fmt(0, 0), 4});
	v[fmt(0, 0)] = 1;

	while(!q.empty()){
		pr c = q.front();
		q.pop();
		pr ff = ifmt(c.a);
		dp[ff.a][ff.b] = min(dp[ff.a][ff.b], min(real(ff.a, ff.b, QUEEN), {c.b+1, QUEEN}));

		for(int i = ff.a-1; valid(i, ff.b); --i){
			if(v[fmt(i, ff.b)]) continue;

			q.push({fmt(i, ff.b), c.b+1});
			v[fmt(i, ff.b)] = 1;
		}

		for(int i = ff.a+1; valid(i, ff.b); ++i){
			if(v[fmt(i, ff.b)]) continue;

			q.push({fmt(i, ff.b), c.b+1});
			v[fmt(i, ff.b)] = 1;
		}

		for(int i = ff.b-1; valid(ff.a, i); --i){
			if(v[fmt(ff.a, i)]) continue;

			q.push({fmt(ff.a, i), c.b+1});
			v[fmt(ff.a, i)] = 1;
		}

		for(int i = ff.b+1; valid(ff.a, i); ++i){
			if(v[fmt(ff.a, i)]) continue;

			q.push({fmt(ff.a, i), c.b+1});
			v[fmt(ff.a, i)] = 1;
		}

		for(int dx = ff.a-1, dy = ff.b+1; valid(dx, dy); --dx, ++dy){
			if(v[fmt(dx, dy)]) continue;

			q.push({fmt(dx, dy), c.b+1});
			v[fmt(dx, dy)] = 1;
		}
		for(int dx = ff.a-1, dy = ff.b-1; valid(dx, dy); --dx, --dy){
			if(v[fmt(dx, dy)]) continue;

			q.push({fmt(dx, dy), c.b+1});
			v[fmt(dx, dy)] = 1;
		}
		for(int dx = ff.a+1, dy = ff.b-1; valid(dx, dy); ++dx, --dy){
			if(v[fmt(dx, dy)]) continue;

			q.push({fmt(dx, dy), c.b+1});
			v[fmt(dx, dy)] = 1;
		}
		for(int dx = ff.a+1, dy = ff.b+1; valid(dx, dy); ++dx, ++dy){
			if(v[fmt(dx, dy)]) continue;

			q.push({fmt(dx, dy), c.b+1});
			v[fmt(dx, dy)] = 1;
		}

	}

}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cerr.tie(nullptr);

	cin >> n >> m;
	for(int i = 0; i < n; ++i){
		string s; cin >> s;
		for(int j = 0; j < m; ++j){
			a[i][j] = s[j] == '#';
		}
	}

	#ifdef OFFLINE
		for(int i = 0; i < n; ++i){
			for(int j = 0; j < m; ++j){
				cerr << a[i][j] << ' ';
			}
			cerr << endl;
		}
			cerr << endl;
	#endif		

	for(int i = 0; i < n; ++i)
	for(int j = 0; j < m; ++j)
		dp[i][j] = {INT32_MAX-200, 0};

	#ifdef OFFLINE
		cerr << 'd';
		for(int i = 0; i < n; ++i){
			for(int j = 0; j < m; ++j){
				cerr << (dp[i][j].a != INT32_MAX-200 ? dp[i][j].a : 0) << ' ';
			}
			cerr << endl;
		}
		cerr << endl;
	#endif	

	fillK();
	/*
	#ifdef OFFLINE
		for(int i = 0; i < n; ++i){
			for(int j = 0; j < m; ++j){
				cerr << (dp[i][j].a != INT32_MAX-200 ? dp[i][j].a : 0) << ' ';
			}
			cerr << endl;
		}
		cerr << endl;
	#endif
	*/

	fillB();
	/*
	#ifdef OFFLINE
		for(int i = 0; i < n; ++i){
			for(int j = 0; j < m; ++j){
				cerr << (dp[i][j].a != INT32_MAX-200 ? dp[i][j].a : 0) << ' ';
			}
			cerr << endl;
		}
		cerr << endl;
	#endif
	*/
	fillR();
	/*
	#ifdef OFFLINE
		for(int i = 0; i < n; ++i){
			for(int j = 0; j < m; ++j){
				cerr << (dp[i][j].a != INT32_MAX-200 ? dp[i][j].a : 0) << ' ';
			}
			cerr << endl;
		}
		cerr << endl;
	#endif
	*/
	fillN();
	/*
	#ifdef OFFLINE
		for(int i = 0; i < n; ++i){
			for(int j = 0; j < m; ++j){
				cerr << (dp[i][j].a != INT32_MAX-200 ? dp[i][j].a : 0) << ' ';
			}
			cerr << endl;
		}
		cerr << endl;
	#endif
	*/
	fillQ();
	/*
	#ifdef OFFLINE
		for(int i = 0; i < n; ++i){
			for(int j = 0; j < m; ++j){
				cerr << (dp[i][j].a != INT32_MAX-200 ? dp[i][j].a : 0) << ' ';
			}
			cerr << endl;
		}
		cerr << endl;
	#endif
	*/

	cout << dp[n-1][m-1].a << endl;


}