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 Common Lisp (SBCL 1.1.14) (judge verdict: Accepted)

;; -*- coding: utf-8 -*-
(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0)))
  #+swank (progn (ql:quickload '(:cl-debug-print :fiveam))
                 (shadow :run)
                 (use-package :fiveam)))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)

;; BEGIN_INSERTED_CONTENTS
(defstruct (queue (:constructor make-queue
                    (&optional list &aux (tail (last list)))))
  (list nil :type list)
  (tail nil :type (or null (cons t null))))

(declaim (inline enqueue))
(defun enqueue (obj queue)
  (symbol-macrolet ((list (queue-list queue))
                    (tail (queue-tail queue)))
    (if (null list)
        (setf tail (list obj)
              list tail)
        (setf (cdr tail) (list obj)
              tail (cdr tail))))
  queue)

(declaim (inline dequeue))
(defun dequeue (queue)
  (pop (queue-list queue)))

(declaim (inline queue-empty-p))
(defun queue-empty-p (queue)
  (null (queue-list queue)))

(declaim (inline read-line-into))
(defun read-line-into (buffer-string &key (in *standard-input*) (terminate-char #\Space))
  (declare (simple-base-string buffer-string))
  (loop for c of-type base-char =
           #-swank (code-char (read-byte in nil #.(char-code #\Newline)))
           #+swank (read-char in nil #\Newline)
        for idx from 0
        until (char= c #\Newline)
        do (setf (schar buffer-string idx) c)
        finally (when (< idx (length buffer-string))
                  (setf (schar buffer-string idx) terminate-char))
                (return (values buffer-string idx))))

(defmacro dbg (&rest forms)
  #+swank
  (if (= (length forms) 1)
      `(format *error-output* "~A => ~A~%" ',(car forms) ,(car forms))
      `(format *error-output* "~A => ~A~%" ',forms `(,,@forms)))
  #-swank (declare (ignore forms)))

(defmacro define-int-types (&rest bits)
  `(progn
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "UINT~A" b)) () '(unsigned-byte ,b))) bits)
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "INT~A" b)) () '(signed-byte ,b))) bits)))
(define-int-types 2 4 7 8 15 16 31 32 62 63 64)

(declaim (inline println))
(defun println (obj &optional (stream *standard-output*))
  (let ((*read-default-float-format* 'double-float))
    (prog1 (princ obj stream) (terpri stream))))

(defconstant +mod+ 1000000007)

;; Body

(declaim (inline encode decode))
(defun encode (d i j)
  (dpb j (byte 16 32) (dpb i (byte 16 16) d)))

(defun main ()
  (declare #.OPT)
  (let* ((h (read))
         (w (read))
         (plan (make-array (list h w) :element-type 'uint16 :initial-element #xffff))
         (line (make-string w :element-type 'base-char))
         ;; i|j|dist
         (q (make-queue)))
    (declare (uint32 h w))
    (dotimes (i h)
      (read-line-into line)
      (dotimes (j w)
        (when (char= #\# (aref line j))
          (setf (aref plan i j) 0)
          (enqueue (encode 0 i j) q))))
    (labels ((frob (next-d next-i next-j)
               (declare (fixnum next-d next-i next-j))
               (when (= #xffff (aref plan next-i next-j))
                 (enqueue (encode next-d next-i next-j) q)
                 (setf (aref plan next-i next-j) next-d))))
      (declare (inline frob))
      (loop until (queue-empty-p q)
            for node of-type uint62 = (dequeue q)
            for d = (ldb (byte 16 0) node)
            for i = (ldb (byte 16 16) node)
            for j = (ldb (byte 16 32) node)
            do (when (< 0 i)
                 (frob (+ 1 d) (- i 1) j))
               (when (< i (- h 1))
                 (frob (+ 1 d) (+ i 1) j))
               (when (< 0 j)
                 (frob (+ 1 d) i (- j 1)))
               (when (< j (- w 1))
                 (frob (+ 1 d) i (+ j 1)))))
    (println (reduce #'max (array-storage-vector plan)))))

#-swank(main)