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

package main

import (
	"fmt"
	"strings"
	"sync"
	"unsafe"
)

const p = 1000

var semaphore = make(chan bool, p)

func decode(s string) []byte {
	s = strings.Replace(s, "#", "1", -1)
	s = strings.Replace(s, ".", "0", -1)
	vec := *(*[]byte)(unsafe.Pointer(&s))

	for i := range vec {
		vec[i] -= '0'
	}
	return vec
}

func orVec(op0, op1 []byte) {
	for i := range op0 {
		op0[i] |= op1[i]
	}
}

func orMatrix(op0, op1 [][]byte) {
	var wg sync.WaitGroup

	for i := range op0 {
		wg.Add(1)
		semaphore <- true
		go func(op0 []byte, op1 []byte, wg *sync.WaitGroup) {
			defer func() {
				wg.Done()
				<-semaphore
			}()
			orVec(op0, op1)
		}(op0[i], op1[i], &wg)
	}
	wg.Wait()
}

func checkFullVec(b []byte) bool {
	for _, v := range b {
		if v == 0 {
			return false
		}
	}
	return true
}

func checkFullMatrix(d [][]byte) bool {
	for _, v := range d {
		if !checkFullVec(v) {
			return false
		}
	}
	return true
}

func genMask(op0, op1 [][]byte) {
	var wg sync.WaitGroup
	for h := range op0 {
		wg.Add(1)
		semaphore <- true
		go func(h int, wg *sync.WaitGroup) {
			func() {
				wg.Done()
				<-semaphore
			}()

			for w, v := range op0[h] {
				if v == 1 {
					op1[h][w] = 1
					if h != 0 {
						op1[h-1][w] = 1
					}
					if w != 0 {
						op1[h][w-1] = 1
					}
					if h != len(op0)-1 {
						op1[h+1][w] = 1
					}
					if w != len(op0[h])-1 {
						op1[h][w+1] = 1
					}
				}
			}
		}(h, &wg)

	}
	wg.Wait()
}

func main() {
	var h, w int

	fmt.Scanf("%d%d", &h, &w)

	a := [][]byte{}
	for i := 0; i < h; i++ {
		var s string
		fmt.Scanf("%s", &s)
		a = append(a, decode(s))
	}

	buf := make([][]byte, len(a))

	for i := 0; i < h; i++ {
		buf[i] = make([]byte, len(a[i]))
	}

	if checkFullMatrix(a) {
		fmt.Println(0)
		return
	}

	cnt := 0
	for {
		genMask(a, buf)
		cnt++
		if checkFullMatrix(buf) {
			fmt.Println(cnt)
			return
		}
		//orMatrix(a, buf)
		a, buf = buf, a
	}
}