Problem:
正方形探索

縦に n 行、横に n 列並べられた、合計 n × n のマス目があります。いくつかのマス目には印がついています。各マス目の印の状態を読み込み、印のついていないマス目だけからなる最大の正方形の辺の長さを出力として表示するプログラムを作成してください。

たとえば各データセットで以下のようなデータが与えられます。

10
...*....**
..........
**....**..
........*.
..*.......
..........
.*........
..........
....*..***
.*....*...

入力データの一行が、一行のマス目を表現します。入力データの文字列のうち、.（ピリオド）は印のついていないマス目、*（アスタリスク）は印のついているマス目を示しています。

上記の例では、下図の 0 で示される正方形が最大となります。

...*....**
..........
**....**..
...00000*.
..*00000..
...00000..
.*.00000..
...00000..
....*..***
.*....*...

よって、5 と出力すれば正解になります。

なお、すべてのマス目に印がついている場合には、0 を出力してください。

Input

上記形式で複数のデータセットが与えられます。
n が 0 のとき入力の最後とします。n は 1000 以下とします。入力データの文字列には、ピリオド、アスタリスク、改行以外の文字は含まれません。データセットの数は 50 を超えません。

Output

各データセットに対し、最大の正方形の辺の長さ（整数）を１行に出力して下さい。

Sample Input

10
...*....**
..........
**....**..
........*.
..*.......
..........
.*........
..........
....*..***
.*....*...
10
****.*****
*..*.*....
****.*....
*....*....
*....*****
..........
****.*****
*..*...*..
****...*..
*..*...*..
0

Output for the Sample Input

5
3

Solution in C (judge verdict: Accepted)

/*
Aizu Vol-0 0092: Square Searching
2017.8.12 bal4u@uu
????????°n???????????£?¶????????????????1??????????????????k?
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *gets();

#define SIZE 1000
char buf[SIZE + 5], *p, *pe;

#define W 32   //  must > 1000/32
unsigned map[SIZE + 10][W], *q; int len;

int lt[256] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8 };
int rt[256] = {
    0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
    0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6,
    0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
    0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7,
    0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
    0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6,
    0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
    0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 8 };
int mt[256] = {
    0, 0, 1, 0, 1, 1, 2, 0, 1, 1, 1, 1, 2, 2, 3, 0, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 2, 3, 3, 4, 0,
    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 0,
    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 2, 3, 1, 1, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 3, 4, 1,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 0,
    0, 0, 1, 0, 1, 1, 2, 0, 1, 1, 1, 1, 2, 2, 3, 0, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 2, 3, 3, 4, 0,
    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 0,
    0, 0, 1, 0, 1, 1, 2, 0, 1, 1, 1, 1, 2, 2, 3, 0, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 2, 3, 3, 4, 0,
    0, 0, 1, 0, 1, 1, 2, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0, 0, 1, 0, 1, 1, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0 };

int maxBits(unsigned *a, int len)
{
	int i, k, n, p, l, m, r;
	unsigned *e = a + len;
	k = p = 0;
	while (a < e) {
        if (!*a) { if (p > k) k = p; p = 0; }
        else if (*a == 0xffffffffU) p += 32;
        else {
            for (i = 24; i >= 0; i -= 8) {
                n = ((*a) >> i) & 0xff;
                l = lt[n], m = mt[n], r = rt[n];
                if (l == 8) p += 8;
                else {
                    if (m > k) k = m;
                    p += l; if (p > k) k = p; p = r;
                }
            }
		}
		a++;
	}
	if (p > k) k = p;
	return k;
}

int main()
{
	int n, i, j, k, max;
	unsigned m, *d;

	while (1) {
		gets(buf); if (!(n = atoi(buf))) break;
		pe = buf + n, max = 0;
		for (i = 0; i < n; i++) {
			gets(p = buf), q = map[i], k = 0, m = 0;
			while (p < pe) {
				m <<= 1;
				if (*p++ == '.') m |= 1;
				if (++k == 32) { if (m) max = 1; *q++ = m, k = 0, m = 0; }
			}
			if (k) {m <<= (32-k); *q++ = m; if (m) max = 1; }
			len = q - map[i];
		}
		if (!max) { puts("0"); continue; }
		for (i = 0; i < n; i++) {
			for (j = i + 1; j < n; j++) {
				for (d = map[i], q = map[j], k = len; k--; ) *d++ &= *q++;
				k = maxBits(map[i], len);
                if (k < max) break;
                if (k > j - i + 1) k = j - i + 1;
                if (k > max) max = k;
			}
		}
		printf("%d\n", max);
	}
	return 0;
}