// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;



int vis[1010][1010];

char ch[1010][1010];



int main() {

	memset(vis, -1, sizeof(vis));

	ios_base::sync_with_stdio(0);

	cin.tie(0); cout.tie(0);

	

	int x, y;

	cin >> x >> y;

	

	queue<pair<int, pair<int, int> > > q;

	for(int i = 1; i <= x; i++) {

		for(int j = 1; j <= y; j++) {

			cin >> ch[i][j];

			

			if(ch[i][j] == '#') {

				vis[i][j] = 0;

				q.push(make_pair(0, make_pair(i, j)));

			}

		}

	}

	

	int ans = 0;

	while(!q.empty()) {

		int val = q.front().first;

		int tarX = q.front().second.first;

		int tarY = q.front().second.second;

		q.pop();

		

		ans = max(ans, val);

		if(tarX < x && vis[tarX + 1][tarY] == -1) {

			vis[tarX + 1][tarY] = val + 1;

			q.push(make_pair(val + 1, make_pair(tarX + 1, tarY)));

		}

		

		if(tarX > 1 && vis[tarX - 1][tarY] == -1) {

			vis[tarX - 1][tarY] = val + 1;

			q.push(make_pair(val + 1, make_pair(tarX - 1, tarY)));

		}

		

		if(tarY < y && vis[tarX][tarY + 1] == -1) {

			vis[tarX][tarY + 1] = val + 1;

			q.push(make_pair(val + 1, make_pair(tarX, tarY + 1)));

		}

		

		if(tarY > 1 && vis[tarX][tarY - 1] == -1) {

			vis[tarX][tarY - 1] = val + 1;

			q.push(make_pair(val + 1, make_pair(tarX, tarY - 1)));

		}

	}

	

	cout << ans << "\n";

}

// Faster C++ solution for the same problem (measured speedup: 4.979443175508475x):
#include <bits/stdc++.h>

#define pb push_back



using namespace std;



void debug_out() { cerr << '\n'; }

template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) { cerr << " " << H; debug_out(T...);}

#define dbg(...) cerr << #__VA_ARGS__ << " ->", debug_out(__VA_ARGS__)

#define dbg_v(x, n) do{cerr<<#x"[]: ";for(int _=0;_<n;++_)cerr<<x[_]<<" ";cerr<<'\n';}while(0)

#define dbg_ok cerr<<"OK!\n"



typedef pair<int,int> pii;

typedef long long int ll;

typedef long double ld;



inline int two(int n) { return 1 << n; }

inline int test(int n, int pos) { return (bool) (n & two(pos)); }

inline void set_bit(int &n, int b) { n |= two(b); }

inline void unset_bit(int &n, int b) { n &= ~two(b); }

inline int last_bit(int n) { return n & (-n); }



const int DMAX = 1e3+10;



struct nume{

    int node,val;

};



vector <int> arb[DMAX];



queue <pii> Coada;



bool uz[DMAX][DMAX];

int M[DMAX][DMAX];



int dl[]={1,-1,0,0};

int dc[]={0,0,1,-1};



int n,ans,m;



void lee();



int main(){

    ios_base::sync_with_stdio(false);

    cin.tie(0);



    int t,i,j,val;

    char c;



    cin>>n>>m;

    for(i=1;i<=n;i++)

        for(j=1;j<=m;j++){

            cin>>c;

            if(c == '#'){

                Coada.push({i,j});

                uz[i][j]=true;

            }

        }

    lee();

    cout<<ans<<'\n';

    return 0;

}

void lee(){

    int i,k,x,y;

    pii node;

    while(!Coada.empty()){

            node=Coada.front();

            Coada.pop();

            for(k=0;k<4;k++){

                x=node.first+dl[k];

                y=node.second+dc[k];

                if(x>=1 && x<=n && y>=1 && y<=m && !uz[x][y]){

                   Coada.push({x,y});

                   M[x][y]=M[node.first][node.second]+1;

                   uz[x][y]=true;

                   ans=max(ans,M[x][y]);

                }

            }

      }

}