Problem:
Score : 300 points

Problem Statement

You are given a grid of squares with H horizontal rows and W vertical columns, where each square is painted white or black.
HW characters from A_{11} to A_{HW} represent the colors of the squares.
A_{ij} is # if the square at the i-th row from the top and the j-th column from the left is black, and A_{ij} is . if that square is white.

We will repeatedly perform the following operation until all the squares are black:

Every white square that shares a side with a black square, becomes black.

Find the number of operations that will be performed.
The initial grid has at least one black square.

Constraints

1 \leq H,W \leq 1000

A_{ij} is # or ..

The given grid has at least one black square.

Input

Input is given from Standard Input in the following format:

H W
A_{11}A_{12}...A_{1W}
:
A_{H1}A_{H2}...A_{HW}

Output

Print the number of operations that will be performed.

Sample Input 1

3 3
...
.#.
...

Sample Output 1

2

After one operation, all but the corners of the grid will be black. After one more operation, all the squares will be black.

Sample Input 2

6 6
..#..#
......
#..#..
......
.#....
....#.

Sample Output 2

3

Solution in C++ (GCC 9.2.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef pair<int, int> P;

#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()

int inf = 1000000000;
int di[4] = {0, 1, 0, -1};
int dj[4] = {1, 0, -1, 0};

int main(){
  int h, w; cin >> h >> w;
  char a[h][w];
  int dist[h][w];
  rep(i, h)rep(j, w) dist[i][j] = inf;
  deque <P> d;
  rep(i, h)rep(j, w){
    cin >> a[i][j];
    if (a[i][j] == '#'){
      dist[i][j] = 0;
      d.emplace_back(P(i, j));
    }
  }
  while (d.size() > 0){
    int now_i = d.front().first;
    int now_j = d.front().second;
    d.pop_front();
    rep(i, 4){
      int nex_i = now_i + di[i];
      int nex_j = now_j + dj[i]; 
      if (nex_i < 0 || nex_i >= h||nex_j < 0 || nex_j >= w) continue;
      else if (a[nex_i][nex_j] ==  '#')continue;
      else{
        dist[nex_i][nex_j] = min(dist[now_i][now_j] + 1,  dist[nex_i][nex_j]);
        a[nex_i][nex_j] = '#';
        d.emplace_back(P(nex_i, nex_j));
      }
    }
  }
  int ans = 0;
  rep(i, h)rep(j, w) {
    ans = max(ans, dist[i][j]);
  }
  cout << ans << endl;
}