#pragma GCC optimize("Ofast")
#include <iostream>
#include <map>
#include <vector>
#include <deque>
#include <queue>
#include <algorithm>
#include <bitset>
#include <cstring>
#include <math.h>
#include <string>
#include <set>
#include <iomanip>
#include <bitset>
#include <random>
#include <complex>
#include <random>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
using namespace std;
#define pb push_back
#define ll long long
#define mp make_pair
#define fdeg firdeg
#define snd second
#define ins insert
#define ld long double
#define mt make_tuple
#define fst first
const double PI = acos(-1);
// = 5e5 + 17;
ll MOD = 1e9 + 7;
const int INF = 1e9;
const int MaXN = 105;
const int N = 3e5;
const int maxlog = 18;
ld ecr = 1e-8;
random_device rd;
mt19937 rnd(rd());
uniform_int_distribution<ll> nextRand(0,(ll)1e9);
template<class A, class B>
void sum(A &a, B b)
{
    a += b;
    if (a < 0LL) a += MOD;
    if (a >= MOD) a -= MOD;
}
ll add(ll a, ll b)
{
    a += b;
    if (a < 0) a += MOD;
    if (a >= MOD) a -= MOD;
    return a;
    
}
int to_i(char c)
{
    return c - 'a';
}
ll mult(ll a, ll b)
{
    ll val = a * b - (ll) ((ld) a * b / MOD) * MOD;
    if (val < 0)
    {
        val += MOD;
    }
    if (val >= MOD)
    {
        val -= MOD;
    }
    return val;
}

ll gcd (ll a, ll b)
{
    if (b == 0)
        return a;
    else
        return gcd (b, a % b);
}
ll gcd_eu (ll a, ll b, ll & x, ll & y)
{
    if (a == 0)
    {
        x = 0LL; y = 1LL;
        return b;
    }
    ll x1, y1;
    ll d = gcd_eu (b%a, a, x1, y1);
    x = y1 - (b / a) * x1;
    y = x1;
    return d;
}
long long poww(long long a, long long b)
{
    long long val = 1;
    a %= MOD;
    while (b > 0)
    {
        if (b % 2) val = mult(a, val);
        a = mult(a, a);
        b >>= 1;
    }
    return val % MOD;
}
ll inv(ll a)
{
    return poww(a , MOD - 2);
}
char c[2000][2000];
bitset<1001> t[1001];
signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n , m;
    cin >> n >> m;
    int cnt = 0;
    queue<pair<int , int>> p;
    int cntx = 0;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            cin >> c[i][j];
            if(c[i][j] == '.')
            {
                cnt++;
            }
            else
            {
                cntx++;
                p.push(mp(i , j));
            }
        }
    }
    //cout << cnt << "\n";
    int ans = 0;
    
    while (cnt > 0)
    {
        ans++;
        int old = cntx;
        int it = 0;
        int x = p.size();
        for(int it = 0; it < x; it++)
        {
            pair<int , int> pt = p.front();
            p.pop();
            int i = pt.first;
            int j = pt.second;
            if(i - 1 >= 0 && c[i - 1][j] != '#')
            {
                cnt--;
                c[i - 1][j] = '#';
                p.push(mp(i - 1 , j));
                cntx++;
            }
            if(j - 1 >= 0 && c[i][j - 1] != '#')
            {
                cnt--;
                c[i][j - 1] = '#';
                p.push(mp(i , j - 1));
                cntx++;
            }
            if(i + 1 < n && c[i + 1][j] != '#')
            {
                cnt--;
                c[i + 1][j] = '#';
                p.push(mp(i + 1 , j));
                cntx++;
            }
            if(j + 1 < m && c[i][j + 1] != '#')
            {
                cnt--;
                c[i][j + 1] = '#';
                p.push(mp(i , j + 1));
                cntx++;
            }
        }
//        for(int i = 0; i < n; i++)
//        {
//            for(int j = 0; j < m; j++)
//            {
//                cout << c[i][j];
//            }
//            cout << "\n";
//        }
//        cout << "\n";
//        for(auto x : p)
//        {
//            cout << x.first << " " << x.second << "\n";
//        }
//        cout << "\n";
    }
    cout << ans << "\n";
    return 0;
}


Measured memory_bytes: 10384