
#include<cstdio>

//マップの最大値
#define MAP_MAX		100

//マップの文字列
char wh_map[MAP_MAX][MAP_MAX + 1];



//----- 再帰関数 -----//
void f_saiki(int , int , int , int , char);

//----- 答えを返す関数 -----//
int f_ans(int , int);

//----- 初期化関数 -----//
void f_syokika(int);




//*****----- main -----*****//

int main(void)
{
	//縦のマップと横のマップ
	int tate = 0 , yoko = 0;
	//答えを格納する変数
	int ans = 0;
	
	//縦と横を入力
	while (1)
	{
		scanf("%d%d" , &tate , &yoko);
		if (tate == 0 && yoko == 0)
		{
			return 0;
		}

		//マップを入力
		f_syokika(tate);

		//関数で処理
		ans = f_ans(tate , yoko);
		printf("%d\n" , ans);
	}
}



//*****----- 再帰関数 -----*****//

void f_saiki(int x , int y , int tate , int yoko , char tansakumozi)
{
	//まず現在座標をNULLとする
	wh_map[y][x] = NULL;

	//4方向を実現する配列
	int h_tate[4] = {1 , -1 , 0 , 0};
	int h_yoko[4] = {0 , 0 , 1 , -1};

	for (int i = 0; i < 4; i++)
	{
		//次座標
		int nextx = x + h_yoko[i];
		int nexty = y + h_tate[i];

		//４方向の座標で、行ける且つ文字が同じところを探す
		if (nexty >= 0 && nexty < tate && nextx >= 0 && nextx < yoko)
		{
			//同じ文字が続く
			if (wh_map[nexty][nextx] == tansakumozi)
			{
				f_saiki(nextx , nexty , tate , yoko , tansakumozi);
			}
		}
	}
}



//*****----- 答えを返す関数 -----*****//

int f_ans(int tate , int yoko)
{
	//答えを返す変数
	int ans = 0;

	for (int i = 0; i < tate; i++)
	{
		for (int j = 0; j < yoko; j++)
		{
			//まだ探索していない
			if (wh_map[i][j] != NULL)
			{
				ans++;
				//再帰関数で同じ文字を消す
				f_saiki(j , i , tate , yoko , wh_map[i][j]);
			}
		}
	}

	return ans;
}




//*****----- 初期化関数 -----*****//

void f_syokika(int tate)
{
	for (int i = 0; i < tate; i++)
	{
		scanf("%s" , wh_map[i]);
	}
}