#include <bits/stdc++.h>

#define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
#define FILL0(x) memset(x,0,sizeof(x))

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
 

struct point {int x, y, cost; };

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);

    int H, W;
    cin >> H >> W;

    vector<string> maze(H);
    rep(i, H)
    {
        cin >> maze[i];
    }

    point start;

    bool ready = false;

    rep(i, H)
    {
        rep(j, W)
        {
            if(maze[i][j]=='.')
            {
                start.x = i;
                start.y = j;
                start.cost = 0;
                ready = true;
                break;
            }
        }
        if(ready)
        {
            break;
        }
    }

    queue<point> q;
    q.push(start);
    

    int dx[4] = {1, 0, -1, 0};
    int dy[4] = {0, 1, 0, -1};

    bool used[H][W]={false};

    while(!q.empty())
    {
        point cp = q.front();
        q.pop();
        int x = cp.x;
        int y = cp.y;

        rep(i, 4)
        {   
            if(0<=x+dx[i]&&x+dx[i]<W)
            if(0<=y+dy[i]&&y+dy[i]<H)
            if(maze[y+dy[i]][x+dx[i]]=='.')
            if(!used[y+dy[i]][x+dx[i]])
            {
                point tmp;
                tmp.x=x+dx[i];
                tmp.y=y+dy[i];
                tmp.cost=cp.cost+1;

                q.push(tmp);
                used[y+dy[i]][x+dx[i]]=true;
            }
        }
        if(q.empty())
        {
            start=cp;
            start.cost=0;
        }
    }

    q.push(start);

    bool used2[H][W]={false};

     while(!q.empty())
    {
        point cp = q.front();
        q.pop();
        int x = cp.x;
        int y = cp.y;

        rep(i, 4)
        {   
            if(x+dx[i]>=0&&x+dx[i]<W&&y+dy[i]>=0&&y+dy[i]<H&&maze[y+dy[i]][x+dx[i]]=='.'&& !used2[y+dy[i]][x+dx[i]])
            {
                point tmp;
                tmp.x=x+dx[i];
                tmp.y=y+dy[i];
                tmp.cost=cp.cost+1;

                q.push(tmp);
                used2[tmp.y][tmp.x]=true;
            }
        }

        if(q.empty())
        {
            cout << cp.cost << endl;
            return 0;
        }
    }




    
 

 

 

    return 0;
}
 

//cout << setprecision(13);
//next_permutation();
//__gcd();
//reverse();
//set ,tuple ,pair;
//bitset
//vector.find

