Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var (
	sc = bufio.NewScanner(os.Stdin)
)

type Color int

const (
	ColorBlack Color = iota
	ColorRed
)

type Node struct {
	ID    int
	X, Y  int
	Color Color
	Nexts []*Node
}

func main() {
	for sc.Scan() {
		if sc.Text() == "0 0" {
			break
		}
		chunks := strings.Split(sc.Text(), " ")
		w, _ := strconv.Atoi(chunks[0])
		h, _ := strconv.Atoi(chunks[1])

		// Initialize map
		m := map[int]map[int]*Node{}
		for x := 1; x <= w; x++ {
			m[x] = map[int]*Node{}
			for y := 1; y <= h; y++ {
				m[x][y] = &Node{ID: x + y*w, X: x, Y: y}
			}
		}
		for x := 1; x <= w; x++ {
			for y := 1; y <= h; y++ {
				nexts := []*Node{}
				if n, ok := m[x-1][y]; ok {
					nexts = append(nexts, n)
				}
				if n, ok := m[x][y-1]; ok {
					nexts = append(nexts, n)
				}
				if n, ok := m[x+1][y]; ok {
					nexts = append(nexts, n)
				}
				if n, ok := m[x][y+1]; ok {
					nexts = append(nexts, n)
				}
				m[x][y].Nexts = nexts
			}
		}

		// Set colors
		queue := []*Node{}
		touchedIDs := map[int]struct{}{}
		for y := 1; y <= h; y++ {
			sc.Scan()
			for i, c := range sc.Text() {
				switch c {
				case '.', '@':
					n := m[i+1][y]
					n.Color = ColorBlack
					if c == '@' {
						queue = append(queue, n)
						touchedIDs[n.ID] = struct{}{}
					}
				case '#':
					m[i+1][y].Color = ColorRed
				}
			}
		}

		// Search
		visitedIDs := map[int]struct{}{}
		for {
			if len(queue) == 0 {
				break
			}
			n := queue[0]
			queue = queue[1:]
			visitedIDs[n.ID] = struct{}{}
			for _, next := range n.Nexts {
				if next.Color == ColorRed {
					continue
				}
				if _, ok := touchedIDs[next.ID]; !ok {
					queue = append(queue, next)
					touchedIDs[n.ID] = struct{}{}
				}
			}
		}
		fmt.Println(len(visitedIDs))
	}
}

C++: #include <iostream>
#include <cstring>
#include <string>

using namespace std;

const int MAX_H = 20;
const int MAX_W = 20;

// 入力
int W, H;
char field[MAX_H][MAX_W+1]; // ヌル文字を考慮
int startx, starty;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};

void dfs(int x, int y) {
	field[y][x] = '$';
	for (int i = 0; i < 4; i++) {
		int newX = x + dx[i];
		int newY = y + dy[i];
		if (field[newY][newX] == '.') {
			dfs(newX, newY);
		}
	}
}

int main() {
	while (true) {
		cin >> W >> H;
		if (W == 0) {
			break;
		}
		
		memset(field, 0, sizeof(field));
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				cin >> field[i][j];
				if (field[i][j] == '@') {
					startx = j;
					starty = i;
				}
			}
		}
		
		dfs(startx, starty);
		
		int ans = 0;
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				if (field[i][j] == '$') {
					ans++;
				}
			}
		}
		cout << ans << endl;
	}
	
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <map>
#include <stack>
#include <list>
#include <queue>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <math.h>

#define PREP(i, m, n) for(int i = m; i < n; i++)
#define MREP(i, m, n) for(int i = m - 1; i >= n; i--)
using namespace std;

const int dirX[] = {-1, 0, 1, 0};
const int dirY[] = {0, -1, 0, 1};

struct point{
	int x;
	int y;
	point(int x = 0, int y = 0):x(x), y(y){}
};

int wideSearch(point start, vector<string> &map){
	int count = 1;
	queue<point> usablepos;
	usablepos.push(start);
	while(1){
		if(usablepos.size() == 0) break;
		point current = usablepos.front();
		usablepos.pop();
		for(int i = 0; i < 4; i++){
			if((current.y + dirY[i] >= 0 && current.y + dirY[i] < map.size()) && (current.x + dirX[i] >= 0 && current.x + dirX[i] < map[0].size())){
				if(map[current.y + dirY[i]][current.x + dirX[i]] == '.'){
					map[current.y + dirY[i]][current.x + dirX[i]] = '#';
					point tmp(current.x + dirX[i], current.y + dirY[i]);
					count++;
					usablepos.push(tmp);
				}
			}
		}
	}
	return count;
}

int main(){
	int w = 0, h = 0;
	while(cin >> w >> h && (w != 0 || h != 0)){
		vector<string> map;
		point start;
		string input;
		for(int i = 0; i < h; i++){
			cin >> input;
			map.push_back(input);
			for(int j = 0; j < w; j++){
				if(map[i][j] == '@'){
					start.x = j;
					start.y = i;
				}
			}
		}
		cout << wideSearch(start, map) << endl;
	}
	return 0;
}

C++: #include<iostream>
#include<vector>
using namespace std;
const int MAX = 20;
char map[MAX][MAX];
bool book[MAX][MAX];
struct Point
{
	int x;
	int y;
	Point(int x = 0, int y = 0) :x(x), y(y) {}
}start;
int sum = 0;
void depthFSearch(int H, int W, Point start)
{
	int next[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
	for (int k = 0; k <= 3; k++)
	{
		int nx = start.x + next[k][0];
		int ny = start.y + next[k][1];
		if (nx < 0 || nx >= H || ny < 0 || ny >= W)
			continue;
		if (!book[nx][ny] && map[nx][ny] == '.')
		{
			book[nx][ny] = true;
			Point p(nx, ny);
			sum++;
			depthFSearch(H, W, p);
		}
	}
	return;
}
int main()
{
	while (true)
	{
		int H, W;
		cin >> H >> W;
		if (!H && !W)
			break;
		for (int i = 0; i < H; i++)
			for (int j = 0; j < W; j++)
			{
				cin >> map[i][j];
				if (map[i][j] == '@')
					start = Point(i, j);
			}
		book[start.x][start.y] = true;
		sum = 1;
		depthFSearch(H, W, start);
		cout << sum << endl;
	}
}

C++: #include <stdio.h>

int cnt;

void dp(char fld[20][20], int y, int x)	{
	
	fld[y][x] = '#';
	cnt++;
	///
	//printf("%d %d\n", x, y);
	///
	
	for (int dy = -1; dy <= 1; dy++)	{
		for (int dx = -1; dx <= 1; dx++)	{
			if (dy != 0 && dx != 0)	continue;
			if (y + dy < 0 || y + dy >= 20 || x + dx < 0 || x + dx >= 20)	continue;
			
			if (fld[y+dy][x+dx] == '.')	{
				dp(fld, y+dy, x+dx);
			}
		}
	}	
}

int main()	{
	
	int w, h, cy, cx;
	char temp;
	char fld[20][20];
	
	while (true)	{
		
		scanf("%d %d%*c", &w, &h);
		if (w == 0)	break;
		
		// initialize
		for (int y = 0; y < 20; y++)	{
			for (int x = 0; x < 20; x++)	{
				fld[y][x] = '#';
			}
		}
		
		for (int i = 0; i < h; i++)	{
			///
			//printf("%d列目\n", i);
			///
			for (int j = 0; j < w; j++)	{
				scanf("%c", &temp);
				fld[i][j] = temp;
				
				if (temp == '@')	{
					cy = i;
					cx = j;
				}
			}
			scanf("%*c");
		}
		
		/*
		for (int y = 0; y < 20; y++)	{
			printf("%2d: ", y);
			for (int x = 0; x < 20; x++)	{
				printf("%c", fld[y][x]);
			}
			printf("\n");
		}
		*/
		
		cnt = 0;
		
		dp(fld, cy, cx);
		
		printf("%d\n", cnt);
	}
	
	return 0;
}

C++: #include <iostream>
#include <queue>
using namespace std;

static const int WHITE = 0;
static const int ABLE  = 1;
static const int N = 20;

char a[N][N];
int judge[N][N];

void search(int x, int y, int w, int h) {
	queue<int> qx, qy;
	qx.push(x);
	qy.push(y);
	judge[y][x] = ABLE;
	
	int tx, ty;
	while (!qx.empty() && !qy.empty()) {
		tx = qx.front();
		qx.pop();
		ty = qy.front();
		qy.pop();
		
		if (ty + 1 < h && a[ty+1][tx] != '#' && judge[ty+1][tx] == WHITE) {
			judge[ty+1][tx] = ABLE;
			qx.push(tx);
			qy.push(ty+1);
		}
		if (ty - 1 >= 0 && a[ty-1][tx] != '#' && judge[ty-1][tx] == WHITE) {
			judge[ty-1][tx] = ABLE;
			qx.push(tx);
			qy.push(ty-1);
		}
		if (tx + 1 < w && a[ty][tx+1] != '#' && judge[ty][tx+1] == WHITE) {
			judge[ty][tx+1] = ABLE;
			qx.push(tx+1);
			qy.push(ty);
		}
		if (tx - 1 >= 0 && a[ty][tx-1] != '#' && judge[ty][tx-1] == WHITE) {
			judge[ty][tx-1] = ABLE;
			qx.push(tx-1);
			qy.push(ty);
		}
	}
}

int main() {
	while (1) {
		int w, h;
		cin >> w >> h;
		if (h == 0) break;
		
		int startx, starty;
		for (int i = 0; i < h; i++)
			for (int j = 0; j < w; j++)
				cin >> a[i][j];
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				if (a[i][j] == '.' || a[i][j] == '#') judge[i][j] = WHITE;
				else {
					startx = j;
					starty = i;
					judge[i][j] = WHITE;
				}
			}
		}
		
		search(startx, starty, w, h);
		
		int count = 0;
		for (int i = 0; i < h; i++)
			for (int j = 0; j < w; j++)
				if (judge[i][j] == ABLE) count++;
			
		cout << count << endl;
	}
	return 0;
}