#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
namespace boost {template <class T>struct integer_iterator {T a;bool operator != (integer_iterator const & it) const { return a != it.a; }T operator * () const { return a; }integer_iterator & operator ++ () { ++ a; return *this; }integer_iterator operator ++ (int) { return { a ++ }; }};template <class T>struct integer_range {T l, r;typedef integer_iterator<T> iterator;iterator begin() const { return { l }; }iterator end  () const { return { r }; }};template <class T>integer_range<T> irange(T l, T r) { assert (l <= r); return { l, r }; }template <class T>struct integer_iterator_with_step {T a, d, i;bool operator != (integer_iterator_with_step const & it) const { return a != it.a or d != it.d or i != it.i; }T operator * () const { return a+d*i; }integer_iterator_with_step & operator ++ () { ++ i; return *this; }integer_iterator_with_step operator ++ (int) { return { a, d, i ++ }; }};template <class T>struct strided_integer_range {T l, r, s;typedef integer_iterator_with_step<T> iterator;iterator begin() const { return { l, s, 0 }; }iterator end  () const { return { l, s, (r - l) / s }; }};template <class T>strided_integer_range<T> irange(T l, T r, T s) { assert (s > 0 ? l <= r : s < 0 ? l >= r : false); return { l, r, s }; }}
typedef long long ll;
using namespace std;
using namespace boost;
bool on_board(int y, int x, int h, int w) {
    return 0 <= y and y < h and 0 <= x and x < w;
}
int dx[] = {  0, 0, 1, -1 };
int dy[] = { -1, 1, 0,  0 };
int grouping(int y, int x, int k, vector<vector<int> > & group, vector<vector<char> > const & a) {
    assert (a[y][x] == '.' and not group[y][x]);
    int h = a.size();
    int w = a.front().size();
    group[y][x] = k;
    int s = 1;
    for (int i : irange(0,4)) {
        int ny = y + dy[i];
        int nx = x + dx[i];
        if (not on_board(ny, nx, h, w)) continue;
        if (a[ny][nx] == '.' and not group[ny][nx]) {
            s += grouping(ny, nx, k, group, a);
        }
    }
    return s;
}
int main() {
    while (true) {
        int w, h; cin >> w >> h;
        if (w == 0 and h == 0) break;
        vector<vector<char> > a(h, vector<char>(w));
        for (int y : irange(0,h)) {
            for (int x : irange(0,w)) {
                cin >> a[y][x];
            }
        }
        vector<vector<int> > group(h, vector<int>(w));
        int group_num = 0;
        vector<int> group_size;
        group_size.push_back(-1); // dummy, to make 1-origin
        for (int y : irange(0,h)) {
            for (int x : irange(0,w)) {
                if (a[y][x] == '.' and not group[y][x]) {
                    group_num += 1;
                    int s = grouping(y, x, group_num, group, a);
                    group_size.push_back(s);
                }
            }
        }
        vector<pair<bool,bool> > connected(group_num + 1); // 0 is dummy, to make 1-origin
        for (int y : irange(0,h)) {
            for (int x : irange(0,w)) {
                int k = group[y][x];
                if (k) {
                    for (int i : irange(0,4)) {
                        int ny = y + dy[i];
                        int nx = x + dx[i];
                        if (not on_board(ny, nx, h, w)) continue;
                        if (a[ny][nx] == 'B') connected[k].first  = true;
                        if (a[ny][nx] == 'W') connected[k].second = true;
                    }
                }
            }
        }
        int black = 0, white = 0;
        for (int k : irange(1,group_num+1)) { // 1-origin
            if (connected[k].first and not connected[k].second) {
                black += group_size[k];
            } else if (not connected[k].first and connected[k].second) {
                white += group_size[k];
            }
        }
        cout << black << " " << white << endl;
    }
    return 0;
}

Measured memory_bytes: 1472