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

## constant

MAX_DIST = 1 << 30

### subroutines

def paint(x, y, n, m, chmap, armap, aid)
  ch = chmap[y][x]
  area = [aid, ch, false]
  armap[y][x] = area

  queue = [[x, y]]
  while ! queue.empty?
    x0, y0 = queue.shift
    cands = []
    if x0 > 0
      cands << [x0 - 1, y0]
    else
      area[2] = true
    end
    if x0 < n - 1
      cands << [x0 + 1, y0]
    else
      area[2] = true
    end
    if y0 > 0
      cands << [x0, y0 - 1]
    else
      area[2] = true
    end
    if y0 < m - 1
      cands << [x0, y0 + 1]
    else
      area[2] = true
    end

    for c in cands
      nx, ny = c
      if armap[ny][nx].nil? && chmap[ny][nx] == ch
        armap[ny][nx] = area
        queue << [nx, ny]
      end
    end
  end

  area
end

def gen_areas(n, m, chmap, armap)
  areas = []
  aid = 0

  for y in (0...m)
    for x in (0...n)
      if armap[y][x].nil?
        area = paint(x, y, n, m, chmap, armap, aid)
        areas << area
        aid += 1
      end
    end
  end

  areas
end

def gen_nbrs(n, m, armap, areas)
  nbrs = (0...areas.length).map{[]}

  for y in (0...m)
    for x in (0...n)
      aid, ach = armap[y][x]
      cands = []
      cands << armap[y][x - 1] if x > 0
      cands << armap[y][x + 1] if x < n - 1
      cands << armap[y - 1][x] if y > 0
      cands << armap[y + 1][x] if y < m - 1

      for ar0 in cands
        nbrs[aid] << ar0[0] if ! nbrs[aid].include? ar0[0]
      end
    end
  end

  nbrs
end

### main

while true
  n, m = gets.strip.split(' ').map{|s| s.to_i}
  break if n == 0 && m == 0

  chmap = []
  armap = []

  m.times.each do
    hl = gets.strip
    chmap << hl
    armap << ([nil] * n)
  end

  areas = gen_areas(n, m, chmap, armap)
  an = areas.length
  nbrs = gen_nbrs(n, m, armap, areas)

  st = nil
  for area in areas
    if area[1] == '&'
      st = area[0]
      break
    end
  end

  dist = areas.map{MAX_DIST}
  dist[st] = 0
  prev = areas.map{nil}
  queue = areas.map{|ar| ar[0]}

  while ! queue.empty?
    u = queue.min{|a, b| dist[a] <=> dist[b]}
    queue.delete u

    for v in nbrs[u]
      ndist = dist[u] + ((areas[v][1] == '#') ? 2 : 1)
      if dist[v] > ndist
        dist[v] = ndist
        prev[v] = u
      end
    end
  end

  gl = (0...an).select{|i| areas[i][2]}.min{|a, b| dist[a] <=> dist[b]}

  count = 0
  v = gl
  while v != st
    if areas[v][1] == '#'
      count += 1
    end
    v = prev[v]
  end

  puts count
end