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 <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
using namespace std;

#define rep(i,a,n) for(int (i)=(a); (i)<(n); (i)++)
#define repq(i,a,n) for(int (i)=(a); (i)<=(n); (i)++)
#define repr(i,a,n) for(int (i)=(a); (i)>=(n); (i)--)
#define all(v) begin(v), end(v)
#define pb(a) push_back(a)
#define fr first
#define sc second
#define INF 2000000000
#define int long long int

#define X real()
#define Y imag()
#define EPS (1e-10)
#define EQ(a,b) (abs((a) - (b)) < EPS)
#define EQV(a,b) ( EQ((a).X, (b).X) && EQ((a).Y, (b).Y) )
#define LE(n, m) ((n) < (m) + EPS)
#define LEQ(n, m) ((n) <= (m) + EPS)
#define GE(n, m) ((n) + EPS > (m))
#define GEQ(n, m) ((n) + EPS >= (m))

typedef vector<int> VI;
typedef vector<VI> MAT;
typedef pair<int, int> pii;
typedef long long ll;

typedef complex<double> P;
typedef pair<P, P> L;
typedef pair<P, double> C;

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

namespace std {
    bool operator<(const P& a, const P& b) {
        return a.X != b.X ? a.X < b.X : a.Y < b.Y;
    }
}

signed main() {
    int h, w;
    while(cin >> w >> h, h || w) {
        char board[30][30];
        bool visit[30][30] = {};
        pii st;
        rep(i,0,h) rep(j,0,w) {
            cin >> board[i][j];
            if(board[i][j] == '@') {
                st = pii(i, j);
                visit[i][j] = true;
            }
        }

        int ans = 0;
        queue<pii> q;
        q.push(st);
        while(!q.empty()) {
            pii t = q.front(); q.pop();
            ans++;
            rep(i,0,4) {
                int x = t.fr + dx[i];
                int y = t.sc + dy[i];
                if(x < 0 || x >= h || y < 0 || y >= w) continue;
                if(board[x][y] == '#') continue;
                if(visit[x][y]) continue;
                visit[x][y] = true;
                q.push(pii(x, y));
            }
        }
        cout << ans << endl;
    }
    return 0;
}

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

using namespace std;

int w,h;
int ans=1;
char tile[21][21];

void saiki(int x,int y){
	tile[x][y]='#';
	if(tile[x-1][y]=='.')ans++,saiki(x-1,y);
	if(tile[x+1][y]=='.')ans++,saiki(x+1,y);
	if(tile[x][y-1]=='.')ans++,saiki(x,y-1);
	if(tile[x][y+1]=='.')ans++,saiki(x,y+1);
}

int main(void){
	int a,b; 
	while(1){
		scanf("%d %d",&w,&h);
		if(w==0 && h==0)break;
		ans=1;
		for(a=0;a<h;a++){
			scanf("%s",tile[a]);
		}
		for(a=0;a<h;a++){
			for(b=0;b<w;b++){
				if(tile[a][b]=='@')saiki(a,b);
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

C++: #include<iostream>
#include<algorithm>

using namespace std;

char tyle[30][30]={'0'};

int find_tyle(int i,int j){
  if(tyle[i+1][j]=='.'){
    tyle[i+1][j]='a';
    find_tyle(i+1,j);
  }
  if(tyle[i][j+1]=='.'){
    tyle[i][j+1]='a';
    find_tyle(i,j+1);
  }
  if(tyle[i-1][j]=='.'){
    tyle[i-1][j]='a';
    find_tyle(i-1,j);
  }
  if(tyle[i][j-1]=='.'){
    tyle[i][j-1]='a';
    find_tyle(i,j-1);
  }
}

int main(){
  
  int w,h;
  
  while(cin>>w>>h,w){
    int ans=0;
    for(int i=1;i<=h;++i){
      for(int j=1;j<=w;++j){
      cin>>tyle[i][j];
      }
    }
    for(int i=1;i<=h;++i){
      for(int j=1;j<=w;++j){
	if(tyle[i][j]=='@'){
	  find_tyle(i,j);
	  tyle[i][j]='a';
	}
      }
    }
    for(int i=1;i<=h;++i){
      for(int j=1;j<=w;++j){
	if(tyle[i][j]=='a'){
	  ans++;
      }
    }
  }
    cout<<ans<<endl;

   for(int i=0;i<30;++i){
      for(int j=0;j<=30;++j){
      tyle[i][j]='0';
      }
    }
    
  }
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>

#define rep(i, n) for(int i = 0; i < n; i ++)
#define ALL(T) T.begin(), T.end()
#define mp make_pair
#define pb push_back
#define X first
#define Y second

using namespace std;

typedef pair<int, int> pii;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<string> vs;

const int INF = 1 << 24;
const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, 1, -1};

int cnt, w, h;
char m[20][20];

void dfs(pii);

int main(void){
    while(cin >> w >> h, w){
        cnt = 0;
        pii p;

        rep(y, h){
            cin >> m[y];
            rep(x, w) if(m[y][x] == '@') m[y][x] = '.', p = mp(x, y);
        }

        dfs(p);
        cout << cnt << endl;
    }

    return 0;
}

void dfs(pii p){
    if(p.X < 0 || w <= p.X ||
            p.Y < 0 || h <= p.Y) return;

    if(m[p.Y][p.X] == '.') cnt ++;
    else return;
    m[p.Y][p.X] = '#';

    rep(i, 4){
        pii next = mp(p.X + dx[i], p.Y + dy[i]);
        dfs(next);
    }
}

C++: #include<iostream>
#include<string.h>
using namespace std;

static int cnt;

void check(int pw,int ph,char **dt,int w,int h);
void dtallput(int h,int w,char **dt);

int main(void){
	int w,h;
	int ph,pw;
	char c;

	while(1){

	//入力
	cin >> w >> h;
	if(w==0&&h==0)break;

	char **dt = new char*[h+2];
	for(int i=0; i<h+2; i++){
		dt[i] = new char[w+2];
		memset(dt[i],'#',sizeof(char)*(w+2));
	}
	
	c=getchar();
	for(int i=0; i<h; i++){
		for(int j=0; j<w; j++){
			c=getchar();
			if(c=='.'||c=='#')
				dt[i+1][j+1]=c;
			else if(c=='@'){
				dt[i+1][j+1]=c;
				ph=i+1; pw=j+1;
			}
		}
		c=getchar();
	}
	
	//測定
	cnt=1;
	check(pw,ph,dt,w,h);

	//出力
	cout << cnt << endl;

	}
	return 0;
}

void check(int pw,int ph,char **dt,int w,int h){
	int dw[]={0,0,1,-1};
	int dh[]={1,-1,0,0};

	for(int i=0; i<4; i++){
		if(dt[ph+dh[i]][pw+dw[i]]=='.'){	
			dt[ph+dh[i]][pw+dw[i]]='@';
			cnt++;
			check(pw+dw[i],ph+dh[i],dt,w,h);
		}
	}
}

void dtallput(int h,int w,char **dt){
	cout << endl;
	for(int i=0; i<h+2; i++){
		for(int j=0; j<w+2; j++){
			cout << dt[i][j];
		}
		cout << endl;
	}
	cout << endl;
}