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++: #if 0
????????£?????????????´?1?????????
?°?????????¨?????£??????????????????????????§?????????
???????????????????????°????????????????±?legal??¢??°?????????????????¨?????????????????????
x<h???y<w???????????????????????????
#endif

#include <iostream>
#include <queue>
using namespace std;
int w,h;
int g[21][21];
bool visited[21][21];
int moves[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int count;
bool legal(int x, int y)
{
  if(visited[x][y]!=true&&0<=x&&x<h&&0<=y&&y<w&&g[x][y]==0)
    return true;
  else
    return false;
}

void dfs(int x,int y)
{
  visited[x][y]=true;
  count++;
  for(int i=0;i<4;i++)
  {
    int newx=x+moves[i][0];
    int newy=y+moves[i][1];
    if(legal(newx,newy))
    {
      dfs(newx,newy);
    }
  }
}

int main()
{
  while(1)
  {
    cin>>w>>h;
    if(w==0&&h==0) break;
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
      {
        g[i][j]=-1;
        visited[i][j]=false;
      }
    int psx,psy;
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
      {
        char s;
        cin>>s;
        switch(s)
        {
          case '.':
            g[i][j]=0;break;
          case '#':
            g[i][j]=1;break;
          case '@':
            g[i][j]=2;psx=i;psy=j;break;
        }
      }
    count=0;
    dfs(psx,psy);
/*    int count=0;
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
      {
        count+=visited[i][j];
      }
*/  cout<<count<<endl;

  }
}

C++: #define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//bool c[22][22] = {};
int cnt,w, h, p[22][22] = {};

int main() {
	int j, f,cx,cy;
	char in[21];
	while (1) {
		for (int i = 0; i < 484; i++) {
			p[i / 22][i % 22] = 0;
		}
		cnt = 0;
		f = 1;
		scanf("%d %d", &w, &h);
		if (w ==0&& h == 0)
			break;
		scanf("\n", &j);
		for (int i = 0; i < h; i++) {
			scanf("%s", &in);
			for (j = 0; j < w; j++) {
				switch (in[j]) {
				case '#':
//					c[j+1][i+1] = 0;
					p[j+1][i+1] = -1;
					break;
				case '@':
					cx = j;
					cy = i;
					p[j+1][i+1] = 1;
//				case '.':
//					c[j+1][i+1] = 1;
				}
			}
		}

		/*for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++)
				printf("%3d", c[j][i]);
			printf("\n");
		}*/

		while (f == 1) {
			f = 0;
		/*	for (int i = 0; i < h; i++) {
				for (int j = 0; j < w; j++)
					printf("%3d", p[j+1][i+1]);
				printf("\n");
			}
			printf("\n");
*/			//if (w != 1 && h != 1) {
				for (int i = 0; i < w*h; i++) {
					if (p[i / h+1][i%h+1] == 0 && (p[i / h + 2][i % h+1] == 1 || p[i / h][i % h+1] == 1 || p[i / h+1][i % h + 2] == 1 || p[i / h+1][i % h] == 1)) {
						p[i / h+1][i%h+1] = 1;
						f = 1;
					}
				}
			//}
			/*if (w == 1 && h != 1) {
				for (int i = 0; i < h; i++) {
					if (p[1][i+1] == 0 && (p[1][i + 2] == 1 || p[0][i] == 1)) {
						p[1][i+1] = 1;
						f = 1;
						printf("a");
					}
				}
			}

			if (w != 1 && h == 1) {
				for (int i = 0; i < w; i++) {
					if (p[i+1][1] == 0 && (p[i + 2][1] == 1 || p[i][1] == 1)) {
						p[i+1][1] = 1;
						f = 1;
					}
				}
			}*/
		}

		for (int i = 0; i < w*h; i++) {
			if (p[i / h+1][i%h+1] == 1)
				cnt++;
		}
		printf("%d\n", cnt);
	}
	return 0;
}

C++: #include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <utility>
#include <iomanip>

#define ll long long int
#define pb push_back
#define mk make_pair
#define pq priority_queue

using namespace std;
typedef pair<int, int> P;
typedef pair<ll, int> Pl;
const int inf = 1e9;
const ll linf = 1LL << 50;

int h, w;
int sx, sy;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
bool used[21][21];
int color[21][21];

void dfs(int x, int y){
		for(int i = 0; i < 4; i++){
				int nx = x + dx[i];
				int ny = y + dy[i];
				if(nx >= 0 && nx < h && ny >= 0 && ny < w && !used[nx][ny] && color[nx][ny] == 1){
						used[nx][ny] = true;
						dfs(nx, ny);
				}
		}
}

int main(int argc, char const* argv[])
{
	while(true){
			cin >> w >> h;
			if(w == 0)break;
			for(int i = 0; i < h; i++){
					string s;
					cin >> s;
					for(int j = 0; j < w; j++){
							if(s[j] == '.' || s[j] == '@')color[i][j] = 1;
							else color[i][j] = -1;
							if(s[j] == '@'){
									sx = i; sy = j;
							}
							used[i][j] = false;
					}
			}
			dfs(sx, sy);
			int res = 0;
			used[sx][sy] = true;
			for(int i = 0; i < h; i++){
					for(int j = 0; j < w; j++){
							if(used[i][j] == 1)res++;
					}
			}
			cout << res << endl;
	}
	return 0;
}

C++: #include<iostream>
#include<vector>
#include<queue>

using namespace std;

int ans = 0;
void dfs(vector<string> v, int x,int y,vector< vector<int> > &vv){
	int dx[4] = {-1, 1, 0, 0};
	int dy[4] = { 0, 0,-1, 1};
	if (vv[y][x] == 1) return ;
	if (v[y][x] == '#') return ;	
	vv[y][x] = 1;
	ans++;
	for (int i = 0; i < 4; i++){
		if (0 <= x + dx[i] and x + dx[i] < v[0].size() and 0 <= y + dy[i] and y + dy[i] < v.size()){
			dfs(v,x + dx[i],y + dy[i],vv);
		}
	}
	return ;
}
int main(){
	while(1){
		int w,h; cin >> w >> h;
		ans = 0;
		if (w + h == 0) break;
		vector<string> tile(h);
		vector< vector<int> > check(h, vector<int>(w,0));
		int at_x;
		int at_y;
		for (int i = 0; i < h; i++){
			cin >> tile[i];
			for (int j = 0; j < w; j++){
				if (tile[i][j] == '@'){
					at_x = j;
					at_y = i;
				}
			}
		}
		dfs(tile,at_x,at_y,check);
		cout << ans << endl;
	}
return 0;
}