#include <bits/stdc++.h>
using namespace std;
#define f first
#define s second
#define pb push_back
#define sz(v) ((int)v.size())
#define rad(a) a * PI / 180
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef pair<int,char> ic;
typedef pair<ll, bool> llb;
const int SIGMA = 300;
const int MAX = 1000010;
const int MAXT = 1200010;
const int INF = 300000;
const int P = 1000000007;
const double EPS = 1e-6;
const double PI = 3.14159265358979;
const int UNVISITED = -1;
int n, m;
vector<string> mat;
void read(){
cin >> n >> m;
string row;
for(int i = 0; i < n; i++){
cin >> row;
mat.pb(row);
}
}
int di[] = {1, 0}, dj[] = {0, 1};
vector<int> graph[MAX];
void build_graph(){
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(mat[i][j] == '#') continue;
int v = i*m + j;
for(int k = 0; k < 2; k++){
int ni = i+di[k];
int nj = j+dj[k];
if(0 <= ni && ni < n &&
0 <= nj && nj < m &&
mat[ni][nj] == '.' ){
int u = ni*m + nj;
graph[u].pb(v);
graph[v].pb(u);
}
}
}
}
}
int dfs_counter, rootChild;
int dfs_num[MAX], dfs_low[MAX];
set<int> artVert;
void dfs(int u, int p){
dfs_num[u] = dfs_low[u] = dfs_counter++;
for(int i = 0; i < sz(graph[u]); i++){
int v = graph[u][i];
if(dfs_num[v] == UNVISITED){
if(p == -1) rootChild++;
dfs(v, u);
if(dfs_low[u] <= dfs_low[v]){
artVert.insert(u);
}
dfs_low[u] = min(dfs_low[u], dfs_low[v]);
}
else if(v != p){
dfs_low[u] = min(dfs_low[u], dfs_num[v]);
}
}
}
void find_art_vert(){
for(int i = 0; i < MAX; i++){
dfs_num[i] = dfs_low[i] = UNVISITED;
}
dfs_counter = 0;
for(int i = 0; i < MAX; i++){
if(dfs_num[i] == UNVISITED){
rootChild = 0;
dfs(i, -1);
if(rootChild == 0) continue;
if(rootChild == 1) artVert.erase(i);
else artVert.insert(i);
}
}
}
int component[MAX];
void dfs2(int u, int comp){
component[u] = comp;
for(int i = 0; i < sz(graph[u]); i++){
int v = graph[u][i];
if(component[v] == UNVISITED && artVert.find(v) == artVert.end()){
dfs2(v, comp);
}
}
}
void find_components(){
for(int i = 0; i < MAX; i++){
component[i] = UNVISITED;
}
int comp = 0;
for(int i = 0; i < MAX; i++){
if(component[i] == UNVISITED){
dfs2(i, comp++);
}
}
}
set<int> vis;
void dfs3(int i, int j){
vis.insert(i*m+j);
for(int k = 0; k < 2; k++){
int ni = i+di[k];
int nj = j+dj[k];
if(0 <= ni && ni < n &&
0 <= nj && nj < m &&
mat[ni][nj] == '.' &&
vis.find(ni*m + nj) == vis.end() ){
dfs3(ni,nj);
}
}
}
bool no_path(){
dfs3(0,0);
return vis.find((n-1)*m + m-1) == vis.end();
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
read();
if(no_path()){
printf("0\n");
return 0;
}
build_graph();
find_art_vert();
find_components();
int end = (n-1)*m + m-1;
if(component[end] != component[0]){
printf("1\n");
}
else{
printf("2\n");
}
return 0;
}