There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles.

Write a program to count the number of black tiles which he can reach by repeating the moves described above.



Input

The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20.

There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.

* '.' - a black tile
* '#' - a red tile
* '@' - a man on a black tile(appears exactly once in a data set)


The end of the input is indicated by a line consisting of two zeros.

Output

For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself).

Examples

Input

6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0


Output

45
59
6
13


Input

6 9
....#.
.....#
......
......
......
......
......
@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
.###
...@...
.###
..#.#..
..#.#..
0 0


Output

45
59
6
13

Difficulty: UNKNOWN_DIFFICULTY

Starter code:

Solutions:
from collections import deque
y = [-1, 0, 1, 0]
x = [0, -1, 0, 1]

def main():
	(h, w) = (0, 0)
	c = []

	def check(i, j):
		return 0 <= i and i < h and (0 <= j) and (j < w)

	def bfs(a, b):
		res = 0
		d = deque()
		d.append([a, b])
		f = [[False] * w for _ in range(h)]
		while len(d):
			(i, j) = d.popleft()
			if not check(i, j):
				continue
			if c[i][j] == '#':
				continue
			if f[i][j] == True:
				continue
			res += 1
			f[i][j] = True
			for k in range(4):
				d.append([i + y[k], j + x[k]])
		return res
	while True:
		(w, h) = map(int, input().split())
		if h == 0 and w == 0:
			break
		c = []
		for i in range(h):
			c.append(input())
		res = 0
		for i in range(h):
			for j in range(w):
				if c[i][j] == '@':
					res = bfs(i, j)
		print(res)
main()


while True:
	(w, h) = map(int, input().split())
	if h == 0:
		break
	m = [list(input()) for _ in range(h)]
	sx = 0
	sy = 0
	for (yi, row) in enumerate(m):
		if '@' in row:
			sy = yi
			sx = row.index('@')

	def dfs(x, y):
		if x < 0 or w <= x or y < 0 or (h <= y) or (m[y][x] == '#'):
			return 0
		else:
			m[y][x] = '#'
			dy = [1, -1] + [0] * 2
			dx = [0] * 2 + [1, -1]
			return sum([dfs(x + dx[i], y + dy[i]) for i in range(4)]) + 1
	print(dfs(sx, sy))


import collections
while True:
	(w, h) = map(int, input().split())
	if w == h == 0:
		break
	else:
		ans = 1
		L = []
		q = collections.deque()
		for i in range(h):
			s = input()
			T = []
			for j in range(w):
				if s[j] == '@':
					T.append(0)
					q.append([i, j])
				else:
					T.append(s[j])
			L.append(T)
		dy_dx = [[1, 0], [0, 1], [-1, 0], [0, -1]]
		while len(q) > 0:
			cur = q.popleft()
			for i in range(4):
				y = cur[0] + dy_dx[i][0]
				x = cur[1] + dy_dx[i][1]
				if 0 <= x < w and 0 <= y < h:
					if L[y][x] == '.':
						L[y][x] = L[cur[0]][cur[1]] + 1
						ans += 1
						q.append([y, x])
		print(ans)


def main():
	while 1:
		(w, h) = map(int, input().split())
		if w == 0:
			break
		fld = [[] for i in range(h)]
		for i in range(h):
			readline = input()
			for j in range(w):
				item = readline[j]
				fld[i].append(item)
				if item == '@':
					(sy, sx) = (i, j)
		solve(fld, sy, sx)
		count = 0
		for i in range(h):
			for j in range(w):
				if fld[i][j] == 'A':
					count += 1
		print(count)

def solve(fld, cy, cx):
	vy = [1, -1, 0, 0]
	vx = [0, 0, 1, -1]
	fld[cy][cx] = 'A'
	for i in range(4):
		ny = cy + vy[i]
		nx = cx + vx[i]
		if ny < 0 or nx < 0 or ny >= len(fld) or (nx >= len(fld[0])):
			continue
		elif fld[ny][nx] == '.':
			solve(fld, ny, nx)
main()


from queue import Queue
while True:
	(w, h) = map(int, input().split())
	if w == h == 0:
		break
	tile = [input() for i in range(h)]
	for (x, col) in enumerate(tile):
		if '@' in col:
			y = col.index('@')
			s = (x, y)
			break
	visit = [[False for i in range(w)] for j in range(h)]
	dx = (0, -1, 1, 0)
	dy = (1, 0, 0, -1)
	que = Queue()
	que.put(s)
	while not que.empty():
		(x, y) = que.get()
		if visit[x][y]:
			continue
		visit[x][y] = True
		for j in range(4):
			sx = x + dx[j]
			sy = y + dy[j]
			if sx < 0 or sx >= h or sy < 0 or (sy >= w):
				continue
			if tile[sx][sy] != '#':
				que.put((sx, sy))
	ans = 0
	for col in visit:
		ans += col.count(True)
	print(ans)


import array
import collections
import itertools

class DepthFirstSearchWithStack(object):

	def __init__(self, width, height, tiles):
		self.width = width
		self.height = height
		self.tiles = tiles
		self.reached = [array.array('B', (False for y in range(height))) for x in range(width)]
		for (x, y) in itertools.product(range(width), range(height)):
			if tiles[x][y] == '@':
				self.start_tile = (x, y)
				break

	def search(self, x0, y0):
		stack = collections.deque()
		self.reached[x0][y0] = True
		stack.append((x0, y0))
		while stack:
			(x, y) = stack.pop()
			for (i, j) in [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]:
				if i < 0 or self.width <= i or j < 0 or (self.height <= j):
					pass
				elif self.tiles[i][j] == '#':
					pass
				elif not self.reached[i][j]:
					self.reached[i][j] = True
					stack.append((i, j))

	def count_reachable_tiles(self):
		self.search(*self.start_tile)
		reachable_tiles = sum([self.reached[x][y] for (x, y) in itertools.product(range(self.width), range(self.height))])
		return reachable_tiles
while True:
	(width, height) = map(int, input().split())
	if width == 0 and height == 0:
		break
	else:
		tiles = [x for x in zip(*[input() for y in range(height)])]
		dfs = DepthFirstSearchWithStack(width, height, tiles)
		print(dfs.count_reachable_tiles())


from collections import deque

def solve(W, H, field):
	dire = [(1, 0), (0, 1), (-1, 0), (0, -1)]
	for i in range(H):
		for j in range(W):
			if field[i][j] == '@':
				s = (i, j)
	check = [[0] * W for i in range(H)]
	q = deque()
	q.append(s)
	check[s[0]][s[1]] = 1
	ret = 1
	while q:
		(y, x) = q.popleft()
		for (dy, dx) in dire:
			if y + dy < H and y + dy >= 0 and (x + dx < W) and (x + dx >= 0):
				if field[y + dy][x + dx] == '.' and (not check[y + dy][x + dx]):
					q.append((y + dy, x + dx))
					check[y + dy][x + dx] = 1
					ret += 1
	return ret

def main():
	ans = []
	while True:
		(W, H) = list(map(int, input().split()))
		if not W and (not H):
			break
		field = [input() for i in range(H)]
		ans.append(solve(W, H, field))
	for i in ans:
		print(i)
main()


import sys
sys.setrecursionlimit(10000000)
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
while True:
	(width, hight) = map(int, input().split())
	if width == 0:
		break
	d = []
	for _ in range(hight):
		d.append(list(input()))

	def dfs(x, y):
		d[y][x] = 'd'
		for i in range(4):
			ny = y + dx[i]
			nx = x + dy[i]
			if 0 <= ny and ny < hight and (0 <= nx) and (nx < width) and (d[ny][nx] == '.'):
				dfs(nx, ny)
	for y in range(hight):
		for x in range(width):
			if d[y][x] == '@':
				dfs(x, y)
	sum = 0
	for _ in range(hight):
		sum = sum + d[_].count('d')
	print(sum)


(lambda f: f(f))(lambda T, A=lambda L, yp, ri=lambda l: R.append([{xi: x} for (xi, x) in enumerate(l)]): [P.__setitem__('x', L.index('@')), P.__setitem__('y', yp), ri(L)] if '@' in L else ri(L), S=lambda X, Y, s, u: [R[Y][X].__setitem__(X, '@'), s(X - 1, Y, s, u) + s(X + 1, Y, s, u) + s(X, Y + 1, s, u) + s(X, Y - 1, s, u) + 1][1] if 0 <= X < W[0] and 0 <= Y < W[1] and u(X, Y) else 0, u=lambda X, Y: R[Y][X].get(X) is '.', g=globals: [g().__setitem__('W', list(map(int, input().split()))), g().__setitem__('R', []), g().__setitem__('P', {'x': 9, 'y': 9}), [A(input(), Y) for Y in range(W[1])], [R[P['y']][P['x']].__setitem__(P['x'], '.'), print(S(P['x'], P['y'], S, u)), T(T)] if R else 9])


while 1:
	(x, y) = list(map(int, input().split()))
	if x == 0:
		break
	mx = [1, -1, 0, 0]
	my = [0, 0, 1, -1]
	m = []
	for i in range(y):
		m.append(list(input()))
		if '@' in m[-1]:
			sx = m[-1].index('@')
			sy = i
	cnt = 0

	def move(cur_x, cur_y):
		global cnt
		if cur_y >= y or cur_y < 0 or cur_x >= x or (cur_x < 0):
			return
		if m[cur_y][cur_x] == '.' or m[cur_y][cur_x] == '@':
			cnt += 1
			m[cur_y][cur_x] = '0'
			for i in range(4):
				move(cur_x + mx[i], cur_y + my[i])
	move(sx, sy)
	print(cnt)


def dfs(s, Map, H, W):
	dxdy = [(1, 0), (-1, 0), (0, 1), (0, -1)]
	for i in range(4):
		Map[s[0]][s[1]] = '*'
		nextPos = (s[0] + dxdy[i][0], s[1] + dxdy[i][1])
		if nextPos[0] >= 0 and nextPos[1] >= 0 and (nextPos[0] < H) and (nextPos[1] < W):
			if Map[nextPos[0]][nextPos[1]] == '.':
				dfs(nextPos, Map, H, W)
while True:
	(W, H) = map(int, input().split(' '))
	if W == 0 and H == 0:
		break
	Map = [list(input()) for i in range(0, H)]
	for i in range(H):
		for j in range(W):
			if Map[i][j] == '@':
				S = (i, j)
	dfs(S, Map, H, W)
	print(sum([1 if Map[i][j] == '*' else 0 for i in range(H) for j in range(W)]))


from logging import getLogger, StreamHandler, NullHandler, DEBUG, INFO
logger = getLogger(__name__)
handler = NullHandler()
logger.setLevel(DEBUG)
handler.setLevel(DEBUG)
logger.addHandler(handler)
logger.propagate = False
g_field = []
g_count = 0
g_W = -1
g_H = -1
OFFSETS = [(1, 0), (-1, 0), (0, 1), (0, -1)]
while True:
	(g_W, g_H) = [int(s) for s in input().strip().split()]
	if g_W == 0 and g_H == 0:
		break
	g_field = []
	for _ in range(g_H):
		row = list(input().strip())
		g_field.append(row)
	g_count = 0
	for y in range(g_H):
		for x in range(g_W):
			if g_field[y][x] == '@':
				start_x = x
				start_y = y
				break
	queue = [(start_x, start_y)]
	while len(queue) > 0:
		(x, y) = queue.pop()
		g_count += 1
		g_field[y][x] = '-'
		for (dx, dy) in OFFSETS:
			logger.debug('diff: {} {}'.format(dx, dy))
			new_x = x + dx
			new_y = y + dy
			if new_x < 0 or new_x >= g_W:
				continue
			if new_y < 0 or new_y >= g_H:
				continue
			new_tile = g_field[new_y][new_x]
			if new_tile == '#' or new_tile == '-':
				continue
			if (new_x, new_y) in queue:
				continue
			logger.debug('{}, {}'.format(new_x, new_y))
			queue.append((new_x, new_y))
	print(g_count)


import sys
sys.setrecursionlimit(10000)

def dfs(x, y):
	global cout
	if 0 <= x < H - 1 and tile[x + 1][y] == '.':
		cout += 1
		tile[x + 1][y] = '#'
		dfs(x + 1, y)
	if 0 < x < H and tile[x - 1][y] == '.':
		cout += 1
		tile[x - 1][y] = '#'
		dfs(x - 1, y)
	if 0 <= y < W - 1 and tile[x][y + 1] == '.':
		cout += 1
		tile[x][y + 1] = '#'
		dfs(x, y + 1)
	if 0 < y < W and tile[x][y - 1] == '.':
		cout += 1
		tile[x][y - 1] = '#'
		dfs(x, y - 1)
	return 0

def search_start():
	for i in range(H):
		for j in range(W):
			if tile[i][j] == '@':
				tile[i][j] = '#'
				return (i, j)
while True:
	(W, H) = map(int, input().split())
	if W == 0 and H == 0:
		break
	tile = [list(input()) for _ in range(H)]
	cout = 1
	start = search_start()
	dfs(start[0], start[1])
	print(cout)


while 1:
	(w, h) = list(map(int, input().strip().split()))
	if w == h == 0:
		break
	data = []
	data = []
	for _ in range(h):
		data.append(list(input()))
	visited = []
	for i in range(h):
		if '@' in data[i]:
			stack = [(i, data[i].index('@'))]
	count = 0
	while len(stack) != 0:
		(y, x) = stack.pop()
		count += 1
		if y - 1 >= 0 and (not (y - 1, x) in visited) and (data[y - 1][x] == '.'):
			visited.append((y - 1, x))
			stack.append((y - 1, x))
		if x - 1 >= 0 and (not (y, x - 1) in visited) and (data[y][x - 1] == '.'):
			visited.append((y, x - 1))
			stack.append((y, x - 1))
		if y + 1 < h and (not (y + 1, x) in visited) and (data[y + 1][x] == '.'):
			visited.append((y + 1, x))
			stack.append((y + 1, x))
		if x + 1 < w and (not (y, x + 1) in visited) and (data[y][x + 1] == '.'):
			visited.append((y, x + 1))
			stack.append((y, x + 1))
	print(count)


from collections import deque
while True:
	(W, H) = map(int, input().split())
	if W | H == 0:
		break
	tiles = [input() for i in range(H)]
	first = ()
	for h in range(H):
		index = tiles[h].find('@')
		if index != -1:
			first = (index, h)
			break
	memo = {first: 0}
	que = deque([first])
	count = 1
	while len(que) > 0:
		(x, y) = que.popleft()
		for (dx, dy) in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
			if (x + dx, y + dy) not in memo:
				if 0 <= x + dx < W and 0 <= y + dy < H and (tiles[y + dy][x + dx] == '.'):
					count += 1
					memo[x + dx, y + dy] = 1
					que.append((x + dx, y + dy))
	print(count)


x = 0
y = 0
b = []
t = []
dir = [[1, 0], [0, 1], [-1, 0], [0, -1]]
ans = 0

def dfs(p_x, p_y):
	global b, t, ans
	if t[p_y][p_x] or not b[p_y][p_x]:
		return
	ans += 1
	t[p_y][p_x] = True
	for i in dir:
		dfs(p_x + i[0], p_y + i[1])
while True:
	x = 0
	y = 0
	(w, h) = map(int, input().split())
	if w == 0 and h == 0:
		break
	b = [[False] * (w + 2) for i in range(h + 2)]
	t = [[False] * (w + 2) for i in range(h + 2)]
	ans = 0
	for i in range(1, h + 1):
		tmp = list(input())
		for j in range(1, w + 1):
			b[i][j] = tmp[j - 1] in {'.', '@'}
			if tmp[j - 1] == '@':
				x = j
				y = i
	dfs(x, y)
	print(ans)


adjR = [-1, 0, 0, 1]
adjC = [0, 1, -1, 0]

def isValid(row, col, ROWS, COLS):
	return row >= 0 and row < ROWS and (col >= 0) and (col < COLS)

def floodfill(board, row, col, ROWS, COLS):
	global adjR
	global adjC
	if not isValid(row, col, ROWS, COLS):
		return 0
	if board[row][col] == '#':
		return 0
	board[row][col] = '#'
	total = 1
	for x in range(4):
		rr = row + adjR[x]
		cc = col + adjC[x]
		total += floodfill(board, rr, cc, ROWS, COLS)
	return total
while True:
	(COLS, ROWS) = list(map(int, input().split()))
	if ROWS == 0 and COLS == 0:
		break
	board = []
	for i in range(ROWS):
		line = input()
		board.append([c for c in line])
		if '@' in line:
			row = i
			col = line.find('@')
	print(floodfill(board, row, col, ROWS, COLS))


dxy = [(1, 0), (0, 1), (-1, 0), (0, -1)]

def rec(maze, visited, locat):
	for i in dxy:
		n_locat = (locat[0] + i[0], locat[1] + i[1])
		if 0 <= n_locat[0] < len(maze) and 0 <= n_locat[1] < len(maze[0]):
			if maze[n_locat[0]][n_locat[1]] == '.':
				if visited[n_locat[0]][n_locat[1]] == False:
					global count
					count += 1
					visited[n_locat[0]][n_locat[1]] = True
					rec(maze, visited, n_locat)
	return count
while True:
	(w, h) = map(int, input().split())
	if w == 0 and h == 0:
		break
	maze = [[] for i in range(h)]
	visited = [[False for i in range(w)] for j in range(h)]
	for i in range(h):
		mazel = list(input())
		maze[i] = mazel
	count = 1
	for i in range(h):
		for j in range(w):
			if maze[i][j] == '@':
				s = [i, j]
				break
		else:
			continue
		break
	print(rec(maze, visited, s))


from collections import deque
while True:
	(w, h) = map(int, input().split())
	if w == 0 and h == 0:
		break
	else:
		m = []
		d = deque()
		for i in range(h):
			r = input()
			m.append(list(r))
			s = r.find('@')
			if s != -1:
				d.append((s, i))
		while len(d):
			(rw, rh) = d.popleft()
			m[rh][rw] = 'Y'
			if 0 < rw and m[rh][rw - 1] == '.':
				d.append((rw - 1, rh))
				m[rh][rw - 1] = 'Y'
			if rw < w - 1 and m[rh][rw + 1] == '.':
				d.append((rw + 1, rh))
				m[rh][rw + 1] = 'Y'
			if 0 < rh and m[rh - 1][rw] == '.':
				d.append((rw, rh - 1))
				m[rh - 1][rw] = 'Y'
			if rh < h - 1 and m[rh + 1][rw] == '.':
				d.append((rw, rh + 1))
				m[rh + 1][rw] = 'Y'
		a = 0
		for i in m:
			a += i.count('Y')
		print(a)


while True:
	(w, h) = map(int, input().split())
	if w == 0:
		break
	a = []
	for i in range(h):
		t = list(input())
		a.append(t)
		if '@' in t:
			x = i
			y = t.index('@')
	stk = [[x, y]]
	c = 1
	while True:
		if stk == []:
			break
		(x, y) = stk.pop()
		if y != w - 1 and a[x][y + 1] == '.':
			a[x][y + 1] = '@'
			stk.append([x, y + 1])
		if y != 0 and a[x][y - 1] == '.':
			a[x][y - 1] = '@'
			stk.append([x, y - 1])
		if x != h - 1 and a[x + 1][y] == '.':
			a[x + 1][y] = '@'
			stk.append([x + 1, y])
		if x != 0 and a[x - 1][y] == '.':
			a[x - 1][y] = '@'
			stk.append([x - 1, y])
	print(sum([t.count('@') for t in a]))


from collections import deque
while True:
	(W, H) = map(int, input().split())
	if W == 0:
		break
	src = [input() for i in range(H)]
	for (y, row) in enumerate(src):
		x = row.find('@')
		if x < 0:
			continue
		(sx, sy) = (x, y)
		break
	visited = [[0 for x in range(W)] for y in range(H)]
	visited[sy][sx] = 1
	q = deque([(sx, sy)])
	ans = 1
	while q:
		(x, y) = q.popleft()
		for (dx, dy) in zip([1, 0, -1, 0], [0, 1, 0, -1]):
			(nx, ny) = (x + dx, y + dy)
			if not 0 <= nx < W or not 0 <= ny < H:
				continue
			if src[ny][nx] == '#' or visited[ny][nx]:
				continue
			visited[ny][nx] = 1
			ans += 1
			q.append((nx, ny))
	print(ans)


from queue import *
d = [(1, 0), (0, 1), (-1, 0), (0, -1)]
temp = {}
while True:
	(W, H) = (int(x) for x in input().split())
	mmap = []
	visited = []
	flag = 0
	count = 1
	q = Queue()
	if W == 0 & H == 0:
		break
	for i in range(0, H):
		mmap.append(list(input()))
	for i in range(0, H):
		for j in range(0, W):
			if mmap[i][j] == '@':
				start = [i, j]
	q.put(start)
	visited.append(list(start))
	while not q.empty():
		now = q.get()
		for myd in d:
			now2 = list(now)
			now2[0] += myd[0]
			now2[1] += myd[1]
			if not (now2[0] == -1 or now2[0] == H or now2[1] == -1 or (now2[1] == W)):
				if mmap[now2[0]][now2[1]] != '#':
					flag = 0
					for v in visited:
						if now2 == v:
							flag = 1
							break
					if flag == 0:
						count += 1
						q.put(now2)
						visited.append(list(now2))
	print(count)


import sys
input = sys.stdin.readline

def main():
	while 1:
		(w, h) = map(int, input().split())
		if w == 0 and h == 0:
			break
		mp = []
		for i in range(h):
			mp.append(list(input().strip()))
			if '@' in mp[-1]:
				stj = mp[-1].index('@')
				sti = i
		flag = [[0] * w for i in range(h)]
		flag = dfs(sti, stj, flag, mp)
		ans = sum([flag[i].count(1) for i in range(h)])
		print(ans)

def dfs(rw, cm, flag, mp):
	flag[rw][cm] = 1
	try:
		c = mp[rw][cm - 1]
		b = flag[rw][cm - 1]
	except:
		c = '#'
	if c == '.' and b == 0 and (rw >= 0) and (cm > 0):
		dfs(rw, cm - 1, flag, mp)
	try:
		c = mp[rw - 1][cm]
		b = flag[rw - 1][cm]
	except:
		c = '#'
	if c == '.' and b == 0 and (rw > 0) and (cm >= 0):
		dfs(rw - 1, cm, flag, mp)
	try:
		c = mp[rw][cm + 1]
		b = flag[rw][cm + 1]
	except:
		c = '#'
	if c == '.' and b == 0:
		dfs(rw, cm + 1, flag, mp)
	try:
		c = mp[rw + 1][cm]
		b = flag[rw + 1][cm]
	except:
		c = '#'
	if c == '.' and b == 0:
		dfs(rw + 1, cm, flag, mp)
	return flag
main()


import queue
dxy = [(1, 0), (0, 1), (-1, 0), (0, -1)]

def bfs(sx, sy, H, W):
	q = queue.Queue()
	visited = [[False] * W for _ in range(H)]
	q.put((sx, sy))
	visited[sx][sy] = True
	ans = 1
	while not q.empty():
		(px, py) = q.get()
		for (dx, dy) in dxy:
			nx = px + dx
			ny = py + dy
			if 0 <= nx < H and 0 <= ny < W:
				if c[nx][ny] == '.' and visited[nx][ny] == False:
					visited[nx][ny] = True
					q.put((nx, ny))
					ans += 1
	return ans
while True:
	(W, H) = map(int, input().split())
	if W == 0 and H == 0:
		break
	c = [input() for _ in range(H)]
	for i in range(H):
		if '@' in c[i]:
			sx = i
			sy = c[i].index('@')
	print(bfs(sx, sy, H, W))


import sys
sys.setrecursionlimit(10 ** 6)
W = None
H = None
MMAP = None
D = [(0, 1), (0, -1), (1, 0), (-1, 0)]

def main():
	global W, H, MMAP, D
	while True:
		(W, H) = map(int, input().split())
		if not W and (not H):
			return
		MMAP = [[] for _ in range(H)]
		(sx, sy) = (0, 0)
		for y in range(H):
			row = list(input())
			if '@' in row:
				sy = y
				sx = row.index('@')
			MMAP[y] = row
		print(calc(sx, sy))

def calc(x, y):
	global W, H, MMAP, D
	if not (x >= 0 and x < W and (y >= 0) and (y < H)):
		return 0
	if MMAP[y][x] == 'v' or MMAP[y][x] == '#':
		return 0
	ssum = 1
	MMAP[y][x] = 'v'
	for (dx, dy) in D:
		nx = x + dx
		ny = y + dy
		ssum += calc(x + dx, y + dy)
	return ssum

def gprint(tiles):
	for r in tiles:
		print(str('|'.join(r)))
main()


from collections import deque

def bfs():
	while 1:
		(W, H) = map(int, input().split())
		if W == 0 and H == 0:
			break
		maze = [list(input()) for _ in range(H)]
		check = [[False for _ in range(W)] for _ in range(H)]
		dx = [1, 0, -1, 0]
		dy = [0, 1, 0, -1]
		for i in range(H):
			for j in range(W):
				if maze[i][j] == '@':
					(sx, sy) = (j, i)
					check[i][j] = True
		ans = 1
		que = deque()
		que.append((sx, sy))
		while que:
			(x, y) = que.pop()
			for i in range(4):
				(nx, ny) = (x + dx[i], y + dy[i])
				if 0 <= nx < W and 0 <= ny < H and (maze[ny][nx] == '.') and (check[ny][nx] == False):
					que.append((nx, ny))
					check[ny][nx] = True
					ans += 1
		print(ans)
	return
bfs()


import sys

def dfs(rw, cm):
	global flag
	flag[rw][cm] = 1
	if 0 <= rw - 1 and mp[rw - 1][cm] == '.' and (flag[rw - 1][cm] == 0):
		dfs(rw - 1, cm)
	if cm + 1 < m and mp[rw][cm + 1] == '.' and (flag[rw][cm + 1] == 0):
		dfs(rw, cm + 1)
	if 0 <= cm - 1 and mp[rw][cm - 1] == '.' and (flag[rw][cm - 1] == 0):
		dfs(rw, cm - 1)
	if rw + 1 < n and mp[rw + 1][cm] == '.' and (flag[rw + 1][cm] == 0):
		dfs(rw + 1, cm)
while 1:
	(m, n) = map(int, input().split())
	if m == 0 and n == 0:
		break
	mp = []
	for i in range(n):
		mp.append(list(input()))
		if '@' in mp[-1]:
			stj = mp[-1].index('@')
			sti = i
	flag = [[0 for i in range(m)] for j in range(n)]
	dfs(sti, stj)
	print(sum((flag[i].count(1) for i in range(n))))


anslist = []

def sarch(i, j, visited):
	if 0 < i:
		if visited[i - 1][j] == 0:
			visited[i - 1][j] = 1
			sarch(i - 1, j, visited)
	if i < len(visited) - 1:
		if visited[i + 1][j] == 0:
			visited[i + 1][j] = 1
			sarch(i + 1, j, visited)
	if 0 < j:
		if visited[i][j - 1] == 0:
			visited[i][j - 1] = 1
			sarch(i, j - 1, visited)
	if j < len(visited[0]) - 1:
		if visited[i][j + 1] == 0:
			visited[i][j + 1] = 1
			sarch(i, j + 1, visited)
	return visited
while True:
	(w, h) = map(int, input().split())
	if w == 0 and h == 0:
		break
	grid = [list(input()) for i in range(h)]
	visited = [[0 for i in range(w)] for j in range(h)]
	starti = 0
	startj = 0
	for i in range(h):
		for j in range(w):
			if grid[i][j] == '@':
				starti = i
				startj = j
				visited[i][j] = 1
			elif grid[i][j] == '#':
				visited[i][j] = -1
			else:
				visited[i][j] = 0
	visited = sarch(starti, startj, visited)
	ans = 0
	for i in visited:
		for j in i:
			if j == 1:
				ans += 1
	anslist.append(ans)
for i in anslist:
	print(i)


def dfs(graph, sx, sy):
	stack = [[sx, sy]]
	visited = []
	cnt = 0
	while stack:
		label = stack.pop(0)
		try:
			g = graph[label[1]][label[0]]
			if label[0] < 0 or label[0] > graph[0].__len__() - 1:
				continue
			if label[1] < 0 or label[1] > graph.__len__() - 1:
				continue
			if g == '#':
				continue
			if [label[0], label[1]] not in visited:
				cnt += 1
				visited = [[label[0], label[1]]] + visited
				stack = [[label[0] + 1, label[1]], [label[0] - 1, label[1]], [label[0], label[1] + 1], [label[0], label[1] - 1]] + stack
		except IndexError:
			pass
	return cnt
STR = []
(W, H) = [int(i) for i in input().split()]
while W != 0:
	for j in range(H):
		STR.append(list(input()))
		if '@' in STR[j]:
			(sx, sy) = (STR[j].index('@'), j)
	print(dfs(STR, sx, sy))
	STR = []
	(W, H) = [int(i) for i in input().split()]


from collections import deque
(dx, dy) = ([1, 0, -1, 0], [0, 1, 0, -1])
while True:
	(w, h) = map(int, input().split())
	if w == 0 and h == 0:
		break
	field = [input() for i in range(h)]
	for i in range(h):
		if '@' in field[i]:
			(sx, sy) = (i, field[i].find('@'))
	visited = [[False for i in range(w)] for j in range(h)]
	que = deque()
	que.append((sx, sy))
	visited[sx][sy] = True
	while que:
		p = que.popleft()
		for i in range(4):
			(nx, ny) = (p[0] + dx[i], p[1] + dy[i])
			if 0 <= nx < h and 0 <= ny < w and (field[nx][ny] != '#') and (not visited[nx][ny]):
				visited[nx][ny] = True
				que.append((nx, ny))
	cnt = 0
	for i in range(h):
		for j in range(w):
			cnt += visited[i][j]
	print(cnt)


def solve(w, h, tile):
	ok = False
	for y in range(h):
		for x in range(w):
			if tile[y][x] == '@':
				s_x = x
				s_y = y
				ok = True
				break
		if ok:
			break
	count = 0
	check = [[s_x, s_y]]
	check_map = [[False for j in range(w)] for i in range(h)]
	while len(check) > 0:
		(x, y) = check.pop(0)
		if x in range(w) and y in range(h):
			if check_map[y][x] == False:
				if tile[y][x] == '.' or tile[y][x] == '@':
					check_map[y][x] = True
					count += 1
					check.append([x, y - 1])
					check.append([x, y + 1])
					check.append([x + 1, y])
					check.append([x - 1, y])
	return count
while True:
	try:
		(w, h) = map(int, input().split())
		if w == 0:
			break
		tile = [''] * h
		for i in range(h):
			tile[i] = input()
		print(solve(w, h, tile))
	except:
		break


I = input

def f(x, y, r):
	if not (0 <= x < len(r[0]) and 0 <= y < len(r)) or r[y][x] == '#':
		return 0
	r[y][x] = '#'
	return 1 + sum((f(x + dx, y + dy, r) for (dx, dy) in [[-1, 0], [1, 0], [0, -1], [0, 1]]))
while 1:
	(w, h) = map(int, I().split())
	if w == 0:
		break
	r = [list(input()) for _ in [0] * h]
	for (a, b) in enumerate(r):
		if '@' in b:
			y = a
			x = b.index('@')
			break
	print(f(x, y, r))


h = 0
w = 0
while 1:
	(w, h) = map(int, input().split())
	if h == 0 and w == 0:
		break
	grid = []
	sx = -1
	sy = -1
	ans = 1
	used = [[0] * w for i in range(h)]

	def valid(i, j):
		return i >= 0 and j >= 0 and (i < h) and (j < w) and (grid[i][j] == '.') and (not used[i][j])
	for i in range(h):
		row = input()
		grid.append(row)
		for j in range(w):
			if row[j] == '@':
				sx = i
				sy = j
	stk = [(sx, sy)]
	while stk:
		x = stk[-1][0]
		y = stk[-1][1]
		stk.pop()
		for d in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
			xx = x + d[0]
			yy = y + d[1]
			if valid(xx, yy):
				stk.append((xx, yy))
				used[xx][yy] = 1
				ans += 1
	print(ans)


def dfs(x, y, W, H):
	if x >= H or y >= W or x < 0 or (y < 0):
		return
	if visited[x][y] == 1:
		return
	if gridgraph[x][y] == '.' or gridgraph[x][y] == '@':
		visited[x][y] = 1
		dfs(x + 1, y, W, H)
		dfs(x, y + 1, W, H)
		dfs(x - 1, y, W, H)
		dfs(x, y - 1, W, H)
	if gridgraph[x][y] == '#':
		return
	return
while True:
	(W, H) = map(int, input().split())
	if W == 0 and W == 0:
		break
	gridgraph = [list(input()) for _ in range(H)]
	visited = [[0] * W for _ in range(H)]
	sx = -1
	sy = -1
	for (i, row) in enumerate(gridgraph):
		for j in range(len(row)):
			if row[j] == '@':
				sx = i
				sy = j
	dfs(sx, sy, W, H)
	ans = 0
	for row in visited:
		ans += sum(row)
	print(ans)


from collections import deque

def bfs():
	d = [[False] * w for i in range(h)]
	dx = [1, 0, -1, 0]
	dy = [0, 1, 0, -1]
	que = deque([])
	que.append((sx, sy))
	d[sx][sy] = True
	cnt = 1
	while que:
		p = que.popleft()
		for i in range(4):
			nx = p[0] + dx[i]
			ny = p[1] + dy[i]
			if 0 <= nx < h and 0 <= ny < w and (Map[nx][ny] != '#') and (d[nx][ny] == False):
				cnt += 1
				que.append((nx, ny))
				d[nx][ny] = True
	return cnt
while 1:
	(w, h) = map(int, input().split())
	if w == 0 and h == 0:
		break
	Map = [str(input()) for i in range(h)]
	for i in range(h):
		for j in range(w):
			if Map[i][j] == '@':
				sx = i
				sy = j
	print(bfs())


class dfs:

	def __init__(self, W, H, m):
		self.W = W
		self.H = H
		self.m = m
		self.ans = 0
		self.visited = [[False] * W for _ in range(H)]

	def trav(self, x, y):
		self.visited[x][y] = True
		self.ans += 1
		offset = [(-1, 0), (0, -1), (1, 0), (0, 1)]
		for (dx, dy) in offset:
			x2 = x + dx
			y2 = y + dy
			if 0 <= x2 < self.H and 0 <= y2 < self.W and (self.m[x2][y2] == '.') and (self.visited[x2][y2] == False):
				self.trav(x2, y2)
while True:
	(W, H) = map(int, input().split())
	if not (W and H):
		break
	m = []
	for i in range(H):
		L = list(input())
		if '@' in L:
			(sx, sy) = (i, L.index('@'))
		m.append(L)
	D = dfs(W, H, m)
	D.trav(sx, sy)
	print(D.ans)


import math

def search(w, h, data):
	for i in range(h):
		if '@' in data[i]:
			(stx, sty) = (i, data[i].index('@'))
	stack = [[stx, sty]]
	check = [[stx, sty]]
	while True:
		if len(stack) != 0:
			s = stack[-1]
			(Hnow, Wnow) = (s[0], s[1])
		else:
			return len(check)
		stack.pop()
		if Hnow < h - 1:
			if data[Hnow + 1][Wnow] == '.' and [Hnow + 1, Wnow] not in check:
				stack.append([Hnow + 1, Wnow])
				check.append([Hnow + 1, Wnow])
		if Wnow < w - 1:
			if data[Hnow][Wnow + 1] == '.' and [Hnow, Wnow + 1] not in check:
				stack.append([Hnow, Wnow + 1])
				check.append([Hnow, Wnow + 1])
		if Hnow > 0:
			if data[Hnow - 1][Wnow] == '.' and [Hnow - 1, Wnow] not in check:
				stack.append([Hnow - 1, Wnow])
				check.append([Hnow - 1, Wnow])
		if Wnow > 0:
			if data[Hnow][Wnow - 1] == '.' and [Hnow, Wnow - 1] not in check:
				stack.append([Hnow, Wnow - 1])
				check.append([Hnow, Wnow - 1])
a = []
while True:
	(w, h) = list(map(int, input().split()))
	if w == 0 and h == 0:
		break
	else:
		data = [list(input()) for l in range(h)]
		a.append(search(w, h, data))
for i in a:
	print(i)


dxy = [[1, 0], [-1, 0], [0, 1], [0, -1]]
n = 0

def rec(x, y):
	global n
	if (x < 0 or x >= h or y < 0 or (y >= w)) or (visited[x][y] or tile[x][y] != '.'):
		return 0
	visited[x][y] = True
	n += 1
	for (dx, dy) in dxy:
		x2 = x + dx
		y2 = y + dy
		rec(x2, y2)
	return 0
(w, h) = map(int, input().split())
ans = []
while (w, h) != (0, 0):
	n = 0
	tile = []
	for _ in range(h):
		tile.append(list(input()))
	visited = [[False] * w for _ in range(h)]
	for a in range(h):
		for b in range(w):
			if tile[a][b] == '@':
				pos_x = a
				pos_y = b
				tile[a][b] = '.'
	rec(pos_x, pos_y)
	ans.append(n)
	(w, h) = map(int, input().split())
for a in ans:
	print(a)


import math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, random, time, copy, functools
sys.setrecursionlimit(10 ** 7)
inf = 10 ** 20
eps = 1.0 / 10 ** 10
mod = 10 ** 9 + 7

def LI():
	return [int(x) for x in sys.stdin.readline().split()]

def LI_():
	return [int(x) - 1 for x in sys.stdin.readline().split()]

def LF():
	return [float(x) for x in sys.stdin.readline().split()]

def LS():
	return sys.stdin.readline().split()

def I():
	return int(sys.stdin.readline())

def F():
	return float(sys.stdin.readline())

def S():
	return input()

def pf(s):
	return print(s, flush=True)

def main():
	rr = []
	dd = [(-1, 0), (1, 0), (0, -1), (0, 1)]
	while True:
		(w, h) = LI()
		if w == 0:
			break
		a = [S() for _ in range(h)]
		q = []
		f = collections.defaultdict(bool)
		for i in range(h):
			for j in range(w):
				if a[i][j] == '@':
					q.append((i, j))
		qi = 0
		while len(q) > qi:
			(i, j) = q[qi]
			qi += 1
			for (di, dj) in dd:
				ni = i + di
				nj = j + dj
				if 0 <= ni < h and 0 <= nj < w and (a[ni][nj] == '.') and (not f[ni, nj]):
					f[ni, nj] = True
					q.append((ni, nj))
		rr.append(len(q))
	return '\n'.join(map(str, rr))
print(main())


while True:
	(w, h) = map(int, input().split())
	if w == 0 and h == 0:
		break
	m = []
	for _ in range(h):
		m.append(list(input()))
	visited = [[False] * w for _ in range(h)]
	dxy = [(1, 0), (0, 1), (-1, 0), (0, -1)]
	answer = 0

	def rec(x, y):
		global answer
		visited[x][y] = True
		answer += 1
		for (dx, dy) in dxy:
			x2 = x + dx
			y2 = y + dy
			if 0 <= x2 < h and 0 <= y2 < w:
				if m[x2][y2] == '.':
					if not visited[x2][y2]:
						rec(x2, y2)
	for i in range(h):
		for j in range(w):
			if m[i][j] == '@':
				rec(i, j)
				break
		else:
			continue
		break
	print(answer)


def count_area(h, w):
	count = 0
	if h > 0 and s[h - 1][w] == '.':
		s[h - 1][w] = '#'
		count += count_area(h - 1, w)
	if h < H - 1 and s[h + 1][w] == '.':
		s[h + 1][w] = '#'
		count += count_area(h + 1, w)
	if w > 0 and s[h][w - 1] == '.':
		s[h][w - 1] = '#'
		count += count_area(h, w - 1)
	if w < W - 1 and s[h][w + 1] == '.':
		s[h][w + 1] = '#'
		count += count_area(h, w + 1)
	return count + 1
while True:
	(W, H) = map(int, input().split())
	if H == 0 & W == 0:
		break
	s = [list(input()) for i in range(H)]
	for h in range(H):
		for w in range(W):
			if s[h][w] == '@':
				s[h][w] = '#'
				print(count_area(h, w))
				break


import collections
while True:
	(w, h) = map(int, input().split())
	if w == 0 and h == 0:
		break
	tile = []
	tile.append(['#'] * (w + 2))
	for _ in range(h):
		temp = list(input())
		temp = ['#'] + temp + ['#']
		tile.append(temp)
	tile.append(['#'] * (w + 2))
	route = [[[0, 0, 0, 0] for i in range(w)] for j in range(h)]
	for i in range(1, h + 1):
		for j in range(1, w + 1):
			if tile[i + 1][j] == '.':
				route[i - 1][j - 1][0] = 1
			if tile[i - 1][j] == '.':
				route[i - 1][j - 1][1] = 1
			if tile[i][j + 1] == '.':
				route[i - 1][j - 1][2] = 1
			if tile[i][j - 1] == '.':
				route[i - 1][j - 1][3] = 1
			if tile[i][j] == '@':
				st = [i - 1, j - 1]
	dir = [[1, 0], [-1, 0], [0, 1], [0, -1]]
	d = [[0] * w for i in range(h)]
	d[st[0]][st[1]] = 1
	q = collections.deque()
	q.append(st)
	while len(q) > 0:
		cur = q.popleft()
		for i in range(4):
			if route[cur[0]][cur[1]][i] == 1 and d[cur[0] + dir[i][0]][cur[1] + dir[i][1]] == 0:
				d[cur[0] + dir[i][0]][cur[1] + dir[i][1]] = 1
				q.append([cur[0] + dir[i][0], cur[1] + dir[i][1]])
	ans = 0
	for i in range(h):
		for j in range(w):
			if d[i][j] == 1:
				ans += 1
	print(ans)


import array
import itertools
import sys
UNDET_POINT = (-1, -1)

class RecursiveDepthFirstSearch(object):

	def __init__(self, width, height, tiles):
		self.width = width
		self.height = height
		self.tiles = tiles
		self.reached = [array.array('B', (False for j in range(height))) for i in range(width)]
		self.start_tile = UNDET_POINT
		for (x, y) in itertools.product(range(width), range(height)):
			if tiles[x][y] == '@':
				self.start_tile = (x, y)
				break

	def search(self, x, y):
		if x < 0 or self.width <= x or y < 0 or (self.height <= y):
			pass
		elif self.tiles[x][y] == '#':
			pass
		elif self.reached[x][y]:
			pass
		else:
			self.reached[x][y] = True
			self.search(x + 1, y)
			self.search(x - 1, y)
			self.search(x, y + 1)
			self.search(x, y - 1)

	def count_reachable_tiles(self):
		self.search(*self.start_tile)
		reachable_tiles = sum([self.reached[x][y] for (x, y) in itertools.product(range(self.width), range(self.height))])
		return reachable_tiles
sys.setrecursionlimit(10000)
while True:
	(width, height) = map(int, input().split())
	if width == 0 and height == 0:
		break
	else:
		tiles = [x for x in zip(*[input() for y in range(height)])]
		dfs = RecursiveDepthFirstSearch(width, height, tiles)
		print(dfs.count_reachable_tiles())


from collections import deque

def bfs(h, w, f, s):
	count = 1
	q = deque()
	q.append(s)
	move = ((0, 1), (0, -1), (1, 0), (-1, 0))
	while q:
		(i, j) = q.popleft()
		for (di, dj) in move:
			(ni, nj) = (i + di, j + dj)
			if 0 <= ni < w and 0 <= nj < h and (f[ni][nj] == '.'):
				count += 1
				q.append((ni, nj))
				f[ni][nj] = '#'
	return count

def search_atmark(h, w, f):
	for i in range(h):
		for j in range(w):
			if f[i][j] == '@':
				return (i, j)

def solve(h, w, f):
	s = search_atmark(w, h, f)
	return bfs(h, w, f, s)
while True:
	(w, h) = map(int, input().split())
	if w == 0 and h == 0:
		break
	f = [list(input()) for i in range(h)]
	print(solve(w, h, f))


while True:
	(w, h) = map(int, input().split())
	if w == 0:
		break
	around = ''
	for i in range(w + 2):
		around += '#'
	maze = [around]
	cnt = 1
	for i in range(h):
		row = '#' + input() + '#'
		maze.append(row)
		if '@' in row:
			loc = [[i + 1, row.index('@')]]
	maze.append(around)
	visted = loc
	left = True
	while left:
		next_loc = []
		for (x, y) in loc:
			for (i, j) in ([1, 0], [0, 1], [-1, 0], [0, -1]):
				if maze[x + i][y + j] == '.' and [x + i, y + j] not in visted:
					cnt += 1
					next_loc.append([x + i, y + j])
					visted.append([x + i, y + j])
			if next_loc == []:
				print(cnt)
				left = False
				break
		loc = next_loc


(w, h) = map(int, input().split())
while w != 0 or h != 0:
	maps = []
	flag = False
	ans = 0
	for i in range(h):
		k = list(input())
		maps.append(k)
	for i in range(h):
		if flag:
			break
		for j in range(w):
			if maps[i][j] == '@':
				maps[i][j] = '#'
				pos_x = i
				pos_y = j
				flag = True
				break

	def check(x, y):
		global maps
		if 0 <= x < h and 0 <= y < w:
			pass
		else:
			return False
		if maps[x][y] == '#':
			return False
		else:
			return True

	def bfs(x, y):
		global ans
		global maps
		for i in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
			p = i[0]
			q = i[1]
			if check(x + p, y + q):
				ans += 1
				maps[x + p][y + q] = '#'
				bfs(x + p, y + q)
	bfs(pos_x, pos_y)
	print(ans + 1)
	(w, h) = map(int, input().split())


while True:
	(W, H) = map(int, input().split())
	if W == 0 and H == 0:
		break
	maze = []
	for _ in range(H):
		maze.append(list(input()))
	visited = [[False] * W for _ in range(H)]
	dxy = [(1, 0), (0, 1), (-1, 0), (0, -1)]
	ans = 0

	def rec(x, y):
		global ans
		visited[x][y] = True
		ans += 1
		for (dx, dy) in dxy:
			x2 = x + dx
			y2 = y + dy
			if 0 <= x2 < H and 0 <= y2 < W:
				if maze[x2][y2] == '.':
					if not visited[x2][y2]:
						rec(x2, y2)
	for h in range(H):
		for w in range(W):
			if maze[h][w] == '@':
				rec(h, w)
				break
		else:
			continue
		break
	print(ans)


import queue
while True:
	(w, h) = map(int, input().split())
	if w == 0 and h == 0:
		break
	maze = [input() for _ in range(h)]
	visited = [[-1] * w for _ in range(h)]
	for i in range(h):
		if '@' in maze[i]:
			x_f = i
	for i in range(w):
		if maze[x_f][i] == '@':
			y_f = i
	visited[x_f][y_f] = 1
	q = queue.Queue()
	q.put([x_f, y_f])
	cnt = 1
	while not q.empty():
		(x, y) = q.get()
		for (dx, dy) in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
			if 0 <= x + dx < h and 0 <= y + dy < w:
				if visited[x + dx][y + dy] == -1 and maze[x + dx][y + dy] == '.':
					cnt += 1
					visited[x + dx][y + dy] = 1
					q.put([x + dx, y + dy])
	print(cnt)


d = [[-1, 0], [1, 0], [0, -1], [0, 1]]

def search(w, h, x, y, m):
	if not (0 <= x < w and 0 <= y < h) or m[y][x] == '#':
		return 0
	m[y][x] = '#'
	return sum([search(w, h, x + dx, y + dy, m) for (dx, dy) in d]) + 1
while True:
	(w, h) = map(int, input().split())
	if w == h == 0:
		break
	m = []
	for (i, l) in enumerate([list(input()) for _ in range(h)]):
		if '@' in l:
			(x, y) = (l.index('@'), i)
		m += [l]
	print(search(w, h, x, y, m))


def Check(A, i, j, W, H):
	if j - 1 >= 0:
		if A[i][j - 1] == '.':
			A[i][j - 1] = '+'
			Check(A, i, j - 1, W, H)
	if i + 1 < H:
		if A[i + 1][j] == '.':
			A[i + 1][j] = '+'
			Check(A, i + 1, j, W, H)
	if j + 1 < W:
		if A[i][j + 1] == '.':
			A[i][j + 1] = '+'
			Check(A, i, j + 1, W, H)
	if i - 1 >= 0:
		if A[i - 1][j] == '.':
			A[i - 1][j] = '+'
			Check(A, i - 1, j, W, H)
	return A
while True:
	(W, H) = map(int, input().split())
	if W == 0 and H == 0:
		break
	Tile = [list(input()) for i in range(H)]
	for i in range(H):
		for j in range(W):
			if Tile[i][j] == '@':
				my_i = i
				my_j = j
	Tile[my_i][my_j] = '+'
	Tile_new = Check(Tile, my_i, my_j, W, H)
	count = 0
	for i in range(H):
		for j in range(W):
			if Tile_new[i][j] == '+':
				count += 1
	print(count)


def getter(targ, x, y):
	if 0 > x or x >= len(targ) or 0 > y or (y >= len(targ[0])) or (targ[x][y] == '#'):
		return 0
	else:
		targ[x][y] = '#'
		return 1 + getter(targ, x + 1, y) + getter(targ, x - 1, y) + getter(targ, x, y + 1) + getter(targ, x, y - 1)
(width, height) = [int(n) for n in input().split(' ')]
global lab
while True:
	(lab, start) = ([], [])
	for a in range(height):
		disp = [n for n in input().rstrip('\n')]
		if '@' in disp:
			start.extend([disp.index('@'), a])
		lab.append(disp)
	else:
		(a, b) = start
		print(getter(lab, b, a))
		(width, height) = [int(n) for n in input().split(' ')]
		if width == 0 and height == 0:
			break


from collections import deque
ans = []
while True:
	(w, h) = map(int, input().split())
	if not w and (not h):
		break
	roadmap = []
	d = deque()
	able = [[False for i in range(w)] for j in range(h)]
	for i in range(h):
		roadmap.append(input())
	for i in range(h):
		for j in range(w):
			if roadmap[i][j] == '@':
				able[i][j] = True
				d.append([i, j])
	while len(d):
		(y, x) = d.pop()
		for course in [[0, 1], [1, 0], [-1, 0], [0, -1]]:
			(tmpy, tmpx) = (y + course[0], x + course[1])
			if tmpy < 0 or tmpy >= h or tmpx < 0 or (tmpx >= w):
				continue
			if not able[tmpy][tmpx] and roadmap[tmpy][tmpx] == '.':
				able[tmpy][tmpx] = True
				d.append([tmpy, tmpx])
	a = 0
	for i in range(h):
		a += len(list(filter(lambda x: x, able[i])))
	ans.append(a)
[print(i) for i in ans]


def fill(y, x):
	global l, c, w, h
	if 0 <= x + 1 < w and 0 <= y < h and (l[y][x + 1] == '.'):
		c += 1
		l[y][x + 1] = 1
		fill(y, x + 1)
	if 0 <= x - 1 < w and 0 <= y < h and (l[y][x - 1] == '.'):
		c += 1
		l[y][x - 1] = 1
		fill(y, x - 1)
	if 0 <= x < w and 0 <= y + 1 < h and (l[y + 1][x] == '.'):
		c += 1
		l[y + 1][x] = 1
		fill(y + 1, x)
	if 0 <= x < w and 0 <= y - 1 < h and (l[y - 1][x] == '.'):
		c += 1
		l[y - 1][x] = 1
		fill(y - 1, x)
	return c
while 1:
	(w, h) = map(int, input().split())
	if not w and (not h):
		break
	l = [list(input()) for _ in range(h)]
	(y, x) = [[n, i.index('@')] for (n, i) in enumerate(l) if '@' in i][0]
	l[y][x] = 1
	c = 1
	print(fill(y, x))


def search(x, y, m):
	if x < 0 or y < 0 or x >= len(m[0]) or (y >= len(m)):
		return 0
	if m[y][x] == '#':
		return 0
	m[y][x] = '#'
	return 1 + search(x + 1, y, m) + search(x - 1, y, m) + search(x, y + 1, m) + search(x, y - 1, m)
while True:
	(w, h) = map(int, input().split())
	if w == 0:
		break
	room = []
	for i in range(h):
		tmp = list(input())
		room.append(tmp[:w])
		if '@' in tmp:
			y = i
			x = tmp.index('@')
	print(search(x, y, room))


vec = [[1, 0], [0, 1], [-1, 0], [0, -1]]

def dfs(nw, nh):
	global count
	count += 1
	visited[nh][nw] = True
	for (x, y) in vec:
		new_w = nw + x
		new_h = nh + y
		if 0 <= new_w and new_w < w:
			if 0 <= new_h and new_h < h:
				if lis_f[new_h][new_w] == '.' and visited[new_h][new_w] == False:
					dfs(new_w, new_h)
while True:
	(w, h) = map(int, input().split())
	if (w, h) == (0, 0):
		break
	lis_f = []
	for _ in range(h):
		lis_f.append(list(input()))
	visited = [[False for _ in range(w)] for _ in range(h)]
	count = 0
	id_w = 0
	id_h = 0
	set_w = 0
	set_h = 0
	while id_h < h:
		while id_w < w:
			if lis_f[id_h][id_w] == '@':
				set_w = id_w
				set_h = id_h
			id_w += 1
		id_h += 1
		id_w = 0
	dfs(set_w, set_h)
	print(count)


while True:
	(W, H) = map(int, input().split())
	room = []
	for i in range(H):
		room.append(input())
	for i in range(H):
		for j in range(W):
			if room[i][j] == '@':
				(sx, sy) = (j, i)
	dx = (-1, 0, 1, 0)
	dy = (0, -1, 0, 1)
	visited = [[False] * W for i in range(H)]

	def rec(x, y):
		visited[y][x] = True
		for i in range(4):
			nx = x + dx[i]
			ny = y + dy[i]
			if 0 <= nx < W and 0 <= ny < H and (room[ny][nx] == '.'):
				if not visited[ny][nx]:
					rec(nx, ny)
	if W == 0 or H == 0:
		break
	rec(sx, sy)
	ans = 0
	for a in visited:
		for b in a:
			if b:
				ans += 1
	print(ans)


while 1:
	(w, h) = list(map(int, input().strip().split()))
	if w == h == 0:
		break
	data = []
	data = []
	for _ in range(h):
		data.append(list(input()))
	visited = []
	position = (0, 0)
	for i in range(h):
		if '@' in data[i]:
			position = (i, data[i].index('@'))
	stack = []
	count = 0
	stack.append(position)
	while len(stack) != 0:
		(y, x) = stack.pop()
		count += 1
		if y - 1 >= 0 and (not (y - 1, x) in visited) and (data[y - 1][x] == '.'):
			visited.append((y - 1, x))
			stack.append((y - 1, x))
		if x - 1 >= 0 and (not (y, x - 1) in visited) and (data[y][x - 1] == '.'):
			visited.append((y, x - 1))
			stack.append((y, x - 1))
		if y + 1 < h and (not (y + 1, x) in visited) and (data[y + 1][x] == '.'):
			visited.append((y + 1, x))
			stack.append((y + 1, x))
		if x + 1 < w and (not (y, x + 1) in visited) and (data[y][x + 1] == '.'):
			visited.append((y, x + 1))
			stack.append((y, x + 1))
	print(count)


while 1:
	(x, y) = list(map(int, input().split()))
	if x == 0:
		break
	pp = [1, -1, 0, 0]
	qq = [0, 0, 1, -1]
	m = []
	for i in range(y):
		m.append(list(input()))
		if '@' in m[-1]:
			ss = m[-1].index('@')
			tt = i
	cnt = 0

	def move(cx, cy):
		global cnt
		if cy >= y or cy < 0 or cx >= x or (cx < 0):
			return
		if m[cy][cx] == '.' or m[cy][cx] == '@':
			cnt += 1
			m[cy][cx] = '0'
			for i in range(4):
				move(cx + pp[i], cy + qq[i])
	move(ss, tt)
	print(cnt)


c = {'#': 0, '@': 1, '.': 2, '*': 3}
d = [[0, -1], [0, 1], [-1, 0], [1, 0]]
output = []
while True:
	(w, h) = input().split()
	w = int(w)
	h = int(h)
	if w == 0:
		break
	tiles = [[0 for i in range(w)] for j in range(h)]
	for i in range(h):
		row = input()
		for j in range(w):
			tiles[i][j] = c[row[j]]
			if tiles[i][j] == 1:
				queue = [(j, i)]
	count = 1
	while queue:
		(x, y) = queue[0]
		queue.pop(0)
		for (ud, rl) in d:
			xt = x + ud
			yt = y + rl
			if xt >= 0 and xt <= w - 1 and (yt >= 0) and (yt <= h - 1):
				if tiles[yt][xt] == 2:
					tiles[yt][xt] = 3
					count += 1
					queue.append((xt, yt))
	output.append(count)
for num in output:
	print(num)


def location(field, wanted):
	for (i, row) in enumerate(field):
		for (j, cell) in enumerate(row):
			if cell == wanted:
				return (i, j)

def count(field, wanted):
	result = 0
	for row in field:
		for cell in row:
			if cell == wanted:
				result += 1
	return result

def neighborhood(center, w, h):
	(i, j) = center
	return filter(lambda x: 0 <= x[0] and x[0] < h and (0 <= x[1]) and (x[1] < w), [(i - 1, j), (i, j - 1), (i, j + 1), (i + 1, j)])
printed_later = []
while True:
	(w, h) = map(int, input().split())
	if w == 0 and h == 0:
		break
	field = []
	for i in range(h):
		field.append(list(input()))
	queue = [location(field, '@')]
	field[queue[0][0]][queue[0][1]] = ','
	while len(queue) > 0:
		for cell in neighborhood(queue.pop(0), w, h):
			if field[cell[0]][cell[1]] == '.':
				queue.append(cell)
				field[cell[0]][cell[1]] = ','
	printed_later.append(count(field, ','))
for line in printed_later:
	print(line)


from collections import deque
while 1:
	(W, H) = map(int, input().split())
	if W == 0 and H == 0:
		break
	tizu = []
	for i in range(H):
		row = input()
		if '@' in row:
			start = (i, row.index('@'))
		tizu.append(row)
	went = [[False] * W for i in range(H)]
	went[start[0]][start[1]] = True
	ans = 1
	queue = deque()
	queue.append(start)
	while queue:
		(curh, curw) = queue.popleft()
		for (dh, dw) in ((0, 1), (0, -1), (1, 0), (-1, 0)):
			newh = curh + dh
			neww = curw + dw
			if 0 <= newh < H and 0 <= neww < W:
				if tizu[newh][neww] == '.' and (not went[newh][neww]):
					went[newh][neww] = True
					queue.append((newh, neww))
					ans += 1
	print(ans)


(W, H) = (int(i) for i in input().split())
while W != 0 or H != 0:
	a = []
	T = []
	for i in range(H):
		T.append(input())
		a.append([])
		for j in range(W):
			a[i].append(0)
	i = 0
	j = 0
	while T[i][j] != '@':
		j = 0
		while j < W and T[i][j] != '@':
			j += 1
		if j >= W:
			j -= 1
		if T[i][j] != '@':
			i += 1
	s = [[i, j]]
	a[i][j] = 1
	c = 1
	while s != []:
		u = []
		for l in range(len(s)):
			i = s[l][0]
			j = s[l][1]
			i -= 1
			k = 0
			while k < 2:
				if 0 <= i < H and a[i][j] == 0 and (T[i][j] == '.'):
					a[i][j] = 1
					u.append([i, j])
					c += 1
				i += 2
				k += 1
			i -= 3
			j -= 1
			k = 0
			while k < 2:
				if 0 <= j < W and a[i][j] == 0 and (T[i][j] == '.'):
					a[i][j] = 1
					u.append([i, j])
					c += 1
				j += 2
				k += 1
		s = u
	print(c)
	(W, H) = (int(i) for i in input().split())


import sys
cnt = 0

def solve():
	while 1:
		(w, h) = map(int, sys.stdin.readline().split())
		if w == h == 0:
			return
		room = [list(sys.stdin.readline().rstrip()) for i in range(h)]
		for i in range(h):
			if '@' in room[i]:
				si = i
				sj = room[i].index('@')
				break
		global cnt
		cnt = 0
		dfs(w, h, room, si, sj)
		print(cnt)

def dfs(w, h, room, i, j):
	if i < 0 or i >= h or j < 0 or (j >= w) or (room[i][j] == '#'):
		return
	global cnt
	cnt += 1
	room[i][j] = '#'
	dfs(w, h, room, i + 1, j)
	dfs(w, h, room, i - 1, j)
	dfs(w, h, room, i, j + 1)
	dfs(w, h, room, i, j - 1)
solve()


import collections
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]

def movable(dst):
	if dst[0] < 0 or dst[0] > b - 1:
		return False
	elif dst[1] < 0 or dst[1] > a - 1:
		return False
	elif MM[dst[0]][dst[1]] == '#':
		return False
	else:
		return True
while True:
	c = 1
	(a, b) = map(int, input().split())
	if a == 0 and b == 0:
		exit()
	else:
		MM = []
		for i in range(b):
			q = list(input())
			MM.append(q)
			if '@' in q:
				st = [i, q.index('@')]
		D = [[-1 for _ in range(a)] for _ in range(b)]
		D[st[0]][st[1]] = 0
		Q = collections.deque()
		Q.append(st)
		while len(Q) > 0:
			cur = Q.popleft()
			for dir in range(4):
				dst = [cur[0] + dx[dir], cur[1] + dy[dir]]
				if movable(dst) and D[dst[0]][dst[1]] == -1:
					D[dst[0]][dst[1]] = D[cur[0]][cur[1]] + 1
					c += 1
					Q.append(dst)
		print(c)


while True:
	(w, h) = map(int, input().split())
	if w == 0:
		break
	tile = [''] * h
	for i in range(h):
		tile[i] = input()
	ok = False
	for y in range(h):
		for x in range(w):
			if tile[y][x] == '@':
				s_x = x
				s_y = y
				ok = True
				break
		if ok:
			break
	count = 0
	check = [[s_x, s_y]]
	check_map = [[False for j in range(w)] for i in range(h)]
	while len(check) > 0:
		(x, y) = check.pop(0)
		if x in range(w) and y in range(h):
			if check_map[y][x] == False:
				if tile[y][x] == '.' or tile[y][x] == '@':
					check_map[y][x] = True
					count += 1
					check.append([x, y - 1])
					check.append([x, y + 1])
					check.append([x + 1, y])
					check.append([x - 1, y])
	print(count)


def get_start(tile, h, w):
	for i in range(w):
		for j in range(h):
			if tile[i][j] == '@':
				return (i, j)
dirs = [(-1, 0), (0, -1), (1, 0), (0, 1)]
while True:
	(w, h) = map(int, input().split())
	if (w, h) == (0, 0):
		break
	tile = [list(input()) for i in range(h)]
	start = get_start(tile, w, h)
	count = 0
	q = [start]
	while q:
		(x, y) = q.pop()
		for d in dirs:
			xx = x + d[0]
			yy = y + d[1]
			if (0 <= xx and xx < h) and (0 <= yy and yy < w):
				if tile[xx][yy] == '.':
					tile[xx][yy] = '_'
					count += 1
					q.append((xx, yy))
	print(count + 1)


c = 0

def calc(t, X, Y):
	global c
	c += 1
	t[Y][X] = '#'
	for (x, y) in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
		if t[Y + y][X + x] == '.':
			calc(t, X + x, Y + y)
while True:
	c = 0
	(w, h) = map(int, input().split())
	if w == h == 0:
		break
	t = [['#'] * (w + 2)] + [['#'] + list(input()) + ['#'] for _ in range(h)] + [['#'] * (w + 2)]
	for sy in range(h + 2):
		if '@' in t[sy]:
			sx = t[sy].index('@')
			break
	calc(t, sx, sy)
	print(c)


import copy
(w, h) = map(int, input().split())
while [h, w] != [0, 0]:
	area = []
	a = 1
	for i in range(h):
		area.append(list(input()))
		area[i].insert(0, '#')
		area[i].append('#')
	area.insert(0, ['#' for i in range(w + 2)])
	area.append(['#' for i in range(w + 2)])
	que = []
	for i in range(1, h + 1):
		for j in range(1, w + 1):
			if area[i][j] == '@':
				que.append([i, j])
				break
		else:
			continue
		break
	while True:
		nque = []
		for i in que:
			h1 = i[0]
			w1 = i[1]
			if area[h1 - 1][w1] == '.':
				area[h1 - 1][w1] = '*'
				nque.append([h1 - 1, w1])
				a += 1
			if area[h1 + 1][w1] == '.':
				area[h1 + 1][w1] = '*'
				nque.append([h1 + 1, w1])
				a += 1
			if area[h1][w1 - 1] == '.':
				area[h1][w1 - 1] = '*'
				nque.append([h1, w1 - 1])
				a += 1
			if area[h1][w1 + 1] == '.':
				area[h1][w1 + 1] = '*'
				nque.append([h1, w1 + 1])
				a += 1
		if nque == []:
			break
		que = copy.deepcopy(nque)
	print(a)
	(w, h) = map(int, input().split())


(lambda f: f(f))(lambda this, atin=lambda line, yp, ri=lambda l: room.append([{xi: x} for (xi, x) in enumerate(l)]): [point.__setitem__('x', line.index('@')), point.__setitem__('y', yp), ri(line)] if '@' in line else ri(line), search=lambda xpoint, ypoint, srch, now: [room[ypoint][xpoint].__setitem__(xpoint, '@'), srch(xpoint - 1, ypoint, srch, now) + srch(xpoint + 1, ypoint, srch, now) + srch(xpoint, ypoint + 1, srch, now) + srch(xpoint, ypoint - 1, srch, now) + 1][1] if 0 <= xpoint < wh[0] and 0 <= ypoint < wh[1] and now(xpoint, ypoint) else 0, now=lambda xpoint, ypoint: room[ypoint][xpoint].get(xpoint) is '.': [globals().__setitem__('wh', list(map(int, input().split()))), globals().__setitem__('room', []), globals().__setitem__('point', {'x': None, 'y': None}), [atin(input(), ypoint) for ypoint in range(wh[1])], [room[point['y']][point['x']].__setitem__(point['x'], '.'), print(search(point['x'], point['y'], search, now)), this(this)] if room else None])


from logging import getLogger, StreamHandler, NullHandler, DEBUG, INFO
logger = getLogger(__name__)
handler = NullHandler()
logger.setLevel(DEBUG)
handler.setLevel(DEBUG)
logger.addHandler(handler)
logger.propagate = False
g_field = []
g_count = 0
g_W = -1
g_H = -1
OFFSETS = [(1, 0), (-1, 0), (0, 1), (0, -1)]

def dfs(x, y):
	global g_field
	global g_count
	global g_W
	global g_H
	g_count += 1
	g_field[y][x] = '-'
	for (dx, dy) in OFFSETS:
		logger.debug('diff: {} {}'.format(dx, dy))
		new_x = x + dx
		new_y = y + dy
		if new_x < 0 or new_x >= g_W:
			continue
		if new_y < 0 or new_y >= g_H:
			continue
		new_tile = g_field[new_y][new_x]
		if new_tile == '#' or new_tile == '-':
			continue
		logger.debug('{}, {}'.format(new_x, new_y))
		dfs(new_x, new_y)
while True:
	(g_W, g_H) = [int(s) for s in input().strip().split()]
	if g_W == 0 and g_H == 0:
		break
	g_field = []
	for _ in range(g_H):
		row = list(input().strip())
		g_field.append(row)
	g_count = 0
	for y in range(g_H):
		for x in range(g_W):
			if g_field[y][x] == '@':
				start_x = x
				start_y = y
				break
	dfs(start_x, start_y)
	print(g_count)


def dfs(now, origin, drawn):
	positive = '.'
	negative = '#'
	direct = [0, 0, 0, 0]
	height = len(origin)
	width = len(origin[0])
	now_h = now[0]
	now_w = now[1]
	if now_h != 0 and origin[now_h - 1][now_w] == positive and (drawn[now_h - 1][now_w] == 0):
		direct[0] = 1
	if now_h != height - 1 and origin[now_h + 1][now_w] == positive and (drawn[now_h + 1][now_w] == 0):
		direct[1] = 1
	if now_w != 0 and origin[now_h][now_w - 1] == positive and (drawn[now_h][now_w - 1] == 0):
		direct[2] = 1
	if now_w != width - 1 and origin[now_h][now_w + 1] == positive and (drawn[now_h][now_w + 1] == 0):
		direct[3] = 1
	if sum(direct) == 0:
		return 0
	d = {0: [now_h - 1, now_w], 1: [now_h + 1, now_w], 2: [now_h, now_w - 1], 3: [now_h, now_w + 1]}
	for i in range(4):
		if direct[i] == 1:
			drawn[d[i][0]][d[i][1]] = 1
			dfs(d[i], origin, drawn)
	return 0
while True:
	(W, H) = map(int, input().split())
	if W == 0 and H == 0:
		break
	tiles = [list(input()) for i in range(H)]
	possible_tiles = [[0 for i in range(W)] for j in range(H)]
	for h in range(H):
		for w in range(W):
			if tiles[h][w] == '@':
				now = [h, w]
				break
	possible_tiles[now[0]][now[1]] = 1
	dfs(now, tiles, possible_tiles)
	ans = 0
	for h in range(H):
		for w in range(W):
			if possible_tiles[h][w] == 1:
				ans += 1
	print(ans)


from queue import Queue

def calcReachableTileNumByBFSearch(room, start_pos):
	q = Queue()
	q.put(start_pos)
	count = 1
	while not q.empty():
		cur_pos = q.get()
		D0 = [1, 0, -1, 0]
		D1 = [0, -1, 0, 1]
		for d in range(4):
			nc = [0, 0]
			nc[0] = cur_pos[0] + D0[d]
			nc[1] = cur_pos[1] + D1[d]
			if room[nc[0]][nc[1]] == '.':
				room[nc[0]][nc[1]] = '*'
				q.put([nc[0], nc[1]])
				count += 1
	return count

def solve(width, height):
	room = [['#' for i in range(width + 2)] for j in range(height + 2)]
	for i in range(height):
		row = input()
		for j in range(width):
			room[i + 1][j + 1] = row[j]
			if room[i + 1][j + 1] == '@':
				start = [i + 1, j + 1]
	return calcReachableTileNumByBFSearch(room, start)

def main():
	while True:
		(width, height) = map(int, input().split())
		if width == 0 and height == 0:
			break
		print(solve(width, height))
main()


import queue

def solve(w, h):
	q = queue.Queue()
	m = [['#' for i in range(w + 2)] for j in range(h + 2)]
	for i in range(h):
		inp = input()
		for j in range(w):
			m[i + 1][j + 1] = inp[j]
			if m[i + 1][j + 1] == '@':
				start = [i + 1, j + 1]
	q.put(start)
	c = 1
	while not q.empty():
		cur = q.get()
		XY = [(1, 0), (-1, 0), (0, 1), (0, -1)]
		for (x, y) in XY:
			cx = cur[0] + x
			cy = cur[1] + y
			if m[cx][cy] == '.':
				m[cx][cy] = '#'
				q.put([cx, cy])
				c += 1
	return c
while True:
	(w, h) = [int(i) for i in input().split()]
	if w == 0 and h == 0:
		break
	print(solve(w, h))


def f(h, w):
	global W, H, S, A
	if h < 0 or h >= H or w < 0 or (w >= W) or (S[h][w] == '#') or (A[h][w] == 1):
		return
	A[h][w] = 1
	f(h - 1, w)
	f(h + 1, w)
	f(h, w - 1)
	f(h, w + 1)
while True:
	(W, H) = map(int, input().split())
	if W + H == 0:
		break
	S = [list(input()) for h in range(H)]
	A = [[0 for w in range(W)] for h in range(H)]
	for h in range(H):
		for w in range(W):
			if S[h][w] == '@':
				f(h, w)
				break
	ans = 0
	for i in A:
		ans += sum(i)
	print(ans)


import sys
sys.setrecursionlimit(10000000)
MOD = 10 ** 9 + 7
INF = 10 ** 15
Dy = (-1, 0, 1, 0)
Dx = (0, 1, 0, -1)
from collections import deque, defaultdict, Counter

def solve(H, W):
	grid = [input() for _ in range(H)]
	cnt = [[0] * W for _ in range(H)]
	for i in range(H):
		for j in range(W):
			if grid[i][j] == '@':
				(sy, sx) = (i, j)
				break
	q = deque([(sy, sx)])
	cnt[sy][sx] = 1
	ans = 1
	while q:
		(ny, nx) = q.popleft()
		for (dy, dx) in zip(Dy, Dx):
			y = ny + dy
			x = nx + dx
			if y < 0 or y >= H:
				continue
			if x < 0 or x >= W:
				continue
			if grid[y][x] == '#':
				continue
			if cnt[y][x] == 1:
				continue
			cnt[y][x] = 1
			ans += 1
			q.append((y, x))
	print(ans)

def main():
	while True:
		(W, H) = map(int, input().split())
		if H == 0 and W == 0:
			return
		solve(H, W)
main()


from collections import deque
d = [(1, 0), (-1, 0), (0, 1), (0, -1)]
while 1:
	(w, h) = map(int, input().split())
	if w == h == 0:
		break
	s = [input() for i in range(h)]
	bfs_map = [[1 for i in range(w)] for j in range(h)]
	for y in range(h):
		for x in range(w):
			if s[y][x] == '@':
				ans = 1
				q = deque()
				q.append((y, x))
				bfs_map[y][x] = 0
				while q:
					(y, x) = q.popleft()
					for (dy, dx) in d:
						y_ = y + dy
						x_ = x + dx
						if 0 <= y_ < h and 0 <= x_ < w:
							if bfs_map[y_][x_] and s[y_][x_] == '.':
								ans += 1
								bfs_map[y_][x_] = 0
								q.append((y_, x_))
				print(ans)
				break


from collections import deque
dxy = [(1, 0), (0, 1), (-1, 0), (0, -1)]
while True:
	(W, H) = map(int, input().split())
	if W == 0 and H == 0:
		break
	sx = -1
	sy = -1
	mat = [[None for _ in range(W)] for _ in range(H)]
	for i in range(H):
		s = input()
		for j in range(W):
			if s[j] == '@':
				sx = j
				sy = i
			mat[i][j] = s[j]
	ans = 0
	q = deque()
	q.append((sx, sy))
	while q:
		(cx, cy) = q.popleft()
		ans += 1
		for (dx, dy) in dxy:
			nx = cx + dx
			ny = cy + dy
			if 0 <= nx < W and 0 <= ny < H:
				if mat[ny][nx] == '.':
					mat[ny][nx] = '#'
					q.append((nx, ny))
	print(ans)


def solve(w, h, tile):
	ok = False
	for y in range(h):
		for x in range(w):
			if tile[y][x] == '@':
				s_x = x
				s_y = y
				ok = True
				break
		if ok:
			break
	count = 0
	check = [[s_x, s_y]]
	check_map = [[False for j in range(w)] for i in range(h)]
	while len(check) > 0:
		(x, y) = check.pop(0)
		if x in range(w) and y in range(h):
			if check_map[y][x] == False:
				if tile[y][x] == '.' or tile[y][x] == '@':
					check_map[y][x] = True
					count += 1
					check.append([x, y - 1])
					check.append([x, y + 1])
					check.append([x + 1, y])
					check.append([x - 1, y])
	return count
while True:
	try:
		(w, h) = map(int, input().split())
		if w == 0:
			break
		tile = [''] * h
		for i in range(h):
			tile[i] = input()
		print(solve(w, h, tile))
	except:
		break


move = [[0, 1], [0, -1], [1, 0], [-1, 0]]
from collections import deque

def main(w, h):
	field = [list(input()) for i in range(h)]
	check = [[True] * w for i in range(h)]
	q = deque()
	for i in range(h):
		for k in range(w):
			if field[i][k] == '@':
				q.append((k, i))
				check[i][k] = False
	ans = 1
	while q:
		(x, y) = q.popleft()
		for (mx, my) in move:
			xm = mx + x
			ym = my + y
			if 0 <= xm < w and 0 <= ym < h:
				if field[ym][xm] == '.' and check[ym][xm]:
					check[ym][xm] = False
					q.append((xm, ym))
					ans += 1
	print(ans)
while 1:
	(w, h) = map(int, input().split())
	if w == h == 0:
		break
	main(w, h)


while True:
	(W, H) = [int(n) for n in input().split()]
	if W == H == 0:
		break
	next_target = []
	room = []
	for n in range(H):
		s = list(input())
		room.append(s)
		for y in range(W):
			if s[y] == '@':
				next_target.append((n, y))
	result = 0
	while len(next_target) > 0:
		t = next_target.pop()
		if t[0] - 1 >= 0 and room[t[0] - 1][t[1]] == '.':
			next_target.append((t[0] - 1, t[1]))
			room[t[0] - 1][t[1]] = '@'
		if t[1] + 1 < W and room[t[0]][t[1] + 1] == '.':
			next_target.append((t[0], t[1] + 1))
			room[t[0]][t[1] + 1] = '@'
		if t[0] + 1 < H and room[t[0] + 1][t[1]] == '.':
			next_target.append((t[0] + 1, t[1]))
			room[t[0] + 1][t[1]] = '@'
		if t[1] - 1 >= 0 and room[t[0]][t[1] - 1] == '.':
			next_target.append((t[0], t[1] - 1))
			room[t[0]][t[1] - 1] = '@'
		result += 1
	print(result)


def floodfill(matrix, x, y):
	global count
	if matrix[x][y] == '.' or matrix[x][y] == '@':
		count += 1
		matrix[x][y] = 'check'
		if x > 0:
			floodfill(matrix, x - 1, y)
		if x < len(matrix) - 1:
			floodfill(matrix, x + 1, y)
		if y > 0:
			floodfill(matrix, x, y - 1)
		if y < len(matrix[0]) - 1:
			floodfill(matrix, x, y + 1)
	return count
while True:
	(x, y) = map(int, input().split())
	if x == y == 0:
		break
	room = []
	for i in range(y):
		room.append([i for i in input()])
	for (key, list) in enumerate(room):
		if '@' in list:
			(ax, ay) = (key, list.index('@'))
	count = 0
	print(floodfill(room, ax, ay))


def check(p):
	global ans
	global field
	ans += 1
	if field[p[1]][p[0]] == '.':
		field[p[1]][p[0]] = '#'
	if 0 <= p[0] + 1 < w and field[p[1]][p[0] + 1] == '.':
		check((p[0] + 1, p[1]))
	if 0 <= p[0] - 1 < w and field[p[1]][p[0] - 1] == '.':
		check((p[0] - 1, p[1]))
	if 0 <= p[1] + 1 < h and field[p[1] + 1][p[0]] == '.':
		check((p[0], p[1] + 1))
	if 0 <= p[1] - 1 < h and field[p[1] - 1][p[0]] == '.':
		check((p[0], p[1] - 1))
while 1:
	ans = 0
	(w, h) = map(int, input().split())
	if w == 0:
		break
	field = []
	for i in range(h):
		s = input()
		t = s.find('@')
		if t != -1:
			st = (t, i)
		field.append(list(s))
	check(st)
	print(ans)


from collections import deque
move = ((0, 1), (1, 0), (0, -1), (-1, 0))

def inmap(x, y):
	if 0 <= x <= Lx - 1 and 0 <= y <= Ly - 1:
		return True
	return False
while True:
	(Lx, Ly) = map(int, input().split())
	if Lx == 0:
		break
	curx = -1
	cury = -1
	orimap = [[] for _ in range(Ly)]
	for i in range(Ly):
		for j in input():
			orimap[i].append(j)
	for y in range(len(orimap)):
		for x in range(len(orimap[y])):
			if orimap[y][x] == '@':
				(curx, cury) = (x, y)
				orimap[y][x] = '#'
				break
		if curx != -1:
			break
	Q = deque()
	Q.append([curx, cury])
	count = 1
	while len(Q) > 0:
		(curx, cury) = Q.popleft()
		for (dx, dy) in move:
			nextx = curx + dx
			nexty = cury + dy
			if inmap(nextx, nexty):
				if orimap[nexty][nextx] != '#':
					orimap[nexty][nextx] = '#'
					Q.append([nextx, nexty])
					count += 1
	print(count)


mx = [0, 1, 0, -1]
my = [-1, 0, 1, 0]
while True:
	(w, h) = map(int, input().split())
	if w == h == 0:
		break
	tiles = [[i for i in input()] for j in range(h)]
	ax = ay = 0
	for i in range(h):
		for j in range(w):
			if tiles[i][j] == '@':
				(ax, ay) = (j, i)
	que = [(ax, ay)]
	tiles[ay][ax] = '#'
	cnt = 1
	while 0 < len(que):
		new_que = []
		for (x, y) in que:
			for i in range(4):
				(nx, ny) = (x + mx[i], y + my[i])
				if 0 <= nx <= w - 1 and 0 <= ny <= h - 1:
					if tiles[ny][nx] == '.':
						cnt += 1
						new_que.append((nx, ny))
						tiles[ny][nx] = '#'
		que = new_que
	print(cnt)


while 1:
	(w, h) = list(map(int, input().strip().split()))
	if w == h == 0:
		break
	data = []
	data = []
	for _ in range(h):
		data.append(list(input()))
	visited = []
	position = (0, 0)
	for i in range(h):
		if '@' in data[i]:
			position = (i, data[i].index('@'))
	stack = []
	count = 0
	stack.append(position)
	while len(stack) != 0:
		position = stack.pop()
		count += 1
		if position[0] - 1 >= 0 and (not (position[0] - 1, position[1]) in visited) and (data[position[0] - 1][position[1]] == '.'):
			visited.append((position[0] - 1, position[1]))
			stack.append((position[0] - 1, position[1]))
		if position[1] - 1 >= 0 and (not (position[0], position[1] - 1) in visited) and (data[position[0]][position[1] - 1] == '.'):
			visited.append((position[0], position[1] - 1))
			stack.append((position[0], position[1] - 1))
		if position[0] + 1 < h and (not (position[0] + 1, position[1]) in visited) and (data[position[0] + 1][position[1]] == '.'):
			visited.append((position[0] + 1, position[1]))
			stack.append((position[0] + 1, position[1]))
		if position[1] + 1 < w and (not (position[0], position[1] + 1) in visited) and (data[position[0]][position[1] + 1] == '.'):
			visited.append((position[0], position[1] + 1))
			stack.append((position[0], position[1] + 1))
	print(count)


import sys
from collections import deque

def solve():
	while 1:
		(w, h) = map(int, sys.stdin.readline().split())
		if w == h == 0:
			return
		room = [[False] * w for i in range(h)]
		si = sj = -1
		for i in range(h):
			line = input()
			for (j, ch) in enumerate(line):
				if ch == '@':
					room[i][j] = True
					si = i
					sj = j
				elif ch == '.':
					room[i][j] = True
		ans = bfs(w, h, room, si, sj)
		print(ans)
dx = (1, 0, -1, 0)
dy = (0, 1, 0, -1)

def bfs(w, h, room, si, sj):
	visited = [[False] * w for i in range(h)]
	visited[si][sj] = True
	q = deque([(si, sj)])
	cnt = 1
	while q:
		(ci, cj) = q.popleft()
		for k in range(len(dx)):
			ni = ci + dy[k]
			nj = cj + dx[k]
			if 0 <= ni < h and 0 <= nj < w and room[ni][nj] and (not visited[ni][nj]):
				visited[ni][nj] = True
				q.append((ni, nj))
				cnt += 1
	return cnt
solve()


def search(a, b, dx, dy, t, check, li, answer):
	for i in range(len(dx)):
		temp = [t[0] + dx[i], t[1] + dy[i]]
		if mapCheck(a, b, temp):
			if check[temp[1]][temp[0]] == 0:
				if li[temp[1]][temp[0]] == '.':
					answer += 1
					check[temp[1]][temp[0]] = 1
					answer = search(a, b, dx, dy, temp, check, li, answer)
	return answer

def mapCheck(a, b, t):
	if t[0] <= a - 1 and t[0] >= 0:
		if t[1] <= b - 1 and t[1] >= 0:
			return True
	return False
while True:
	li = []
	answer = 1
	start = [0, 0]
	(a, b) = map(int, input().strip().split(' '))
	dx = [1, 0, -1, 0]
	dy = [0, 1, 0, -1]
	if a == 0 and b == 0:
		break
	for i in range(b):
		li.append(input().strip().split())
	check = [[0 for i in range(a)] for j in range(b)]
	for i in range(len(li)):
		li[i] = str(li[i])
		li[i] = list(li[i])
		del li[i][0]
		del li[i][0]
		del li[i][len(li[i]) - 1]
		del li[i][len(li[i]) - 1]
		for j in range(len(li[i])):
			if li[i][j] == '@':
				start = [j, i]
	print(search(a, b, dx, dy, start, check, li, answer))


from collections import defaultdict

def explore(now, cnt):
	if cnt > W * H:
		a = 0
	else:
		d[now] = 1
		if now[1] + 1 < W:
			if not data[now[0]][now[1] + 1] == '#':
				if not (now[0], now[1] + 1) in d.keys():
					explore((now[0], now[1] + 1), cnt + 1)
		if now[0] + 1 < H:
			if not data[now[0] + 1][now[1]] == '#':
				if not (now[0] + 1, now[1]) in d.keys():
					explore((now[0] + 1, now[1]), cnt + 1)
		if now[0] - 1 >= 0:
			if not data[now[0] - 1][now[1]] == '#':
				if not (now[0] - 1, now[1]) in d.keys():
					explore((now[0] - 1, now[1]), cnt + 1)
		if now[1] - 1 >= 0:
			if not data[now[0]][now[1] - 1] == '#':
				if not (now[0], now[1] - 1) in d.keys():
					explore((now[0], now[1] - 1), cnt + 1)
while True:
	(W, H) = map(int, input().split())
	if W == 0 and H == 0:
		break
	data = [list(input()) for _ in range(H)]
	d = defaultdict()
	for i in range(H):
		for j in range(W):
			if data[i][j] == '@':
				start = (i, j)
				break
	now = start
	cnt = 0
	explore(now, cnt)
	print(len(d.keys()))


def dfs(tiles, w, h, x, y):
	cnt = 1
	tiles[y][x] = '@'
	for (dx, dy) in ((0, 1), (0, -1), (-1, 0), (1, 0)):
		if 0 <= x + dx < w and 0 <= y + dy < h and (tiles[y + dy][x + dx] == '.'):
			cnt += dfs(tiles, w, h, x + dx, y + dy)
	return cnt

def main():
	while True:
		(W, H) = [int(x) for x in input().split()]
		if W == 0 and H == 0:
			exit()
		tiles = [[c for c in input()] for h in range(H)]
		for i in range(H):
			if '@' in tiles[i]:
				Y = i
				X = tiles[i].index('@')
		answer = dfs(tiles, W, H, X, Y)
		print(answer)
main()