Mr. Tanaka died leaving the orchard of HW Earl. The orchard is divided into H x W plots in the north, south, east, and west directions, and apples, oysters, and oranges are planted in each plot. Mr. Tanaka left such a will.

Divide the orchard into as many relatives as possible on a parcel basis. However, if the same kind of fruit is planted in a plot that is located in either the north, south, east, or west direction of a plot, treat them as one large plot because the boundaries of the plot are unknown.

For example, in the following 3 × 10 section ('li' represents an apple,'ka' represents an oyster, and'mi' represents a mandarin orange)

<image>


Eliminating the boundaries between plots with the same tree gives:

<image>


In the end, it will be divided into 10 compartments, or 10 people.

The distribution must be completed before it snows and the boundaries of the plot disappear. Your job is to determine the number of plots to distribute based on the map of the orchard.

Create a program that reads the map of the orchard and outputs the number of relatives who can receive the distribution.



Input

Given multiple datasets. Each dataset is given a string of H lines consisting of the characters H x W, starting with a line containing H, W (H, W ≤ 100) separated by blanks. Only three characters appear in this string:'@' for apples,'#' for oysters, and'*' for oranges.

The input ends with two lines of zeros. The number of datasets does not exceed 20.

Output

For each dataset, output the number of people to be distributed on one line.

Examples

Input

10 10
####*****@
@#@@@@#*#*
@##***@@@*
#****#*@**
##@*#@@*##
*@@@@*@@@#
***#@*@##*
*@@@*@@##@
*@*#*@##**
@****#@@#@
0 0


Output

33


Input

10 10
*****@
@#@@@@#*#*
@##***@@@*
****#*@**
@*#@@*##
*@@@@*@@@#
***#@*@##*
*@@@*@@##@
*@*#*@##**
@****#@@#@
0 0


Output

33

Source: aizu | Difficulty: UNKNOWN_DIFFICULTY


Solutions:
import sys
sys.setrecursionlimit(100000)

def solve(x, y, char):
	for deltaX in [1, -1]:
		if 0 <= x + deltaX and x + deltaX < w and (matrix[y][x + deltaX] == char):
			matrix[y][x + deltaX] = '.'
			solve(x + deltaX, y, char)
	for deltaY in [1, -1]:
		if 0 <= y + deltaY and y + deltaY < h and (matrix[y + deltaY][x] == char):
			matrix[y + deltaY][x] = '.'
			solve(x, y + deltaY, char)
while True:
	line = sys.stdin.readline().rstrip()
	if line == '' or line == '0 0':
		break
	(h, w) = (int(i) for i in line.split())
	matrix = []
	count = 0
	for i in range(h):
		matrix.append(list(input().rstrip()))
	for (j, row) in enumerate(matrix):
		for (i, cell) in enumerate(row):
			char = matrix[j][i]
			if char != '.':
				matrix[j][i] = '.'
				count += 1
				solve(i, j, char)
	print(count)


import sys
sys.setrecursionlimit(1000000)

def dfs(x, y, fru):
	field[x][y] = '.'
	for dx in [-1, 0, 1]:
		nx = x + dx
		if 0 <= nx and nx < H and (field[nx][y] == fru):
			dfs(nx, y, fru)
	for dy in [-1, 0, 1]:
		ny = y + dy
		if 0 <= ny and ny < W and (field[x][ny] == fru):
			dfs(x, ny, fru)

def solv(H, W):
	count = 0
	for i in range(H):
		for j in range(W):
			if field[i][j] == '@':
				dfs(i, j, '@')
				count += 1
			elif field[i][j] == '#':
				dfs(i, j, '#')
				count += 1
			elif field[i][j] == '*':
				dfs(i, j, '*')
				count += 1
	print(count)
f = 0
while f == 0:
	(H, W) = map(int, input().split())
	if H != 0 and W != 0:
		field = []
		for i in range(H):
			field.append(list(input()))
		solv(H, W)
	else:
		f = 1


class UnionSet:

	def __init__(self, nmax):
		self.size = [1] * nmax
		self.id = [i for i in range(nmax + 1)]

	def root(self, i):
		while i != self.id[i]:
			self.id[i] = self.id[self.id[i]]
			i = self.id[i]
		return i

	def connected(self, p, q):
		return self.root(p) == self.root(q)

	def unite(self, p, q):
		(i, j) = (self.root(p), self.root(q))
		if i == j:
			return
		if self.size[i] < self.size[j]:
			self.id[i] = j
			self.size[j] += self.size[i]
		else:
			self.id[j] = i
			self.size[i] += self.size[j]
while 1:
	(H, W) = map(int, input().split())
	if H == 0 and W == 0:
		break
	tbl = [''] * H
	for r in range(H):
		tbl[r] = input()
	u = UnionSet(H * W)
	rr = 0
	for r in range(H):
		for c in range(W):
			if c + 1 < W and tbl[r][c] == tbl[r][c + 1]:
				u.unite(rr + c, rr + c + 1)
			if r + 1 < H and tbl[r][c] == tbl[r + 1][c]:
				u.unite(rr + c, rr + W + c)
		rr += W
	ans = 0
	for k in range(H * W):
		if u.root(k) == k:
			ans += 1
	print(ans)


import sys

def dfs(x, y, sym):
	tile[x][y] = '.'
	for i in range(len(DX)):
		nx = x + DX[i]
		ny = y + DY[i]
		if 0 <= nx and nx < N and (0 <= ny) and (ny < M) and (tile[nx][ny] is sym):
			dfs(nx, ny, sym)

def solve():
	res = 0
	for i in range(N):
		for j in range(M):
			sym = tile[i][j]
			if tile[i][j] != '.':
				if tile[i][j] is sym:
					dfs(i, j, sym)
					res += 1
	print(res)
counter = 0
DX = [-1, 0, 1, 0]
DY = [0, -1, 0, 1]
sys.setrecursionlimit(10 ** 7)
while True:
	line = input()
	if ' ' in line:
		nums = line.split(' ')
		N = int(nums[0])
		M = int(nums[1])
		tile = [[0 for i in range(M)] for j in range(N)]
	else:
		tile[counter - 1] = list(line)
	if N is 0 and M is 0:
		break
	counter += 1
	if counter - 1 is N:
		solve()
		counter = 0


import sys
sys.setrecursionlimit(10 ** 6)

def search(values, hp, vp, item):
	if not 0 <= hp < len(values):
		return
	if not 0 <= vp < len(values[hp]):
		return
	if item != values[hp][vp]:
		return
	values[hp][vp] = True
	search(values, hp - 1, vp, item)
	search(values, hp + 1, vp, item)
	search(values, hp, vp - 1, item)
	search(values, hp, vp + 1, item)

def solve(values):
	(count, valid_items) = (0, set(['@', '#', '*']))
	for i in range(len(values)):
		for j in range(len(values[i])):
			if values[i][j] in valid_items:
				search(values, i, j, values[i][j])
				count += 1
	return count

def main():
	(line, values) = (input().strip(), list())
	while line != '0 0':
		(H, W) = list(map(int, line.split(' ')))
		value = list()
		for _ in range(H):
			value.append(list((x for x in input().strip())))
		print(solve(value))
		line = input().strip()
main()


import sys

def solve():
	person = 0
	for i in range(0, H):
		for j in range(0, W):
			if geo[i][j] is not '_':
				temp = geo[i][j]
				search(i, j, temp)
				person += 1
	print(person)

def search(i, j, temp):
	geo[i][j] = '_'
	for a in range(0, 4):
		(idx, jdy) = (i + dx[a], j + dy[a])
		if isOnMap(idx, jdy):
			if isNeededToSolve(temp, idx, jdy):
				search(idx, jdy, temp)

def isOnMap(i, j):
	return 0 <= i and 0 <= j and (i < H) and (j < W)

def isNeededToSolve(temp, i, j):
	target = geo[i][j]
	return target is not '_' and temp is target
limit = 10 ** 7
sys.setrecursionlimit(limit)
(H, W, tempH) = (-1, -1, 0)
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]
geo = [[0 for i in range(1)] for j in range(1)]
while True:
	line = input()
	if H is -1 and W is -1:
		p = line.split(' ')
		(H, W) = (int(p[0]), int(p[1]))
		geo = [[0 for i in range(W)] for j in range(H)]
	else:
		geo[tempH] = list(line)
		tempH += 1
	if H is 0 and W is 0:
		break
	if tempH is H:
		solve()
		(H, W, tempH) = (-1, -1, 0)


import sys

def solve(data):
	size = len(data[0])
	data.insert(0, ['0' for _ in range(size)])
	data.insert(len(data), ['0' for _ in range(size)])
	processing_area = []
	area_id = 0
	for y in range(1, len(data)):
		for x in range(1, len(data[0])):
			mark = data[y][x]
			data[y][x] = '0'
			if mark != '0':
				area_id += 1
				processing_area.append((y, x))
				while processing_area:
					(yy, xx) = processing_area.pop()
					if data[yy - 1][xx] == mark:
						data[yy - 1][xx] = '0'
						processing_area.append((yy - 1, xx))
					if data[yy + 1][xx] == mark:
						data[yy + 1][xx] = '0'
						processing_area.append((yy + 1, xx))
					if data[yy][xx - 1] == mark:
						data[yy][xx - 1] = '0'
						processing_area.append((yy, xx - 1))
					if data[yy][xx + 1] == mark:
						data[yy][xx + 1] = '0'
						processing_area.append((yy, xx + 1))
				mark = '0'
	return area_id

def main(args):
	while True:
		(h, w) = [int(x) for x in input().split(' ')]
		if h == 0 and w == 0:
			break
		data = []
		for _ in range(h):
			temp = list(input())
			temp.insert(0, '0')
			temp.append('0')
			data.append(temp)
		result = solve(data)
		print(result)
main(sys.argv[1:])


import sys
sys.setrecursionlimit(1000000)

def dfs(x, y, fru):
	field[x][y] = '.'
	for dx in [-1, 0, 1]:
		nx = x + dx
		if 0 <= nx and nx < H and (field[nx][y] == fru):
			dfs(nx, y, fru)
	for dy in [-1, 0, 1]:
		ny = y + dy
		if 0 <= ny and ny < W and (field[x][ny] == fru):
			dfs(x, ny, fru)

def solv(H, W):
	count = 0
	for i in range(H):
		for j in range(W):
			if field[i][j] == '@':
				dfs(i, j, '@')
				count += 1
			elif field[i][j] == '#':
				dfs(i, j, '#')
				count += 1
			elif field[i][j] == '*':
				dfs(i, j, '*')
				count += 1
	print(count)
f = 0
while f == 0:
	(H, W) = map(int, input().split())
	if H != 0 and W != 0:
		field = []
		for i in range(H):
			field.append(list(input()))
		solv(H, W)
	else:
		f = 1


import sys

def solve(data):
	size = len(data[0])
	data.insert(0, ['0' for _ in range(size)])
	data.insert(len(data), ['0' for _ in range(size)])
	processing_area = []
	area_id = 0
	for y in range(1, len(data) - 1):
		for x in range(1, len(data[0])):
			mark = data[y][x]
			data[y][x] = '0'
			if mark != '0':
				area_id += 1
				processing_area.append((y, x))
				while processing_area:
					(yy, xx) = processing_area.pop()
					if data[yy - 1][xx] == mark:
						data[yy - 1][xx] = '0'
						processing_area.append((yy - 1, xx))
					if data[yy + 1][xx] == mark:
						data[yy + 1][xx] = '0'
						processing_area.append((yy + 1, xx))
					if data[yy][xx - 1] == mark:
						data[yy][xx - 1] = '0'
						processing_area.append((yy, xx - 1))
					if data[yy][xx + 1] == mark:
						data[yy][xx + 1] = '0'
						processing_area.append((yy, xx + 1))
				mark = '0'
	return area_id

def main(args):
	while True:
		(h, w) = [int(x) for x in input().split(' ')]
		if h == 0 and w == 0:
			break
		data = []
		for _ in range(h):
			temp = list(input())
			temp.insert(0, '0')
			temp.append('0')
			data.append(temp)
		result = solve(data)
		print(result)
main(sys.argv[1:])


import sys
sys.setrecursionlimit(20000)

def search(table, visited, i, j, c):
	visited[i][j] = True
	if table[i + 1][j] == c and visited[i + 1][j] == False:
		search(table, visited, i + 1, j, c)
	if table[i - 1][j] == c and visited[i - 1][j] == False:
		search(table, visited, i - 1, j, c)
	if table[i][j + 1] == c and visited[i][j + 1] == False:
		search(table, visited, i, j + 1, c)
	if table[i][j - 1] == c and visited[i][j - 1] == False:
		search(table, visited, i, j - 1, c)
while True:
	(H, W) = [int(i) for i in input().split()]
	if H == 0 and W == 0:
		break
	visited = [[False for i in range(W + 2)] for j in range(H + 2)]
	table = [['.' for i in range(W + 2)] for j in range(H + 2)]
	for i in range(1, H + 1):
		s = input()
		for j in range(1, W + 1):
			table[i][j] = s[j - 1]
	ans = 0
	for i in range(1, H + 1):
		for j in range(1, W + 1):
			if visited[i][j] == False:
				ans += 1
				search(table, visited, i, j, table[i][j])
	print(ans)


import sys
sys.setrecursionlimit(100000)
while True:
	(h, w) = map(int, input().split())
	if not h:
		break
	mp = [list('X' + input() + 'X') for _ in range(h)]
	mp.insert(0, ['X'] * (w + 2))
	mp.append(['X'] * (w + 2))
	direct = ((0, 1), (0, -1), (1, 0), (-1, 0))

	def search(x, y, target):
		mp[y][x] = 'X'
		for (dx, dy) in direct:
			(nx, ny) = (x + dx, y + dy)
			if mp[ny][nx] == target:
				search(nx, ny, target)
	ans = 0
	for x in range(1, w + 1):
		for y in range(1, h + 1):
			target = mp[y][x]
			if target != 'X':
				search(x, y, target)
				ans += 1
	print(ans)


import queue
dr = [0, 0, 1, -1]
dc = [1, -1, 0, 0]
while True:
	a = [int(num) for num in input().split(' ')]
	if a[0] == 0:
		break
	s = []
	cnt = 0
	for i in range(a[0]):
		s.append(list(input()))
	q = queue.Queue()
	for i in range(a[0]):
		for j in range(a[1]):
			if s[i][j] == '.':
				continue
			f = s[i][j]
			q.put([i, j])
			while not q.empty():
				cor = q.get()
				for k in range(4):
					r = cor[0] + dr[k]
					c = cor[1] + dc[k]
					if 0 <= r < a[0] and 0 <= c < a[1] and (s[r][c] == f):
						s[r][c] = '.'
						q.put([r, c])
			cnt += 1
	print(cnt)


import sys
sys.setrecursionlimit(20000)
field = []
w = 0
h = 0

def main():
	global field, w, h
	while True:
		(h, w) = map(int, input().split())
		if h == 0 and w == 0:
			break
		count = 0
		field = []
		[field.append(list(input())) for _ in range(h)]
		for y in range(h):
			for x in range(w):
				if field[y][x] != -1:
					dfs(field[y][x], x, y)
					count += 1
		print(count)

def dfs(kind, x, y):
	global field
	field[y][x] = -1
	for (dx, dy) in zip([0, 0, -1, 1], [1, -1, 0, 0]):
		next_x = x + dx
		next_y = y + dy
		if next_x < 0 or next_y < 0 or next_x >= w or (next_y >= h) or (field[next_y][next_x] != kind):
			continue
		dfs(field[next_y][next_x], next_x, next_y)
main()


import sys
sys.setrecursionlimit(10 ** 6)

def search(values, hp, vp, item):
	if not 0 <= hp < len(values):
		return
	if not 0 <= vp < len(values[hp]):
		return
	if item != values[hp][vp]:
		return
	values[hp][vp] = True
	search(values, hp - 1, vp, item)
	search(values, hp + 1, vp, item)
	search(values, hp, vp - 1, item)
	search(values, hp, vp + 1, item)

def solve(values):
	(count, valid_items) = (0, set(['@', '#', '*']))
	for i in range(len(values)):
		for j in range(len(values[i])):
			if values[i][j] in valid_items:
				search(values, i, j, values[i][j])
				count += 1
	return count

def main():
	(line, values) = (input().strip(), list())
	while line != '0 0':
		(H, W) = list(map(int, line.split(' ')))
		value = list()
		for _ in range(H):
			value.append(list(input().strip()))
		print(solve(value))
		line = input().strip()
main()


def Labeling(terrain):
	label = terrain
	offset = [[-1, 0], [0, -1], [1, 0], [0, 1]]
	signs = ['@', '#', '*']
	step = 0
	for row in range(1, len(label) - 1):
		for col in range(1, len(label[row]) - 1):
			mark = label[row][col]
			if mark in signs:
				pointStack = [[row, col]]
				label[row][col] = step
				while 0 < len(pointStack):
					(rowIndex, colIndex) = pointStack.pop()
					for (x, y) in offset:
						(offsetRow, offsetCol) = (rowIndex + x, colIndex + y)
						if label[offsetRow][offsetCol] == mark:
							pointStack.append([offsetRow, offsetCol])
							label[offsetRow][offsetCol] = step
				step += 1
	return step
Sentinel = '1'
while True:
	(col, row) = [int(item) for item in input().split()]
	if row == 0 and col == 0:
		break
	land = []
	land.append([item for item in Sentinel * row + Sentinel * 2])
	for lp in range(col):
		part = [item for item in input()]
		land.append([])
		land[-1].extend([Sentinel])
		land[-1].extend(part)
		land[-1].extend([Sentinel])
	land.append([item for item in Sentinel * row + Sentinel * 2])
	result = Labeling(land)
	print(result)


import sys
sys.setrecursionlimit(10000000)

def search(values, hp, vp, item):
	if not 0 <= hp < len(values):
		return
	if not 0 <= vp < len(values[hp]):
		return
	if item != values[hp][vp]:
		return
	values[hp][vp] = True
	search(values, hp - 1, vp, item)
	search(values, hp + 1, vp, item)
	search(values, hp, vp - 1, item)
	search(values, hp, vp + 1, item)

def solve(values):
	(count, valid_items) = (0, set(['@', '#', '*']))
	for i in range(len(values)):
		for j in range(len(values[i])):
			if values[i][j] in valid_items:
				search(values, i, j, values[i][j])
				count += 1
	return count

def main():
	(line, values) = (input().strip(), list())
	while line != '0 0':
		(H, W) = list(map(int, line.split(' ')))
		value = list()
		for _ in range(H):
			value.append(list((x for x in input().strip())))
		values.append(value)
		line = input().strip()
	for value in values:
		print(solve(value))
main()


import sys

def setLine(tempH, line):
	for i in range(0, len(line)):
		geo[tempH][i] = line[i:i + 1]

def solve():
	person = 0
	for i in range(0, H):
		for j in range(0, W):
			if geo[i][j] is not '_':
				search(i, j)
				person += 1
	print(person)

def search(i, j):
	temp = geo[i][j]
	geo[i][j] = '_'
	for a in range(0, 4):
		(idx, jdy) = (i + dx[a], j + dy[a])
		if isOnMap(idx, jdy):
			if isNeededToSolve(temp, idx, jdy):
				search(idx, jdy)

def isOnMap(i, j):
	return 0 <= i and 0 <= j and (i < H) and (j < W)

def isNeededToSolve(temp, i, j):
	target = geo[i][j]
	return target is not '_' and temp is target
limit = 10 ** 7
sys.setrecursionlimit(limit)
(H, W, tempH) = (-1, -1, 0)
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]
geo = [[0 for i in range(1)] for j in range(1)]
while True:
	line = input()
	if H is -1 and W is -1:
		p = line.split(' ')
		(H, W) = (int(p[0]), int(p[1]))
		geo = [[0 for i in range(W)] for j in range(H)]
	else:
		setLine(tempH, line)
		tempH += 1
	if H is 0 and W is 0:
		break
	if tempH is H:
		solve()
		(H, W, tempH) = (-1, -1, 0)


import sys
sys.setrecursionlimit(20000)
h = 0
w = 0
list1 = []

def dfs(x, y, f):
	list1[y] = list1[y][:x] + '1' + list1[y][x + 1:]
	if y - 1 >= 0:
		if list1[y - 1][x] == f:
			dfs(x, y - 1, f)
	if y + 1 < h:
		if list1[y + 1][x] == f:
			dfs(x, y + 1, f)
	if x - 1 >= 0:
		if list1[y][x - 1] == f:
			dfs(x - 1, y, f)
	if x + 1 < w:
		if list1[y][x + 1] == f:
			dfs(x + 1, y, f)
	return
while True:
	(h, w) = list(map(lambda x: int(x), input().split(' ')))
	if 0 in (h, w):
		break
	n = 0
	for i in range(0, h):
		list1.append(input())
	for i in range(0, h):
		for j in range(0, w):
			if list1[i][j] != '1':
				dfs(j, i, list1[i][j])
				n += 1
	print(n)
	list1 = []


import sys
sys.setrecursionlimit(2000000)

def dfschain(L, i, j):
	if L[i][j] == ' ':
		return
	else:
		P = L[i][j]
		L[i][j] = ' '
	for k in [-1, 1]:
		ni = i + k
		if ni not in range(len(L)):
			continue
		if L[ni][j] == P:
			dfschain(L, ni, j)
	for k in [-1, 1]:
		nj = j + k
		if nj not in range(len(L[0])):
			continue
		if L[i][nj] == P:
			dfschain(L, i, nj)
	return
while True:
	(line, row) = [int(x) for x in input().split()]
	if line == 0 and row == 0:
		break
	L = []
	for _ in range(line):
		l = list(input())
		L.append(l)
	cnt = 0
	for i in range(line):
		for j in range(row):
			if L[i][j] != ' ':
				cnt += 1
				dfschain(L, i, j)
	print(cnt)


import queue
dr = [0, 0, 1, -1]
dc = [1, -1, 0, 0]
while True:
	a = [int(num) for num in input().split(' ')]
	if a[0] == 0:
		break
	s = []
	cnt = 0
	for i in range(a[0]):
		s.append(list(input()))
	q = queue.Queue()
	for i in range(a[0]):
		for j in range(a[1]):
			if s[i][j] == '.':
				continue
			f = s[i][j]
			l = [[i, j]]
			while len(l) != 0:
				next_depth = []
				for cor in l:
					for k in range(4):
						r = cor[0] + dr[k]
						c = cor[1] + dc[k]
						if 0 <= r < a[0] and 0 <= c < a[1] and (s[r][c] == f):
							s[r][c] = '.'
							next_depth.append([r, c])
				l = next_depth
			cnt += 1
	print(cnt)


import sys
import os
import math
directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
for s in sys.stdin:
	(H, W) = map(int, s.split())
	if H == W == 0:
		break
	M = []
	for i in range(H):
		s = input().strip()
		M.append(s)
	A = [[None for i in range(W)] for j in range(H)]

	def drawable(x, y):
		if 0 <= x < W and 0 <= y < H and (A[y][x] == None):
			return True
		else:
			return False
	color_num = 0

	def fill(x, y):
		global color_num
		Q = [(x, y)]
		while Q:
			p = Q.pop(0)
			_x = p[0]
			_y = p[1]
			A[_y][_x] = color_num
			for direction in directions:
				new_x = _x + direction[0]
				new_y = _y + direction[1]
				if drawable(new_x, new_y) and M[_y][_x] == M[new_y][new_x]:
					A[new_y][new_x] = color_num
					Q.append((new_x, new_y))
	for y in range(H):
		for x in range(W):
			if drawable(x, y):
				color_num += 1
				fill(x, y)
	print(color_num)


import sys

def setLine(tempH, line):
	for i in range(0, len(line)):
		geo[tempH][i] = line[i:i + 1]

def solve():
	person = 0
	for i in range(0, H):
		for j in range(0, W):
			if geo[i][j] is not '_':
				search(i, j)
				person += 1
	print(person)

def search(i, j):
	temp = geo[i][j]
	geo[i][j] = '_'
	dx = [-1, 0, 1, 0]
	dy = [0, -1, 0, 1]
	for a in range(0, 4):
		(idx, jdy) = (i + dx[a], j + dy[a])
		if isOnMap(idx, jdy):
			if isNeededToSolve(temp, idx, jdy):
				search(idx, jdy)

def isOnMap(i, j):
	return 0 <= i and 0 <= j and (i < H) and (j < W)

def isNeededToSolve(temp, i, j):
	target = geo[i][j]
	return target is not '_' and temp is target
limit = 10 ** 7
sys.setrecursionlimit(limit)
(H, W, tempH) = (-1, -1, 0)
geo = [[0 for i in range(1)] for j in range(1)]
while True:
	line = input()
	if H is -1 and W is -1:
		p = line.split(' ')
		(H, W) = (int(p[0]), int(p[1]))
		geo = [[0 for i in range(W)] for j in range(H)]
	else:
		setLine(tempH, line)
		tempH += 1
	if H is 0 and W is 0:
		break
	if tempH is H:
		solve()
		(H, W, tempH) = (-1, -1, 0)


import sys
sys.setrecursionlimit(100000)

def load_fields():
	fields = []
	i = 0
	(H, W) = (0, 0)
	field = []
	for line in sys.stdin:
		line = line.rstrip()
		if line[0] not in ['#', '@', '*']:
			line = line.split(' ')
			H = int(line[0])
			W = int(line[1])
			if len(field) != 0:
				fields.append(field)
				field = []
			if H == 0 and W == 0:
				break
		else:
			field.append(list(line))
		i += 1
	return fields

def dfs(x, y, fruit):
	field[x][y] = '0'
	for dx in [-1, 0, 1]:
		if dx == -1:
			width = [0]
		if dx == 0:
			width = [-1, 0, 1]
		if dx == 1:
			width = [0]
		for dy in width:
			nx = x + dx
			ny = y + dy
			inField = 0 <= nx and 0 <= ny and (nx < H) and (ny < W)
			if inField and field[nx][ny] == fruit:
				dfs(nx, ny, fruit)
fields = load_fields()
count = 0
for field in fields:
	H = len(field)
	W = len(field[0])
	for x in range(H):
		for y in range(W):
			if field[x][y] != '0':
				dfs(x, y, field[x][y])
				count += 1
	print(count)
	count = 0


import sys
sys.setrecursionlimit(10 ** 6)

def search(field, hp, vp, item):
	if not 0 <= hp < len(field):
		return
	if not 0 <= vp < len(field[hp]):
		return
	if item != field[hp][vp]:
		return
	field[hp][vp] = True
	for (dh, dv) in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
		search(field, hp + dh, vp + dv, item)

def solve(field):
	(count, valid_items) = (0, set(['@', '#', '*']))
	for i in range(len(field)):
		for j in range(len(field[i])):
			if field[i][j] in valid_items:
				search(field, i, j, field[i][j])
				count += 1
	return count

def main():
	line = input().strip()
	while line != '0 0':
		(H, W) = list(map(int, line.split(' ')))
		field = list()
		for _ in range(H):
			field.append(list(input().strip()))
		print(solve(field))
		line = input().strip()
main()


class UnionSet:

	def __init__(self, nmax):
		self.size = [1] * nmax
		self.id = [i for i in range(nmax + 1)]

	def root(self, i):
		while i != self.id[i]:
			self.id[i] = self.id[self.id[i]]
			i = self.id[i]
		return i

	def connected(self, p, q):
		return self.root(p) == self.root(q)

	def unite(self, p, q):
		(i, j) = (self.root(p), self.root(q))
		if i == j:
			return
		if self.size[i] < self.size[j]:
			self.id[i] = j
			self.size[j] += self.size[i]
		else:
			self.id[j] = i
			self.size[i] += self.size[j]
while 1:
	(H, W) = map(int, input().split())
	if H == 0 and W == 0:
		break
	tbl = [''] * H
	for r in range(H):
		tbl[r] = list(input())
	u = UnionSet(H * W)
	for r in range(H):
		for c in range(W):
			if c + 1 < W and tbl[r][c] == tbl[r][c + 1]:
				u.unite(r * W + c, r * W + c + 1)
			if r + 1 < H and tbl[r][c] == tbl[r + 1][c]:
				u.unite(r * W + c, (r + 1) * W + c)
	ans = 0
	for k in range(H * W):
		if u.root(k) == k:
			ans += 1
	print(ans)


import sys
sys.setrecursionlimit(100000)

def count(h, w, fruits):
	if h < 0 or h >= H:
		return False
	if w < 0 or w >= W:
		return False
	if fruits == '_':
		return False
	if fruits != land[h][w]:
		return False
	land[h][w] = '_'
	count(h + 1, w, fruits)
	count(h - 1, w, fruits)
	count(h, w + 1, fruits)
	count(h, w - 1, fruits)
while True:
	(H, W) = list(map(int, input().split()))
	if H == 0:
		break
	ans = 0
	land = [list(input()) for _ in range(H)]
	for i in range(H):
		for j in range(W):
			if land[i][j] != '_':
				ans += 1
				count(i, j, land[i][j])
	print(ans)


import sys
sys.setrecursionlimit(20000)
while True:
	(H, W) = map(int, input().split())
	if H == W == 0:
		exit()
	orchard = [list(input()) for i in range(H)]

	def dfs(i, j, fruit):
		orchard[i][j] = '.'
		move = [[0, 1], [0, -1], [1, 0], [-1, 0]]
		for (di, dj) in move:
			if 0 <= i + di < H and 0 <= j + dj < W and (orchard[i + di][j + dj] == fruit):
				dfs(i + di, j + dj, fruit)
	count = 0
	for i in range(H):
		for j in range(W):
			if orchard[i][j] != '.':
				count += 1
				dfs(i, j, orchard[i][j])
	print(count)


import sys

def solve():
	person = 0
	for i in range(0, H):
		for j in range(0, W):
			if geo[i][j] is not '_':
				search(i, j)
				person += 1
	print(person)

def search(i, j):
	temp = geo[i][j]
	geo[i][j] = '_'
	for a in range(0, 4):
		(idx, jdy) = (i + dx[a], j + dy[a])
		if isOnMap(idx, jdy):
			if isNeededToSolve(temp, idx, jdy):
				search(idx, jdy)

def isOnMap(i, j):
	return 0 <= i and 0 <= j and (i < H) and (j < W)

def isNeededToSolve(temp, i, j):
	target = geo[i][j]
	return target is not '_' and temp is target
limit = 10 ** 7
sys.setrecursionlimit(limit)
(H, W, tempH) = (-1, -1, 0)
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]
geo = [[0 for i in range(1)] for j in range(1)]
while True:
	line = input()
	if H is -1 and W is -1:
		p = line.split(' ')
		(H, W) = (int(p[0]), int(p[1]))
		geo = [[0 for i in range(W)] for j in range(H)]
	else:
		geo[tempH] = list(line)
		tempH += 1
	if H is 0 and W is 0:
		break
	if tempH is H:
		solve()
		(H, W, tempH) = (-1, -1, 0)


def Labeling(terrain):
	label = terrain
	offset = [[-1, 0], [0, -1], [1, 0], [0, 1]]
	signs = ['@', '#', '*']
	(rowLength, colLength) = (len(label) - 1, len(label[0]) - 1)
	step = 0
	for row in range(1, rowLength):
		for col in range(1, colLength):
			mark = label[row][col]
			if mark in signs:
				pointStack = [[row, col]]
				label[row][col] = step
				while 0 < len(pointStack):
					(rowIndex, colIndex) = pointStack.pop()
					for (x, y) in offset:
						(offsetRow, offsetCol) = (rowIndex + x, colIndex + y)
						if label[offsetRow][offsetCol] == mark:
							pointStack.append([offsetRow, offsetCol])
							label[offsetRow][offsetCol] = step
				step += 1
	return step
Sentinel = '1'
while True:
	(col, row) = [int(item) for item in input().split()]
	if row == 0 and col == 0:
		break
	land = []
	sentinels = [item for item in Sentinel * row + Sentinel * 2]
	land.append(sentinels)
	for lp in range(col):
		part = [item for item in input()]
		part = [Sentinel] + part + [Sentinel]
		land.append(part)
	land.append(sentinels)
	result = Labeling(land)
	print(result)


import sys
sys.setrecursionlimit(10 ** 7)

def search(values, hp, vp, item):
	if not 0 <= hp < len(values):
		return
	if not 0 <= vp < len(values[hp]):
		return
	if item != values[hp][vp]:
		return
	values[hp][vp] = True
	search(values, hp - 1, vp, item)
	search(values, hp + 1, vp, item)
	search(values, hp, vp - 1, item)
	search(values, hp, vp + 1, item)

def solve(values):
	(count, valid_items) = (0, set(['@', '#', '*']))
	for i in range(len(values)):
		for j in range(len(values[i])):
			if values[i][j] in valid_items:
				search(values, i, j, values[i][j])
				count += 1
	return count

def main():
	(line, values) = (input().strip(), list())
	while line != '0 0':
		(H, W) = list(map(int, line.split(' ')))
		value = list()
		for _ in range(H):
			value.append(list((x for x in input().strip())))
		values.append(value)
		line = input().strip()
	for value in values:
		print(solve(value))
main()


def Labeling(terrain):
	label = terrain
	offset = [[-1, 0], [0, -1], [1, 0], [0, 1]]
	signs = ['@', '#', '*']
	(rowLength, colLength) = (len(label) - 1, len(label[0]) - 1)
	step = 0
	for row in range(1, rowLength):
		for col in range(1, colLength):
			mark = label[row][col]
			if mark in signs:
				pointStack = [[row, col]]
				label[row][col] = step
				while 0 < len(pointStack):
					(rowIndex, colIndex) = pointStack.pop()
					for (x, y) in offset:
						(offsetRow, offsetCol) = (rowIndex + x, colIndex + y)
						if label[offsetRow][offsetCol] == mark:
							pointStack.append([offsetRow, offsetCol])
							label[offsetRow][offsetCol] = step
				step += 1
	return step
Sentinel = '1'
while True:
	(col, row) = [int(item) for item in input().split()]
	if row == 0 and col == 0:
		break
	land = []
	land.append([item for item in Sentinel * row + Sentinel * 2])
	for lp in range(col):
		part = [item for item in input()]
		land.append([])
		land[-1].extend([Sentinel])
		land[-1].extend(part)
		land[-1].extend([Sentinel])
	land.append([item for item in Sentinel * row + Sentinel * 2])
	result = Labeling(land)
	print(result)


import sys
sys.setrecursionlimit(10000000)

def dfs(x, y, fru):
	field[x][y] = '.'
	for dx in [-1, 0, 1]:
		nx = x + dx
		if 0 <= nx and nx < H and (field[nx][y] == fru):
			dfs(nx, y, fru)
	for dy in [-1, 0, 1]:
		ny = y + dy
		if 0 <= ny and ny < W and (field[x][ny] == fru):
			dfs(x, ny, fru)

def solv(H, W):
	count = 0
	for i in range(H):
		for j in range(W):
			if field[i][j] != '.':
				dfs(i, j, field[i][j])
				count += 1
	print(count)
f = 0
while f == 0:
	(H, W) = map(int, input().split())
	if H != 0 and W != 0:
		field = []
		for i in range(H):
			field.append(list(input()))
		solv(H, W)
	else:
		f = 1


def calc(H, W, property):
	visit = [[False for i in range(W + 2)] for j in range(H + 2)]
	retval = 0
	_property = [['.' for i in range(W + 2)]]
	for p in property:
		_property.append(['.'] + p + ['.'])
	_property.append(['.' for i in range(W + 2)])
	property = _property
	for i in range(1, H + 1):
		for j in range(1, W + 1):
			if visit[i][j]:
				continue
			visit[i][j] = True
			retval += 1
			next = [(i, j)]
			while len(next) > 0:
				_next = []
				for p in next:
					if visit[p[0] - 1][p[1]] == False and property[p[0]][p[1]] == property[p[0] - 1][p[1]]:
						_next.append((p[0] - 1, p[1]))
						visit[p[0] - 1][p[1]] = True
					if visit[p[0] + 1][p[1]] == False and property[p[0]][p[1]] == property[p[0] + 1][p[1]]:
						_next.append((p[0] + 1, p[1]))
						visit[p[0] + 1][p[1]] = True
					if visit[p[0]][p[1] - 1] == False and property[p[0]][p[1]] == property[p[0]][p[1] - 1]:
						_next.append((p[0], p[1] - 1))
						visit[p[0]][p[1] - 1] = True
					if visit[p[0]][p[1] + 1] == False and property[p[0]][p[1]] == property[p[0]][p[1] + 1]:
						_next.append((p[0], p[1] + 1))
						visit[p[0]][p[1] + 1] = True
				next = _next
	return retval
while True:
	(H, W) = [int(i) for i in input().split(' ')]
	if H == 0 and W == 0:
		break
	property = [[s for s in input()] for i in range(H)]
	print(calc(H, W, property))


import sys

def setLine(tempH, line):
	for i in range(0, len(line)):
		geo[tempH][i] = line[i:i + 1]

def solve():
	person = 0
	for i in range(0, H):
		for j in range(0, W):
			if geo[i][j] is not '_':
				search(i, j)
				person += 1
	print(person)

def search(i, j):
	temp = geo[i][j]
	geo[i][j] = '_'
	dx = [-1, 0, 1, 0]
	dy = [0, -1, 0, 1]
	for a in range(0, 4):
		idx = i + dx[a]
		jdy = j + dy[a]
		if isOnMap(idx, jdy):
			if isNeededToSolve(temp, idx, jdy):
				search(idx, jdy)

def isOnMap(i, j):
	return 0 <= i and 0 <= j and (i < H) and (j < W)

def isNeededToSolve(temp, i, j):
	target = geo[i][j]
	return target is not '_' and temp is target
limit = 10 ** 7
sys.setrecursionlimit(limit)
H = -1
W = -1
tempH = 0
geo = [[0 for i in range(1)] for j in range(1)]
repeat = True
while repeat:
	line = input()
	if H is -1 and W is -1:
		H = int(line.split(' ')[0])
		W = int(line.split(' ')[1])
		geo = [[0 for i in range(W)] for j in range(H)]
	else:
		setLine(tempH, line)
		tempH += 1
	if H is 0 and W is 0:
		break
	if tempH is H:
		solve()
		H = -1
		W = -1
		tempH = 0


import sys
sys.setrecursionlimit(10 ** 6)

def search(values, hp, vp, item):
	if not 0 <= hp < len(values):
		return
	if not 0 <= vp < len(values[hp]):
		return
	if item != values[hp][vp]:
		return
	values[hp][vp] = True
	for (dh, dv) in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
		search(values, hp + dh, vp + dv, item)

def solve(values):
	(count, valid_items) = (0, set(['@', '#', '*']))
	for i in range(len(values)):
		for j in range(len(values[i])):
			if values[i][j] in valid_items:
				search(values, i, j, values[i][j])
				count += 1
	return count

def main():
	line = input().strip()
	while line != '0 0':
		(H, W) = list(map(int, line.split(' ')))
		values = list()
		for _ in range(H):
			values.append(list(input().strip()))
		print(solve(values))
		line = input().strip()
main()


import sys
sys.setrecursionlimit(10 ** 6)

def search(values, hp, vp, item):
	if not 0 <= hp < len(values):
		return
	if not 0 <= vp < len(values[hp]):
		return
	if item != values[hp][vp]:
		return
	values[hp][vp] = True
	search(values, hp - 1, vp, item)
	search(values, hp + 1, vp, item)
	search(values, hp, vp - 1, item)
	search(values, hp, vp + 1, item)

def solve(values):
	(count, valid_items) = (0, set(['@', '#', '*']))
	for i in range(len(values)):
		for j in range(len(values[i])):
			if values[i][j] in valid_items:
				search(values, i, j, values[i][j])
				count += 1
	return count

def main():
	line = input().strip()
	while line != '0 0':
		(H, W) = list(map(int, line.split(' ')))
		values = list()
		for _ in range(H):
			values.append(list(input().strip()))
		print(solve(values))
		line = input().strip()
main()


def solve():
	from sys import stdin
	f_i = stdin
	while True:
		(H, W) = map(int, f_i.readline().split())
		if H == 0:
			break
		mp = ['X'] * (W + 2)
		for i in range(H):
			mp += list('X' + f_i.readline().rstrip() + 'X')
		mp += ['X'] * (W + 2)
		direction = (W + 2, -W - 2, -1, 1)
		ans = 0
		for i in range(W + 3, (W + 2) * (H + 1), W + 2):
			for j in range(i, i + W):
				f = mp[j]
				if f != 'X':
					mp[j] = 'X'
					parcel = [j]
					while parcel:
						p = parcel.pop()
						for d in direction:
							adj = p + d
							if mp[adj] == f:
								parcel.append(adj)
								mp[adj] = 'X'
					ans += 1
		print(ans)
solve()


import sys
sys.setrecursionlimit(100000)

def load_fields():
	fields = []
	i = 0
	(H, W) = (0, 0)
	field = []
	for line in sys.stdin:
		line = line.rstrip()
		if line[0] not in ['#', '@', '*']:
			line = line.split(' ')
			(H, W) = (int(line[0]), int(line[1]))
			if len(field) != 0:
				fields.append(field)
				field = []
			if H == 0 and W == 0:
				break
		else:
			field.append(list(line))
		i += 1
	return fields

def dfs(x, y, fruit):
	field[x][y] = '0'
	for dx in [-1, 0, 1]:
		if dx == -1:
			width = [0]
		if dx == 0:
			width = [-1, 0, 1]
		if dx == 1:
			width = [0]
		for dy in width:
			nx = x + dx
			ny = y + dy
			inField = 0 <= nx < H and 0 <= ny < W
			if inField and field[nx][ny] == fruit:
				dfs(nx, ny, fruit)
fields = load_fields()
count = 0
for field in fields:
	H = len(field)
	W = len(field[0])
	for x in range(H):
		for y in range(W):
			if field[x][y] != '0':
				dfs(x, y, field[x][y])
				count += 1
	print(count)
	count = 0


import sys
sys.setrecursionlimit(100000)
dir = ((0, 1), (0, -1), (1, 0), (-1, 0))

def search(x, y, target):
	mp[y][x] = 'X'
	for (dx, dy) in dir:
		nx = x + dx
		ny = y + dy
		if mp[ny][nx] == target:
			search(nx, ny, target)
while True:
	(h, w) = map(int, input().split())
	if h == 0:
		break
	mp = [list('X' + input() + 'X') for _ in range(h)]
	mp.insert(0, ['X'] * (w + 2))
	mp.append(['X'] * (w + 2))
	ans = 0
	for x in range(1, w + 1):
		for y in range(1, h + 1):
			target = mp[y][x]
			if target != 'X':
				search(x, y, target)
				ans += 1
	print(ans)


h = w = 0
slist = []
list1 = []

def dfs(f):
	while True:
		if len(slist) == 0:
			return 1
		coordinate = slist.pop()
		x = coordinate[0]
		y = coordinate[1]
		list1[y] = list1[y][:x] + '1' + list1[y][x + 1:]
		if x + 1 < w:
			if list1[y][x + 1] == f:
				slist.append([x + 1, y])
		if x - 1 >= 0:
			if list1[y][x - 1] == f:
				slist.append([x - 1, y])
		if y + 1 < h:
			if list1[y + 1][x] == f:
				slist.append([x, y + 1])
		if y - 1 >= 0:
			if list1[y - 1][x] == f:
				slist.append([x, y - 1])
while True:
	(h, w) = list(map(lambda x: int(x), input().split(' ')))
	if 0 in (h, w):
		break
	n = 0
	for i in range(0, h):
		list1.append(input())
	for i in range(0, h):
		for j in range(0, w):
			if list1[i][j] != '1':
				slist.append([j, i])
				n += dfs(list1[i][j])
	print(n)
	list1 = []


import sys
sys.setrecursionlimit(10 ** 8)

def Z():
	return int(input())

def ZZ():
	return [int(_) for _ in input().split()]

def main():
	for _ in range(22):
		(h, w) = ZZ()
		if h == 0 and w == 0:
			break
		A = [input() for _ in range(h)]
		D = [(1, 0), (-1, 0), (0, 1), (0, -1)]
		done = [[False] * w for _ in range(h)]
		ans = 0

		def dfs(x, y, fluit):
			if done[x][y]:
				return
			done[x][y] = True
			for (dx, dy) in D:
				(nx, ny) = (x + dx, y + dy)
				if 0 <= nx < h and 0 <= ny < w and (A[nx][ny] == fluit):
					dfs(nx, ny, fluit)
		ans = 0
		for i in range(h):
			for j in range(w):
				if done[i][j]:
					continue
				ans += 1
				dfs(i, j, A[i][j])
		print(ans)
	return
main()


import sys
sys.setrecursionlimit(10000000)

def search(values, hp, vp, item):
	if not 0 <= hp < len(values):
		return
	if not 0 <= vp < len(values[hp]):
		return
	if item != values[hp][vp]:
		return
	values[hp][vp] = True
	search(values, hp - 1, vp, item)
	search(values, hp + 1, vp, item)
	search(values, hp, vp - 1, item)
	search(values, hp, vp + 1, item)

def solve(values):
	count = 0
	for i in range(len(values)):
		for j in range(len(values[i])):
			if values[i][j] in ['@', '#', '*']:
				search(values, i, j, values[i][j])
				count += 1
	return count

def main():
	(line, values) = (input().strip(), list())
	while line != '0 0':
		(H, W) = list(map(int, line.split(' ')))
		value = list()
		for _ in range(H):
			value.append(list((x for x in input().strip())))
		values.append(value)
		line = input().strip()
	for value in values:
		print(solve(value))
main()