stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



int n, m;

char arr[1010][1010];

int ans[1010][1010];

bool visited[1010][1010];

queue<pair<int, int>>bfs;



void solve(){

	while (!bfs.empty()){

		pair<int, int> tmp = bfs.front();

		bfs.pop();

		int temp1, temp2;



		temp1 = tmp.first+1;

		temp2 = tmp.second;

		if (temp1 >= 0 && temp2 >= 0 && temp1 < n && temp2 < m && !visited[temp1][temp2]){

			visited[temp1][temp2] = true;

			ans[temp1][temp2] = ans[tmp.first][tmp.second] + 1;

			bfs.push({temp1, temp2});

		}

		temp1 = tmp.first;

		temp2 = tmp.second+1;

		if (temp1 >= 0 && temp2 >= 0 && temp1 < n && temp2 < m && !visited[temp1][temp2]){

			visited[temp1][temp2] = true;

			ans[temp1][temp2] = ans[tmp.first][tmp.second] + 1;

			bfs.push({temp1, temp2});

		}

		temp1 = tmp.first-1;

		temp2 = tmp.second;

		if (temp1 >= 0 && temp2 >= 0 && temp1 < n && temp2 < m && !visited[temp1][temp2]){

			visited[temp1][temp2] = true;

			ans[temp1][temp2] = ans[tmp.first][tmp.second] + 1;

			bfs.push({temp1, temp2});

		}

		temp1 = tmp.first;

		temp2 = tmp.second-1;

		if (temp1 >= 0 && temp2 >= 0 && temp1 < n && temp2 < m && !visited[temp1][temp2]){

			visited[temp1][temp2] = true;

			ans[temp1][temp2] = ans[tmp.first][tmp.second] + 1;

			bfs.push({temp1, temp2});

		}

	}	

}



int main(){

	ios_base::sync_with_stdio(0); cin.tie(0);



	cin >> n >> m;

	for (int i = 0; i < n; i++){

		for (int j = 0; j < m; j++){

			cin >> arr[i][j];

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

				bfs.push({i, j});

				visited[i][j] = true;

			}

		}

	}



	solve();



	int anss = 0;

	for (int i = 0; i < n; i++){

		for (int j = 0; j < m; j++){

			anss = max(anss, ans[i][j]);

		}

	}



	cout << anss << endl;



	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.102172663886473x):
#include<cstdio>

#include<queue>

#include<algorithm>

using namespace std;



char c[1001][1002];

int d[1000001];

int main(){

	int n,m;

	scanf("%d%d",&n,&m);

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

		scanf("%s",c[i]+1);

	queue<int>q;

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

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

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

				q.push((i-1)*m+j);

				d[(i-1)*m+j]=1;

			}

	int ans=0;

	while(!q.empty()){

		int u=q.front();

		q.pop();

		ans=max(ans,d[u]);

		for(int i=0;i<4;i++){

			int v=u;

			if(i==0&&u<=m||i==1&&u%m==1%m||i==2&&u>=(n-1)*m+1||i==3&&u%m==0)

				continue;

			if(i==0)v-=m;

			else if(i==1)v--;

			else if(i==2)v+=m;

			else v++;

			if(!d[v]){

				d[v]=d[u]+1;

				q.push(v);

			}

		}

	}

	printf("%d\n",ans-1);

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

using namespace std;

int arr[1005][1005];

queue <pair<int,int> > q;

int langkah[1005][1005];

int main(){

	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	int x,y; cin >> x >> y;

	char c;

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

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

			cin >> c;

			langkah[i][j]=-1;

			if(c=='#'){

				arr[i][j]=1;

				q.push({i,j});

				langkah[i][j]=0;

			}

			else arr[i][j]=0;

		}

		while(!q.empty()){

			pair<int,int> qq;

			qq=q.front();

			int a = qq.first;

			int b = qq.second;

			q.pop();

			//cout << a <<' '<<b <<' '<<langkah[a][b]<<" LOL "<<endl;

			if(b<y && langkah[a][b+1]==-1){

				q.push({a,b+1}); 

				langkah[a][b+1]=langkah[a][b]+1;

			}

			if(b>1 && langkah[a][b-1]==-1){

				q.push({a,b-1});

				langkah[a][b-1]=langkah[a][b]+1;

			}

			if(a<x && langkah[a+1][b]==-1){

				q.push({a+1,b});

				langkah[a+1][b]=langkah[a][b]+1;

			}

			if(a>1 && langkah[a-1][b]==-1){

				q.push({a-1,b});

				langkah[a-1][b]=langkah[a][b]+1;

			}

		}

		int maxi = -100000;

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

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

				maxi=max(maxi,langkah[i][j]);

			}

		cout << maxi << endl;

}

// Faster C++ solution for the same problem (measured speedup: 1.1022140278496848x):
#include<cstdio>

#include<queue>

#include<algorithm>

using namespace std;



char c[1001][1002];

int d[1000001];

int main(){

	int n,m;

	scanf("%d%d",&n,&m);

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

		scanf("%s",c[i]+1);

	queue<int>q;

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

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

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

				q.push((i-1)*m+j);

				d[(i-1)*m+j]=1;

			}

	int ans=0;

	while(!q.empty()){

		int u=q.front();

		q.pop();

		ans=max(ans,d[u]);

		for(int i=0;i<4;i++){

			int v=u;

			if(i==0&&u<=m||i==1&&u%m==1%m||i==2&&u>=(n-1)*m+1||i==3&&u%m==0)

				continue;

			if(i==0)v-=m;

			else if(i==1)v--;

			else if(i==2)v+=m;

			else v++;

			if(!d[v]){

				d[v]=d[u]+1;

				q.push(v);

			}

		}

	}

	printf("%d\n",ans-1);

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

using namespace std;

typedef pair<int,int> pii;

typedef pair<int,pii> piii;

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

vector<pii> black;

const int MAXN=1005;

bool visited[MAXN][MAXN];

char a[MAXN][MAXN];



bool border(int x,int y){

	return x>=1 && x<=r && y>=1 && y<=c;

}



int main(){

	ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);

	cin >> r >> c;

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

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

			cin >> a[i][j];

			if(a[i][j]=='#')black.push_back({i,j});

		}

	}

	queue<piii> Q;

	memset(visited,0,sizeof(visited));

	for(auto isi : black){

		Q.push({0,{isi.first,isi.second}});

		visited[isi.first][isi.second]=true;

	}

	int ans=-1;

	while(!Q.empty()){

		piii now=Q.front();

		ans=max(ans,now.first);

		Q.pop();

		for(int i=0;i<4;i++){

			int xnow=now.second.first+dr[i],ynow=now.second.second+dc[i];

			if(!visited[xnow][ynow] && border(xnow,ynow) && a[xnow][ynow]=='.'){

				visited[xnow][ynow]=true;

				Q.push({now.first+1,{xnow,ynow}});

			}

		}

	}

	cout << ans << endl;

	return 0;

}




// Faster C++ solution for the same problem (measured speedup: 2.200673221805359x):
#include<cstdio>

#include<queue>

#include<algorithm>

using namespace std;



char c[1001][1002];

int d[1000001];

int main(){

	int n,m;

	scanf("%d%d",&n,&m);

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

		scanf("%s",c[i]+1);

	queue<int>q;

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

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

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

				q.push((i-1)*m+j);

				d[(i-1)*m+j]=1;

			}

	int ans=0;

	while(!q.empty()){

		int u=q.front();

		q.pop();

		ans=max(ans,d[u]);

		for(int i=0;i<4;i++){

			int v=u;

			if(i==0&&u<=m||i==1&&u%m==1%m||i==2&&u>=(n-1)*m+1||i==3&&u%m==0)

				continue;

			if(i==0)v-=m;

			else if(i==1)v--;

			else if(i==2)v+=m;

			else v++;

			if(!d[v]){

				d[v]=d[u]+1;

				q.push(v);

			}

		}

	}

	printf("%d\n",ans-1);

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

using namespace std;

void debug_out() { cerr << endl; }

template<class T> ostream& prnt(ostream& out, T v) { out << v.size() << '\n'; for(auto e : v) out << e << ' '; return out;}

template<class T> ostream& operator<<(ostream& out, vector <T> v) { return prnt(out, v); }

template<class T> ostream& operator<<(ostream& out, set <T> v) { return prnt(out, v); }

template<class T1, class T2> ostream& operator<<(ostream& out, map <T1, T2> v) { return prnt(out, v); }

template<class T1, class T2> ostream& operator<<(ostream& out, pair<T1, T2> p) { return out << '(' << p.st << ' ' << p.nd << ')'; }

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"

#define ll long long

#define ld long double

#define ull unsigned long long

#define pii pair<int,int>

#define MOD 1000000007

#define zeros(x) x&(x-1)^x

#define fi first

#define se second

#define Nmax 500005

const long double PI = acos(-1);



char mat[1003][1003];

int n,m,mn[1003][1003],ans;

queue<pii>H;

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

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



bool OK(int x, int y){

    if (x <= n && x >= 1 && y <= m && y >= 1) return 1;

    return 0;

}



int main(){

    ios::sync_with_stdio(false);

    cin >> n >> m;

    memset(mn,0xff,sizeof(mn));

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

        cin >> mat[i]+1;

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

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

                H.push({i,j});

                mn[i][j] = 0;

            }

        }

    }



    while (!H.empty()){

        pii crt = H.front();

        H.pop();



        for (int i=0;i<4;i++){

                int X = crt.first + dx[i];

                int Y = crt.second + dy[i];

                if (OK(X,Y) && mn[X][Y] == -1){

                    mn[X][Y] = mn[crt.first][crt.second] + 1;

                    ans = max(ans, mn[X][Y]);

                    H.push({X,Y});

                }

        }

    }



    cout << ans << '\n';



    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.53978708180537x):
#include<cstdio>

#include<queue>

#include<algorithm>

using namespace std;



char c[1001][1002];

int d[1000001];

int main(){

	int n,m;

	scanf("%d%d",&n,&m);

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

		scanf("%s",c[i]+1);

	queue<int>q;

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

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

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

				q.push((i-1)*m+j);

				d[(i-1)*m+j]=1;

			}

	int ans=0;

	while(!q.empty()){

		int u=q.front();

		q.pop();

		ans=max(ans,d[u]);

		for(int i=0;i<4;i++){

			int v=u;

			if(i==0&&u<=m||i==1&&u%m==1%m||i==2&&u>=(n-1)*m+1||i==3&&u%m==0)

				continue;

			if(i==0)v-=m;

			else if(i==1)v--;

			else if(i==2)v+=m;

			else v++;

			if(!d[v]){

				d[v]=d[u]+1;

				q.push(v);

			}

		}

	}

	printf("%d\n",ans-1);

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <deque>

using namespace std;



struct pt{

	int x,y,k;

};



vector<vector<bool>> v(1001,vector<bool> (1001));

int h,w,ret=0;

deque<pt> q;

vector<pair<int,int>> dir={{0,1},{1,0},{-1,0},{0,-1}};



int bfs(){

	while (!q.empty()){

		auto f=q.front();

		ret=max(ret,f.k);

		q.pop_front();

		for (auto& i:dir){

			int nx=i.first+f.x,ny=f.y+i.second;

			if (nx < h and ny < w and nx >= 0 and ny >= 0 and !v[nx][ny]){

				v[nx][ny]=true;

				q.emplace_back(pt{nx,ny,f.k+1});

			}

		}

	}

	return ret;

}



int main(){

	char c;

	cin >> h >> w;

	for (int i=0; i<h; ++i){

		for (int j=0; j<w; ++j){

			cin >> c;

			if (c == '#'){

				q.emplace_back(pt{i,j,0});

				v[i][j]=true;

			}

		}

	}

	cout << bfs();

	return 0;

}

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

using namespace std;



class floodfill{

  struct pt{

    int x,y,n;

  };

  vector<pt> dirs = { {0,1,1}, {0,-1,1}, {1,0,1}, {-1,0,1} };

  int h,w;

  vector<string> vs;

public:

  floodfill(int _h,int _w,vector<string>& _vs) : h(_h),w(_w),vs(_vs) {}

  int dist(){

    int ans = 0;

    queue<pt> q;

    for(int i = 0; i < h; ++i){

      for(int j = 0; j < w; ++j){

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

          vs[i][j] = true;

          q.emplace(pt{i,j,0});

        }

      }

    }

    while(!q.empty()){

      auto p = q.front();

      q.pop();

      for(auto& d : dirs){

        int x=p.x+d.x,y=p.y+d.y,n=p.n+d.n;

        if(0 <= x and x < h and 0 <= y and y < w){

          if(vs[x][y] == '.'){

            vs[x][y] = '#';

            ans = max(ans,n);

            q.emplace(pt{x,y,n});

          }

        }

      }

    }

    return ans;

  }

};



int main(){

  ios::sync_with_stdio(0);

  cin.tie(0);

  int h,w,nb = 0;

  cin >> h >> w;

  vector<string> vs(h);

  for(int i = 0; i < h; ++i) cin >> vs[i];

  floodfill ff(h,w,vs);

  cout << ff.dist();

  return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

#include <deque>

using namespace std;



struct pt{

	int x,y,k;

};



vector<vector<bool>> v(1001,vector<bool> (1001));

int h,w,ret=0;

deque<pt> q;

vector<pair<int,int>> dir={{0,1},{1,0},{-1,0},{0,-1}};



int bfs(){

	while (!q.empty()){

		auto f=q.front();

		ret=max(ret,f.k);

		q.pop_front();

		for (auto& i:dir){

			int nx=i.first+f.x,ny=f.y+i.second;

			if (nx < h and ny < w and nx >= 0 and ny >= 0 and !v[nx][ny]){

				v[nx][ny]=true;

				q.emplace_back(pt{nx,ny,f.k+1});

			}

		}

	}

	return ret;

}



int main(){

	char c;

	cin >> h >> w;

	for (int i=0; i<h; ++i){

		for (int j=0; j<w; ++j){

			cin >> c;

			if (c == '#'){

				q.emplace_back(pt{i,j,0});

				v[i][j]=true;

			}

		}

	}

	cout << bfs();

	return 0;

}

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

using namespace std;

struct pt{

  int x,y,n;

};

vector<pt> dirs = { {0,1,1}, {0,-1,1}, {1,0,1}, {-1,0,1} };

int main(){

  ios::sync_with_stdio(0);

  cin.tie(0);

  int h,w,nb = 0;

  cin >> h >> w;

  vector<string> vs(h);

  queue<pt> q;

  for(int i = 0; i < h; ++i){

    cin >> vs[i];

    for(int j = 0; j < w; ++j){

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

        vs[i][j] = true;

        q.emplace(pt{i,j,0});

      }

    }

  }

  while(!q.empty()){

    auto p = q.front();

    q.pop();

    for(auto& d : dirs){

      int x=p.x+d.x,y=p.y+d.y,n=p.n+d.n;

      if(0 <= x and x < h and 0 <= y and y < w){

        if(vs[x][y] == '.'){

          vs[x][y] = '#';

          nb = max(nb,n);

          q.emplace(pt{x,y,n});

        }

      }

    }

  }

  cout << nb;

  return 0;

}
// Slower C++ solution:
#include <iostream>

using namespace std;



#define QUEUE_SIZE 1000002

#define next(a) (((a)+1)%QUEUE_SIZE)



int queue[QUEUE_SIZE];

int front,rear;

void enqueue(int x){

	if(next(rear)==front){

		exit(1);

	}

	queue[rear]=x;

	rear = next(rear);

}

int dequeue(){

	if(front==rear){

		exit(1);

	}

	int x = queue[front];

	front = next(front);

	return x;

}



int empty(){

	return front==rear;

}

void init(){

	front = rear = 0;

}

int black[1000001];

int score[1001][1001];

void init2(){

	for(int i=0;i<1001;i++)for(int j=0;j<1001;j++)score[i][j]=-1;

}

int main(void){

	int H,W;

	int bc=0;

	init2();

	cin >> H >> W;

	string s[H];

	for(int i=0;i<H;i++){

		cin >> s[i];

	}

	//初期の黒い点の座標を保存する

	for(int i=0;i<H;i++){

		for(int j=0;j<W;j++){

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

				enqueue(100000*i+j);

				score[i][j]=0;

			}

		}

	}

	while(empty()==0){

		int temp = dequeue();

		int x = temp/100000;

		int y = temp%100000;

		

		for(int i=0;i<4;i++){

			int dx[4]={0,0,1,-1};

			int dy[4]={1,-1,0,0};

			if(x+dx[i]<0 || x+dx[i]>H || y+dy[i]<0 || y+dy[i]>W)continue;

			if(score[x+dx[i]][y+dy[i]]==-1 ||score[x+dx[i]][y+dy[i]]>score[x][y]+1){

				score[x+dx[i]][y+dy[i]] = score[x][y]+1;

				enqueue((x+dx[i])*100000+y+dy[i]);

			}

		}

	}

	int ans = 0;

	for(int i=0;i<H;i++){

		for(int j=0;j<W;j++){

			if(ans<score[i][j])ans=score[i][j];

		}

	}

	cout << ans;

}

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

using namespace std;

#define ALL(A) (A).begin(),(A).end()

#define ll long long

const ll mod = 1e9+7;

const ll INF = 2*1e18;

const int inf = 1e9+7;



char s[1005][1005];

int main(void){

	cin.tie(0);

	ios::sync_with_stdio(false);

	int H,W;

	cin >> H >> W;

	for(int i=0;i<H;i++)cin >> s[i];

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

	for(int i=0;i<H;i++){

		for(int j=0;j<W;j++){

			if(s[i][j]=='#')q2.push(pair<int,int>(i,j));

		}

	}

	int dx[4] = {-1,0,0,1};

	int dy[4] = {0,-1,1,0};

	int ans = 0;

	bool f = 1;

	while(f){

		f = 0;

		q = q2;

		q2 = emptyq;

		while(!q.empty()){

			pair<int,int> p = q.front();q.pop();

			for(int i=0;i<4;i++){

				int nx = p.first + dx[i];

				int ny = p.second+ dy[i];

				if(nx>=0&&ny>=0&&nx<H&&ny<W){

					if(s[nx][ny]=='.'){

						f = 1;

						s[nx][ny] = '#';

						q2.push(pair<int,int>(nx,ny));

					}

				}

			}

		}

		if(f)ans++;

	}

	cout << ans << endl;

}
// Slower C++ solution:
#include<iostream>

#include<vector>

#include<algorithm>

#include<queue>

#include<map>

#include<stack>

#include<cmath>

#include<iomanip>

#include<set>

#include<numeric>

#include<sstream>

#include<random>

#include<cassert>

#include<climits>

#include<cstring>

using namespace std;

typedef long long ll;

#define rep(i, n) for (int i = 0; i < n; ++i)

#define rrep(i, st, n) for (int i = st; i < n; ++i)

using pii = pair<int, int>;

const int inf = 1e9 + 7;

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

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

#define ceil(a, b) a / b + !!(a % b)

#define chmax(a, b) a = max(a, b)

#define chmin(a, b) a = min(a, b)



int main() {

    int h, w; cin >> h >> w;

    char a[h][w]; rep(i, h) rep(j, w) cin >> a[i][j];

    int c = 0;

    int reached[1001][1001] = {0};

    queue<pii> q;

    rep(i, h) rep(j, w) if (a[i][j] == '#') q.push({i, j});

    while (!q.empty()) {

        int y = q.front().first, x = q.front().second;

        q.pop();

        rep(k, 4) {

            int ny = y + dy[k], nx = x + dx[k];

            if (ny < 0 || ny >= h || nx < 0 || nx >= w) continue;

            if (a[ny][nx] == '#') continue;

            reached[ny][nx] = reached[y][x] + 1;

            a[ny][nx] = '#';

            q.push({ny, nx});

        }

    }

    int ans = 0;

    rep(i, h) rep(j, w) chmax(ans, reached[i][j]);

    cout << ans << endl;

    //rep(i, h) {rep(j, w) cout << reached[i][j] << " "; cout << endl;}

}


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

using namespace std;

typedef long long ll;

#define F first

#define S second

#define pii pair<int, int>

#define eb emplace_back

#define all(v) v.begin(), v.end()

#define rep(i, n) for (int i = 0; i < n; ++i)

#define rep3(i, l, n) for (int i = l; i < n; ++i)

#define chmax(a, b) a = (a >= b ? a : b)

#define chmin(a, b) a = (a <= b ? a : b)

#define out(a) cout << a << endl

#define outa(a, n) rep(_, n) cout << a[_] << " "; cout << endl

#define SZ(v) (int)v.size()

#define inf (int)(1e9+7)

#define abs(x) (x >= 0 ? x : -(x))

#define ceil(a, b) a / b + !!(a % b)

#define FIX(a) fixed << setprecision(a)



int h, w;

const int MAX_N = 1000;

char c[MAX_N + 1][MAX_N + 1];

int cnt;

int used[MAX_N + 1][MAX_N + 1];

int main() {

    cin >> h >> w;

    queue<pii> q;

    rep(i, h) rep(j, w) { cin >> c[i][j]; if (c[i][j] == '#') { q.push({i, j}); used[i][j] = 1; } }

    

    while (1) {

        queue<pii> qq;

        while (!q.empty()) {

            int y = q.front().F, x = q.front().S;

            q.pop();

            rep3(i, -1, 2) rep3(j, -1, 2) {

                if ((i != 0 && j != 0) || ((i | j) == 0)) continue;

                int ny = y + i;

                int nx = x + j;

                if (ny < 0 || ny >= h || nx < 0 || nx >= w) continue;

                if (c[ny][nx] == '#' || used[ny][nx]) continue;

                c[ny][nx] = '#';

                used[ny][nx] = 1;

                qq.push({ny, nx});

            }

        }

        q = qq;

        

        if (SZ(q) == 0) break;

        cnt++;

    }

    out(cnt);

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

using namespace std;

typedef long long ll;

typedef long double ld;

#define rep(i, n) for (ll i = 0; i < n; i++)

#define FOR(i, a, b) for (ll i = a; i < b; i++)

#define len(v) ll(v.size())



//vector書き出し

template <class T>

void cout_vec(const vector<T> &vec1){

  rep(i,len(vec1)){

    cout<<vec1[i]<<' ';

  }

  cout<<'\n';

}



typedef pair<int,int> P;

const ll mod=1e9+7;



int main(){

    cin.tie(0);

    ios::sync_with_stdio(false);

    int h,w;

    cin>>h>>w;

    vector<vector<char> > a(1010,vector<char>(1010));

    vector<int> dx={1,-1,0,0},dy={0,0,1,-1};

    vector<vector<int> > d(1010,vector<int>(1010,-1));

    queue<P> que;

    FOR(i,1,h+1){

      FOR(j,1,w+1){

        cin>>a[i][j];

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

          que.push({i,j});

          d[i][j]=0;

        }

      }

    }

    while(!que.empty()){

      P p=que.front();

      que.pop();

      rep(i,4){

        int nx=p.first+dx[i],ny=p.second+dy[i];

        if(1<=nx && nx<=h && 1<=ny && ny<=w && d[nx][ny]==-1){

          d[nx][ny]=d[p.first][p.second]+1;

          que.push({nx,ny});

        }

      }

    }

    int ans=0;

    FOR(i,1,h+1){

      FOR(j,1,w+1){

        if(ans<d[i][j]) ans=d[i][j];

      }

    }

    cout<<ans<<endl;

}

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

using namespace std;

typedef long long ll;

typedef long double ld;

#define rep(i, n) for (ll i = 0; i < n; i++)

#define FOR(i, a, b) for (ll i = a; i < b; i++)

#define len(v) ll(v.size())



template <class T>

void cout_vec(const vector<T> &vec){

  for(auto itr:vec) cout<<itr<<' ';

  cout<<'\n';

}



typedef pair<ll,ll> P;

const ll mod=1e9+7;



int main(){

    cin.tie(0);

    ios::sync_with_stdio(false);

    int h,w;

    cin>>h>>w;

    char a[h+1][w+1];

    int dx[4]={1,-1,0,0};

    int dy[4]={0,0,1,-1};

    queue<P> que;

    ll dist[h+1][w+1];

    ll inf=1e15;

    rep(i,h+1)rep(j,w+1) dist[i][j]=inf;

    FOR(i,1,h+1)FOR(j,1,w+1){

      cin>>a[i][j];

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

        que.push(P(i,j));

        dist[i][j]=0;

      }

    }

    while(!que.empty()){

      P v=que.front();

      que.pop();

      rep(i,4){

        int nx=v.first+dx[i];

        int ny=v.second+dy[i];

        if(1<=nx && nx<=h && 1<=ny && ny<=w){

          if(dist[nx][ny]==inf){

            dist[nx][ny]=dist[v.first][v.second]+1;

            que.push(P(nx,ny));

          }

        }

      }

    }

    ll ans=0;

    FOR(i,1,h+1)FOR(j,1,w+1) ans=max(ans,dist[i][j]);

    cout<<ans<<endl;

}
// Slower C++ solution:
#include <iostream>

#include <stdio.h>

#include <iomanip>

#include <climits>

#include <vector>

#include <cstring>

#include <algorithm>

#include <queue>

#define ll long long

#define REP(a,b) for(int a=0; a<b; a++)

using namespace std;



int H, W;

int grid[1005][1005];

queue<pair<int, int>> q;

int mx[4] = {-1, 0, 1, 0};

int my[4] = {0, -1, 0, 1};



bool inside(int r, int c){

return r >= 0 && r < H && c >= 0 && c < W;

}



int main() {

  ios_base::sync_with_stdio(false);

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

  cin >> H >> W;

  REP(i, H){

    string temp;

    cin >> temp;

    REP(j, W){

      if(temp[j] == '#'){

        grid[i][j] = 0;

        q.emplace(i, j);

      }

    }

  }

  while(!q.empty()){

    pair<int, int> coord = q.front();

    q.pop();

    REP(i, 4){

      int xx = coord.first+mx[i];

      int yy = coord.second+my[i];

      if(inside(xx, yy))if(grid[xx][yy] == -1){

        grid[xx][yy] = grid[coord.first][coord.second]+1;

        q.emplace(xx, yy);

      }

    }

  }

  int mxm = 0;

  REP(i, H){

    REP(j, W){

      if(grid[i][j] > mxm) mxm = grid[i][j];

    }

  }

  cout << mxm << endl;

}

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

#define ll long long

#define mp make_pair

#define se second

#define fi first

ll a,b,h,w,ans,to,r,c,jarak;

char cc;

bool bb[1010][1010];

using namespace std;



int main(){

    cin>>h>>w;

    queue<pair<ll, pair <ll, ll> > > q;

    

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

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

            cin>>cc;

            if (cc=='#'){

                bb[i][j]=1;

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

            }

            else bb[i][j]=0;

        }

    }

    

    while (!q.empty()){

        r=q.front().se.fi;

        c=q.front().se.se;

        jarak=q.front().fi;

        q.pop();

        

		if (jarak!=0 && (r<1 || r>h || c<1 || c>w || bb[r][c])) continue;

        

		ans=jarak;

        bb[r][c]=1;

        q.push(mp(jarak+1,mp(r+1,c)));

        q.push(mp(jarak+1,mp(r-1,c)));

        q.push(mp(jarak+1,mp(r,c+1)));

        q.push(mp(jarak+1,mp(r,c-1)));

    }

    

    cout<<ans<<endl;

}