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# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;

namespace AGC033A
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] HW = ConsoleInput.IntArray();
            var H = HW[0];
            var W = HW[1];
            string[] A = new string[H];
            for (int i = 0; i < H; i++)
            {
                A[i] = ConsoleInput.String();
            }
            List<Black> queue = new List<Black>();
            for (int i = 0; i < H; i++)
            {
                for (int j = 0; j < W; j++)
                {
                    if (A[i][j] == '#')
                    {
                        queue.Add(new Black(j, i, 0));
                    }
                }
            }

            int[][] data = new int[HW[0]][];
            for (int i = 0; i < HW[0]; i++)
            {
                data[i] = new int[HW[1]];
                for (int j = 0; j < HW[1]; j++)
                {
                    data[i][j] = A[i][j] == '.' ? -1 : 0;
                }
            }
            long deepest = 0;
            while (queue.Count > 0)
            {
                Black pop = queue.First();
                queue.Remove(pop);

                foreach (Black variable in pop.N(H, W))
                {
                    if (variable.isNew(data))
                    {
                        data[variable.Y][variable.X] = variable.Deep;
                        deepest = Math.Max(deepest, variable.Deep);
                        queue.Add(variable);
                    }
                }
            }
            
            Console.WriteLine(deepest);
        }
    }

    class Black
    {
        public int X;
        public int Y;
        public int Deep;

        public Black(int X, int Y, int Deep)
        {
            this.X = X;
            this.Y = Y;
            this.Deep = Deep;
        }

        public Black[] N(int H, int W)
        {
            List<Black> b = new List<Black>();
            if (X > 0)
            {
                b.Add(new Black(X - 1, Y, Deep + 1));
            }

            if (X < W - 1)
            {
                b.Add(new Black(X + 1, Y, Deep + 1));
            }

            if (Y > 0)
            {
                b.Add(new Black(X, Y - 1, Deep + 1));
            }

            if (Y < H - 1)
            {
                b.Add(new Black(X, Y + 1, Deep + 1));
            }

            return b.ToArray();
        }

        public bool isNew(int[][] Data)
        {
            return Data[Y][X] == -1;// | Data[Y][X] > Deep;
        }
    }


    internal static class ConsoleInput
    {
        public static string String()
        {
            return Console.ReadLine();
        }

        public static int Int()
        {
            return int.Parse(Console.ReadLine());
        }

        public static int[] IntArray()
        {
            return Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
        }

        public static long Long()
        {
            return long.Parse(Console.ReadLine());
        }

        public static long[] LongArray()
        {
            return Console.ReadLine().Split(' ').Select(long.Parse).ToArray();
        }

        public static double[] DoubleArray()
        {
            return Console.ReadLine().Split(' ').Select(double.Parse).ToArray();
        }
    }
}