/*



i read editional


*/
#include <iostream>

#include <vector>
#include <set>
#include <string>
#include <algorithm>
#include <utility>
#include <numeric>
#include <array>
#include <cmath>
#include <memory>
#include <queue>
using namespace std;
#define DEB(variable) cout << #variable << '=' << variable << endl

#define FOR(LoopVariable,numberOFbegin,numberOFend) for (long long int LoopVariable = (numberOFbegin); (LoopVariable) < (numberOFend); (LoopVariable)++)
#define DEFOR(LoopVariable,numberOFbegin,numberOFend) for (long long int LoopVariable = (numberOFbegin)-1; (LoopVariable) >= (numberOFend); (LoopVariable)--)
#define REP(LoopVariable,numberOFend) for(long long int LoopVariable = 0;(LoopVariable)<(numberOFend);LoopVariable++)

using llint = long long int;

constexpr long long int linf = numeric_limits<long long int>::max()-5;
constexpr long long int inf= numeric_limits<int>::max()-5;
constexpr long long int mod = 1000000007;

int main(){
    llint h, w;
    cin >> h >> w;
    vector<string> grids(h);
    REP(i,h){
        cin >> grids[i];
    }

    struct cell{
        llint y;
        llint x;
        llint cost;
    };
    queue<cell> q;
    vector<vector<llint>> resultgrid(h, vector<llint>(w, linf));
    REP(i,h){
        REP(j,w){
            if(grids[i][j]=='#'){
                resultgrid[i][j] = 0;
                q.push({i, j, 0});
            }
        }
    }
    while(!q.empty()){
        if(0<q.front().y){
            if(grids[q.front().y-1][q.front().x]=='.'){
                grids[q.front().y-1][q.front().x]='#';

                resultgrid[q.front().y-1][q.front().x] = min(resultgrid[q.front().y-1][q.front().x],
                                                 q.front().cost + 1);
                q.push({q.front().y - 1, q.front().x, q.front().cost + 1});
            }
        }
        if(q.front().y<h-1){
            if(grids[q.front().y+1][q.front().x]=='.'){
                grids[q.front().y+1][q.front().x]='#';
                resultgrid[q.front().y+1][q.front().x] = min(resultgrid[q.front().y+1][q.front().x],
                                                 q.front().cost + 1);
                q.push({q.front().y + 1, q.front().x, q.front().cost + 1});
            }
        }
        if(0<q.front().x){
            if(grids[q.front().y][q.front().x-1]=='.'){
                grids[q.front().y][q.front().x-1]='#';
                resultgrid[q.front().y][q.front().x-1] = min(resultgrid[q.front().y][q.front().x-1],
                                                 q.front().cost + 1);
                q.push({q.front().y, q.front().x-1, q.front().cost + 1});
            }
        }
        if(q.front().x<w-1){
            if(grids[q.front().y][q.front().x+1]=='.'){
                grids[q.front().y][q.front().x+1]='#';
                resultgrid[q.front().y][q.front().x+1] = min(resultgrid[q.front().y][q.front().x+1],
                                                 q.front().cost + 1);
                q.push({q.front().y, q.front().x+1, q.front().cost + 1});
            }
        }
        q.pop();
    }
    llint result=0;
    REP(i,h){
        REP(j,w){
            result = max(result, resultgrid[i][j]);
        }
    }
    cout << result << endl;
}

Measured memory_bytes: 33280