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 PHP7 (7.0.15) (judge verdict: Time Limit Exceeded)

#!/usr/bin/env php
<?php
const BLACK = '#';
const WHITE = '.';
function genInputs() {
    while(($input = rtrim(fgets(STDIN))) !== false) {
        foreach (explode(' ', $input) as $v) {
            yield $v;
        }
    }
}
function getNext($gen) {
    $value = $gen->current();
    $gen->next();
    return $value;
}
$gen = genInputs();

$H = (int)getNext($gen);
$W = (int)getNext($gen);

$change = [];
for ($i = 0; $i < $H; $i++) {
    $item = getNext($gen);
    for ($j = 0; $j < $W; $j++) {
        if ($item[$j] == BLACK) {
            $change[$i][$j] = 0;
        }
    }
}
$add_change = function($i, $j, $n) use($H, $W, &$change, &$add_change) {
    if (!isset($change[$i][$j])) {
        $change[$i][$j] = $n;
    } elseif ($change[$i][$j] > $n) {
        $change[$i][$j] = $n;
    } else {
        return false;
    }
    return true;
};
$number = 0;
$next = true;
while ($next) {
    $next = false;
    foreach ($change as $i => $row) {
        foreach ($row as $j => $item) {
            if ($item != $number) {
                continue;
            }
            foreach ([[$i - 1, $j], [$i + 1, $j], [$i, $j - 1], [$i, $j + 1]] as $pos) {
                if ($pos[0] < 0 || $pos[0] >= $H || $pos[1] < 0 || $pos[1] >= $W) {
                    continue;
                }
                $ret = $add_change($pos[0], $pos[1], $number + 1);
                if ($ret) {
                    $next = true;
                }
            }
        }
    }
    $number++;
}
echo max(array_map(function($child) { return max($child); }, $change)).PHP_EOL;