Problem:
城の堀

いま、忍者が城外から天守閣に忍び入ろうと計画を立てています。この忍者は地面を走ったり、堀の中を泳いだりすることは難なくできますが、堀から這い上がることはとても苦手なので、忍者は堀に入る回数をできるだけ少なくしたいと考えています。

お城の見取図を入力とし、城外から天守閣に至るまでに、堀から這い上がらなくてはならない最小回数を出力するプログラムを作成して下さい。お城の見取図は二次元格子として与えられます。見取り図に描かれた記号には、天守閣の位置を示す「&」と堀の位置を示す「#」の位置が記され、そのほかの地点には「.」（半角ピリオド）が記されています。なお、お城には天守閣は一つだけあるものとし、忍者は走ったり泳いだりして移動するときに東西南北方向に1マスずつ移動するものとし、斜めには移動しません。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロ２つの行で示されます。各データセットは以下の形式で与えられます。

n m
c1,1c1,2...c1,n
c2,1c2,2...c2,n
:
cm,1cm,2...cm,n

１行目に見取図の東西の幅 n と 南北の幅 m (1 ≤ n, m ≤ 100) が与えられる。続くm 行に見取り図の i 行目の情報が与えられる。各情報は記号「&」、「#」、「.」からなる長さ n の文字列である。

データセットの数は 50 を越えない。

Output

データセットごとに堀から這い上がらなくてはならない最小回数（整数）を１行に出力します。

Sample Input

5 5
.###.
#...#
#.&.#
#...#
.###.
18 15
..####....####....
####..####....####
#...............##
.#.############.##
#..#..........#.##
.#.#.########.#.##
#..#.#......#.#.##
.#.#....&...#.#.##
#..#........#.#.##
.#.#.########.#.##
#..#..........#.##
.#.############.##
#...............##
.#################
##################
9 10
#########
........#
#######.#
#.....#.#
#.###.#.#
#.#&#.#.#
#.#...#.#
#.#####.#
#.......#
#########
9 3
###...###
#.#.&.#.#
###...###
0 0

Output for the Sample Input

1
2
0
0

Solution in C (judge verdict: Runtime Error)

/*
   Aizu Vol-1 0156 Moats around the Castle
   2017.8.22 bal4u@uu
   ?????¢?????£?????§???Union???????????§?????????
*/
#include <stdio.h>
//#include <stdlib.h>
#include <string.h>

#define N 105			// >= 100+2
#define MAX 11500		// >= N*N

/* <UNION-FIND library> */
int p[MAX], rank[MAX];
void make_set(int x) { p[x] = x, rank[x] = 0; }
void link(int x, int y) {
	if (rank[x] > rank[y]) p[y] = x;
	else { p[x] = y; if (rank[x] == rank[y]) rank[y] = rank[y] + 1; }
}
int find_set(int x) { if (x != p[x]) p[x] = find_set(p[x]);	return p[x]; }
void union_set(int x, int y) { link(find_set(x), find_set(y)); }
/* </UNION-FIND library> */

typedef struct { char c; int x; } T;
T map[N+5][N+5]; int R, C;
int gr, gc;

void lnk(int r1, int c1, int r2, int c2) { union_set(map[r1][c1].x, map[r2][c2].x); }

#define MAX2 1500
int node[MAX2], len;
int dis[MAX2][MAX2];
int f[MAX];
int s, g;

#define INF 100000
char visited[MAX2+2];
int total[MAX2+2];

int search(int n, int s, int g)
{
	int  i, j, next, min;

	for (i = 0; i < n; i++) visited[i] = 0, total[i] = INF;
	total[s] = 0, next = s;
	do {
		i = next, visited[i] = 1, min = INF;
		for (j = 0; j < n; j++) {
			if (visited[j]) continue;
			if (dis[i][j] > 0 && total[i] + dis[i][j] < total[j]) {
				total[j] = total[i] + dis[i][j];
			}
			if (total[j] < min) min = total[j], next = j;
		}
	} while (min < INF);
	return total[g];
}

int main()
{
	int r, c, r2, c2, k, cc, x1, x2;
	char buf[N];
	int mv[4][2] = { {-1,0}, {1,0}, {0,-1}, {0,1} };

	while (scanf("%d%d", &C, &R) && C) {
		for (r = 1; r <= R; r++) {
			scanf("%s", buf);
			for (c = 1; c <= C; c++) map[r][c].c = buf[c-1];
		}
		R += 2, C += 2;
		for (r = 0; r < R; r++) map[r][0].c = map[r][C-1].c = '.';
		for (c = 0; c < C; c++) map[0][c].c = map[R-1][c].c = '.';
		for (k = r = 0; r < R; r++) for (c = 0; c < C; c++) map[r][c].x = k, make_set(k++);
		for (r = 0; r < R; r++) lnk(r, 0, 0, 0), lnk(r, C-1, 0, 0);
		for (c = 0; c < R; c++) lnk(0, c, 0, 0), lnk(R-1, c, 0, 0);

		R--, C--;
		for (r = 1; r < R; r++) for (c = 1; c < C; c++) {
			if (map[r][c].c == '&') gr = r, gc = c;
			cc = map[r][c].c;
			for (k = 0; k < 4; k++) {
				r2 = r + mv[k][0], c2 = c + mv[k][1];
				if (map[r2][c2].c == cc) lnk(r2, c2, r, c);
			}
		}
		for (k = 0; k < 4; k++) {
			r2 = gr + mv[k][0], c2 = gc + mv[k][1];
			if (map[r2][c2].c == '.') lnk(r2, c2, gr, gc);
		}
		if (p[map[0][0].x] == p[map[gr][gc].x]) { puts("0"); continue; }

		memset(f, -1, sizeof(f)); memset(dis, -1, sizeof(dis));
		for (len = 0, r = 0; r <= R; r++) for (c = 0; c <= C; c++) {
			x1 = p[map[r][c].x];
			if (f[x1] < 0) f[x1] = len, node[len++] = x1;
		}
		for (r = 1; r <= R; r++) for (c = 1; c < C; c++) {
			for (k = 0; k < 4; k++) {
				r2 = r + mv[k][0], c2 = c + mv[k][1];
				if (map[r][c].x != map[r2][c2].x) {
					x1 = f[p[map[r][c].x]], x2 = f[p[map[r2][c2].x]];
					dis[x1][x2] = dis[x2][x1] = 1;
				}
			}
		}
		k = search(len, f[p[map[0][0].x]], f[p[map[gr][gc].x]]);
		if (k & 1) k++;
		printf("%d\n", k >> 1);
	}
	return 0;
}