#include <bits/stdc++.h>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
typedef long long int ll;

#define PI (acos(-1))
#define REP(i,n) for(ll (i)=0;(i)<(n);(i)++)

#define dump(x)  cerr << #x << " = " << (x) << endl;
#define dumparr(x) cerr << #x ; for(auto elem: x){cerr << " " << elem;} cerr << endl;
#define dumppairs(x) cerr << #x ; for(auto elem: x){cerr << "(" << elem.first << " " << elem.second << ") ";} cerr << endl;
#define dumpline cerr << "**********************" << endl;
#define dumpwline(x) cerr << "******** " << #x << "=" << (x) << " ********" << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;
#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))

int main(void){
    ll h; cin >> h;
    ll w; cin >> w;
    vector <string> m;
    string pad;
    REP(i, w+2){
        pad += '#';
    }
    m.push_back(pad);
    REP(i, h){
        string s; cin >> s;
        m.push_back('#' + s + '#');
    }
    m.push_back(pad);

    vector <ll> start;
    REP(i, h+2){
        REP(j, w+2){
            if (m[i][j] == '.'){
                start = {i, j, 0};
            }
        }
    }
    dumparr(start)

    vector <pair <ll, ll>> dhdw = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

    queue <vector <ll>> nodes;
    vector <vector <bool>> visited(h+2, vector<bool>(w+2, false));
    nodes.push(start);
    visited[start[0]][start[1]] = true;
    vector <ll> now;
    while (!nodes.empty()){
        now = nodes.front();
        nodes.pop();
        REP(i, 4){
            ll next_h;
            ll next_w;
            next_h = now[0] + dhdw[i].first;
            next_w = now[1] + dhdw[i].second;
            if (visited[next_h][next_w]){
                continue;
            }
            if (m[next_h][next_w] == '#'){
                continue;
            }
            visited[next_h][next_w] = true;
            nodes.push({next_h, next_w, now[2]+1});
        }
    }

    REP(i, h+2){REP(j, w+2) {visited[i][j] = false;}}
    nodes.push({now[0], now[1], 0});
    visited[now[0]][now[1]] = true;
    while (!nodes.empty()){
        now = nodes.front();
        nodes.pop();
        REP(i, 4){
            ll next_h;
            ll next_w;
            next_h = now[0] + dhdw[i].first;
            next_w = now[1] + dhdw[i].second;
            if (visited[next_h][next_w]){
                continue;
            }

            if (m[next_h][next_w] == '#'){
                continue;
            }
            visited[next_h][next_w] = true;
            nodes.push({next_h, next_w, now[2]+1});
        }
    }
    cout << now[2] << endl;
    return 0;
}