#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 

using namespace __gnu_pbds;
using namespace std;

// MACROS

#define ll long long
#define ull unsigned long long
#define ld long double

#define vi vector<int>
#define vll vector<ll>
#define vld vector<ld>
#define u_s unordered_set

#define pii pair<int,int>
#define pll pair<ll,ll>

#define FOR(i, n) for (ll (i) = 0; i < n; i++)
#define FORN(i, a, b) for (ll (i) = a; i < b; i++)
#define FORE(i, l) for (auto (i) : l)

#define pb push_back
#define pob pop_back
#define emp emplace
#define fi first
#define se second

#define all(n) (n).begin(), (n).end()
#define in(n) cin >> (n);
#define debug(n) cout << #n << ": " << n << '\n';

// FUNCTIONS

template< typename T >
inline T gcd(T a, T b) { if (b) return gcd(b, a % b); return a; }

template< typename T >
inline T ext_gcd(T a, T b, T & x, T & y) { if (a == 0) { x = 0; y = 1; return b; } T x1, y1; T g = ext_gcd(b % a, a, x1, y1); x = y1 - (b / a) * x1; y = x1; return g; }

#define INF (ll)(1e9)

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);	
    //cout << setprecision(15);
        
    ll n, m;
    cin >> n >> m;
    vector<string> maze(n);
    FOR(i, n) cin >> maze[i];
    vector<vll> shadow(n, vll(m, INF));
    queue<ll> q;
    ll sr = 0;
    ll sc = 0;
    FOR(i, n)
    {
        FOR(j, m)
        {
            if (maze[i][j] == '.')
            {
                sr = i;
                sc = j;
            }
        }
    }
    q.push(sr); q.push(sc); q.push(0);
    while (!q.empty())
    {
        ll r = q.front(); q.pop();
        ll c = q.front(); q.pop();
        ll s = q.front(); q.pop();
        if (r < 0 || r >= n || c < 0 || c >= m || shadow[r][c] <= s || maze[r][c] == '#') continue;
        shadow[r][c] = s;
        q.push(r + 1); q.push(c); q.push(s + 1);
        q.push(r - 1); q.push(c); q.push(s + 1);
        q.push(r); q.push(c + 1); q.push(s + 1);
        q.push(r); q.push(c - 1); q.push(s + 1);
    }
    ll ma = -1;
    FOR(i, n)
    {
        FOR(j, m)
        {
            if (shadow[i][j] != INF && shadow[i][j] > ma)
            {
                sr = i;
                sc = j;
                ma = shadow[i][j];
            }
            shadow[i][j] = INF;
        }
    }
    q.push(sr); q.push(sc); q.push(0);
    while (!q.empty())
    {
        ll r = q.front(); q.pop();
        ll c = q.front(); q.pop();
        ll s = q.front(); q.pop();
        if (r < 0 || r >= n || c < 0 || c >= m || shadow[r][c] <= s || maze[r][c] == '#') continue;
        shadow[r][c] = s;
        q.push(r + 1); q.push(c); q.push(s + 1);
        q.push(r - 1); q.push(c); q.push(s + 1);
        q.push(r); q.push(c + 1); q.push(s + 1);
        q.push(r); q.push(c - 1); q.push(s + 1);
    }
    ma = -1;
    FOR(i, n)
    {
        FOR(j, m)
        {
            if (shadow[i][j] != INF && shadow[i][j] > ma)
            {
                sr = i;
                sc = j;
                ma = shadow[i][j];
            }
        }
    }
    cout << ma << '\n';
}

