#include <iostream>
#include <queue>
#include <cstring>
#include <chrono>

using namespace std;

struct pos{
    int row;
    int col;
    pos(){}
    pos(int r, int c){
        row = r;
        col = c;
    }
};

int dc[4] = {1, 0, -1, 0};
int dr[4] = {0, 1, 0, -1};
char grid[1001][1001];
bool vis[1001][1001];
int R, C;

vector<pos> source;

bool out(int r, int c){return r<0 || c<0 || r>=R || c>=C;}

void mark_source()
{
    for(int i=0; i<R; i++){
        for(int j=0; j<C; j++){
            if(grid[i][j] == '#') source.push_back(pos(i, j));
        }
    }
}

int blackout()
{
    if(source.empty() || (R == 1 && C == 1)) return 0;

    queue<pos> Q;
    queue<pos> layer;
    int turn_count = 0, new_row, new_col;

    for(auto i : source){
        vis[i.row][i.col] = true;
        Q.push(i);
    }

    while(!Q.empty()){
        
        layer = Q;
        Q = {};

        while(!layer.empty()){
            for(int i=0; i<4; i++){
                new_row = layer.front().row + dr[i];
                new_col = layer.front().col + dc[i];

                if(out(new_row, new_col) || vis[new_row][new_col]) continue;

                Q.push(pos(new_row, new_col));
                vis[new_row][new_col] = true;
            }
            layer.pop();
        }
        
        if(!Q.empty()) turn_count++;
    }

    return turn_count;
}

int main()
{
    //auto start = chrono::steady_clock::now();

    freopen("dump.txt","r",stdin);
    memset(vis, false, sizeof(vis));
    cin >> R >> C;

    for(int i=0; i<R; i++){
        for(int j=0; j<C; j++){
            cin >> grid[i][j];
        }
    }

    mark_source();
    cout << blackout() << "\n";
/*
    auto end = chrono::steady_clock::now();
    auto diff = end - start;
    cout << chrono::duration <double, milli> (diff).count() << " ms" << endl;
//*/
    return 0;
}