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 "bits/stdc++.h"

using namespace std;

#define rep(a,b) for(int (a)=0;(a)<(b);(a)++)

int main(){
    int w,h;
    while(cin>>w>>h){
    if(w==0 && h==0)break;
    int sx,sy;
    int sum=0;
    int dy[]={-1,0,1,0};
    int dx[]={0,-1,0,1};
    
    
    string data[30]={};
    
    for(int i=0;i<h;i++){
        cin>>data[i];
    }
    
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            if(data[i][j]=='@'){
                sx=j;sy=i;
                break;
            }
        }
    }
    
    bool visited[30][30]={};
    
    queue<pair<int,int> > que;
    
    que.push( pair<int,int>(sy,sx) );
    visited[sy][sx]=true;
    
    while(que.size()){
        int qff=que.front().first,qfs=que.front().second;
        sum++;
        rep(i,4){
            if( qff+dy[i]<h && qff+dy[i]>=0 && qfs+dx[i]<w && qfs>=0 && visited[ qff+dy[i] ][ qfs+dx[i] ]==false && data[ qff+dy[i] ][ qfs+dx[i] ]=='.' ){
                que.push( pair<int,int>(qff+dy[i] , qfs+dx[i]) );
                visited[ qff+dy[i] ][ qfs+dx[i] ]=true;
            }
        }
            
        que.pop();
    }
    
    cout<<sum<<endl;
    }
    
    return 0;
}

C++: #include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <algorithm>
#include <utility>
#include <cstdio>
#include <cstring>

using namespace std;

#define REP(var, count) for(int var=0; var<count; var++)

int main(void) {
	while(true) {
		int W, H;
		scanf("%d %d", &W, &H);
		if ( W==0 ) { break; }
		
		char line[26][26];
		
		queue<pair<int, int> > que;
		
		strcpy(line[0], "#######################");
		strcpy(line[H+1], "#######################");
		
		for(int y=1; y<=H; y++) {
			line[y][0] = '#';
			scanf("%s", &line[y][1]);
			
			if ( char* p = strchr(line[y], '@') ) {
				que.push(make_pair(y, p - line[y]));
			}
		}
		
		int ret = 1;
		
		while(que.size()) {
			
			int y = que.front().first;
			int x = que.front().second;
			que.pop();
			
			int m[][2] = { {-1,0},{1,0},{0,1},{0,-1} };
			REP(d, 4) {
				if ( line[y+ m[d][0]] [x+ m[d][1]] == '.' ) {
					line[y+ m[d][0]] [x+ m[d][1]] = '+';
					ret++;
					que.push( make_pair(y+ m[d][0], x+ m[d][1]) );
				}
			}
		}
		
		cout << ret << endl;
	}
}

C++: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (typeof((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(typeof(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}



int H, W;
vector<string> field;

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

bool seen[30][30];

void dfs(pint x) {
    seen[x.FI][x.SE] = true;
    for (int i = 0; i < 4; ++i) {
        int nx = x.FI + dx[i];
        int ny = x.SE + dy[i];
        if (nx >= 0 && nx < H && ny >= 0 && ny < W) {
            if (!seen[nx][ny] && field[nx][ny] != '#') {
                dfs(MP(nx, ny));
            }
        }
    }
}

int main() {
    //freopen( "/Users/macuser/Documents/Programming/Contest/input.in", "r", stdin );
    
    while (cin >> W >> H) {
        if (W == 0) break;
        
        field.clear();
        for (int i = 0; i < H; ++i) {
            string str;
            cin >> str;
            field.PB(str);
        }
        
        pint start;
        for (int i = 0; i < H; ++i) 
            for (int j = 0; j < W; ++j) 
                if (field[i][j] == '@')
                    start = MP(i,j);
        
        memset(seen, 0, sizeof(seen));
        dfs(start);
        
        int res = 0;
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < W; ++j) 
                if (seen[i][j]) ++res;
        
        cout << res << endl;
    }
    
    return 0;
}

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

const int kSize = 20 + 2;

std::array<int, 4> ways = {-1, -kSize, +1, +kSize};

inline int xy2pos(const int x, const int y){
    return x + y * kSize;
}

std::array<bool, kSize*kSize> Bfs(const std::array<bool, kSize*kSize> &tiles, int pos){
    std::array<bool, kSize*kSize> arrived;
    std::queue<int> q;
    q.push(pos);
    std::fill(arrived.begin(), arrived.end(), false);
    while(!q.empty()){
        pos = q.front();
        q.pop();
        arrived[pos] = true;
        for(int way : ways)
            if(tiles.at(pos + way) && !arrived.at(pos + way))
                q.push(pos + way);
    }
    return arrived;
}

int main(){
    int w,h;
    std::array<bool,kSize*kSize> tiles; ///< true if black
    while((std::cin >> w >> h) && w != 0){
        std::fill(tiles.begin(), tiles.end(), false);
        int pos;
        for(int y=1; y<=h; ++y){
            for(int x=1; x<=w; ++x){
                char c;
                std::cin >> c;
                tiles[xy2pos(x,y)] = (c == '.');
                if(c == '@'){
                    pos = xy2pos(x,y);
                    tiles[pos] = true;
                }
            }
        }
        auto arrived = Bfs(tiles, pos);
        int sum = 0;
        for(bool v : arrived)
            sum += (v) ? 1 : 0;
        std::cout << sum << std::endl;
    }
}