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++: // #define USE_CPP11
// #define USE_PRINTF

#include <iostream>
#include <iomanip>
#include <map>
#include <set>
#include <utility>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <numeric>
#include <complex>
#include <memory>
#include <sstream>

#ifdef USE_CPP11
#include <unordered_map>
#include <unordered_set>
#include <functional>
#endif

#define PRINT(obj) cout << obj << endl
#define REP(i, n) for(int (i) = 0; (i) < (n); i++)

typedef long long ll;

using namespace std;

namespace Scanner {
#ifdef USE_PRINTF
  int    nextInt()    { int    d; scanf("%d" , &d); return d; }
  float  nextFloat()  { float  f; scanf("%f" , &f); return f; }
  double nextDouble() { double f; scanf("%lf", &f); return f; }  
  string nextString() { string s; scanf("%s" , &s); return s; }
  ll     nextll()     { ll     l; scanf("%ll", &l); return l; }
#else
  int    nextInt()    { int    d; cin >> d; return d; }
  float  nextFloat()  { float  f; cin >> f; return f; }
  double nextDouble() { double f; cin >> f; return f; }  
  string nextString() { string s; cin >> s; return s; }
  ll     nextll()     { ll     l; cin >> l; return l; }
#endif

  string getLine() { 
    string input;
    getline(cin, input);
    return input;
  }
};

namespace myLibrary {
  vector<string> split(const string& str, char delim) {
    vector<string> ret;
    size_t current = 0, found;
    while ((found = str.find_first_of(delim, current)) != string::npos) {
      ret.push_back(string(str, current, found - current));
      current = found + 1;
    }
    ret.push_back(string(str, current, str.size() - current));
    return ret;
  }
  
#ifdef USE_CPP11
  ///
  /// higher-order functional
  /// This is like map in haskell, python, etc.
  /// Sample usage:
  ///   vector<int> a = {1, 2, 3, 4, 5};
  ///   vector<int> b = myLibrary::_Map<int, int>(a, [](int n){
  ///     return n * n;
  ///   });
  /// Result:
  ///   b = 1, 4, 9, 16, 25
  ///
  template<typename T_IN, typename T_OUT, class Functor>
  vector<T_OUT> _Map(vector<T_IN> src, Functor func) {
    vector<T_OUT> ret;
    for (int i = 0; i < src.size(); i++) {
      ret.push_back(func(src[i]));
    }
    return ret;
  }
#endif
};

struct State {
public:
  bool onGrand;
  bool isLeftUp;
  bool isRightUp;
  
  State(): onGrand(true), isLeftUp(false), isRightUp(false) { }
};

enum Square {
  BLACK, RED
};

struct Position {
public:
  int x, y;
  Position() { };
  Position(int x, int y): x(x), y(y) { };
};

int main() {
  while (true) {
    int W = Scanner::nextInt();
    int H = Scanner::nextInt();
    if (W + H == 0) break;
    
    Square field[21][21];
    memset(field, RED, sizeof(field));
    
    Position startPos;    
    REP(i, H) {
      string input = Scanner::nextString();
      REP(j, W) {
        switch (input[j]) {
          case '.': { field[i][j] = BLACK;  break; }
          case '#': { field[i][j] = RED;    break; }
          case '@': { 
            startPos.x = i;
            startPos.y = j;
            field[i][j] = RED; 
            break; 
          }
        }
      }  
    }
    
    int count = 1;
    
    queue<Position> q;
    q.push(startPos);
     
    int dx[4] = { 0, -1, 1, 0 };
    int dy[4] = { -1, 0, 0, 1 };
    
    while (!q.empty()) {
      Position p = q.front(); q.pop();
      REP(i, 4) {
        int nx = p.x + dx[i];
        int ny = p.y + dy[i];
        if (nx < 0) continue;
        if (ny < 0) continue;
        
        if (field[nx][ny] == BLACK) {
          q.push(Position(nx, ny));
          field[nx][ny] = RED;
          count++;
        } 
      }  
    } 
    PRINT(count);
  }
  return 0;
}

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

using namespace std;

typedef struct {
	int x;
	int y;
} POSITION;

int main() {
	int W, H;
	while (cin >> W >> H, W + H != 0) {
		bool board[W][H];
		vector<POSITION> movable;
		POSITION myPosition;
		int ans = 1;
		for (int y = 0; y < H; y++) {
			string str;
			cin >> str;
			for (int x = 0; x < W; x++) {
				switch (str[x]) {
				case '.': {
					board[x][y] = true;
					break;
				}
				case '@': {
					board[x][y] = false;
					myPosition.x = x;
					myPosition.y = y;
				}	
				case '#': {
					board[x][y] = false;
					break;
				}
				}
			}
		}
		if (myPosition.x - 1 >= 0 && board[myPosition.x - 1][myPosition.y]) {
			movable.push_back( {myPosition.x - 1, myPosition.y} );
			board[myPosition.x - 1][myPosition.y] = false;
			ans++;
		}
		if (myPosition.x + 1 < W && board[myPosition.x + 1][myPosition.y]) {
			movable.push_back( {myPosition.x + 1, myPosition.y} );
			board[myPosition.x + 1][myPosition.y] = false;
			ans++;
		}
		if (myPosition.y - 1 >= 0 && board[myPosition.x][myPosition.y - 1]) {
			movable.push_back( {myPosition.x, myPosition.y - 1} );
			board[myPosition.x][myPosition.y - 1] = false;
			ans++;
		}
		if (myPosition.y + 1 < H && board[myPosition.x][myPosition.y + 1]) {
			movable.push_back( {myPosition.x, myPosition.y + 1} );
			board[myPosition.x][myPosition.y + 1] = false;
			ans++;
		}

		while (movable.size() != 0) {
			POSITION sp = movable[movable.size() - 1];
			movable.pop_back();
			if (sp.x - 1 >= 0 && board[sp.x - 1][sp.y]) {
				movable.push_back( {sp.x - 1, sp.y} );
				board[sp.x - 1][sp.y] = false;
				ans++;
			}
			if (sp.x + 1 < W && board[sp.x + 1][sp.y]) {
				movable.push_back( {sp.x + 1, sp.y} );
				board[sp.x + 1][sp.y] = false;
				ans++;
			}
			if (sp.y - 1 >= 0 && board[sp.x][sp.y - 1]) {
				movable.push_back( {sp.x, sp.y - 1} );
				board[sp.x][sp.y - 1] = false;
				ans++;
			}
			if (sp.y + 1 < H && board[sp.x][sp.y + 1]) {
				movable.push_back( {sp.x, sp.y + 1} );
				board[sp.x][sp.y + 1] = false;
				ans++;
			}
		}
		cout << ans << endl;
	}
	return 0;
}