#include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (int)(n); i++)
#define REP(i,n) for (int i = 1; i < (int)(n); i++)
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define debug(var) do{cout << #var << " : "; view(var);}while(0)
template<class T> bool chmin(T &a, T b) {if(a>b) {a=b;return 1;}return 0;}
template<class T> bool chmax(T &a, T b) {if(a<b) {a=b;return 1;}return 0;}
using namespace std;
template<class T> void view(T e) {cout << e << endl;}
template<class T> void view(const vector<T> &v) {for(const auto &e : v){cout << e << " ";} cout << endl;}
template<class T> void view(const vector<vector<T>> &vv) {for(const auto &v : vv){view(v);}}
using vint = vector<int>;
using vvint = vector<vector<int>>;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<int,int>;
const int inf = 1e9;
const ll inf_l = 1e18;
const int MAX = 1e5;

vint dx = {1,0,-1,0};
vint dy = {0,1,0,-1};

int main() {
    int h, w; cin >> h >> w;
    vector<string> field(h);
    rep(i,h) cin >> field[i];
    queue<P> q;
    rep(i,h)rep(j,w) if (field[i][j] == '#') q.push(P(i,j));
    int ans = 0;
    while (true) {
        if (q.empty()) {ans--; break;}
        queue<P> tmp_q;
        while (!q.empty()) {
            int x = q.front().second;
            int y = q.front().first;
            q.pop();
            rep(i,4) {
                int n_x = x + dx[i];
                int n_y = y + dy[i];
                if (n_x >= 0 && n_x < w && n_y >= 0 && n_y < h && field[n_y][n_x] != '#') {
                    field[n_y][n_x] = '#';
                    tmp_q.push(P(n_y,n_x));
                }
            }
        }
        swap(q,tmp_q);
        ans++;
    }
    cout << ans << endl;
}
#include <iostream>
#include <vector>
#include <string>
using namespace std;

class edge;

class vertex{
    public:
        vector<edge*> edges;
        int color;
        vertex(int _color){
            color = _color;
        }
};

class edge{
    public:
        vertex *to;
        edge(vertex *_to){
            to = _to;
        }
};

class list_node{
    public:
        list_node *prev,*next;
        vertex *data;
        list_node(list_node *_prev,list_node *_next,vertex *_data){
            prev = _prev;
            next = _next;
            data = _data;
        }
};

class list{
    public:
        list_node *back,*front;
        list(){
            back = new list_node(0,0,0);
            front = new list_node(0,back,0);
            back->prev = front;
        }
        list_node *get_first(){
            return front->next;
        }
        list_node *get_last(){
            return back->prev;
        }
        void push_back(vertex *data){
            list_node *node = back->prev;
            node->next = new list_node(node,back,data);
            back->prev = node->next;
        }
        bool isEmpty(){
            if(front->next == back) return true;
            return false;
        }
};

int bfs(list l){
    int count = 0;
    list *L = new list[10000];
    L[0] = l;
    while(true){
        for(list_node *j = L[count].get_first(); j != L[count].back; j = j->next){
            vertex *v = j->data;
            for(int k = 0; k < v->edges.size(); k++){
                vertex *to = v->edges[k]->to;
                if(to->color) continue;
                to->color = 1;
                L[count+1].push_back(to);
            }
        }
        if(L[count+1].isEmpty()) break;
        count++;
    }
    return count;
}

int main(){
    int H,W,color;
    string str;
    cin >> H >> W;
    list l;
    vertex *A[H+2][W+2];
    for(int i = 0; i <= H+1; i++){
        if(i != 0 && i != H+1) cin >> str;
        for(int j = 0; j <= W+1; j++){
            if(i  == 0 || j == 0 || i == H+1|| j == W+1){
                A[i][j] = new vertex(1);
            }else{
                if(str[j-1] == '.') color = 0;
                else color = 1;
                A[i][j] = new vertex(color);
            }
        }
    }

    for(int i = 1; i <= H; i++){
        for(int j = 1; j <= W; j++){
            if(A[i][j]->color) l.push_back(A[i][j]);
            A[i][j]->edges.push_back(new edge(A[i-1][j]));
            A[i][j]->edges.push_back(new edge(A[i][j+1]));
            A[i][j]->edges.push_back(new edge(A[i+1][j]));
            A[i][j]->edges.push_back(new edge(A[i][j-1]));
        }
    }

    cout << bfs(l) << endl;
    
}