#define _CRT_SECURE_NO_WARNINGS
#include"bits/stdc++.h"
#ifdef _DEBUG
#define DBG(n) n
#else
#define DBG(n)
#endif
#define INF            1e9
#define INFLL          1e18
#define EPS            1e-9
#define REP(i,n)       for(ll i=0,i##_len=(n);i<i##_len;++i)
#define REP1(i,n)      for(ll i=1,i##_len=(n);i<=i##_len;++i)
#define REPR(i,n)      for(ll i=(n)-1;i>=0;--i)
#define REPR1(i,n)     for(ll i=(n);i>0;--i)
#define REPC(i,obj)    for(auto i:obj)
#define ALL(obj)       (obj).begin(),(obj).end()
#define SETP(n)        cout<<fixed<<setprecision(n)
#define VEC2(T,h,w)    move(vector<vector<T>>(h,vector<T>(w)))
#define VEC2I(T,h,w,i) move(vector<vector<T>>(h,vector<T>(w,i)))
using namespace std;
using ll = long long;
template<typename T, ll h, ll w>using vec2 = vector<vector<T>>;
template<typename T = ll>inline T in() { T ret; cin >> ret; return ret; }

class union_find {
private:
	vector<ll> par, sz, rank;
	ll cnt;
public:
	union_find(ll n) : par(n), sz(n), rank(n)
	{
		cnt = n;
		REP(i, n) {
			par[i] = i;
			sz[i] = 1;
			rank[i] = 0;
		}
	}
	ll find(ll x)
	{
		return par[x] == x ? x : par[x] = find(par[x]);
	}
	void unite(ll x, ll y)
	{
		x = find(x);
		y = find(y);
		if (x != y) {
			if (rank[x] < rank[y]) {
				par[x] = y;
				sz[y] += sz[x];
			} else {
				par[y] = x;
				sz[x] += sz[y];
				if (rank[x] == rank[y]) {
					rank[x]++;
				}
			}
			cnt--;
		}
	}
	bool same(ll x, ll y)
	{
		return find(x) == find(y);
	}
	ll size(ll n)
	{
		return sz[find(n)];
	}
	ll count()
	{
		return cnt;
	}
};
signed main()
{
	ll h, w;
	while (cin >> h >> w, h) {
		auto fr = VEC2(char, h, w);
		REP(i, h)REP(j, w)fr[i][j] = in<char>();
		union_find uf(h * w);
		REP1(i, h - 1)if (fr[i - 1][0] == fr[i][0])uf.unite((i - 1) * w, i * w);
		REP1(j, w - 1)if (fr[0][j] == fr[0][j - 1])uf.unite(j - 1, j);
		REP1(i, h - 1) {
			REP1(j, w - 1) {
				if (fr[i - 1][j] == fr[i][j]) uf.unite((i - 1) * w + j, i * w + j);
				if (fr[i][j - 1] == fr[i][j]) uf.unite(i * w + j, i * w + j - 1);
			}
		}
		cout << uf.count() << endl;
	}
}
