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 <queue>
#include <utility>
#include <algorithm>
using namespace std;

int w, h;
char tiles[20][21];

int dx[4] = { 0, 1, 0,-1};
int dy[4] = { 1, 0,-1, 0};

bool isRegion(int x, int y){
    return x >= 0 && x < w && y >= 0 && y < h;
}

int main(){
    while(1){
        cin >> w >> h;
        if(!w && !h) break;
        
        int sx, sy;
        for(int i = 0; i < h; i++){
            cin >> tiles[i];
            
            auto j = find(tiles[i], tiles[i]+w, '@');
            if(j != tiles[i] + w){
                sx = j - tiles[i]; sy = i;
            }
        }
        
        int cnt = 0;
        queue<pair<int, int> > q;
        q.push(make_pair(sx, sy));
        while(!q.empty()){
            cnt++;
            int x = q.front().first, y = q.front().second;
            q.pop();
            
            for(int i = 0; i < 4; i++){
                int nx = x + dx[i], ny = y + dy[i];
                
                if(isRegion(nx, ny) && tiles[ny][nx] == '.'){
                    tiles[ny][nx] = '#';
                    q.push(make_pair(nx, ny));
                }
            }
        }
        cout << cnt << endl;
        
    }
}

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

int dx[]={-1,0,1,0};
int dy[]={0,-1,0,1};

char f[50][50];
bool v[50][50];

int M,N;

int dfs(int x, int y)
{
	int ret=1;
	v[x][y]=1;

	for(int i=0; i<4; i++)
	{
		int tx=x+dx[i], ty=y+dy[i];
		if(tx<0||tx>=M||ty<0||ty>=N) continue;
		if(f[tx][ty]=='#') continue;
		if(v[tx][ty]) continue;

		ret+=dfs(tx,ty);
	}

	return ret;
}

int main()
{
	while(cin >> M >> N, (M||N))
	{
		int sx,sy;
		memset(v,0,sizeof(v));
		for(int i=0; i<N; i++)
		for(int j=0; j<M; j++)
		{
			cin >> f[j][i];
			if(f[j][i]=='@')
			{
				sx=j;
				sy=i;
			}
		}

		cout << dfs(sx,sy) << endl;
	}
}

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

const int dx[] = {1,0,-1,0};
const int dy[] = {0,-1,0,1};

int a,b,ans;
int q[20+5][20+5];
char p[20+5][20+5];

using namespace std;
int main() {
	queue<pair<int,int> > M;
	pair<int,int> X;
	cin >> a >> b;
	for (int i=1; i<=b; i++){
		for (int j=1; j<=a; j++){
			cin >> p[i][j];
			if (p[i][j] == '@'){
				M.push(make_pair(i,j));
				ans = 1;
				q[i][j] = 1;
			}
		}
	}
	

	while(!M.empty()){
		a = M.front().first;
		b = M.front().second;
		M.pop();
		for (int i=0; i<=3; i++){		
			if (p[a+dx[i]][b+dy[i]]=='.' && q[a+dx[i]][b+dy[i]]==0){
				M.push(make_pair(a+dx[i],b+dy[i]));
				q[a+dx[i]][b+dy[i]] = 1;
				ans+=1;
			}
		}
	}
	cout << ans << endl;
	
}

C++: #include <iostream>

using namespace std;

struct D
{
  bool movable[20][20];
};

int const dir[][2] = {
  {  1, 0 },
  { -1, 0 },
  { 0,  1 },
  { 0, -1 }
};

void count( D& d, int& num, int const px, int const py )
{
  if ( !d.movable[px][py] )
    return;

  ++num;
  d.movable[px][py] = false;

  for( int i=0; i<4; ++i ) {
    int const npx = px + dir[i][0];
    int const npy = py + dir[i][1];
    if ( npx < 0 || npy < 0 || npx >= 20 || npy >= 20 )
      continue;
    count( d, num, npx, npy );
  }
}

int main()
{
  int w, h;
  while( cin >> w >> h ) {
    if ( w == 0 && h == 0 )
      break;

    D d = {};
    int px, py;
    for( int y=0; y<h; ++y ) {
      for( int x=0; x<w; ++x ) {
        char c;
        cin >> c;
        if ( c == '@' ) {
          px = x;
          py = y;
        }

        d.movable[x][y] = ( c != '#' );
      }
    }

    int num = 0;
    count( d, num, px, py );
    cout << num << endl;
  }
}

C++: #include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <stack>
#include <numeric>
#include <algorithm>
#include <bitset>
#include <complex>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef long long int llint;
#define MM 1000000000
#define MOD MM+7
#define pi pair<int,int>
#define pl pair<ll,ll>
#define chmax(a,b) (a<b ? a=b:0)
#define chmin(a,b) (a>b ? a=b:0)
const long double PI = acos(-1);
const long long INF = 1e15;
int dx[8] = {-1,0,1,0,-1,-1,1,1};
int dy[8] = {0,-1,0,1,-1,1,1,-1};
template<typename T>
T GCD(T u,T v){
    return v ? GCD(v,u%v) : u;
}
char s[22][22];
bool visited[22][22];
void init(int H, int W){
    for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
            s[i][j] = 'a';
            visited[i][j] = false;
        }
    }
}
void bfs(int sh, int sw, int h, int w){
    queue<pair<int,int> > que;
    que.push(make_pair(sh,sw));
    while(que.size()){
        pair<int,int> F = que.front();
        visited[F.first][F.second] = true;
        que.pop();
        for(int i = 0; i < 4; i++){
            int ny = F.first + dy[i];
            int nx = F.second + dx[i];
            if (s[ny][nx] == '#') continue;
            if (visited[ny][nx] == false && 0 <= nx && 0 <= ny && nx < w && ny < h && (s[ny][nx] == '.' || s[ny][nx] == '@')){
                que.push(make_pair(ny,nx));
                visited[ny][nx] = true;
            }
        }
    }
}
int check(int h, int w){
    int cnt = 0;
    for(int i = 0; i < h; i++){
        for(int j = 0; j < w; j++){
            if (visited[i][j] == true && (s[i][j] == '.' || s[i][j] == '@')){
                cnt++;
            }
        }
    }
    return cnt;
}
void display(int h, int w){
    for(int i = 0; i < h; i++){
        for(int j = 0; j < w; j++){
            cout << visited[i][j] << " ";
        }
        cout << endl;
    }
}


int main(){
    vector<int> v(0);
    while(true){
        int h,w; cin >> w >> h;
        if (h == 0 && w == 0) break;
        init(h,w);
        pair<int,int> start;
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                cin >> s[i][j];
                if (s[i][j] == '@'){
                    start.first = i;
                    start.second = j;
                }
            }
        }
        bfs(start.first, start.second, h, w);
        v.push_back(check(h, w));
        //display(h,w);
    }
    for(int i = 0; i < v.size(); i++){
        cout << v[i] << endl;
    }
}