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<cstdio>
#include<cstdlib>
#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<algorithm>
#define FOR(i,a,b) for (int i=(a);i<(b);i++)
#define RFOR(i,a,b) for (int i=(b)-1;i>=(a);i--)
#define REP(i,n) for (int i=0;i<(n);i++)
#define RREP(i,n) for (int i=(n)-1;i>=0;i--)

using namespace std;
int ans = 0;

void bfs(char **tile, int w, int h){
  ans++;
  tile[w][h] = '#';

  if(tile[w][h-1] == '.')
  bfs(tile, w, h-1);

  if(tile[w][h+1] == '.')
  bfs(tile, w, h+1);

  if(tile[w-1][h] == '.')
  bfs(tile, w-1, h);

  if(tile[w+1][h] == '.')
  bfs(tile, w+1, h);

  return;
}


int main(){
  int W,H,index_w,index_h;

  while(true){
    cin >> W >> H;
    if(W == 0 && H == 0) break;

    char **tile;
    tile = new char* [H+2];
    REP(i,H+2) tile[i] = new char[W+2];

    REP(i,H+2){
      REP(j,W+2){
        if(i == 0 || i == H+1 || j == 0 || j == W+1) tile[i][j] = '#'; //sentry?
        else scanf(" %c",&tile[i][j]);

        if(tile[i][j] == '@') {
          index_h = j;
          index_w = i;
        }

      }
    }
    ans = 0;
    bfs(tile,index_w,index_h);
    
    REP(i,H) delete[] tile[i];
    delete[] tile;
    
    cout << ans << endl;
  }
  return 0;
}

C++: #include <iostream>
#include <vector>
using namespace std;
class Field {
  public:
  vector<vector<bool> > field;
  int nx, ny;
  bool def;
  Field(int nnx, int nny, bool firs, bool ddef) {
    def = ddef;
    nx = nnx;
    ny = nny;
    vector<vector<bool> > buff(nnx, vector<bool>(nny, firs));
    field = buff;
  }
  void set(int x, int y, bool flag) {
    field[x][y] = flag;
  }
  bool get(int x, int y) {
    if(x >= nx || y >= ny || x < 0 || y < 0) return def;
    return field[x][y];
  }
  void print() {
    for(int i = 0; i < ny; ++i) {
      for(int j = 0; j < nx; ++j) {
        cout << field[j][i];
      }
      cout << endl;
    }
    cout << endl;
  }
};
int mark(Field&, Field&, int x, int y);

int main() {
  while(1) {
    int nx, ny;
    cin >> nx >> ny;
    if(!nx && !ny) break;
    Field field(nx, ny, false, false);
    int startx, starty;
    for(int i = 0; i < ny; ++i) {
      for(int j = 0; j < nx; ++j) {
        char c;
        cin >> c;
        field.set(j, i, ((c == '#') ? false : true));
        if(c == '@') {
          startx = j;
          starty = i;
        }
      }
    }
    //for(auto i = field.begin(); i != field.end(); ++i) {
    //  for(auto j = field[i].begin(); j != field[j].end(); ++j) {
    //    cout << field[i][j];
    //  }
    //  cout << endl;
    //}
    Field result(nx, ny, false, true);
    cout << mark(field, result, startx, starty) << endl;
  }
  return 0;
}

int mark(Field &field, Field &result, int x, int y) {
  int count;
  if(field.get(x, y) && !result.get(x, y)) {
    result.set(x, y, true);
    count = mark(field, result, x + 1, y);
    count += mark(field, result, x, y + 1);
    count += mark(field, result, x - 1, y);
    count += mark(field, result, x, y - 1);
    ++count;
    return count;
  } else {
    return 0;
  }
}

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++) {
			c[i / 22][i % 22] = 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;
					}
				}
			}

			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<bits/stdc++.h>
using namespace std;

int main(){
	while(1){
		int W, H, x[30][30] = {};
		char str[30][30];
		cin>>W>>H;
		if(W==0 && H==0) break;
		for(int i = 0; i < W; i++){
			for(int j = 0; j < H; j++){
				cin>>str[i][j];
				if(str[i][j] == '@') x[i][j] = 1;
			}
		}
	
		int q = 0;
		while(1){
			int z = 0;
			for(int i = 0; i < W; i++){
				for(int j = 0; j < H; j++){
					if(x[i][j] == 1){
						if(i > 0 && str[i - 1][j] == '.') x[i - 1][j] = 1;
						if(i < H - 1  && str[i + 1][j] == '.') x[i + 1][j] = 1;
						if(j > 0 && str[i][j - 1] == '.') x[i][j - 1] = 1;
						if(j < W - 1&& str[i][j + 1] == '.') x[i][j + 1] = 1;
					}
				}
			}
			for(int i = 0; i < W; i++){
				for(int j = 0; j < H; j++){
					if(x[i][j] == 1) z++;
				}
			}
			if(z == q) break;
			q = z;
		}
		
		cout<<q<<endl;
	}
	return 0;
}