Problem:
Surrounding Area
土地囲い
English text is not available in this practice contest.
ある 2 人の不動産屋が，客船に乗って南の島に向かっていた．青い空，さわやかな風…．2 人は他の乗客とともに船旅を楽しんでいた．ところが，ある日突然発生した竜巻によって客船が沈んでしまった．他の乗客は救助隊によって救助されたが，どういうわけかこの 2 人だけ見落とされてしまった．数日の漂流の後，彼らはある無人島に流れ着いた．この無人島は長方形であり，以下の図のように格子に区切られていた．
図 C-1: 無人島の形状
彼らはとても欲深かったので，助けを呼ぶことではなく，この無人島の土地を売ることを考えていた．そして，彼らは土地を折半するということはせず，土地の奪い合いを始めた．彼らはそれぞれ自分の土地にしたいところを，一方は黒い杭で，もう一方は白い杭で囲み始めた．全ての杭は格子の中央に打たれ，また 1 つの格子に複数の杭が打たれることはなかった．しばらくすると双方とも疲れ果てて，杭を打つことを止めた．
あなたの仕事は，黒い杭および白い杭で囲まれた土地の面積を求めるプログラムを書くことである．ただし，格子 (
i
,
j
) が黒い杭に囲まれているとは，直感的には「格子 (
i
,
j
) から上下左右に任意に移動したとき，最初に当たる杭は常に黒い杭である」ことを意味する．正確には以下のように定義される．
黒い杭に「拡大隣接した」格子を次のとおりに定める．白い杭についても同様とする．
格子 (
i
,
j
) に杭が存在せず，さらに格子 (
i
,
j
) に隣接する格子のいずれかに黒い杭が存在するならば，格子 (
i
,
j
) は黒い杭に拡大隣接している．
格子 (
i
,
j
) に杭が存在せず，さらに格子 (
i
,
j
) に隣接する格子のいずれかが黒い杭に拡大隣接しているならば，格子 (
i
,
j
) は黒い杭に拡大隣接している．このルールは再帰的に適用される．
このとき，格子 (
i
,
j
) が黒い杭に拡大隣接していて，さらに白い杭に隣接していないとき，またそのときに限って，格子 (
i
,
j
) が黒い杭に囲まれているという．また逆に，格子 (
i
,
j
) が白い杭に拡大隣接していて，さらに黒い杭に隣接していないとき，またそのときに限って，格子 (
i
,
j
) が白い杭に囲まれているという．
Input
入力は複数のデータセットから構成される．各データセットは以下のような構成になっている．
w
h
a
1,1
a
2,1
a
3,1
...
a
w
,1
a
1,2
a
2,2
a
3,2
...
a
w
,2
...
a
1,
h
a
2,
h
a
3,
h
...
a
w
,
h
w
は土地の横幅，
h
は土地の縦幅を表す．これらは 1 ≦
w
,
h
≦ 50 を満たす．各
a
i
,
j
は格子 (
i
,
j
) の状態を表す 1 つの半角文字であり，「
B
」は黒い杭が打たれていることを，「
W
」は白い杭が打たれていることを，「
.
」（ピリオド）はいずれの杭も打たれていないことをそれぞれ示す．
w
=
h
= 0 は入力の終端を表しており，データセットには含まれない．
Output
各データセットについて，黒い杭が囲んだ土地の大きさ，および白い杭が囲んだ土地の大きさを 1 つの空白で区切って 1 行に出力しなさい．
Sample Input
10 10
.....W....
....W.W...
...W...W..
....W...W.
.....W...W
......W.W.
BBB....W..
..B..BBBBB
..B..B....
..B..B..W.
5 3
...B.
...BB
.....
1 1
.
0 0
Output for the Sample Input
6 21
12 0
0 0

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

bool solve() {
    int H, W;
    cin >> W >> H;
    if (H == 0 && W == 0) return false;
    vector<string> S(H);
    for (int i = 0; i < H; i++) cin >> S[i];
    int D[5] = {0, 1, 0, -1, 0};
    int ansB = 0, ansW = 0;
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            if (S[i][j] != '.') continue;
            vector<vector<bool>> vis(H, vector<bool>(W, false));
            vis[i][j] = true;
            queue<pair<int, int>> q;
            q.emplace(i, j);
            bool fnB = false, fnW = false;
            while (q.size()) {
                auto [r, c] = q.front();
                q.pop();
                if (S[r][c] != '.') {
                    fnB = fnB || S[r][c] == 'B';
                    fnW = fnW || S[r][c] == 'W';
                    continue;
                }
                for (int d = 0; d < 4; d++) {
                    int nr = r + D[d], nc = c + D[d + 1];
                    if (0 <= nr && nr < H && 0 <= nc && nc < W && !vis[nr][nc]) {
                        vis[nr][nc] = true;
                        q.emplace(nr, nc);
                    }
                }
            }
            if (fnB && fnW) continue;
            ansB += fnB;
            ansW += fnW;
        }
    }
    cout << ansB << ' ' << ansW << '\n';
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 190
memory_kb: 3456
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

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

int main() {
  while (true) {
    int w, h;
    cin >> w >> h;
    if (w == 0 && h == 0)break;
    vector<vector<char>> grid(h, vector<char>(w));
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> grid[i][j];
      }
    }

    int answ = 0, ansb = 0;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (grid[i][j] != '.')
          continue;
        queue<pair<int, int>> q;
        vector<vector<int>> dist(h, vector<int>(w, -1));
        q.emplace(i, j);
        dist[i][j] = 0;
        bool ww = false, bb = false;
        while (!q.empty()) {
          auto [x, y] = q.front();
          q.pop();
          for (int dir = 0; dir < 4; dir++) {
            int nx = x + dx[dir], ny = y + dy[dir];
            if (nx < 0 || nx >= h || ny < 0 || ny >= w)
              continue;
            if (grid[nx][ny] == 'W')
              ww = true;
            if (grid[nx][ny] == 'B')
              bb = true;
            if (grid[nx][ny] != '.')
              continue;
            if (dist[nx][ny] == -1) {
              dist[nx][ny] = dist[x][y] + 1;
              q.emplace(nx, ny);
            }
          }
        }
        if (ww && !bb)
          answ++;
        if (!ww && bb)
          ansb++;
      }
    }
    cout << ansb << " " << answ << endl;
  }
}
accuracy: 1
time_ms: 180
memory_kb: 3112
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <queue>

using namespace std;

void solve (int w, int h) {
    vector<string> a(h);
    for (auto &i: a) cin >> i;
    const vector<int> dx = {1, -1, 0, 0}, dy = {0, 0, 1, -1};
    int ab = 0, aw = 0;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (a[i][j] != '.') continue;
            bool bf = false, wf = false;
            queue<pair<int, int>> q;
            q.emplace(i, j);
            vector visited(h, vector<bool>(w));
            visited[i][j] = true;
            while(!q.empty()) {
                auto [x, y] = q.front();
                q.pop();
                if (a[x][y] == 'B') {
                    bf = true;
                    continue;
                }
                if (a[x][y] == 'W') {
                    wf = true;
                    continue;
                }
                for (int k = 0; k < 4; k++) {
                    int nx = x + dx[k], ny = y + dy[k];
                    if (0 <= nx && nx < h && 0 <= ny && ny < w && !visited[nx][ny]) {
                        q.emplace(nx, ny);
                        visited[nx][ny] = true;
                    }
                }
            }
            if (bf && !wf) ab++;
            if (wf && !bf) aw++;
        }
    }
    cout << ab << " " << aw << endl;
}

int main() {
    int w, h;
    cin >> w >> h;
    while (w && h) {
        solve(w, h);
        cin >> w >> h;
    }
}
accuracy: 1
time_ms: 250
memory_kb: 3300
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
char judge = 'N';
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

void ju(vector<vector<char>> &G, ll x, ll y, ll h, ll w,
        vector<vector<bool>> &seen) {
    seen[x][y] = true;
    if (G[x][y] != '.') {
        if (judge == 'N') {
            judge = G[x][y];
            return;
        } else if (judge != G[x][y]) {
            judge = 'E';
            return;
        } else if (judge == G[x][y]) {
            return;
        }
    }

    for (ll i = 0; i < 4; ++i) {
        ll nx = x + dx[i];
        ll ny = y + dy[i];

        if (nx >= 0 && nx < h && ny >= 0 && ny < w && !seen[nx][ny]) {
            ju(G, nx, ny, h, w, seen);
        }
    }
}

void solve() {
    while (1) {
        ll h, w;
        cin >> w >> h;
        if (h == 0) return;
        vector<vector<char>> S(h, vector<char>(w));
        for (ll i = 0; i < h; ++i) {
            for (ll j = 0; j < w; ++j) {
                cin >> S[i][j];
            }
        }

        ll white = 0;
        ll black = 0;
        for (ll i = 0; i < h; ++i) {
            for (ll j = 0; j < w; ++j) {
                vector<vector<bool>> seen(h, vector<bool>(w));
                judge = 'N';
                if (S[i][j] != '.') continue;
                ju(S, i, j, h, w, seen);
                if (judge == 'W') ++white;
                else if (judge == 'B') ++black;
            }
        }

        cout << black << ' ' << white << endl;
    }
}

int main() {
    solve();
    return 0;
}
accuracy: 1
time_ms: 290
memory_kb: 3592
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
char judge = 'N';
int dx[4] = {1, 0, -1, 0}; int dy[4] = {0, 1, 0, -1};

void ju(vector<vector<char>> &G, ll x, ll y, ll h, ll w, vector<vector<bool>> &seen) {
    seen[x][y] = true;

    if (G[x][y] != '.' && judge == 'N') {
        judge = G[x][y];
        return;
    } else if (G[x][y] != '.' && judge != G[x][y]) {
        judge = 'E';
        return;
    } else if (G[x][y] != '.' && judge == G[x][y]) {
        return;
    }

    for (ll i = 0; i < 4; ++i) {
        ll nx = x + dx[i];
        ll ny = y + dy[i];

        if (nx >= 0 && nx < h && ny >= 0 && ny < w && !seen[nx][ny]) {
            ju(G,nx,ny,h,w,seen);
        }
    }
}


void solve() {
    while (1) {
    ll h,w;
    cin >> w >> h;
    if (h == 0) return;
    vector<vector<char>> S(h, vector<char>(w));
    for (ll i = 0; i < h; ++i) {
        for (ll j = 0; j < w; ++j) {
            cin >> S[i][j];
        }
    }

    ll white = 0;
    ll black = 0;
    for (ll i = 0; i < h; ++i) {
        for (ll j = 0; j < w; ++j)  {
            vector<vector<bool>> seen(h, vector<bool>(w));
            judge = 'N';
            if (S[i][j] != '.') continue;
            ju(S,i,j,h,w,seen);
            if (judge == 'W') ++white;
            else if (judge == 'B') ++black;
            judge = 'N';
        }
    }

    cout << black << ' ' << white << endl;
    }
}

int main() {
    solve();
    return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 3644
final_rank: 17

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

vi dx = {1, 0, -1, 0}, dy = {0, 1, 0, -1};
pair<int, int> solve(int H, int W){
    vc<string> S(H);rep(i, H) cin >> S[i];
    int l = 0, r = 0;
    rep(i, H) rep(j, W) if (S[i][j] == '.'){
        bool b = false, w = false;
        vvi seen(H, vi(W, 0));
        seen[i][j] = 1;
        deque<pair<int, int>> q;
        q.push_back({i, j});
        while (!q.empty()){
            auto [ni, nj] = q.front(); q.pop_front();
            rep(k, 4){
                int nxi = ni + dx[k], nxj = nj + dy[k];
                if (inside(nxi, nxj, H, W) && !seen[nxi][nxj]){
                    seen[nxi][nxj] = 1;
                    if (S[nxi][nxj] == '.'){
                        q.push_back({nxi, nxj});
                    }
                    if (S[nxi][nxj] == 'B') b = true;
                    if (S[nxi][nxj] == 'W') w = true;
                }
            }
        }
        if (b && !w) l++;
        if (!b && w) r++;
    }
    return {l, r};
}

int main(){
    vc<pair<int, int>> ans;
    while (true){
        int W, H; cin >> W >> H;
        if (W == 0) break;
        ans.push_back(solve(H, W));
    }
    for (auto x : ans) cout << x.first << " " << x.second << endl;
}
accuracy: 1
time_ms: 180
memory_kb: 3420
final_rank: 8

code_snippet: #include "bits/stdc++.h"
#pragma GCC optimize("Ofast")

// Begin Header {{{
#pragma region
using namespace std;

#ifndef DEBUG
#define dump(...)
#endif

#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define rep(i, b, e) for (intmax_t i = (b), i##_limit = (e); i < i##_limit; ++i)
#define repc(i, b, e) for (intmax_t i = (b), i##_limit = (e); i <= i##_limit; ++i)
#define repr(i, b, e) for (intmax_t i = (b), i##_limit = (e); i >= i##_limit; --i)
#define var(Type, ...) \
    Type __VA_ARGS__;  \
    input(__VA_ARGS__)
#define let const auto

constexpr size_t operator""_zu(unsigned long long value) {
    return value;
};
constexpr intmax_t operator""_jd(unsigned long long value) {
    return value;
};
constexpr uintmax_t operator""_ju(unsigned long long value) {
    return value;
};

constexpr int INF = 0x3f3f3f3f;
constexpr intmax_t LINF = 0x3f3f3f3f3f3f3f3f_jd;

using usize = size_t;
using imax = intmax_t;
using uimax = uintmax_t;
using ld = long double;

template <class T, class Compare = less<>>
using MaxHeap = priority_queue<T, vector<T>, Compare>;
template <class T, class Compare = greater<>>
using MinHeap = priority_queue<T, vector<T>, Compare>;

inline void input() {}
template <class Head, class... Tail>
inline void input(Head&& head, Tail&&... tail) {
    cin >> head;
    input(forward<Tail>(tail)...);
}

template <class Container, class Value = typename Container::value_type,
          enable_if_t<!is_same<Container, string>::value, nullptr_t> = nullptr>
inline istream& operator>>(istream& is, Container& vs) {
    for (auto& v: vs) is >> v;
    return is;
}

template <class T, class U>
inline istream& operator>>(istream& is, pair<T, U>& p) {
    is >> p.first >> p.second;
    return is;
}

inline void output() {
    cout << "\n";
}
template <class Head, class... Tail>
inline void output(Head&& head, Tail&&... tail) {
    cout << head;
    if (sizeof...(tail)) cout << " ";
    output(forward<Tail>(tail)...);
}

template <class Container, class Value = typename Container::value_type,
          enable_if_t<!is_same<Container, string>::value, nullptr_t> = nullptr>
inline ostream& operator<<(ostream& os, const Container& vs) {
    static constexpr const char* delim[] = {" ", ""};
    for (auto it = begin(vs); it != end(vs); ++it) {
        os << delim[it == begin(vs)] << *it;
    }
    return os;
}

template <class Iterator>
inline void join(const Iterator& Begin, const Iterator& End, const string& delim = "\n",
                 const string& last = "\n") {
    for (auto it = Begin; it != End; ++it) {
        cout << ((it == Begin) ? "" : delim) << *it;
    }
    cout << last;
}

template <class T>
inline vector<T> makeVector(const T& init_value, size_t sz) {
    return vector<T>(sz, init_value);
}

template <class T, class... Args>
inline auto makeVector(const T& init_value, size_t sz, Args... args) {
    return vector<decltype(makeVector<T>(init_value, args...))>(
        sz, makeVector<T>(init_value, args...));
}

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func> {forward<Func>(f)};
}

template <class Container>
struct reverse_t {
    Container& c;
    reverse_t(Container& c) : c(c) {}
    auto begin() {
        return c.rbegin();
    }
    auto end() {
        return c.rend();
    }
};

template <class Container>
auto reversed(Container& c) {
    return reverse_t<Container>(c);
}

template <class T>
inline bool chmax(T& a, const T& b) noexcept {
    return b > a && (a = b, true);
}

template <class T>
inline bool chmin(T& a, const T& b) noexcept {
    return b < a && (a = b, true);
}

template <class T>
inline T diff(const T& a, const T& b) noexcept {
    return a < b ? b - a : a - b;
}

template <class T>
inline T sigma(const T& l, const T& r) noexcept {
    return (l + r) * (r - l + 1) / 2;
}

template <class T>
inline T ceildiv(const T& n, const T& d) noexcept {
    return (n + d - 1) / d;
}

void operator|=(vector<bool>::reference lhs, const bool rhs) {
    lhs = lhs | rhs;
}

void operator&=(vector<bool>::reference lhs, const bool rhs) {
    lhs = lhs & rhs;
}

void operator^=(vector<bool>::reference lhs, const bool rhs) {
    lhs = lhs ^ rhs;
}

void ioinit() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
    clog << fixed << setprecision(10);
}
#pragma endregion
// }}} End Header

int main() {
    ioinit();

    size_t W, H;
    while (input(W, H), W) {
        vector<string> ss(H);
        input(ss);
        const string T = "BW";
        const auto f = [&](int sr, int sc, int wi) {
            queue<pair<int, int>> que;
            que.emplace(sr, sc);
            auto seen = makeVector<bool>(false, H, W);
            seen[sr][sc] = true;
            constexpr array<int, 8> dr = {0, 1, 0, -1, -1, 1, 1, -1};
            constexpr array<int, 8> dc = {1, 0, -1, 0, 1, 1, -1, -1};
            const auto inside = [](int r, int c, int R, int C) {
                return (0 <= r && r < R && 0 <= c && c < C);
            };
            bool valid = false;
            while (!que.empty()) {
                const auto [r, c] = que.front();
                que.pop();
                rep(dir, 0, 4) {
                    int nr = r + dr[dir];
                    int nc = c + dc[dir];
                    if (!inside(nr, nc, H, W)) continue;
                    if (seen[nr][nc]) continue;
                    if (ss[nr][nc] == T[1 - wi]) return false;
                    if (ss[nr][nc] == T[wi]) valid = true;
                    if (ss[nr][nc] == '.') {
                        seen[nr][nc] = true;
                        que.emplace(nr, nc);
                    }
                }
            }
            return valid;
        };
        int cb = 0, cw = 0;
        rep(sr, 0, H) rep(sc, 0, W) {
            if (ss[sr][sc] == '.') {
                cb += f(sr, sc, 0);
                cw += f(sr, sc, 1);
            }
        }
        output(cb, cw);
    }
    return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 3348
final_rank: 19

code_snippet: #include <iostream>
#include <algorithm>
#include <utility>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <map>
#include <math.h>
#include <string.h>
#include <iomanip>
#include <numeric>
#include <cstdlib>
#include <cstdint>
#include <cmath>
#include <functional>
#include <limits>
#include <cassert>
#include <bitset>
#include <chrono>
#include <random>
#include <memory>
 
/* macro */
 
#define rep(i, a, n) for (int i = (int)(a); i < (int)(n); i++)
#define rrep(i, a, n) for (int i = ((int)(n-1)); i >= (int)(a); i--)
#define Rep(i, a, n) for (i64 i = (i64)(a); i< (i64)(n); i++)
#define RRep(i, a, n) for (i64 i = ((i64)(n-i64(1))); i>=(i64)(a); i--)
#define all(v) (v).begin(),(v).end()
#define rall(v) (v).rbegin(),(v).rend()
#define Bit(n) (1LL<<(n))
 
/* macro end */
 
/* template */
 
namespace ebi {
 
#ifdef LOCAL
#define debug(...)                                                    \
    std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
        debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif
 
void debug_out() { std::cerr << std::endl; }
 
template <typename Head, typename... Tail>
void debug_out(Head h, Tail... t) {
    std::cerr << " " << h;
    if (sizeof...(t) > 0) std::cout << " :";
    debug_out(t...);
}
 
template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, std::pair<T1, T2> pa) {
    return os << pa.first << " " << pa.second;
}
 
template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> vec) {
    for (std::size_t i = 0; i < vec.size(); i++) os << vec[i] << (i + 1 == vec.size() ? "" : " ");
    return os;
}
 
using size_t = std::size_t;
using i64 = std::int64_t;
using u64 = std::uint64_t;
using ld = long double;
 
template<class T> void fill(std::vector<T> &v) { for(T &e: v) std::cin >> e; }
 
template <class T>
inline bool chmin(T &a, T b) {
    if (a > b){
        a = b;
        return true;
    }
    return false;
}
 
template <class T>
inline bool chmax(T &a, T b) {
    if (a < b){
        a = b;
        return true;
    }
    return false;
}
 
template <class T>
T gcd(T a, T b){
    if( b==0 ) return a;
    else return gcd(b, a%b);
}
 
template <class T>
T lcm(T a, T b) {
    a /= gcd(a, b);
    return a*b;
}
 
template<class T>
T Pow(T x, i64 n) {
    T res = 1;
    while(n>0){
        if(n&1) res = res *x;
        x = x*x;
        n>>=1;
    }
    return res;
}
 
template<class T>
T scan() {
    T val;
    std::cin >> val;
    return val;
}
 
constexpr i64 LNF = std::numeric_limits<i64>::max()/4;
 
constexpr int INF = std::numeric_limits<int>::max()/2;
 
const std::vector<int> dy = {1,0,-1,0,1,1,-1,-1};
const std::vector<int> dx = {0,1,0,-1,1,-1,1,-1};
 
}
 
/* template end */

namespace ebi {

void main_() {
    int w,h;
    while(std::cin >> w >> h, !(w == 0 && h == 0)) {
        std::vector<std::string> a(h);
        rep(i,0,h) std::cin >> a[i];
        std::vector seen(h, std::vector<int>(w, -1));
        std::vector table(h, std::vector<int>(w, 0));
        auto dfs = [&](auto &&self, int y, int x, int val) -> void {
            if(a[y][x] != '.') return;
            table[y][x] |= val;
            seen[y][x] = 1;
            rep(i,0,4) {
                int ny = y + dy[i];
                int nx = x + dx[i];
                if(0 <= ny && ny < h && 0 <= nx && nx < w && seen[ny][nx] < 0) {
                    self(self, ny, nx, val);
                }
            }
        };
        rep(i,0,h) {
            rep(j,0,w) {
                int val = 0;
                if(a[i][j] == '.') {
                    continue;
                }
                else if(a[i][j] == 'W') {
                    val = 2;
                }
                else {
                    val = 1;
                }
                seen = std::vector(h, std::vector<int>(w, -1));
                rep(k,0,4) {
                    int ny = i + dy[k];
                    int nx = j + dx[k];
                    if(0 <= ny && ny < h && 0 <= nx && nx < w) {
                        dfs(dfs, ny, nx, val);
                    }
                }
            }
        }
        int black = 0, white = 0;
        rep(i,0,h) {
            rep(j,0,w) {
                if(table[i][j] == 1) {
                    black++;
                }
                else if(table[i][j] == 2) {
                    white++;
                }
            }
        }
        std::cout << black << " " << white << '\n';
    }
}

}
 
int main() {
    std::cout << std::fixed << std::setprecision(15);
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    int t = 1;
    // std::cin >> t;
    while(t--) {
        ebi::main_();
    }
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 3444
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; ++i)
typedef long long ll;
using namespace std;

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

bool gridIn(int y, int x, int H, int W) {
    if (y < 0 || y >= H || x < 0 || x >= W)
        return false;
    return true;
}

int main() {
    int H, W;
    while (cin >> W >> H, H) {
        vector<string> S(H);
        rep(i, H) cin >> S[i];

        int ansB = 0, ansW = 0;
        rep(i, H) rep(j, W) {
            if (S[i][j] != '.') continue;

            bool isB = false, isW = false;
            queue<pair<int, int>> que;
            que.push({i, j});
            vector<vector<bool>> seen(H, vector<bool>(W));
            seen[i][j] = true;

            while (!que.empty()) {
                auto now = que.front();
                que.pop();

                rep(i, 4) {
                    int ny = now.first + dy[i];
                    int nx = now.second + dx[i];

                    if (gridIn(ny, nx, H, W) && !seen[ny][nx]) {
                        if (S[ny][nx] == '.') {
                            que.push({ny, nx});
                            seen[ny][nx] = true;
                        } else if (S[ny][nx] == 'W')
                            isW = true;
                        else
                            isB = true;
                    }
                }
            }

            if (isB == isW) continue;
            if (isB) ansB++;
            if (isW) ansW++;
        }
        cout << ansB << " " << ansW << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3368
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

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

int main() {
    while (true) {
        int w,h;
        cin >> w >> h;
        if(w == 0) {
            return 0;
        }
        vector<vector<char>>a(h,vector<char>(w));
        for(int i = 0; i < h; i++) {
            for(int j = 0; j < w; j++) {
                cin >> a[i][j];
            }
        }
        int B = 0,W = 0;
        for(int i = 0; i < h; i++) {
            for(int j = 0; j < w; j++) {
                if(a[i][j] == '.') {
                    queue<pair<int,int>>que;
                    que.push({i,j});
                    vector<vector<int>>dist(h,vector<int>(w,-1));
                    dist[i][j] = 0;
                    int b = 0,ww = 0;
                    while (!que.empty()) {
                        pair<int,int> x = que.front();
                        que.pop();
                        for(int k = 0; k < 4; k++) {
                            int nx = x.first+dx[k];
                            int ny = x.second+dy[k];
                            if(nx >= 0 && nx < h && ny >= 0 && ny < w) {
                                if(a[nx][ny] == '.') {
                                    if(dist[nx][ny] == -1) {
                                        dist[nx][ny] = 0;
                                        que.push({nx,ny});
                                    }
                                }
                                else {
                                    if(a[nx][ny] == 'B') {
                                        b++;
                                    }
                                    else {
                                        ww++;
                                    }
                                }
                            }
                        }
                    }
                    if(b && !ww) {
                        B++;
                    }
                    if(ww && !b) {
                        W++;
                    }
                }
            }
        }
        cout << B << " " << W << endl;
    }
}
accuracy: 1
time_ms: 160
memory_kb: 3540
final_rank: 5

code_snippet: #include <iostream>
#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>
#include <numeric>
#include <functional>
#include <bitset>
#include <cstddef>
#include <type_traits>
#include <vector>

using namespace std;
const long long int INF = numeric_limits<long long int>::max() / 4;
const int inf = numeric_limits<int>::max() / 4;
const long long int MOD1000000007 = 1000000007;
const long long int MOD998244353 = 998244353;
const double MATH_PI = 3.1415926535897932;

template<typename T1, typename T2>
inline void chmin(T1 &a, const T2 &b) { if (a > b) a = b; }

template<typename T1, typename T2>
inline void chmax(T1 &a, const T2 &b) { if (a < b) a = b; }

#define lint long long int
#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()
#define rep(i, n) for(int i=0;i<(int)(n);i++)
#define VI vector<int>
#define VLL vector<long long>
#define VC vector<char>
#define VB vector<bool>
#define PI pair<int, int>
#define PLL pair<long long, long long>
#define VPI vector<pair<int, int>>
#define VPLL vector<pair<long long, long long>>
#define VVI vector<vector<int>>
#define VVPI vecor<vector<pair<int, int>>>
#define VVPILL vector<vector<pair<int, long long>>>

#define SUM(v) accumulate(ALL(v), 0LL)
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))


int dfs(int i, int j, vector<vector<char>> &g, vector<vector<int>> &color) {
    int h = g.size();
    int w = g[0].size();
    int di[] = {0, -1, 0, 1};
    int dj[] = {1, 0, -1, 0};

    // 何らかの手段で、find_B と find_W を更新する
    bool find_B = false;
    bool find_W = false;
    // 4 方向見てる
    for (int dir = 0; dir < 4; dir++) {
        int ni = i + di[dir];
        int nj = j + dj[dir];

        // 再帰関数を読んで、探索
        if (ni < 0 or nj < 0 or ni >= h or nj >= w) continue;
        // 訪問済みなら continue
        if (color[ni][nj] != 0) {
            int c = color[ni][nj];
            if (c == 3 or c == 1) {
                // B が見つかってる
                find_B = true;
            }
            if (c == 3 or c == 2) {
                // W が見つかってる
                find_W = true;
            }
            continue;
        }
        if (g[ni][nj] == 'B') {
            find_B = true;
        } else if (g[ni][nj] == 'W') {
            find_W = true;
        } else {
            color[ni][nj] = 4;
            int c = dfs(ni, nj, g, color);
            if (c == 3 or c == 1) {
                // B が見つかってる
                find_B = true;
            }
            if (c == 3 or c == 2) {
                // W が見つかってる
                find_W = true;
            }
        }
    }

    if (find_B and find_W) {
        color[i][j] = 3;
    } else if (find_B) {
        color[i][j] = 1;
    } else if (find_W) {
        color[i][j] = 2;
    } else {
        // assert(false);
    }
    return color[i][j];
}
bool solve() {
    int h, w;
    cin >> h >> w;
    swap(h, w);
    if (h == 0) return false;

    vector g(h, vector<char>(w));

    bool all_dot = true;
    rep (i, h) {
        rep (j, w) {
            cin >> g[i][j];
            if (g[i][j] != '.') all_dot = false;
        }
    }

    if (all_dot) {
        cout << 0 << " " << 0 << endl;
        return true;
    }

    // 0 := 未訪問
    // 1 := B だけ見つかる
    // 2 := W だけ見つかる
    // 3 := BW 共に見つかる
    // 4 := 探索中 (now loading)
    int cnt_b = 0;
    int cnt_w = 0;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
           if (g[i][j] == '.') {
               vector color(h, vector<int>(w, 0));
               color[i][j] = 4;
               int c = dfs(i, j, g, color);
               if (c == 1) {
                   cnt_b++;
               }
               if (c == 2) {
                   cnt_w++;
               }
           }
        }
    }
    cout << cnt_b << " " << cnt_w << endl;

    return true;
}

int main() {

    while (solve()) {}
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3396
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
//#include <atcoder/all>
//using namespace atcoder;

using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vvvll = vector<vector<vector<ll>>>;
using vpll = vector<pair<ll, ll>>;
#define rep(i,n) for (ll i = 0; i < (n); i++)
#define all(v) (v).begin(), (v).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
#define pb push_back
#define endl '\n'
#define IOS ios::sync_with_stdio(false); cin.tie(nullptr);
const int inf = 1<<30;
const ll INF = 1ll<<60;
//const ll mod = 1000000007;
const ll mod = 998244353;
const ll dx[4] = {1, 0, -1, 0};
const ll dy[4] = {0, 1, 0, -1};
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }

template<class T> void disp1(vector<T> &array, bool blank=1) {
    rep(i, array.size()) cout << ((i&&blank) ? " " : "") << array[i];
    cout << endl;
    //cout << " ";
}
template<class T> void disp2(vector<vector<T>> &array, bool blank=1) {
    rep(i, array.size()) disp1(array[i], blank);
}

ll rem(ll a, ll b) { return (a % b + b) % b; }      // 余りを0~b-1に丸める
// 小数の入力が文字で与えられたとき、10^n倍したものを返す
ll x10(string str_f, ll n) {
    if (str_f[0] == '-') return -x10(str_f.substr(1), n);
    ll times = 1; rep(i,n) times *= 10;     // times = 10^n
    int id = -1; rep(i,str_f.size()) if (str_f[i] == '.') id = i;
    if (id == -1) { return stoll(str_f)*times; }
    string str_int = str_f.substr(0, id), str_dec = str_f.substr(id+1);
    while (str_dec.size() < n) str_dec += '0';
    return stoll(str_int)*times + stoll(str_dec);
}
// A^N (mod)
ll modpow(ll A, ll N, ll mod) {
    ll RES = 1;
    while (N) {
        if (N & 1) RES = RES * A % mod;
        A = A * A % mod;
        N >>= 1;
    }
    return RES;
}

//using mint = modint998244353;

vvll bfs(vector<string> &s, vvll sta, ll x, ll y) {
    ll h = sz(s), w = sz(s[0]);
    vvll seen(h, vll(w, 0));
    queue<pll> que;
    que.push({x, y});
    while (que.size()) {
        pll p = que.front(); que.pop();
        ll cx = p.fi, cy = p.se;
        if (seen[cx][cy]) continue;
        seen[cx][cy] = 1;
        rep(i,4) {
            ll nx = cx+dx[i], ny = cy+dy[i];
            if (0 <= nx && nx < h && 0 <= ny && ny < w && seen[nx][ny] == 0 && s[nx][ny] == '.') {
                sta[nx][ny]++;
                que.push({nx, ny});
            }
        }
    }
    return sta;
}

int main() {
    ll w, h;
    while (cin >> w >> h, w) {
        vector<string> s(h);
        // bla[i][j] = (i,j)に到達可能なマスの中にBがあれば1, なければ0
        vvll bla(h, vll(w, 0)), whi(h, vll(w, 0));
        rep(i,h) cin >> s[i];
        rep(i,h) rep(j,w) {
            if (s[i][j] == 'W') {
                whi = bfs(s, whi, i, j);
            } else if (s[i][j] == 'B') {
                bla = bfs(s, bla, i, j);
            }
        }
        ll bb = 0, ww = 0;
        rep(i,h) rep(j,w) {
            if (whi[i][j] > 0 && bla[i][j] == 0) ww++;
            if (bla[i][j] > 0 && whi[i][j] == 0) bb++;
        }
        printf("%lld %lld\n", bb, ww);
    }
    return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 3164
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std; typedef unsigned long long _ulong; typedef long long int lint; typedef pair<lint, lint> plint; typedef pair<double long, double long> pld;
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((lint)(x).size())
#define FOR(i, begin, end) for(lint i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(lint i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
#define endk '\n'
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
lint gcd(lint a, lint b) { if (b == 0) return a; else return gcd(b, a % b); }
lint ceil(lint a, lint b) { return (a + b - 1) / b; }
lint digit(lint a) { return (lint)log10(a); }
const lint MOD = 998244353, INF = 1e18;
lint dx[8] = { 0, -1, 1, 0, 1, -1, 1, -1 }, dy[8] = { 1, 0, 0, -1, -1, -1, 1, 1 };
void YN(bool flag) { cout << (flag ? "Yes" : "No") << endk; }
typedef pair<long double, lint> Pa;
typedef pair<lint, plint> tlint;
struct point {
	lint r;
	lint x, y;
};

lint W, H;
int main() {
	while (true) {
		cin >> W >> H;
		if (W == 0 && H == 0) break;
		vector<vector<lint> > mp(H, vector<lint>(W));
		vector<vector<lint> > dp(H, vector<lint>(W));
		REP(i, H) {
			REP(j, W) {
				char c;
				cin >> c;
				if (c == '.') mp[i][j] = 0;
				if (c == 'B') mp[i][j] = 1;
				if (c == 'W') mp[i][j] = 2;
			}
		}
		REP(i, H) {
			REP(j, W) {
				if (!mp[i][j]) continue;
				queue<plint> que;
				que.push({ i, j });
				while (!que.empty()) {
					plint curr = que.front(); que.pop();
					REP(k, 4) {
						lint nh = curr.first + dy[k], nw = curr.second + dx[k];
						if (nh < 0 || nh >= H || nw < 0 || nw >= W) continue;
						if (mp[nh][nw] != 0) continue;
						if ((dp[nh][nw] & mp[i][j]) != 0) continue;
						dp[nh][nw] |= mp[i][j];
						que.push({ nh, nw });
					}
				}
			}
		}
		lint cnt[2] = { 0 };
		REP(i, H) {
			REP(j, W) {
				if (dp[i][j] == 1) cnt[0]++;
				if (dp[i][j] == 2) cnt[1]++;
			}
		}
		cout << cnt[0] << " " << cnt[1] << endk;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3192
final_rank: 2

code_snippet: #include <bits/stdc++.h>

#pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
//#include <boost/multiprecision/cpp_int.hpp>
using namespace std;

//using namespace boost::multiprecision;
//#include<atcoder/all>
//using namespace atcoder;

using dou =long double;
string yes="yes";
string Yes="Yes";
string YES="YES";
string no="no";
string No="No";
string NO="NO";

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
typedef long long ll;
typedef pair<int,int> P;
typedef pair<ll,ll> PL;

const ll mod = 998244353ll;
//const ll mod = 1000000007ll;
//const ll mod = 100000;


struct mint {
  ll x; // typedef long long ll;
  mint(ll x=0):x((x%mod+mod)%mod){}
  mint operator-() const { return mint(-x);}
  mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += mod-a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this;}
  mint operator+(const mint a) const { return mint(*this) += a;}
  mint operator-(const mint a) const { return mint(*this) -= a;}
  mint operator*(const mint a) const { return mint(*this) *= a;}
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }

  // for prime modhttps://atcoder.jp/contests/abc166/submit?taskScreenName=abc166_f
  mint inv() const { return pow(mod-2);}
  mint& operator/=(const mint a) { return *this *= a.inv();}
  mint operator/(const mint a) const { return mint(*this) /= a;}
};

istream& operator>>(istream& is, const mint& a) { return is >> a.x;}
ostream& operator<<(ostream& os, const mint& a) { return os << a.x;}

#define rep(i, n)         for(ll i = 0; i < (ll)(n); i++)
#define brep(n)           for(int bit=0;bit<(1<<n);bit++)
#define bbrep(n)           for(int bbit=0;bbit<(1<<n);bbit++)
#define erep(i,container) for (auto &i : container)
#define itrep(i,container) for (auto i : container)
#define irep(i, n)        for(ll i = n-1; i >= (ll)0ll; i--)
#define rrep(i,m,n) for(ll i = m; i < (ll)(n); i++)
#define reprep(i,j,h,w) rep(i,h)rep(j,w)
#define repreprep(i,j,k,h,w,n) rep(i,h)rep(j,w)rep(k,n)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define VEC(type,name,n) std::vector<type> name(n);rep(i,n)std::cin >> name[i];
#define pb push_back
#define pf push_front
#define query int qq;std::cin >> qq;rep(qqq,qq)
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define itn int
#define mp make_pair
//#define sum(a) accumulate(all(a),0ll)
#define keta fixed<<setprecision
#define vout(a) erep(qxqxqx,a)std::cout << qxqxqx << ' ';std::cout  << std::endl;
#define vvector(name,typ,m,n,a)vector<vector<typ> > name(m,vector<typ> (n,a))
//#define vvector(name,typ,m,n)vector<vector<typ> > name(m,vector<typ> (n))
#define vvvector(name,t,l,m,n,a) vector<vector<vector<t> > > name(l, vector<vector<t> >(m, vector<t>(n,a)));
#define vvvvector(name,t,k,l,m,n,a) vector<vector<vector<vector<t> > > > name(k,vector<vector<vector<t> > >(l, vector<vector<t> >(m, vector<t>(n,a)) ));
#define case std::cout <<"Case #" <<qqq+1<<":"
#define RES(a,i,j) a.resize(i);rep(ii,i)a[ii].resize(j);
#define RESRES(a,i,j,k) a.resize(i);rep(ii,i)a[ii].resize(j);reprep(ii,jj,i,j){dp[ii][jj].resize(k)};
#define res resize
#define as assign
#define ffor for(;;)
#define ppri(a,b) std::cout << a<<" "<<b << std::endl
#define pppri(a,b,c) std::cout << a<<" "<<b <<" "<< c<<std::endl
#define ppppri(a,b,c,d) std::cout << a<<" "<<b <<" "<< c<<' '<<d<<std::endl
#define aall(x,n) (x).begin(),(x).begin()+(n)
#define SUM(a) accumulate(all(a),0ll) 
#define stirng string
#define gin(a,b) int a,b;std::cin >> a>>b;a--;b--;
#define popcount __builtin_popcount
#define permu(a) next_permutation(all(a))
#define aru(a,d) a.find(d)!=a.end()

//#define grid_input(a,type) int h,w;std::cin >> h>>w;vvector(a,type,h,w,0);reprep(i,j,h,w)std::cin >> a[i][j];

//typedef long long T;
ll ceili(ll a,ll b){
    return ((a+b-1)/b);
}
const int INF = 2'000'000'000;
const ll INF64 =32233720854775807ll;
//const ll INF64 = 9223372036854775807ll;

//const ll INF64 = 243'000'000'000'000'000'0;


//const ll MOD = 100'000'000'7ll;
const ll MOD = 998244353ll;
//const ll MOD = 1000003ll;
const ll OD = 1000000000000007ll;
const dou pi=3.141592653589793;

long long modpow(long long a, long long n) { //累乗の剰余
    long long res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % MOD;
        a = a * a % MOD;
        n >>= 1;
    }
    return res;
}

//メモ
//ゲーム(Grundy数とか)の復習をする
//リスニング力をどうにかする
//モノイドをやる！！！！
//特に理由がなければllを使おうキャンペーン
//個数制限付きナップサックの復習
//戻すDP
//周期性の解析結果の考察をする
//いい加減英語スライドを作り始める
//改良モデルを深堀りすると良さそう
//被服調査票を提出する
//PGバトル 10/24 13:00~
//学科棟まで書類を受け取りに行く
//全方位木DPとスライド最小値
//やること困ったらSRM 500番台やるといいかも


int h,w;
bool hani(int i,int j){//grid上探索において範囲内かどうかをreturn
    if(i>=0&&i<h&&j>=0&&j<w)return true;
    else return false;
}

std::vector<int> d{-1,0,1,0,-1};
int main(){
    ffor{
        std::cin >> w>>h;
        if(w==0)break;
        vvector(a,char,h,w,0);
        reprep(i,j,h,w)std::cin >> a[i][j];
        reprep(i,j,h,w){
            if(a[i][j]=='.'){
                queue<P>q;
                q.push(P(i,j));
                bool ww=0,b=0;
                while(!q.empty()){
                    P p=q.front();
                    a[p.fi][p.se]='0';
                    q.pop();
                    rep(ii,4){
                        int y=p.fi+d[ii];
                        int x=p.se+d[ii+1];
                        if(!hani(y,x))continue;
                        if(a[y][x]=='.'){
                            q.push(P(y,x));
                            a[y][x]='0';
                        }
                        if(a[y][x]=='W'){
                            ww=1;
                        }
                        if(a[y][x]=='B'){
                            b=1;
                        }
                    }
                    
                }
               
                if(ww||b){
                    if(!(ww&&b)){
                        char c;
                        if(ww)c='w';
                        else c='b';
                       reprep(ii,jj,h,w)if(a[ii][jj]=='0')a[ii][jj]=c;
                    }
                }
                reprep(ii,jj,h,w)if(a[ii][jj]=='0')a[ii][jj]='1';
                
                
            }
        }
        int ww=0,b=0;
       // ppri(h,w);
        reprep(i,j,h,w){
            if(a[i][j]=='w')ww++;
            if(a[i][j]=='b')b++;
        }
        
        //std::cout  << std::endl;
        ppri(b,ww);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3156
final_rank: 1

code_snippet: #include <bits/stdc++.h>
struct __fastio__ { __fastio__ () { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); } } __fast_io__;
template<class T, class U> bool chmin (T &a, const U &b) { if (a > b) { a = b; return 1; } return 0; }
template<class T, class U> bool chmax (T &a, const U &b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> void print (const T &value) { std::cout << value << '\n'; }
template<class T, class... Args> void print (const T &value, const Args& ...args) { std::cout << value << ' '; print(args...); }
template<class T> void input (T &x) { std::cin >> x; }
template<class T> void input (std::vector<T> &v) { for (T &e : v) input(e); }
template<class T, class... Args> void input (T &x, Args&... args) { input(x); input(args...); }
template<class T> bool zero (const T &x) { return (x == (T)0); }
template<class T, class... Args> bool zero (const T &x, const Args& ...args) { return (x == 0 and zero(args...)); }
template<class T> using matrix = std::vector<std::vector<T>>;
using i32 = std::int_fast32_t;
using u32 = std::uint_fast32_t;
using i64 = std::int_fast64_t;
using u64 = std::uint_fast64_t;
using isize = std::ptrdiff_t;
using usize = std::size_t;

const std::pair<isize, isize> delta[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

void solve (isize w, isize h) {
	std::vector<std::string> s(h);
	for (auto &e : s) std::cin >> e;
	
	auto inside = [&] (isize i, isize j) {
		return (0 <= i and i < h and 0 <= j and j < w);
	};
	auto bfs = [&] (isize si, isize sj) -> i32 {
		std::queue<std::pair<isize, isize>> que({{si, sj}});
		std::vector<std::vector<bool>> seen(h, std::vector<bool>(w, false));
		bool black = false, white = false;
		while (not que.empty()) {
			auto [x, y] = que.front(); que.pop();
			if (seen[x][y]) continue;
			seen[x][y] = true;
			for (auto [dx, dy] : delta) {
				isize i = x + dx, j = y + dy;
				if (not inside(i, j) or seen[i][j]) continue;
				if (s[i][j] == '.') que.emplace(i, j);
				if (s[i][j] == 'B') black = true;
				if (s[i][j] == 'W') white = true;
			}
		}
		if (black and white) return 0;
		if (black) return 1;
		if (white) return 2;
		return 3;
	};
	
	usize black = 0, white = 0;
	for (isize i = 0; i < h; i++) for (isize j = 0; j < w; j++) {
		if (s[i][j] == '.') {
			i32 type = bfs(i, j);
			if (type == 1) black++;
			if (type == 2) white++;
		}
	}
	
	std::cout << black << ' ' << white << '\n';
	return;
}

int main() {
	while (true) {
		isize w, h;
		std::cin >> w >> h;
		if (w == 0 and h == 0) break;
		else solve(w, h);
	}
	return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 3416
final_rank: 15

code_snippet: #include<iostream>
#include<fstream>
#include<bitset>
#include<string>
#include<vector>
#include<list>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<iomanip>
#include<queue>
#include<stack>
#include<numeric>
#include<utility>
#include<regex>
#include<climits>
#include<ctime>
#include<functional>

void Init() {
	std::cin.tie(0); std::ios::sync_with_stdio(false);
	struct Init_caller { Init_caller() { Init(); } }caller;
}

using namespace std;

#define int long long
#define rep(i,n) for(LL i=0;i<(n);i++)
#define rep1(i,n) for(LL i=1;i<(n);i++)
#define rrep(i,n) for(LL i=(n)-1;i>=0;i--)
#define all(a) (a).begin(),(a).end()
#define check() cout<<"! ! !"<<endl
#define endl "\n"
#define _y() cout<<"Yes"<<endl
#define _Y() cout<<"YES"<<endl
#define _n() cout<<"No"<<endl
#define _N() cout<<"NO"<<endl


constexpr long double PI = 3.141592653589793238;
constexpr long long INF = (long long)1e15;
constexpr long long MOD = 1e9 + 7;


using LL = long long;
using st = string;
template<typename T>using vec = vector<T>;
template<typename T>using vvec = vec<vec<T>>;
template<typename T>using vvvec = vec<vvec<T>>;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vd = vector<double>;
using vvd = vector<vd>;
using vvvd = vector<vvd>;
using vc = vector<char>;
using vvc = vector<vc>;
using vs = vector<st>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
using pi = pair<int, int>;
using ppi = pair<pi, int>;
using vpi = vector<pi>;
using vppi = vector<ppi>;
using mii = map<int, int>;
using mpii = map<pi, int>;
using mib = map<int, bool>;
using mci = map<char, int>;
template<typename T>using pq_greater = priority_queue<T>;
template<typename T>using pq_smaller = priority_queue<T, vec<T>, greater<T>>;

//0,1,2
//3,4,5
//6,7,8
int dx4[] = { 0, -1,1,0 };
int dy4[] = { -1,0,0,1 };
int dx9[] = { -1,0,1,-1,0,1,-1,0,1 };
int dy9[] = { -1,-1,-1,0,0,0,1,1,1 };

template<typename T>
istream &operator>>(istream &in, vector<T> &v) {
	rep(i, v.size()) {
		in >> v[i];
	}
	return in;
}

template<typename T, typename U>
istream &operator>>(istream&in, pair<T, U> &p) {

	in >> p.first >> p.second;
	return in;
}

template<typename T>
ostream &operator<<(ostream &out, vector<T> &v) {
	out << "{ ";
	rep(i, v.size()) {
		out << v[i] << " ";
	}
	out << " }";
	return out;
}

template<typename T, typename U>
ostream &operator<<(ostream&out, pair<T, U> &p) {

	out << "(" << p.first << "," << p.second << ")" << endl;
	return out;
}

struct mint {
	int x;
	mint(int x = 0) :x((x%MOD + MOD) % MOD) {}

	mint operator-() const { return mint(-x); }
	mint& operator+=(const mint a) {
		if ((x += a.x) >= MOD) x -= MOD;
		return *this;
	}
	mint& operator-=(const mint a) {
		if ((x += MOD - a.x) >= MOD) x -= MOD;
		return *this;
	}
	mint& operator*=(const mint a) {
		(x *= a.x) %= MOD;
		return *this;
	}
	mint operator+(const mint a) const {
		mint res(*this);
		return res += a;
	}
	mint operator-(const mint a) const {
		mint res(*this);
		return res -= a;
	}
	mint operator*(const mint a) const {
		mint res(*this);
		return res *= a;
	}
	mint pow(int t) const {
		if (!t) return 1;
		mint a = pow(t >> 1);
		a *= a;
		if (t & 1) a *= *this;
		return a;
	}

	mint inv() const {
		return pow(MOD - 2);
	}
	mint& operator/=(const mint a) {
		return (*this) *= a.inv();
	}
	mint operator/(const mint a) const {
		mint res(*this);
		return res /= a;
	}

	friend ostream& operator<<(ostream& out, const mint& m) {
		out << m.x;
		return out;
	}

};

void y_n(bool p) {
	p ? _y() : _n();
}

void Y_N(bool p) {
	p ? _Y() : _N();
}

//MAX,maxpos,MIN,minpos
template<typename T>
pair<pair<T, int>, pair<T, int>> vmaxmin(vector<T> v) {
	int MAX = -INF;
	int MIN = INF;
	int maxpos = 0;
	int minpos = 0;
	rep(i, v.size()) {
		if (MAX < v[i]) {
			maxpos = i;
			MAX = v[i];
		}
		if (MIN > v[i]) {
			minpos = i;
			MIN = v[i];
		}
	}
	return { {MAX,maxpos},{MIN,minpos} };
}

template<typename T>
T vsum(vector<T> v) {
	T sum = 0;
	rep(i, v.size()) {
		sum += v[i];
	}
	return sum;
}

int gcd(int a, int b) {
	if (b == 0) {
		swap(a, b);
	}
	int r;
	while ((r = a % b) != 0) {
		a = b;
		b = r;
	}
	return b;
}

int lcm(int a, int b) {
	return (a / gcd(a, b) * b);
}

bool is_square(int n) {
	if ((int)sqrt(n)*(int)sqrt(n) == n) {
		return true;
	}
	else {
		return false;
	}
}


bool is_prime(int n) {
	if (n <= 1) {
		return false;
	}
	else {
		for (int i = 2; i*i <= n; i++) {
			if (n % i == 0) {
				return false;
			}
		}
	}
	return true;
}

void dec_num(int n, vi &v) {
	int a = 2;
	v.push_back(1);
	v.push_back(n);
	while (a*a <= n) {
		if (n%a == 0) {
			v.push_back(a);
			v.push_back(n / a);
		}
		a++;
	}
	sort(all(v));
	v.erase(unique(all(v)), v.end());
}


void dec_prime(int n, vi &v) {
	//v.push_back(1);
	int a = 2;
	while (a*a <= n) {
		if (n % a == 0) {
			v.push_back(a);
			n /= a;
		}
		else {
			a++;
		}
	}
	v.push_back(n);
}

//n= ...*pow(p_i,m[p_i])*...
void dec_prime_e(int n, map<int, int> &m) {
	for (int i = 2; i*i <= n; i++) {
		if (n%i == 0) {
			int e = 0;
			while (n%i == 0) {
				e++;
				n /= i;
			}
			m[i] += e;
		}
	}
	if (n != 1) m[n]++;
}


int sieve_prime(int a, int b) {
	if (a > b)swap(a, b);
	vb s(b + 1, true);
	int cnt_a = 0, cnt_b = 0;
	for (int i = 2; i <= b; i++) {
		for (int j = 2; i*j <= b; j++) {
			s[i*j] = false;
		}
	}
	//return s;
	for (int i = 2; i <= b; i++) {
		if (s[i]) {
			//cout << i << " ";
			if (i < a) {
				cnt_a++;
			}
			cnt_b++;
		}
	}
	return cnt_b - cnt_a;

}


int factorial(int n) {
	int a = 1, ret = 1;
	while (a < n) {
		a++;
		ret *= a;
		//ret %= MOD;
	}
	return ret;
}

int bit_count(int n) {
	int k = (int)log2(n) + 1;
	int ret = 0;
	rep(i, k) {
		if (n&(1LL << i))ret++;
	}
	return ret;
}

//a^(a+1)^(a+2)^...^b
int XOR(int a, int b) {
	if (a == 0) {
		switch (b % 4) {
		case 0:	return b;
		case 1:	return 1;
		case 2:	return (b + 1);
		case 3:	return 0;
		}
	}
	int A = XOR(0, a - 1);
	int B = XOR(0, b);
	return (A ^ B);
}


const int COMBMAX = 4000;
int comb[COMBMAX + 5][COMBMAX + 5];

void init_comb() {
	comb[0][0] = 1;
	rep(i, COMBMAX) {
		rep(j, i + 1) {
			comb[i + 1][j] += comb[i][j];
			//comb[i + 1][j] %= MOD;
			comb[i + 1][j + 1] += comb[i][j];
			//comb[i + 1][j + 1] %= MOD;
		}
	}
}

int combination(int n, int k) {
	if (k<0 || k>n)return 0;
	else return comb[n][k];
}


const int COMBMODMAX = 5000000;
int fac[COMBMODMAX + 5], facinv[COMBMODMAX + 5], inv[COMBMODMAX + 5];

void init_comb_mod() {
	fac[0] = fac[1] = 1;
	facinv[0] = facinv[1] = 1;
	inv[1] = 1;
	for (int i = 2; i < COMBMODMAX; i++) {
		fac[i] = fac[i - 1] * i%MOD;
		inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD;
		facinv[i] = facinv[i - 1] * inv[i] % MOD;
	}
}

//nCk (mod p)
//nHk = n+k-1Ck
int comb_mod(int n, int k) {
	if (n < k)return 0;
	if (n < 0 || k < 0)return 0;
	return fac[n] * (facinv[k] * facinv[n - k] % MOD) % MOD;
}

//x^n (mod p)
int pow_mod(int x, int n, int p) {
	if (n == 0)return 1;
	int res = pow_mod(x*x%p, n / 2, p);
	if (n % 2 == 1)res = res * x % p;
	return res;
}

struct _p {
	int x, y;

};

struct _t{
	int x, y, z;

};

struct edge {
	int to;
	int cost;
};


using ve = vector<edge>;
using vve = vector<ve>;


/*****************************************************************************/

signed main() {

	int w,h;
	while (cin >> w >> h, w || h) {

		vvc f(h, vc(w));
		
		cin >> f;

		vvi B(h, vi(w, 0));
		vvi W(h, vi(w, 0));
		rep(i, h) {
			rep(j, w) {
				if (f[i][j] != '.') {
					queue<_t>q;
					q.push({ j,i,f[i][j] == 'B' ? 1 : 0 });
					vvb visited(h, (vb(w, false)));
					visited[i][j] = true;
					while (!q.empty()) {
						_t t = q.front();
						q.pop();
						rep(k, 4) {
							int nx = t.x + dx4[k], ny = t.y + dy4[k];
							if (nx < 0 || nx >= w || ny < 0 || ny >= h || visited[ny][nx] || f[ny][nx]!='.')continue;
							visited[ny][nx] = true;
							q.push({ nx,ny,t.z });
							if (t.z == 1) {
								B[ny][nx] = 1;
							}
							else {
								W[ny][nx] = 1;
							}
						}
					}
				}
			}
		}
		//cout << B << endl << W;
		int a = 0, b = 0;
		rep(i, h) {
			rep(j, w) {
				if (B[i][j] && !W[i][j])a++;
				if (!B[i][j] && W[i][j])b++;
			}
		}
		cout << a << " " << b << endl;
	}
}
accuracy: 1
time_ms: 210
memory_kb: 3156
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define rep(i,n) for(int i=0; i<(int)(n); i++)
using P = pair<int, int>;

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

int calc(const vector<vector<char>> &grid, int sy, int sx)
{
    if(grid[sy][sx] != '.') return 0;
    int h = grid.size(), w = grid[0].size();
    vector<vector<int>> checked(h, vector<int>(w, 0));

    bool br = false, wh = false;
    queue<P> que;
    que.push(P(sy, sx));
    checked[sy][sx] = 1;
    while(!que.empty() && (!br || !wh))
    {
        auto p = que.front();
        que.pop();
        int y = p.first, x = p.second;
        rep(i,4)
        {
            int ny = y+dy[i], nx = x+dx[i];
            if(ny < 0 || nx < 0 || ny >= h || nx >= w) continue;
            if(checked[ny][nx]) continue;
            checked[ny][nx] = 1;
            if(grid[ny][nx] == '.')
            {
                que.push(P(ny, nx));
            }
            else if(grid[ny][nx] == 'B')
            {
                br = true;
            }
            else if(grid[ny][nx] == 'W')
            {
                wh = true;
            }
        }
    }
    if(br == wh) return 0;
    else if(br) return 1;
    else if(wh) return 2;
}

int solve()
{
    int w, h;
    cin >> w >> h;
    if(w == 0) return 0;
    vector<vector<char>> grid(h, vector<char>(w));
    rep(i,h) rep(j,w) cin >> grid[i][j];
    int br = 0, wh = 0;
    rep(i,h)
    {
        rep(j,w)
        {
            int f = calc(grid, i, j);
            if(f == 1) br++;
            if(f == 2) wh++;
        }
    }
    cout << br << " " << wh << endl;

    return 1;
}

int main()
{
    while(solve());
    return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 3060
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define rep(i,n) for(int i=0; i<(int)(n); i++)
using P = pair<int, int>;

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

int calc(const vector<vector<char>> &grid, int sy, int sx)
{
    if(grid[sy][sx] != '.') return 0;
    int h = grid.size(), w = grid[0].size();
    vector<vector<int>> checked(h, vector<int>(w, 0));

    bool br = false, wh = false;
    queue<P> que;
    que.push(P(sy, sx));
    checked[sy][sx] = 1;
    while(!que.empty())
    {
        auto p = que.front();
        que.pop();
        int y = p.first, x = p.second;
        rep(i,4)
        {
            int ny = y+dy[i], nx = x+dx[i];
            if(ny < 0 || nx < 0 || ny >= h || nx >= w) continue;
            if(checked[ny][nx]) continue;
            checked[ny][nx] = 1;
            if(grid[ny][nx] == '.')
            {
                que.push(P(ny, nx));
            }
            else if(grid[ny][nx] == 'B')
            {
                br = true;
            }
            else if(grid[ny][nx] == 'W')
            {
                wh = true;
            }
        }
    }
    if(br == wh) return 0;
    else if(br) return 1;
    else if(wh) return 2;
}

int solve()
{
    int w, h;
    cin >> w >> h;
    if(w == 0) return 0;
    vector<vector<char>> grid(h, vector<char>(w));
    rep(i,h) rep(j,w) cin >> grid[i][j];
    int br = 0, wh = 0;
    rep(i,h)
    {
        rep(j,w)
        {
            int f = calc(grid, i, j);
            if(f == 1) br++;
            if(f == 2) wh++;
        }
    }
    cout << br << " " << wh << endl;

    return 1;
}

int main()
{
    while(solve());
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 3112
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
// #define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) {
            os << ',';
        }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

struct Setup {
    Setup() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
    }
} __Setup;

using ll = long long;
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
constexpr int MOD = 1000000007;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

//-------------------------------------

bool aoj = true;

void solve() {
    int w, h;
    cin >> w >> h;
    if(w == 0) {
        aoj = false;
        return;
    }
    vector<string> G(h);
    for(int i = 0; i < h; i++) {
        cin >> G[i];
    }

    vector black(h, vector(w, false));
    vector white(h, vector(w, false));

    auto bfs = [&](int si, int sj, vector<vector<bool>> &used) {
        queue<pair<int, int>> que;
        if(used[si][sj]) {
            return;
        }
        que.emplace(si, sj);
        while(que.size()) {
            auto [nowi, nowj] = que.front();
            que.pop();
            used[nowi][nowj] = true;

            for(int r = 0; r < 4; r++) {
                int nxti = nowi + dy[r];
                int nxtj = nowj + dx[r];
                if(0 <= nxti && nxti < h && 0 <= nxtj && nxtj < w) {
                    if(G[nxti][nxtj] == '.' && !used[nxti][nxtj]) {
                        que.emplace(nxti, nxtj);
                    }
                }
            }
        }
    };

    for(int i = 0; i < h; i++) {
        for(int j = 0; j < w; j++) {
            if(G[i][j] == 'B') {
                bfs(i, j, black);
            } else if(G[i][j] == 'W') {
                bfs(i, j, white);
            }
        }
    }

    int ans[2] = {0, 0};
    for(int i = 0; i < h; i++) {
        for(int j = 0; j < w; j++) {
            if(black[i][j] && !white[i][j]) {
                ans[0]++;
            } else if(!black[i][j] && white[i][j]) {
                ans[1]++;
            }
            if(G[i][j] == 'B') {
                ans[0]--;
            } else if(G[i][j] == 'W') {
                ans[1]--;
            }
        }
    }
    cout << ans[0] << " " << ans[1] << endl;
}

int main() {
    while(aoj) {
        solve();
    }
}
accuracy: 1
time_ms: 910
memory_kb: 55868
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
#define REP(i, n) for(int (i)=0; (i)< (n); ++i)
#define REPR(i, n) for(int (i)=(n); (i)>=0; --i)
#define FOR(i, n, m) for(int (i)=(n); (i)<(m); ++i)
constexpr int INF = 1e9;
//constexpr ll INF = 1LL << 61;
constexpr int mod = 1e9+7;

int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
void solve(int w, int h){
    vector<string> a(h);
    REP(i, h){
        cin >> a[i];
    }
    int black =0, white=0;
    auto check = [&](int sy, int sx){
        queue<pair<int, int>> que;
        vector<vector<bool>> homon(h, vector<bool>(w, false));    
        que.push({sy, sx});
        homon[sy][sx] = true;
        int res = -1;
        while(!que.empty()){
            auto [y, x] = que.front(); que.pop();
            REP(i, 4){
                int ny = y + dy[i], nx = x + dx[i];
                if(ny < 0 || h <= ny || nx < 0 || w <= nx) continue;
                if(homon[ny][nx]) continue;
                if(res == -1 && a[ny][nx] == 'B'){
                    res = 1;
                }
                else if(res==-1 && a[ny][nx] == 'W'){
                    res =2;
                }
                else if((res == 1 && a[ny][nx] == 'W') || (res == 2 && a[ny][nx] == 'B')){
                    res = 0;
                    return res;
                }
                if(a[ny][nx] == '.'){
                    que.push({ny, nx});
                    homon[ny][nx] = true;
                }
            }
        }
        return res;
    };
    REP(cy, h){
        REP(cx, w){
            if(a[cy][cx] != '.') continue;
            int res = check(cy, cx);
            if(res ==1){
                black++;
            }
            else if(res == 2){
                white++;
            }
        }
    }
    cout << black << " " << white << endl;
}

int main(){
  while(true){
      int w, h;
      cin >> w >> h;
      if(w==0 && h==0){
          break;
      }
      solve(w, h);
  }

  return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 3268
final_rank: 12