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 (GCC 5.4.1) (judge verdict: Accepted)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node{
	void *data;
	struct node *next;
	struct node *prev;
};

struct point{
	int x;
	int y;
};


typedef struct node *NodePointer;

NodePointer nil;

void init(){
	nil = malloc(sizeof(struct node));
	nil->next = nil;
	nil->prev = nil;
}

void deleteNode(NodePointer t){
	t->prev->next = t->next;
	t->next->prev = t->prev;
	free(t->data);
	free(t);
}

void backInsert(void *p,int len){
	NodePointer t;
	t = malloc(sizeof(struct node));
	t->data = malloc(len);
	memcpy(t->data,p,len);
	t->next = nil;
	t->prev = nil->prev;
	t->prev->next = t;
	nil->prev = t;
}

void deleteFirst(){
	NodePointer t = nil->next;
	if(t == nil){
		return;
	}
	deleteNode(t);
}

void deleteAll(){
	NodePointer t = nil->next;
	while(t != nil){
		deleteNode(t);
	}
}

void pop(void *np,int len){
	memcpy(np,nil->next->data,len);
	deleteFirst();
}

int main(int argc, char **argv)
{
	int *square;
	char temp[1000];
	int count = 0;
	int r = 0;
	int c = 0;
	int i = 0;
	int j = 0;
	struct point dif[4] = {{0,-1},{1,0},{0,1},{-1,0}}; 

	scanf("%d%d",&r,&c);
	init();

	square = malloc(sizeof(int) * (r * c));
	
	for(i = 0;i < r;i++){
		scanf("%s",temp);
		for(j = 0;j < c;j++){
			if(temp[j] == '#'){
				square[i * c + j] = 0;
				struct point *blackPoint = malloc(sizeof(struct node));
				blackPoint->x = j;
				blackPoint->y = i;
				backInsert(blackPoint,sizeof(blackPoint));
			}
			else{
				square[i * c + j] = -1;
			}
		}
	}
	
	while(nil->next != nil){
		struct point currentPoint;
		pop(&currentPoint,sizeof(currentPoint));
		struct point nextPoint;

		for(i = 0;i < 4;i++){
			nextPoint.x = currentPoint.x + dif[i].x;
			nextPoint.y = currentPoint.y + dif[i].y;
			// if((nextPoint.y) * c + (nextPoint.x) < 0 || r * c < (nextPoint.y) * c + (nextPoint.x) ||
			// 	(nextPoint.x) == c || (nextPoint.x) == -1){
			// }
			if((0 <= nextPoint.x) && (nextPoint.x <= (c-1)) &&
					(0 <= nextPoint.y) && (nextPoint.y <= (r-1)) && (square[nextPoint.y * c + nextPoint.x] == -1)){
				struct point pointP;
				pointP.x = nextPoint.x;
				pointP.y = nextPoint.y;
				backInsert(&pointP,sizeof(pointP));
				square[(nextPoint.y) * c + (nextPoint.x)] = square[(currentPoint.y * c) + currentPoint.x] + 1;
				count = square[(nextPoint.y) * c + (nextPoint.x)];
				// printf("%d\n",(((nextPoint.y) * c)));
				// printf("%d\n",((nextPoint.x)));
				// printf("\n");
			}
			
		}
		
	}
	printf("%d\n",count);
	
	//deleteAll();
	free(nil);
	return 0;
}