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 <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <functional>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <deque>
#include <ctime>

using namespace std;
  
#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define pb push_back
#define mp make_pair
#define all(r) (r).begin(),(r).end()
#define rall(r) (r).rbegin(),(r).rend()
#define fi first
#define se second

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 
const int INF = 1e9;
const ll LINF = 1e18;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;
const double PI = acos(-1);

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

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

int main(){
	int w, h;
	while(cin>>w>>h && w > 0 && h > 0){
		vector<string> v(h);
		rep(i, h) cin>>v[i];
		pii s;
		rep(i, h) rep(j, w) if(v[i][j] == '@') s.fi = i, s.se = j;
		int ans = 0;
		set<pii> used;
		used.insert(s);
		ans++;
		queue<pii> q;
		q.push(s);
		while(!q.empty()){
			pii p = q.front();
			q.pop();

			int x = p.se, y = p.fi;
			rep(i, 4){
				int nx = x + dx[i], ny = y + dy[i];
				if(check(nx, ny, h, w) || used.count({ny, nx}) || v[ny][nx] == '#') continue;
				used.insert({ny, nx});
				q.push({ny, nx});
				ans++;
			}
		}

		cout<<ans<<endl;

	}
}

C++: #include<iostream>
#include<queue>
using namespace std;
int main(){
	int w, h; 
	while (cin >> w >> h) {
		if (!w && !h)return 0;
		char map[21][21];
		bool b[21][21];
		queue<pair<int, int>>bfs;
		for (int i = 0; i < h; i++)for (int j = 0; j < w; j++) {
			cin >> map[i][j];
			b[i][j] = false;
			if (map[i][j] == '@') {
				bfs.push(make_pair(i, j));
				b[i][j] = true;
			}
		}
		int ans = 1;
		while (bfs.size() > 0) {
			pair<int, int>p = bfs.front();
			int x = p.first;
			int y = p.second;
			map[x][y] = '#';
			if (x > 0){
				if (map[x - 1][y] == '.' && !b[x - 1][y]) {
					bfs.push(make_pair(x - 1, y));
					ans++;
					b[x - 1][y] = true;
				}
			}
			if (x < h) {
				if (map[x + 1][y] == '.' && !b[x + 1][y]) {
					bfs.push(make_pair(x + 1, y));
					ans++;
					b[x + 1][y] = true;
				}
			}
			if (y > 0) {
				if (map[x][y - 1] == '.'&& !b[x][y - 1]) {
					bfs.push(make_pair(x, y - 1));
					ans++;
					b[x][y - 1] = true;
				}
			}
			if (y < w) {
				if (map[x][y + 1] == '.' && !b[x][y + 1]) {
					bfs.push(make_pair(x, y + 1));
					ans++;
					b[x][y + 1] = true;
				}
			}
			bfs.pop();
		}
		cout << ans << endl;
	}
}

C++: #include <cstdio>
#include <iostream>
#include <queue>
#include <set>
#include <cstring>
using namespace std;
typedef pair<int,int> pos;
char map[20][20];
const int next[4][2] = {
  {-1,0},{1,0},{0,-1},{0,1},
};
int main()
{
  for(;;){
    int w,h;
    scanf("%d %d",&w,&h);
    if(w == 0 || h == 0) break;
    string dummy;
    getline(cin,dummy);
    memset(map,'.',sizeof(map));
    pos p;
    for(int i=0; i<h; i++){
      string s;
      getline(cin,s);
      for(int j=0; j<w; j++){
        if(s[j] == '@'){
          p = make_pair(i,j);
        }
        map[i][j] = s[j];
      }
    }
    set<pos> memo;
    memo.insert(p);
    queue<pos> q;
    q.push(p);
    for(;;){
      if(q.empty()) break;
      p = q.front(); q.pop();
      for(int i=0; i<4; i++){
        pos pn = make_pair(p.first+next[i][0], p.second+next[i][1]);
        if(pn.first < 0 || pn.first >= h || pn.second < 0 || pn.second >= w ||
           map[pn.first][pn.second] == '#'){
          continue;
        }
        if(memo.insert(pn).second){
          q.push(pn);
        }
      }
    }
    printf("%d\n", memo.size());
  }
  return 0;
}

C++: #include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <complex>
#include <functional>
#include <utility>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

using namespace std;

#define dump(n) cout<<"# "<<#n<<"="<<(n)<<endl
#define debug(n) cout<<__FILE__<<","<<__LINE__<<": #"<<#n<<"="<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,n) repi(i,0,n)
#define iter(c) __typeof((c).begin())
#define tr(c,i) for(iter(c) i=(c).begin();i!=(c).end();i++)
#define allof(c) (c).begin(),(c).end()
#define mp make_pair

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;

int search(int i,int j,vector<string>& field)
{
    int r=field.size(),c=field[0].size();
    if(i<0 || r<=i || j<0 || c<=j)
        return 0;
    if(field[i][j]=='#')
        return 0;
    field[i][j]='#';
    int di[]={-1,1,0,0};
    int dj[]={0,0,-1,1};
    int sum=1;
    rep(k,4)
        sum+=search(i+di[k],j+dj[k],field);
    return sum;
}

int main()
{
	for(int c,r;cin>>c>>r,c|r;){
        vector<string> field(r);
        rep(i,r)
            cin>>field[i];
        rep(i,r)
            rep(j,c)
                if(field[i][j]=='@')
                    cout<<search(i,j,field)<<endl;
    }
}