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))))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)

;; BEGIN_INSERTED_CONTENTS
(declaim (inline fast-read-char))
(defun fast-read-char (stream)
  (declare #-swank (sb-kernel:ansi-stream stream)
           (inline read-byte))
  #+swank (read-char stream nil #\Newline) ; on SLIME
  #-swank (code-char (read-byte stream nil #.(char-code #\Newline))))

(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)))

(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

(defun main ()
  (declare #.OPT)
  (let* ((h (read))
         (w (read))
         (plan (make-array '(1000 1000) :element-type 'uint16 :initial-element 0))
         ;; i|j
         (q (make-queue)))
    (declare (uint32 h w))
    (dotimes (i h)
      (dotimes (j w)
        (if (char= #\# (fast-read-char *standard-input*))
            (enqueue (logxor i (ash j 16)) q)
            (setf (aref plan i j) #xffff)))
      (fast-read-char *standard-input*))
    (labels ((frob (next-d next-i next-j)
               (declare (uint32 next-d next-i next-j))
               (when (= #xffff (aref plan next-i next-j))
                 (enqueue (logxor next-i (ash next-j 16)) q)
                 (setf (aref plan next-i next-j) next-d))))
      (declare (inline frob))
      (loop until (queue-empty-p q)
            for node of-type uint32 = (dequeue q)
            for i = (logand #.(ldb (byte 16 0) -1) node)
            for j = (ash node -16)
            for d = (aref plan i j)
            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 (loop for x across (array-storage-vector plan) maximize x))))

#-swank(main)