A star is a figure of the following type: an asterisk character '*' in the center of the figure and four rays (to the left, right, top, bottom) of the same positive length. The size of a star is the length of its rays. The size of a star must be a positive number (i.e. rays of length $0$ are not allowed).

Let's consider empty cells are denoted by '.', then the following figures are stars:

 [Image] The leftmost figure is a star of size $1$, the middle figure is a star of size $2$ and the rightmost figure is a star of size $3$. 

You are given a rectangular grid of size $n \times m$ consisting only of asterisks '*' and periods (dots) '.'. Rows are numbered from $1$ to $n$, columns are numbered from $1$ to $m$. Your task is to draw this grid using any number of stars or find out that it is impossible. Stars can intersect, overlap or even coincide with each other. The number of stars in the output can't exceed $n \cdot m$. Each star should be completely inside the grid. You can use stars of same and arbitrary sizes.

In this problem, you do not need to minimize the number of stars. Just find any way to draw the given grid with at most $n \cdot m$ stars.


-----Input-----

The first line of the input contains two integers $n$ and $m$ ($3 \le n, m \le 100$) — the sizes of the given grid.

The next $n$ lines contains $m$ characters each, the $i$-th line describes the $i$-th row of the grid. It is guaranteed that grid consists of characters '*' and '.' only.


-----Output-----

If it is impossible to draw the given grid using stars only, print "-1".

Otherwise in the first line print one integer $k$ ($0 \le k \le n \cdot m$) — the number of stars needed to draw the given grid. The next $k$ lines should contain three integers each — $x_j$, $y_j$ and $s_j$, where $x_j$ is the row index of the central star character, $y_j$ is the column index of the central star character and $s_j$ is the size of the star. Each star should be completely inside the grid.


-----Examples-----
Input
6 8
....*...
...**...
..*****.
...**...
....*...
........

Output
3
3 4 1
3 5 2
3 5 1

Input
5 5
.*...
****.
.****
..**.
.....

Output
3
2 2 1
3 3 1
3 4 1

Input
5 5
.*...
***..
.*...
.*...
.....

Output
-1

Input
3 3
*.*
.*.
*.*

Output
-1



-----Note-----

In the first example the output 2

3 4 1

3 5 2



is also correct.

Difficulty: MEDIUM_HARD

Solutions:
def find_stars(h, w, matrix):
	max_size = 0
	if matrix[h][w] == '.':
		return max_size
	size = 1
	while True:
		for next_h in range(h, h + size + 1):
			if next_h >= height or matrix[next_h][w] != '*':
				return max_size
		for next_h in range(h, h - size - 1, -1):
			if next_h < 0 or matrix[next_h][w] != '*':
				return max_size
		for next_w in range(w, w + size + 1):
			if next_w >= width or matrix[h][next_w] != '*':
				return max_size
		for next_w in range(w, w - size - 1, -1):
			if next_w < 0 or matrix[h][next_w] != '*':
				return max_size
		max_size = size
		size += 1
(height, width) = list(map(int, input().split()))
matrix = []
for h in range(height):
	row = input()
	matrix.append(row)
result_matrix = [['.'] * width for h in range(height)]
result_stars = []
for h in range(height):
	for w in range(width):
		found_max_size = find_stars(h, w, matrix)
		if found_max_size == 0:
			continue
		for next_h in range(h, h + found_max_size + 1):
			result_matrix[next_h][w] = '*'
		for next_h in range(h, h - found_max_size - 1, -1):
			result_matrix[next_h][w] = '*'
		for next_w in range(w, w + found_max_size + 1):
			result_matrix[h][next_w] = '*'
		for next_w in range(w, w - found_max_size - 1, -1):
			result_matrix[h][next_w] = '*'
		result_stars.append(str(h + 1) + ' ' + str(w + 1) + ' ' + str(found_max_size))
is_equal = True
for h in range(height):
	for w in range(width):
		if matrix[h][w] != result_matrix[h][w]:
			is_equal = False
if is_equal:
	print(len(result_stars))
	for star in result_stars:
		print(star)
else:
	print(-1)


(n, m) = map(int, input().split())
num = []
used = []
for i in range(n):
	num.append(input())
	used.append([False] * m)
ans = []
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if num[i][j] == '*':
			d1 = 0
			d2 = 0
			d3 = 0
			d4 = 0
			for x in range(j + 1, m):
				if num[i][x] == '.':
					d1 = x - j - 1
					break
			else:
				d1 = m - j - 1
			for x in range(j - 1, -1, -1):
				if num[i][x] == '.':
					d2 = abs(j - x - 1)
					break
			else:
				d2 = j
			for y in range(i + 1, n):
				if num[y][j] == '.':
					d3 = y - i - 1
					break
			else:
				d3 = n - i - 1
			for y in range(i - 1, -1, -1):
				if num[y][j] == '.':
					d4 = abs(i - y - 1)
					break
			else:
				d4 = i
			dist = min(d1, d2, d3, d4)
			if dist != 0:
				ans.append([i + 1, j + 1, dist])
				for x in range(j - dist, j + dist + 1):
					used[i][x] = True
				for y in range(i - dist, i + dist + 1):
					used[y][j] = True
fl = True
for i in range(n):
	for j in range(m):
		if num[i][j] == '*' and (not used[i][j]):
			fl = False
if not fl:
	print(-1)
else:
	print(len(ans))
	for i in range(len(ans)):
		print(*ans[i])


(N, M) = map(int, input().split())
L = []
for a in range(N):
	L.append(list(input()))
ANS = []
for i in range(N):
	for j in range(M):
		if L[i][j] == '*' or L[i][j] == '-':
			k = 1
			l = min(i, j, N - 1 - i, M - 1 - j)
			while k <= l:
				if (L[i + k][j] == '*' or L[i + k][j] == '-') and (L[i][j + k] == '*' or L[i][j + k] == '-') and (L[i - k][j] == '*' or L[i - k][j] == '-') and (L[i][j - k] == '*' or L[i][j - k] == '-'):
					L[i][j] = '-'
					L[i + k][j] = '-'
					L[i - k][j] = '-'
					L[i][j + k] = '-'
					L[i][j - k] = '-'
					k += 1
				else:
					break
			if k > 1:
				ANS.append((i + 1, j + 1, k - 1))
f = True
for a in L:
	if '*' in a:
		f = False
		break
if f:
	print(len(ANS))
	for a in ANS:
		print(' '.join(map(str, a)))
else:
	print(-1)


import collections as cc
import math as mt
import sys
I = lambda : list(map(int, input().split()))
(n, m) = I()
a = [0] * (n + 1)
for i in range(n):
	a[i] = list(input()) + ['.']
a[n] = ['.'] * m
used = [[False] * m for i in range(n)]
ans = []
for i in range(n):
	for j in range(m):
		if a[i][j] == '.':
			continue
		k = 1
		while a[i - k][j] == '*' and a[i + k][j] == '*' and (a[i][j - k] == '*') and (a[i][j + k] == '*'):
			used[i - k][j] = used[i + k][j] = used[i][j - k] = used[i][j + k] = True
			k += 1
		if k > 1:
			used[i][j] = True
			ans += [[i + 1, j + 1, k - 1]]
for i in range(n):
	for j in range(m):
		if a[i][j] == '*' and (not used[i][j]):
			print(-1)
			sys.exit()
print(len(ans))
for i in ans:
	print(*i)


(n, m) = map(int, input().split())
qw = 0
grid = [None] * n
for i in range(n):
	grid[i] = list(input())
ANS = []

def star(x, y, i):
	if x < i or x >= n - i or y < i or (y >= m - i):
		return 0
	if grid[x][y] == '.':
		return 0
	for j in range(1, i + 1):
		if grid[x + i][y] == '.' or grid[x - i][y] == '.' or grid[x][y + i] == '.' or (grid[x][y - i] == '.'):
			return 0
	return 1
for i in range(n):
	for j in range(m):
		for k in range(1, min(n, m) // 2 + 2):
			if star(i, j, k) == 1:
				continue
			else:
				if k > 1:
					ANS += [(i, j, max(k - 1, 1))]
				break
grid2 = [None] * n
for i in range(n):
	grid2[i] = ['.'] * m

def draw(x, y, i):
	grid2[x][y] = '*'
	for i in range(1, i + 1):
		grid2[x + i][y] = '*'
		grid2[x - i][y] = '*'
		grid2[x][y + i] = '*'
		grid2[x][y - i] = '*'
for i in ANS:
	draw(i[0], i[1], i[2])
for i in range(n):
	for j in range(m):
		if grid[i][j] == '*':
			qw = 1
			break
	if qw == 1:
		break
if qw == 0:
	print(0)
elif grid != grid2 or ANS == []:
	print(-1)
else:
	print(len(ANS))
	for i in ANS:
		print(i[0] + 1, i[1] + 1, i[2])


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
import collections
from itertools import permutations
from collections import defaultdict
from collections import deque
import threading
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class SegmentTree:

	def __init__(self, data, default=0, func=lambda a, b: a + b):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class SegmentTree1:

	def __init__(self, data, default=10 ** 6, func=lambda a, b: min(a, b)):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)
MOD = 10 ** 9 + 7

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD
mod = 10 ** 9 + 7
omod = 998244353
prime = [True for i in range(10)]
pp = [0] * 10

def SieveOfEratosthenes(n=10):
	p = 2
	c = 0
	while p * p <= n:
		if prime[p] == True:
			c += 1
			for i in range(p, n + 1, p):
				pp[i] += 1
				prime[i] = False
		p += 1

def binarySearch(arr, n, key):
	left = 0
	right = n - 1
	mid = 0
	res = arr[n - 1]
	while left <= right:
		mid = (right + left) // 2
		if arr[mid] >= key:
			res = arr[mid]
			right = mid - 1
		else:
			left = mid + 1
	return res

def binarySearch1(arr, n, key):
	left = 0
	right = n - 1
	mid = 0
	res = arr[0]
	while left <= right:
		mid = (right + left) // 2
		if arr[mid] > key:
			right = mid - 1
		else:
			res = arr[mid]
			left = mid + 1
	return res
(n, m) = map(int, input().split())
l = []
tot = []
done = [[0 for i in range(m)] for j in range(n)]
for i in range(n):
	l.append(input())
colsum = [[0 for i in range(m)] for j in range(n)]
rowsum = [[0 for i in range(m)] for j in range(n)]
col = [[0 for i in range(m)] for j in range(n)]
row = [[0 for i in range(m)] for j in range(n)]
for i in range(n):
	for j in range(m):
		if l[i][j] == '*':
			rowsum[i][j] = 1
			colsum[i][j] = 1
			row[i][j] = 1
			col[i][j] = 1
for i in range(n):
	for j in range(1, m):
		if l[i][j] == '.':
			continue
		rowsum[i][j] += rowsum[i][j - 1]
for i in range(n):
	for j in range(m - 2, -1, -1):
		if l[i][j] == '.':
			continue
		row[i][j] += row[i][j + 1]
for i in range(m):
	for j in range(n - 2, -1, -1):
		if l[j][i] == '.':
			continue
		col[j][i] += col[j + 1][i]
for i in range(m):
	for j in range(1, n):
		if l[j][i] == '.':
			continue
		colsum[j][i] += colsum[j - 1][i]

def check(x, y):
	i = x
	j = y
	ans = min(row[i][j], rowsum[i][j], colsum[i][j], col[i][j]) - 1
	if ans == 0:
		return []
	return [ans]
h = [[0 for i in range(m + 1)] for j in range(n)]
v = [[0 for i in range(m)] for j in range(n + 1)]
for i in range(n):
	for j in range(m):
		if l[i][j] == '*':
			ans = check(i, j)
			for j1 in ans:
				tot.append([i + 1, j + 1, j1])
				h[i][j - j1] += 1
				h[i][j + j1 + 1] -= 1
				v[i - j1][j] += 1
				v[i + j1 + 1][j] -= 1
for i in range(n):
	for j in range(1, m):
		h[i][j] += h[i][j - 1]
for i in range(m):
	for j in range(1, n):
		v[j][i] += v[j - 1][i]
for i in range(n):
	for j in range(m):
		if l[i][j] == '*' and h[i][j] == 0 and (v[i][j] == 0):
			print(-1)
			sys.exit(0)
print(len(tot))
for i in tot:
	print(*i)


(n, m) = list(map(int, input().split()))
used = [[True] * m for i in range(n)]
Pole = [0] * n
M = []
for i in range(n):
	Pole[i] = list(input())
for i in range(n):
	for g in range(m):
		if Pole[i][g] == '*':
			k = 0
			while i - k - 1 >= 0 and i + k + 1 < n and (g - k - 1 >= 0) and (g + k + 1 < m):
				if Pole[i - k - 1][g] == '*' and Pole[i + k + 1][g] == '*' and (Pole[i][g - k - 1] == '*') and (Pole[i][g + k + 1] == '*'):
					used[i - k - 1][g] = False
					used[i + k + 1][g] = False
					used[i][g - k - 1] = False
					used[i][g + k + 1] = False
					k += 1
					continue
				break
			if k != 0:
				used[i][g] = False
				M.append([i + 1, g + 1, k])
for i in range(n):
	for g in range(m):
		if Pole[i][g] == '*':
			if used[i][g]:
				print(-1)
				break
	else:
		continue
	break
else:
	print(len(M))
	for i in range(len(M)):
		print(*M[i])


(n, m) = map(int, input().split())
s = [list(input()) for i in range(n)]
dp = [['.' for i in range(m)] for j in range(n)]
ans = []
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if s[i][j] == '*' and s[i + 1][j] == '*' and (s[i - 1][j] == '*') and (s[i][j - 1] == '*') and (s[i][j + 1] == '*'):
			x = 0
			while i - x > -1 and x + i < n and (j - x > -1) and (x + j < m) and (s[i + x][j] == '*') and (s[i - x][j] == '*') and (s[i][j - x] == '*') and (s[i][j + x] == '*'):
				(dp[i + x][j], dp[i - x][j], dp[i][j - x], dp[i][j + x]) = ('*', '*', '*', '*')
				x += 1
			if x != 1:
				ans.append([i + 1, j + 1, x - 1])
			else:
				dp[i][j] = '.'
if dp != s:
	print(-1)
else:
	print(len(ans))
	for i in ans:
		print(*i)


(n, m) = list(map(int, input().split()))
pole = []
unfitted = []

def star_fits(x, y, r):
	if x - r >= 0 and x + r < m and (y - r >= 0) and (y + r < n):
		res = True
		for k in range(x - r, x + r + 1):
			if pole[y][k] != '*':
				res = False
		for k in range(y - r, y + r + 1):
			if pole[k][x] != '*':
				res = False
	else:
		return False
	return res

def get_max_r(x, y):
	r = 1
	while x - r >= 0 and x + r < m and (y - r >= 0) and (y + r < n):
		if pole[y][x + r] == '*' and pole[y][x - r] == '*' and (pole[y + r][x] == '*') and (pole[y - r][x] == '*'):
			r += 1
		else:
			return r - 1
	return r - 1

def mark_star(x, y, r):
	if x - r >= 0 and x + r < m and (y - r >= 0) and (y + r < n):
		for k in range(x - r, x + r + 1):
			unfitted[y][k] = False
		for k in range(y - r, y + r + 1):
			unfitted[k][x] = False
for i in range(n):
	pole.append(input().strip()[:m])
	unfitted.append([True] * m)
fin_res = []
for x in range(m):
	for y in range(n):
		if pole[y][x] == '*':
			r = get_max_r(x, y)
			if r > 0:
				mark_star(x, y, r)
				fin_res.append((y + 1, x + 1, r))
for x in range(m):
	for y in range(n):
		if pole[y][x] == '*' and unfitted[y][x]:
			print(-1)
			exit()
print(len(fin_res))
for t in fin_res:
	print(*t)


io = input().split()
n = int(io[0])
m = int(io[1])
arr = []

def analitic(y, x):
	global n, m, arr
	maxValue = min(y, m - x - 1, n - y - 1, x)
	tMax = rMax = bMax = lMax = 0
	for i in range(maxValue):
		if arr[y - i - 1][x] == '.':
			tMax = i
			break
		else:
			tMax = i + 1
	for i in range(maxValue):
		if arr[y][x + i + 1] == '.':
			rMax = i
			break
		else:
			rMax = i + 1
	for i in range(maxValue):
		if arr[y + i + 1][x] == '.':
			bMax = i
			break
		else:
			bMax = i + 1
	for i in range(maxValue):
		if arr[y][x - i - 1] == '.':
			lMax = i
			break
		else:
			lMax = i + 1
	return min(tMax, rMax, bMax, lMax)

def drawChar(currentCahr):
	if currentCahr == 0:
		return '*'
	return currentCahr

def draw(y, x, size):
	global arr
	for i in range(size):
		arr[y - i - 1][x] = drawChar(arr[y - i - 1][x])
	for i in range(size):
		arr[y][x + i + 1] = drawChar(arr[y][x + i + 1])
	for i in range(size):
		arr[y + i + 1][x] = drawChar(arr[y + i + 1][x])
	for i in range(size):
		arr[y][x - i - 1] = drawChar(arr[y][x - i - 1])
for i in range(n):
	arr.append(list(input()))
for i in range(n):
	for j in range(m):
		if arr[i][j] == '.':
			continue
		arr[i][j] = analitic(i, j)
res = []
for i in range(n):
	for j in range(m):
		if arr[i][j] != '.' and arr[i][j] != '*' and (arr[i][j] != 0):
			res.append(str(i + 1) + ' ' + str(j + 1) + ' ' + str(arr[i][j]))
			draw(i, j, arr[i][j])
for i in range(n):
	for j in range(m):
		if arr[i][j] == 0:
			print(-1)
			exit()
print(len(res))
for i in res:
	print(i)


(n, m) = map(int, input().split())
table = [[0] * (m + 2)]
for i in range(n):
	table.append([0])
	s = input()
	for j in range(m):
		table[i + 1].append(2 if s[j] == '*' else 0)
	table[i + 1].append(0)
table.append([0] * (m + 2))
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
answer = []
for i in range(1, n + 1):
	for j in range(1, m + 1):
		if table[i][j] == 0:
			continue
		able = True
		size = 0
		while able:
			size += 1
			for k in range(4):
				if table[i + dx[k] * size][j + dy[k] * size] == 0:
					able = False
		size -= 1
		if size > 0:
			table[i][j] = 1
			for k in range(1, size + 1):
				for q in range(4):
					table[i + dx[q] * k][j + dy[q] * k] = 1
			answer.append([i, j, size])
Ok = True
for i in range(1, n + 1):
	for j in range(1, m + 1):
		if table[i][j] == 2:
			Ok = False
if not Ok:
	print(-1)
else:
	print(len(answer))
	for i in answer:
		print(*i)


def check(x, y, fd, stars, n, m):
	ln = 1
	while y - ln > -1 and x - ln > -1 and (y + ln < m) and (x + ln < n):
		flag = True
		if fd[x - ln][y] == '.':
			flag = False
		if fd[x + ln][y] == '.':
			flag = False
		if fd[x][y - ln] == '.':
			flag = False
		if fd[x][y + ln] == '.':
			flag = False
		if flag:
			fd[x - ln] = fd[x - ln][:y] + '+' + fd[x - ln][y + 1:]
			fd[x + ln] = fd[x + ln][:y] + '+' + fd[x + ln][y + 1:]
			fd[x] = fd[x][:y - ln] + '+' * (ln + ln + 1) + fd[x][y + ln + 1:]
			ln += 1
		elif ln > 1:
			stars.append(str(x + 1) + ' ' + str(y + 1) + ' ' + str(ln - 1))
			return
		else:
			return
	if ln - 1 > 0:
		stars.append(str(x + 1) + ' ' + str(y + 1) + ' ' + str(ln - 1))
(n, m) = map(int, input().split())
stars = []
fd = []
for i in range(n):
	fd.append(input())
final = False
for i in range(1, n):
	for j in range(1, m):
		if fd[i][j] != '.':
			isIsland = False
			if fd[i - 1][j] == '.' and fd[i + 1][j] == '.' and (fd[i][j - 1] == '.') and (fd[i][j + 1] == '.'):
				isIsland = True
			if isIsland:
				final = True
				break
			else:
				check(i, j, fd, stars, n, m)
	if final:
		print(-1)
		break
if not final:
	for i in range(n):
		for j in range(m):
			if fd[i][j] == '*':
				final = True
				break
		if final:
			print(-1)
			break
	if not final:
		print(len(stars))
		for i in stars:
			print(i)


import math as ma
from sys import exit
from decimal import Decimal as dec

def li():
	return list(map(int, input().split()))

def modInverse(a, m):
	m0 = m
	y = 0
	x = 1
	if m == 1:
		return 0
	while a > 1:
		q = a // m
		t = m
		m = a % m
		a = t
		t = y
		y = x - q * y
		x = t
	if x < 0:
		x = x + m0
	return x
m = 10000019

def binomialCoefficient(n, k):
	if k > n - k:
		k = (n - k) % m
	res = 1
	for i in range(k):
		res = res * (n - i) % m
		res = res * modInverse(i + 1, m) % m
	return res

def num():
	return map(int, input().split())

def nu():
	return int(input())

def find_gcd(x, y):
	while y:
		(x, y) = (y, x % y)
	return x
(n, m) = num()
a = [0] * n
b = [0] * n
for i in range(n):
	x = input()
	a[i] = [0] * m
	b[i] = [0] * m
	for j in range(m):
		if x[j] == '*':
			a[i][j] = 1
pp = []
for i in range(n):
	for j in range(m):
		u = 0
		d = 0
		l = 0
		r = 0
		if a[i][j] == 1:
			for k in range(i - 1, -1, -1):
				if a[k][j] == 1:
					u += 1
				else:
					break
			for k in range(i + 1, n):
				if a[k][j] == 1:
					d += 1
				else:
					break
			for k in range(j - 1, -1, -1):
				if a[i][k] == 1:
					l += 1
				else:
					break
			for k in range(j + 1, m):
				if a[i][k] == 1:
					r += 1
				else:
					break
			zz = min(u, d, l, r)
			if zz == 0:
				continue
			pp.append((i + 1, j + 1, zz))
			b[i][j] = 1
			c = 0
			for k in range(i - 1, -1, -1):
				b[k][j] = 1
				c += 1
				if c == zz:
					break
			c = 0
			for k in range(i + 1, n):
				b[k][j] = 1
				c += 1
				if c == zz:
					break
			c = 0
			for k in range(j - 1, -1, -1):
				b[i][k] = 1
				c += 1
				if c == zz:
					break
			c = 0
			for k in range(j + 1, m):
				b[i][k] = 1
				c += 1
				if c == zz:
					break
fl = True
for i in range(n):
	for j in range(m):
		if a[i][j] == 1 and b[i][j] == 0:
			fl = False
			break
if fl:
	print(len(pp))
	for i in range(len(pp)):
		print(pp[i][0], pp[i][1], pp[i][2])
else:
	print(-1)


(n, m) = [int(x) for x in input().split()]
grid = [[x for x in input()] for _ in range(n)]
star_mem = {}
astr_num = set()

def l_0(x):
	return x < 1

def astr_size(x, y, size):
	for i in range(y, y + size + 1, 1):
		astr_num.add((x, i))
	for i in range(y, y - size - 1, -1):
		astr_num.add((x, i))
	for i in range(x, x + size + 1, 1):
		astr_num.add((i, y))
	for i in range(x, x - size - 1, -1):
		astr_num.add((i, y))

def is_star(grid, x, y):
	(left, right, uper, lower) = (-1, -1, -1, -1)
	for i in range(y, m, 1):
		if (x, y) in star_mem:
			left += star_mem[x, y][0]
			break
		if grid[x][i] == '*':
			left += 1
		else:
			break
	if l_0(left):
		return (False, 0)
	for i in range(y, -1, -1):
		if (x, y) in star_mem:
			right += star_mem[x, y][1]
			break
		if grid[x][i] == '*':
			right += 1
		else:
			break
	if l_0(right):
		return (False, 0)
	for i in range(x, n, 1):
		if (x, y) in star_mem:
			uper += star_mem[x, y][2]
			break
		if grid[i][y] == '*':
			uper += 1
		else:
			break
	if l_0(uper):
		return (False, 0)
	for i in range(x, -1, -1):
		if (x, y) in star_mem:
			lower += star_mem[x, y][3]
			break
		if grid[i][y] == '*':
			lower += 1
		else:
			break
	if l_0(lower):
		return (False, 0)
	star_mem[x, y] = (left, right, uper, lower)
	size = min(left, right, uper, lower)
	if size > 0:
		return (True, size)
	return (False, 0)
solution = []
uni_astr = 0
for x in range(n):
	for y in range(m):
		if grid[x][y] == '*':
			uni_astr += 1
		(con, size) = is_star(grid, x, y)
		if con:
			astr_size(x, y, size)
			solution.append((x + 1, y + 1, size))
if uni_astr == len(astr_num):
	print(len(solution))
	for i in solution:
		print(*i)
else:
	print(-1)


from math import inf as inf
(n, m) = map(int, input().split())
l = []
ans = []
for i in range(n):
	s = list(input())
	l.append(s)
	s = ['.'] * len(s)
	ans.append(s)
poss = []
for i in range(n):
	for j in range(m):
		if l[i][j] == '*':
			(h1, h2, h3, h4) = (0, 0, 0, 0)
			for x in range(j + 1, m):
				if l[i][x] == '.':
					break
				else:
					h1 += 1
			for x in range(j - 1, -1, -1):
				if l[i][x] == '.':
					break
				else:
					h2 += 1
			for x in range(i + 1, n):
				if l[x][j] == '.':
					break
				else:
					h3 += 1
			for x in range(i - 1, -1, -1):
				if l[x][j] == '.':
					break
				else:
					h4 += 1
			z = min(h1, h2, h3, h4)
			if z != 0:
				poss.append([i, j, z])
for (a, b, c) in poss:
	ans[a][b] = '*'
	x = a - 1
	temp = 0
	while temp != c:
		ans[x][b] = '*'
		x -= 1
		temp += 1
	x = a + 1
	temp = 0
	while temp != c:
		ans[x][b] = '*'
		x += 1
		temp += 1
	x = b - 1
	temp = 0
	while temp != c:
		ans[a][x] = '*'
		x -= 1
		temp += 1
	x = b + 1
	temp = 0
	while temp != c:
		ans[a][x] = '*'
		x += 1
		temp += 1
if ans == l:
	print(len(poss))
	for (a, b, c) in poss:
		print(a + 1, b + 1, c)
else:
	print(-1)


class StarCell:

	def __init__(self, row, col, top=None, bot=None, left=None, right=None):
		self.row = row
		self.col = col
		self.covered = False
		self.top = top
		self.bot = bot
		self.left = left
		self.right = right
		self._size = None
		self._size_top = None
		self._size_bot = None
		self._size_left = None
		self._size_right = None

	def set_adjacents(self, cells):
		(row, col) = (self.row, self.col)
		self.top = cells.get((row - 1, col), None)
		self.bot = cells.get((row + 1, col), None)
		self.left = cells.get((row, col - 1), None)
		self.right = cells.get((row, col + 1), None)

	def set_covered(self):
		size = self.size
		ctop = self
		cbot = self
		cleft = self
		cright = self
		for _ in range(size):
			ctop = ctop.top
			cbot = cbot.bot
			cleft = cleft.left
			cright = cright.right
			ctop.covered = True
			cbot.covered = True
			cleft.covered = True
			cright.covered = True

	@property
	def size_top(self):
		if not self.top:
			return 0
		if not self._size_top:
			self._size_top = 1 + self.top.size_top
		return self._size_top

	@property
	def size_bot(self):
		if not self.bot:
			return 0
		if not self._size_bot:
			self._size_bot = 1 + self.bot.size_bot
		return self._size_bot

	@property
	def size_left(self):
		if not self.left:
			return 0
		if not self._size_left:
			self._size_left = 1 + self.left.size_left
		return self._size_left

	@property
	def size_right(self):
		if not self.right:
			return 0
		if not self._size_right:
			self._size_right = 1 + self.right.size_right
		return self._size_right

	@property
	def size(self):
		if not self._size:
			self._size = min([self.size_top, self.size_bot, self.size_left, self.size_right])
		return self._size

	def __repr__(self):
		if self.size > 0:
			return 'Star of max size {}'.format(self.size)
		return 'Cell covered? {}'.format(self.covered)

def solve(grid):
	(n, m) = (len(grid), len(grid[0]))
	cells = {}
	for row in range(n):
		for col in range(m):
			if grid[row][col] == '.':
				continue
			cells[row, col] = StarCell(row, col)
	for (key, val) in list(cells.items()):
		val.set_adjacents(cells)
	for (key, val) in list(cells.items()):
		val.set_covered()
	ans = []
	for (key, val) in list(cells.items()):
		if val.size == 0 and (not val.covered):
			return None
		if val.size > 0:
			ans.append([val.row + 1, val.col + 1, val.size])
	return ans

def main():
	(n, m) = list(map(int, input().strip().split()))
	grid = [list(input().strip()) for _ in range(n)]
	results = solve(grid)
	if results is None:
		print('-1')
	else:
		print(len(results))
		for result in results:
			print(*result)

def __starting_point():
	main()
__starting_point()


def main():
	inp = []
	(n, m) = list(map(int, input().split()))
	remaining = 0
	for _ in range(n):
		cur_inp = input()
		inp.append(cur_inp)
		remaining += cur_inp.count('*')
	remaining2 = [[True] * m for _ in range(n)]
	res = []
	for x in range(1, n - 1):
		for y in range(1, m - 1):
			if inp[x][y] == '*':
				last_size = None
				for size in range(1, min(x + 1, n - x, y + 1, m - y)):
					if inp[x - size][y] == inp[x + size][y] == inp[x][y - size] == inp[x][y + size] == '*':
						for (x1, y1) in ((x - size, y), (x + size, y), (x, y - size), (x, y + size)):
							if remaining2[x1][y1]:
								remaining -= 1
								remaining2[x1][y1] = False
						last_size = size
					else:
						break
				if last_size is not None:
					if remaining2[x][y]:
						remaining -= 1
						remaining2[x][y] = False
					res.append((x + 1, y + 1, last_size))
	if remaining:
		print('-1')
	else:
		print(len(res))
		for x in res:
			print(*x)
main()


io = input().split()
n = int(io[0])
m = int(io[1])
arr = []
stars = []
res = []

def analitic(y, x):
	global n, m, arr
	maxValue = min(y, m - x - 1, n - y - 1, x)
	tMax = 0
	for i in range(maxValue):
		if arr[y - i - 1][x] == '.':
			tMax = i
			break
		else:
			tMax = i + 1
	rMax = 0
	for i in range(tMax):
		if arr[y][x + i + 1] == '.':
			rMax = i
			break
		else:
			rMax = i + 1
	bMax = 0
	for i in range(rMax):
		if arr[y + i + 1][x] == '.':
			bMax = i
			break
		else:
			bMax = i + 1
	lMax = 0
	for i in range(bMax):
		if arr[y][x - i - 1] == '.':
			lMax = i
			break
		else:
			lMax = i + 1
	return lMax

def draw(y, x, size):
	global arr
	arr[y][x] = '.'
	for i in range(size):
		arr[y - i - 1][x] = '.'
	for i in range(size):
		arr[y][x + i + 1] = '.'
	for i in range(size):
		arr[y + i + 1][x] = '.'
	for i in range(size):
		arr[y][x - i - 1] = '.'

class Star:

	def __init__(self, y, x, size):
		self.y = y
		self.x = x
		self.size = size
for i in range(n):
	arr.append(list(input()))
for i in range(n - 2):
	for j in range(m - 2):
		if arr[i + 1][j + 1] == '.':
			continue
		starSize = analitic(i + 1, j + 1)
		if starSize:
			stars.append(Star(i + 1, j + 1, starSize))
for i in stars:
	res.append(str(i.y + 1) + ' ' + str(i.x + 1) + ' ' + str(i.size))
	draw(i.y, i.x, i.size)
for i in range(n):
	for j in range(m):
		if arr[i][j] == '*':
			print(-1)
			exit()
count = len(res)
print(count)
for i in res:
	print(i)


(n, m) = map(int, input().split())
arr = []
for i in range(n):
	arr.append(list(input()))
vis = {}
ans = []
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if arr[i][j] == '*':
			if arr[i + 1][j] == '*' and arr[i - 1][j] == '*' and (arr[i][j + 1] == '*') and (arr[i][j - 1] == '*'):
				(w, x, y, z) = ([i + 1, j], [i - 1, j], [i, j + 1], [i, j - 1])
				vis[i, j] = 1
				while True:
					if w[0] >= n or (w[0] < n and arr[w[0]][w[1]] != '*'):
						break
					else:
						w[0] += 1
					if x[0] < 0 or (x[0] >= 0 and arr[x[0]][x[1]] != '*'):
						break
					else:
						x[0] -= 1
					if y[1] >= m or (y[1] < m and arr[y[0]][y[1]] != '*'):
						break
					else:
						y[1] += 1
					if z[1] < 0 or (z[1] >= 0 and arr[z[0]][z[1]] != '*'):
						break
					else:
						z[1] -= 1
					vis[w[0] - 1, w[1]] = 1
					vis[x[0] + 1, x[1]] = 1
					vis[y[0], y[1] - 1] = 1
					vis[z[0], z[1] + 1] = 1
				ans.append([i + 1, j + 1, min(w[0] - i - 1, i - x[0] - 1, y[1] - j - 1, j - z[1] - 1)])
flag = True
for i in range(n):
	for j in range(m):
		if arr[i][j] == '*' and (i, j) not in vis:
			flag = False
			break
if not flag:
	print(-1)
else:
	print(len(ans))
	for i in range(len(ans)):
		print(*ans[i])


(n, m) = map(int, input().split())
g = [[*input()] for _ in range(n)]
c = [[0 for _ in range(m)] for _ in range(n)]
for i in range(n):
	v = 0
	for j in range(m):
		v = (v + 1) * (g[i][j] == '*')
		c[i][j] = v
	v = 0
	for j in range(m - 1, -1, -1):
		v = (v + 1) * (g[i][j] == '*')
		c[i][j] = min(c[i][j], v)
for j in range(m):
	v = 0
	for i in range(n):
		v = (v + 1) * (g[i][j] == '*')
		c[i][j] = min(c[i][j], v)
	v = 0
	for i in range(n - 1, -1, -1):
		v = (v + 1) * (g[i][j] == '*')
		c[i][j] = min(c[i][j], v)
for i in range(n):
	for j in range(m):
		if c[i][j] == 1:
			c[i][j] = 0
for i in range(n):
	v = 0
	for j in range(m):
		v = max(v - 1, c[i][j])
		if v:
			g[i][j] = '.'
	v = 0
	for j in range(m - 1, -1, -1):
		v = max(v - 1, c[i][j])
		if v:
			g[i][j] = '.'
for j in range(m):
	v = 0
	for i in range(n):
		v = max(v - 1, c[i][j])
		if v:
			g[i][j] = '.'
	for i in range(n - 1, -1, -1):
		v = max(v - 1, c[i][j])
		if v:
			g[i][j] = '.'
if all((g[i][j] == '.' for i in range(n) for j in range(m))):
	r = [(i + 1, j + 1, c[i][j] - 1) for i in range(n) for j in range(m) if c[i][j]]
	print(len(r))
	for t in r:
		print(*t)
else:
	print(-1)


import sys
sys.setrecursionlimit(2000)
from collections import Counter
from functools import reduce

def determine_star(grid, row, col, n, m):
	size = 1
	while True:
		score = 0
		score += int(col + size < m and grid[row][col + size] == '*')
		score += int(col - size >= 0 and grid[row][col - size] == '*')
		score += int(row + size < n and grid[row + size][col] == '*')
		score += int(row - size >= 0 and grid[row - size][col] == '*')
		if score == 0:
			if size == 1:
				return (False, 0)
			else:
				return (True, size - 1)
		elif score < 4:
			if size != 1:
				return (True, size - 1)
			else:
				return (False, 0)
		size += 1

def cover_star(grid, row, col, size):
	ind = 0
	while ind <= size:
		grid[row + ind][col] = 'x'
		grid[row - ind][col] = 'x'
		grid[row][col + ind] = 'x'
		grid[row][col - ind] = 'x'
		ind += 1
(n, m) = [int(val) for val in input().split()]
grid = [[val for val in input()] for row in range(n)]
stars = []
for row in range(n):
	for col in range(m):
		if grid[row][col] == '*':
			thing = determine_star(grid, row, col, n, m)
			if thing[0]:
				stars.append((row, col, thing[1]))
for star in stars:
	cover_star(grid, star[0], star[1], star[2])
summ = 0
for row in range(n):
	summ += sum([1 for val in grid[row] if val == '*'])
if summ == 0:
	print(len(stars))
	for star in stars:
		print(star[0] + 1, star[1] + 1, star[2])
else:
	print(-1)


(n, m) = map(int, input().split())
s = [input() for row in range(n)]
f = [[(column == '*') & 1 for column in row] for row in s]
result = []
seq_row = [[] for row in range(0, n)]
seq_column = [[] for column in range(0, m)]
dp = [[[0 for _ in range(0, m)] for __ in range(0, n)] for ___ in range(0, 2)]

def all_vis():
	merge_row = [[] for row in range(0, n)]
	merge_column = [[] for column in range(0, m)]
	vis = [[0 for row in range(0, m)] for column in range(0, n)]
	for i in range(0, n):
		left = -1
		right = -1
		seq_row[i].sort()
		for j in range(0, len(seq_row[i])):
			if left == -1:
				left = seq_row[i][j][0]
				right = seq_row[i][j][1]
			elif left <= seq_row[i][j][0] <= right:
				right = max(right, seq_row[i][j][1])
			else:
				merge_row[i].append((left, right))
				left = -1
				right = -1
		if left != -1 and right != -1:
			merge_row[i].append((left, right))
	for i in range(0, m):
		left = -1
		right = -1
		seq_column[i].sort()
		for j in range(0, len(seq_column[i])):
			if left == -1:
				left = seq_column[i][j][0]
				right = seq_column[i][j][1]
			elif left <= seq_column[i][j][0] <= right:
				right = max(right, seq_column[i][j][1])
			else:
				merge_column[i].append((left, right))
				left = -1
				right = -1
		if left != -1 and right != -1:
			merge_column[i].append((left, right))
	for i in range(0, n):
		for j in range(0, len(seq_row[i])):
			for k in range(seq_row[i][j][0], seq_row[i][j][1] + 1):
				vis[i][k] = 1
	for i in range(0, m):
		for j in range(0, len(seq_column[i])):
			for k in range(seq_column[i][j][0], seq_column[i][j][1] + 1):
				vis[k][i] = 1
	sum1 = 0
	sum2 = 0
	for i in range(0, n):
		for j in range(0, m):
			sum1 += vis[i][j] == 1
			sum2 += f[i][j] == 1
	return sum1 == sum2

def init_dp():
	for i in range(0, n):
		dp[0][i][0] = f[i][0]
		for j in range(1, m):
			dp[0][i][j] = dp[0][i][j - 1] + f[i][j]
	for j in range(0, m):
		dp[1][0][j] = f[0][j]
		for i in range(1, n):
			dp[1][i][j] = dp[1][i - 1][j] + f[i][j]

def get(row, column, mid):
	if not (row - mid >= 0 and row + mid < n and (column - mid >= 0) and (column + mid < m)):
		return False
	l = dp[0][row][column - 1]
	r = dp[0][row][column + mid] - dp[0][row][column]
	u = dp[1][row - 1][column]
	d = dp[1][row + mid][column] - dp[1][row][column]
	if row - mid != 0:
		u = u - dp[1][row - mid - 1][column]
	if column - mid != 0:
		l = l - dp[0][row][column - mid - 1]
	return l == r == u == d == mid

def b_search(left, right, row, column):
	mid = (left + right) // 2
	while left != mid and mid != right:
		if not get(row, column, mid):
			right = mid
		else:
			left = mid
		mid = (left + right) // 2
	if get(row, column, right):
		return right
	if get(row, column, left):
		return left
	return -1
init_dp()
for row in range(0, n, 1):
	for column in range(0, m, 1):
		if f[row][column]:
			max_size = b_search(1, max(n, m), row, column)
			if max_size > 0:
				seq_row[row].append((column - max_size, column + max_size))
				seq_column[column].append((row - max_size, row + max_size))
				result.append([row + 1, column + 1, max_size])
if not all_vis():
	print(-1)
else:
	print(len(result))
	for i in range(0, len(result), 1):
		print(result[i][0], result[i][1], result[i][2])


(n, m) = input().split()
n = int(n)
m = int(m)
lst = [[0] * m for i in range(n)]
rec = [[0] * m for i in range(n)]
fin = [[0] * m for i in range(n)]
ans = 0
cnt = 0
for i in range(n):
	tmp = input()
	for (j, x) in enumerate(tmp):
		if x == '*':
			lst[i][j] = 1
for i in range(n):
	for j in range(m):
		if lst[i][j] == 1 and i > 0 and (j > 0) and (i < n - 1) and (j < m - 1):
			tmp = min(i, j, n - 1 - i, m - 1 - j)
			for k in range(tmp, 0, -1):
				flag = True
				for x in range(1, k + 1):
					if lst[i][j - x] == 0 or lst[i][j + x] == 0 or lst[i - x][j] == 0 or (lst[i + x][j] == 0):
						flag = False
				if flag:
					fin[i][j] = k
					break
for i in range(n):
	for j in range(m):
		if fin[i][j] > 0:
			tmp = fin[i][j]
			ans += 1
			cnt += 1 + tmp * 4
			rec[i][j] = 1
			for x in range(tmp + 1):
				rec[i][j + x] = 1
				rec[i][j - x] = 1
				rec[i - x][j] = 1
				rec[i + x][j] = 1
if rec != lst:
	print(-1)
else:
	print(ans)
	for i in range(n):
		for j in range(m):
			if fin[i][j] > 0:
				print(i + 1, j + 1, fin[i][j])


import sys
from itertools import accumulate

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
INF = 10 ** 18
MOD = 10 ** 9 + 7

def build_grid(H, W, intv, _type, space=True, padding=False):
	if space:
		_input = lambda : input().split()
	else:
		_input = lambda : input()
	_list = lambda : list(map(_type, _input()))
	if padding:
		offset = 1
	else:
		offset = 0
	grid = list2d(H + offset * 2, W + offset * 2, intv)
	for i in range(offset, H + offset):
		row = _list()
		for j in range(offset, W + offset):
			grid[i][j] = row[j - offset]
	return grid
(H, W) = MAP()
grid = build_grid(H, W, '#', str, space=0, padding=1)
ans = []
imosw = list2d(H + 2, W + 2, 0)
imosh = list2d(H + 2, W + 2, 0)

def check(i, j):
	sz = min(L[i][j], R[i][j], U[i][j], D[i][j])
	if sz > 1:
		imosw[i][j - sz + 1] += 1
		imosw[i][j + sz] -= 1
		imosh[i - sz + 1][j] += 1
		imosh[i + sz][j] -= 1
		ans.append((i, j, sz - 1))

def check2():
	for i in range(1, H + 1):
		for j in range(1, W + 1):
			if grid[i][j] == '*' and (not imosw[i][j]) and (not imosh[i][j]):
				return False
	return True
L = list2d(H + 2, W + 2, 0)
R = list2d(H + 2, W + 2, 0)
U = list2d(H + 2, W + 2, 0)
D = list2d(H + 2, W + 2, 0)
for i in range(1, H + 1):
	for j in range(1, W + 1):
		if grid[i][j] == '.':
			L[i][j] = 0
		else:
			L[i][j] = L[i][j - 1] + 1
for i in range(1, H + 1):
	for j in range(W, 0, -1):
		if grid[i][j] == '.':
			R[i][j] = 0
		else:
			R[i][j] = R[i][j + 1] + 1
for j in range(1, W + 1):
	for i in range(1, H + 1):
		if grid[i][j] == '.':
			U[i][j] = 0
		else:
			U[i][j] = U[i - 1][j] + 1
for j in range(1, W + 1):
	for i in range(H, 0, -1):
		if grid[i][j] == '.':
			D[i][j] = 0
		else:
			D[i][j] = D[i + 1][j] + 1
for i in range(1, H + 1):
	for j in range(1, W + 1):
		if grid[i][j] == '*':
			check(i, j)
for i in range(1, H + 1):
	for j in range(W + 1):
		imosw[i][j + 1] += imosw[i][j]
for j in range(1, W + 1):
	for i in range(H + 1):
		imosh[i + 1][j] += imosh[i][j]
if check2():
	print(len(ans))
	[print(h, w, sz) for (h, w, sz) in ans]
else:
	print(-1)


import sys
(n, m) = map(int, input().split())
a = []
k = 0
ans = []
for line in sys.stdin:
	a.append(list(line))
	a[-1].pop()
for i in range(n):
	for j in range(m):
		if a[i][j] == '*':
			ni = i
			nj = j
			p = 0
			l = 0
			v = 0
			vn = 0
			while i < n - 1:
				i += 1
				if a[i][j] == '*':
					p += 1
				else:
					break
			i = ni
			while i > 0:
				i -= 1
				if a[i][j] == '*':
					l += 1
				else:
					break
			i = ni
			while j > 0:
				j -= 1
				if a[i][j] == '*':
					v += 1
				else:
					break
			j = nj
			while j < m - 1:
				j += 1
				if a[i][j] == '*':
					vn += 1
				else:
					break
			j = nj
			if min(p, l, v, vn) >= 1:
				ans.append([i + 1, j + 1, min(p, l, v, vn)])
				k += 1
a1 = []
for i in range(n):
	a1.append(['.'] * m)
for h in range(k):
	i = ans[h][0] - 1
	j = ans[h][1] - 1
	z = ans[h][2]
	a1[i][j] = '*'
	for b in range(1, z + 1):
		a1[i + b][j] = '*'
		a1[i - b][j] = '*'
		a1[i][j + b] = '*'
		a1[i][j - b] = '*'
if a1 == a:
	print(k)
	for i in ans:
		print(*i)
else:
	print(-1)


def i_ints():
	return map(int, input().split())

def stars_to_the_left(s):
	res = []
	n = len(s)
	l = 0
	while l < n:
		r = s.find('*', l)
		if r == -1:
			r = n
		res.extend([0] * (r - l))
		l = s.find('.', r)
		if l == -1:
			l = n
		res.extend(range(1, l - r + 1))
	return res

def main():
	(n, m) = i_ints()
	global cols, ups
	rows = [input() for i in range(n)]
	raveled = ''.join(rows)
	cols = [raveled[i::m] for i in range(m)]
	lefts = [stars_to_the_left(row) for row in rows]
	rights = [stars_to_the_left(row[::-1])[::-1] for row in rows]
	downs = [stars_to_the_left(col) for col in cols]
	ups = [stars_to_the_left(col[::-1])[::-1] for col in cols]
	lr = []
	for l in lefts:
		lr.extend(l)
	rr = []
	for r in rights:
		rr.extend(r)
	dr = [0] * (n * m)
	for (i, d) in enumerate(downs):
		dr[i::m] = d
	ur = [0] * (n * m)
	for (i, u) in enumerate(ups):
		ur[i::m] = u
	res = []
	todo = rr[:]
	for (i, lengths) in enumerate(zip(lr, rr, dr, ur)):
		length = min(lengths) - 1
		if length > 0:
			(x, y) = divmod(i, m)
			res.append((x + 1, y + 1, length))
			todo[i - length * m:i + length * m + m:m] = todo[i - length:i + length + 1] = [0] * (2 * length + 1)
	if max(todo) > 0:
		print(-1)
	else:
		print(len(res))
		for r in res:
			print(*r)
main()


import re
import sys
exit = sys.exit
from bisect import bisect_left as bsl, bisect_right as bsr
from collections import Counter, defaultdict as ddict, deque
from functools import lru_cache
cache = lru_cache(None)
from heapq import *
from itertools import *
from math import inf
from pprint import pprint as pp
enum = enumerate
ri = lambda : int(rln())
ris = lambda : list(map(int, rfs()))
rln = sys.stdin.readline
rl = lambda : rln().rstrip('\n')
rfs = lambda : rln().split()
mod = 1000000007
d4 = [(0, -1), (1, 0), (0, 1), (-1, 0)]
d8 = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]
(m, n) = ris()
A = [list(rl()) for _ in range(m)]
if '*' in {A[0][0], A[0][-1], A[-1][0], A[-1][-1]}:
	print(-1)
	exit()
U = [[0] * n for _ in range(m)]
D = [[0] * n for _ in range(m)]
L = [[0] * n for _ in range(m)]
R = [[0] * n for _ in range(m)]
rem = 0
CC = [0] * n
RC = [0] * m
for i in range(m):
	for j in range(n):
		if A[i][j] == '.':
			continue
		U[i][j] = 1 + (U[i - 1][j] if i > 0 else 0)
		L[i][j] = 1 + (L[i][j - 1] if j > 0 else 0)
		rem += 1
		RC[i] += 1
		CC[j] += 1
for i in range(m - 1, -1, -1):
	for j in range(n - 1, -1, -1):
		if A[i][j] == '.':
			continue
		R[i][j] = 1 + (R[i][j + 1] if j + 1 < n else 0)
		D[i][j] = 1 + (D[i + 1][j] if i + 1 < m else 0)
stars = []
for i in range(1, m - 1):
	for j in range(1, n - 1):
		if A[i][j] == '.':
			continue
		s = min(U[i - 1][j], R[i][j + 1], D[i + 1][j], L[i][j - 1])
		if s == 0:
			continue
		stars.append((i, j, s))
for (i, j, s) in sorted(stars, key=lambda x: -x[2]):
	for k in range(i - s, i + s + 1):
		if CC[j] == 0:
			break
		if A[k][j] == '*':
			A[k][j] = '.'
			rem -= 1
			RC[k] -= 1
			CC[j] -= 1
	for k in range(j - s, j + s + 1):
		if RC[i] == 0:
			break
		if A[i][k] == '*':
			A[i][k] = '.'
			rem -= 1
			RC[i] -= 1
			CC[k] -= 1
	if rem == 0:
		break
if rem > 0:
	print(-1)
	exit()
print(len(stars))
for (i, j, s) in stars:
	print(i + 1, j + 1, s)


import sys, os, io
from sys import stdin
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
t = 1
for _ in range(t):
	(n, m) = [int(x) for x in input().split()]
	l = []
	temp = []
	for i in range(n):
		l.append(list(input()))
		temp.append(['.'] * m)
	ans = []
	for i in range(n):
		for j in range(m):
			ui = i - 1
			di = i + 1
			lj = j - 1
			rj = j + 1
			if l[i][j] == '*':
				cnt = 0
				while ui >= 0 and lj >= 0 and (di < n) and (rj < m):
					if l[ui][j] == l[i][lj] == l[di][j] == l[i][rj] == '*':
						temp[ui][j] = temp[i][lj] = temp[di][j] = temp[i][rj] = '*'
						ui -= 1
						lj -= 1
						di += 1
						rj += 1
						cnt += 1
					else:
						break
				if cnt != 0:
					temp[i][j] = '*'
					ans.append([i + 1, j + 1, cnt])
	f = 0
	for i in range(n):
		for j in range(m):
			if l[i][j] == '*' and temp[i][j] == '.':
				f = 1
				break
	if f == 0:
		print(len(ans))
		for i in ans:
			print(*i)
	else:
		print(-1)


(n, m) = map(int, input().split())
sky = [0] * (n + 1)
for i in range(n):
	sky[i] = list(input()) + ['.']
sky[n] = ['.'] * m
used = [[False] * m for i in range(n)]
ans = []
for i in range(n):
	for j in range(m):
		if sky[i][j] == '.':
			continue
		ln = 1
		while sky[i - ln][j] == '*' and sky[i + ln][j] == '*' and (sky[i][j - ln] == '*') and (sky[i][j + ln] == '*'):
			used[i - ln][j] = used[i + ln][j] = used[i][j - ln] = used[i][j + ln] = True
			ln += 1
		if ln > 1:
			used[i][j] = True
			ans += [[i + 1, j + 1, ln - 1]]
for i in range(n):
	for j in range(m):
		if sky[i][j] == '*' and (not used[i][j]):
			print(-1)
			exit(0)
print(len(ans))
for i in range(len(ans)):
	print(*ans[i])


(n, m) = map(int, input().split())
T = [[] for i in range(n)]
for i in range(n):
	a = list(input())
	T[i] = a
S = [[0] * m for i in range(n)]
for i in range(n):
	for j in range(m):
		if T[i][j] == '*':
			S[i][j] = 1
rec = []
for i in range(n):
	for j in range(m):
		if 1 <= i < n - 1 and 1 <= j < m - 1 and (T[i][j] == '*') and (T[i - 1][j] == '*') and (T[i][j - 1] == '*') and (T[i + 1][j] == '*') and (T[i][j + 1] == '*'):
			S[i][j] = 0
			S[i - 1][j] = 0
			S[i][j - 1] = 0
			S[i + 1][j] = 0
			S[i][j + 1] = 0
			k = 2
			while True:
				if not (0 <= i - k and i + k < n and (0 <= j - k) and (j + k < m)):
					break
				if T[i - k][j] == '*' and T[i][j - k] == '*' and (T[i + k][j] == '*') and (T[i][j + k] == '*'):
					S[i - k][j] = 0
					S[i][j - k] = 0
					S[i + k][j] = 0
					S[i][j + k] = 0
					k += 1
				else:
					break
			rec.append((i + 1, j + 1, k - 1))
q = 0
for i in range(n):
	for j in range(m):
		q += S[i][j]
if q == 0:
	print(len(rec))
	for i in range(len(rec)):
		print('{} {} {}'.format(rec[i][0], rec[i][1], rec[i][2]))
else:
	print(-1)


(n, m) = [int(t) for t in input().split()]
field = [list(input()) for _ in range(n)]
done = [list(map(lambda t: t != '*', line)) for line in field]
muls = sum((t.count('*') for t in field))

def fit_hor(x):
	return 0 <= x < m

def fit_ver(y):
	return 0 <= y < n

def mark(x, y):
	global muls
	global done
	if not done[x][y]:
		done[x][y] = True
		muls -= 1

def get_star_size(i, j):
	size = 0
	i_u = i - 1
	i_d = i + 1
	j_r = j + 1
	j_l = j - 1
	if field[i][j] == '*':
		while fit_hor(j_r) and fit_hor(j_l) and fit_ver(i_u) and fit_ver(i_d) and ('*' == field[i][j_r] == field[i][j_l] == field[i_d][j] == field[i_u][j]):
			mark(i, j_r)
			mark(i, j_l)
			mark(i_u, j)
			mark(i_d, j)
			size += 1
			i_u -= 1
			i_d += 1
			j_r += 1
			j_l -= 1
	return size
stars = []
for i in range(n):
	for j in range(m):
		sz = get_star_size(i, j)
		if sz > 0:
			mark(i, j)
			stars.append((i, j, sz))
if muls > 0:
	print(-1)
else:
	print(len(stars))
	for (i, j, s) in stars:
		print(i + 1, j + 1, s)


import sys
input = sys.stdin.readline

def p(board):
	for row in board:
		print(*row)
(n, m) = map(int, input().split())
grid = [list(input().strip('\n')) for i in range(n)]
up = [[0 for i in range(m)] for j in range(n)]
down = [[0 for i in range(m)] for j in range(n)]
left = [[0 for i in range(m)] for j in range(n)]
right = [[0 for i in range(m)] for j in range(n)]
for i in range(1, n):
	for j in range(m):
		if grid[i - 1][j] == '*':
			up[i][j] = up[i - 1][j] + 1
for i in range(n - 2, -1, -1):
	for j in range(m):
		if grid[i + 1][j] == '*':
			down[i][j] = down[i + 1][j] + 1
for j in range(1, m):
	for i in range(n):
		if grid[i][j - 1] == '*':
			left[i][j] = left[i][j - 1] + 1
for j in range(m - 2, -1, -1):
	for i in range(n):
		if grid[i][j + 1] == '*':
			right[i][j] = right[i][j + 1] + 1
stars = []
for i in range(n):
	for j in range(m):
		if grid[i][j] == '*':
			s = min(up[i][j], down[i][j], right[i][j], left[i][j])
			if s:
				stars.append((i, j, s))
new = [['.' for i in range(m)] for j in range(n)]
for (x, y, s) in stars:
	for i in range(-s, s + 1):
		new[x + i][y] = '*'
		new[x][y + i] = '*'
if new == grid:
	print(len(stars))
	for (i, j, x) in stars:
		print(i + 1, j + 1, x)
else:
	print(-1)


def main():
	(n, m) = map(int, input().split())
	ll = [c == '*' for _ in range(n) for c in input()]
	nm = n * m
	RLUD = [*[range(i, i + m) for i in range(0, nm, m)], *[range(i, nm, m) for i in range(m)]]
	cc = [1000] * nm
	for f in (True, False):
		for r in RLUD:
			v = 0
			for i in r:
				if ll[i]:
					v += 1
					if cc[i] > v:
						cc[i] = v
				else:
					v = cc[i] = 0
		if f:
			ll.reverse()
			cc.reverse()
	cc = [c if c != 1 else 0 for c in cc]
	for f in (True, False):
		for r in RLUD:
			v = 0
			for i in r:
				if v > cc[i]:
					v -= 1
				else:
					v = cc[i]
				if v:
					ll[i] = False
		if f:
			ll.reverse()
			cc.reverse()
	if any(ll):
		print(-1)
	else:
		res = []
		for (i, c) in enumerate(cc):
			if c:
				res.append(f'{i // m + 1} {i % m + 1} {c - 1}')
		print(len(res), '\n'.join(res), sep='\n')
main()


import sys
(n, m) = map(int, input().split())
s = [list(input()) for i in range(n)]
u = [[-1 for i in range(m)] for j in range(n)]
d = [[-1 for i in range(m)] for j in range(n)]
l = [[-1 for i in range(m)] for j in range(n)]
r = [[-1 for i in range(m)] for j in range(n)]
for i in range(m):
	acum = 0
	for j in range(n):
		if s[j][i] == '.':
			acum = 0
		else:
			acum += 1
		u[j][i] = acum
for i in range(m):
	acum = 0
	for j in range(n - 1, -1, -1):
		if s[j][i] == '.':
			acum = 0
		else:
			acum += 1
		d[j][i] = acum
for i in range(n):
	acum = 0
	for j in range(m):
		if s[i][j] == '.':
			acum = 0
		else:
			acum += 1
		l[i][j] = acum
for i in range(n):
	acum = 0
	for j in range(m - 1, -1, -1):
		if s[i][j] == '.':
			acum = 0
		else:
			acum += 1
		r[i][j] = acum
ans = []
t1 = [[0 for i in range(m)] for j in range(n)]
t2 = [[0 for i in range(m)] for j in range(n)]
for i in range(n):
	for j in range(m):
		d1 = min(l[i][j], r[i][j], u[i][j], d[i][j]) - 1
		if d1 > 0:
			ans.append([i + 1, j + 1, d1])
			t1[i + d1][j] += 1
			t1[i - d1][j] -= 1
			t2[i][j - d1] += 1
			t2[i][j + d1] -= 1
dp = [['.' for i in range(m)] for j in range(n)]
for i in range(n):
	acum = 0
	for j in range(m):
		acum += t2[i][j]
		if acum != 0 or t2[i][j] != 0:
			dp[i][j] = '*'
for i in range(m):
	acum = 0
	for j in range(n):
		acum += t1[j][i]
		if acum != 0 or t1[j][i] != 0:
			dp[j][i] = '*'
if dp != s:
	print(-1)
	sys.exit()
print(len(ans))
for i in ans:
	print(*i)


def all_true(stars, n, m):
	for i in range(n):
		for j in range(m):
			if not stars[i][j]:
				return False
	return True

def get_biggest_star(ar, i, j):
	ans = 0
	cur = i - 1
	while cur >= 0 and ar[cur][j] == '*':
		ans += 1
		cur -= 1
	length = 0
	cur = i + 1
	while cur < n and ar[cur][j] == '*':
		length += 1
		cur += 1
	ans = min(ans, length)
	length = 0
	cur = j - 1
	while cur >= 0 and ar[i][cur] == '*':
		length += 1
		cur -= 1
	ans = min(ans, length)
	length = 0
	cur = j + 1
	while cur < m and ar[i][cur] == '*':
		length += 1
		cur += 1
	ans = min(ans, length)
	return ans
(n, m) = map(int, input().split())
ar = []
stars = []
for i in range(n):
	cur = input()
	st = []
	for i in range(m):
		if cur[i] == '.':
			st.append(True)
		else:
			st.append(False)
	stars.append(st)
	ar.append(cur)
finalAns = []
ans = 0
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if ar[i][j] == '.':
			continue
		length = get_biggest_star(ar, i, j)
		if length > 0:
			ans += 1
			finalAns.append([i + 1, j + 1, length])
			stars[i][j] = True
			temp = 0
			while temp < length:
				temp += 1
				stars[i - temp][j] = True
			temp = 0
			while temp < length:
				temp += 1
				stars[i + temp][j] = True
			temp = 0
			while temp < length:
				temp += 1
				stars[i][j - temp] = True
			temp = 0
			while temp < length:
				temp += 1
				stars[i][j + temp] = True
if all_true(stars, n, m):
	print(ans)
	for i in finalAns:
		print(*i)
else:
	print(-1)


def main():
	(n, m) = map(int, input().split())
	w = [c == '*' for i in range(n) for c in input()]
	nm = n * m
	q = [*[range(i, i + m) for i in range(0, nm, m)], *[range(i, nm, m) for i in range(m)]]
	e = [1000] * nm
	for f in (True, False):
		for r in q:
			v = 0
			for i in r:
				if w[i]:
					v += 1
					if e[i] > v:
						e[i] = v
				else:
					v = e[i] = 0
		if f:
			w.reverse()
			e.reverse()
	e = [c if c != 1 else 0 for c in e]
	for f in (True, False):
		for r in q:
			v = 0
			for i in r:
				if v > e[i]:
					v -= 1
				else:
					v = e[i]
				if v:
					w[i] = False
		if f:
			w.reverse()
			e.reverse()
	if any(w):
		print(-1)
	else:
		r = []
		for (i, c) in enumerate(e):
			if c:
				r.append(f'{i // m + 1} {i % m + 1} {c - 1}')
		print(len(r), '\n'.join(r), sep='\n')
main()


(n, m) = input().split()
n = int(n)
m = int(m)
mat = []
count = 0
for i in range(n):
	temp = input()
	mat.append(temp)
	for j in temp:
		if j == '*':
			count += 1
Map = {}
ans = {}
for i in range(n):
	for j in range(m):
		if mat[i][j] == '*':
			u = [i - 1, j]
			d = [i + 1, j]
			r = [i, j + 1]
			l = [i, j - 1]
			size = 0
			while u[0] >= 0 and d[0] < n and (r[1] < m) and (l[1] >= 0) and (mat[u[0]][u[1]] == '*') and (mat[d[0]][d[1]] == '*') and (mat[l[0]][l[1]] == '*') and (mat[r[0]][r[1]] == '*'):
				if (u[0], u[1]) not in Map and (u[0], u[1]) not in ans:
					Map[u[0], u[1]] = True
				if (d[0], d[1]) not in Map and (d[0], d[1]) not in ans:
					Map[d[0], d[1]] = True
				if (l[0], l[1]) not in Map and (l[0], l[1]) not in ans:
					Map[l[0], l[1]] = True
				if (r[0], r[1]) not in Map and (r[0], r[1]) not in ans:
					Map[r[0], r[1]] = True
				u = [u[0] - 1, j]
				d = [d[0] + 1, j]
				l = [i, l[1] - 1]
				r = [i, r[1] + 1]
				size += 1
			if size > 0:
				if (i, j) in Map:
					del Map[i, j]
				ans[i, j] = size
if len(Map) + len(ans) != count:
	print(-1)
else:
	print(len(ans))
	for key in ans:
		print(key[0] + 1, key[1] + 1, ans[key])


(n, m) = map(int, input().split())
import sys
a = [[c for c in l.strip()] for l in sys.stdin]
ans = []
for i in range(n):
	for j in range(m):
		b = a[i][j]
		for k in range(1, 101):
			if i > k - 1 and i < n - k and (j > k - 1) and (j < m - k) and (b == '*'):
				if a[i + k][j] == '*' and a[i - k][j] == '*' and (a[i][j + k] == '*') and (a[i][j - k] == '*'):
					if k == 1:
						ans.append([i + 1, j + 1, k])
					else:
						ans.pop()
						ans.append([i + 1, j + 1, k])
				else:
					break
c = [['.'] * m for i in range(n)]
for i in range(len(ans)):
	(d, e, f) = ans[i]
	d -= 1
	e -= 1
	c[d][e] = '*'
	for j in range(1, f + 1):
		c[d + j][e] = '*'
		c[d - j][e] = '*'
		c[d][e + j] = '*'
		c[d][e - j] = '*'
if c == a:
	print(len(ans))
	for i in range(len(ans)):
		a = map(str, ans[i])
		print(' '.join(a))
else:
	print(-1)


from collections import defaultdict, deque
from heapq import heappush, heappop
from math import inf
ri = lambda : map(int, input().split())

def solve():
	(n, m) = ri()
	A = [[0 for _ in range(m)] for __ in range(n)]
	left = [[0 for _ in range(m)] for __ in range(n)]
	right = [[0 for _ in range(m)] for __ in range(n)]
	up = [[0 for _ in range(m)] for __ in range(n)]
	down = [[0 for _ in range(m)] for __ in range(n)]
	for r in range(n):
		lst = input()
		for c in range(m):
			if lst[c] == '*':
				A[r][c] = left[r][c] = right[r][c] = up[r][c] = down[r][c] = 1
	for r in range(n):
		for c in range(1, m):
			if A[r][c]:
				left[r][c] += left[r][c - 1]
		for c in range(m - 2, -1, -1):
			if A[r][c]:
				right[r][c] += right[r][c + 1]
	for c in range(m):
		for r in range(1, n):
			if A[r][c]:
				up[r][c] += up[r - 1][c]
		for r in range(n - 2, -1, -1):
			if A[r][c]:
				down[r][c] += down[r + 1][c]
	res = []
	stars = 0
	ROWS = [[0 for _ in range(m)] for __ in range(n)]
	COLS = [[0 for _ in range(m)] for __ in range(n)]
	for r in range(n):
		for c in range(m):
			if A[r][c]:
				can = min(left[r][c], right[r][c], up[r][c], down[r][c])
				can -= 1
				if can > 0:
					stars += 1
					res.append((r + 1, c + 1, can))
				ROWS[r - can][c] += can
				if r + can + 1 < n:
					ROWS[r + can + 1][c] -= can
				COLS[r][c - can] += can
				if c + can + 1 < m:
					COLS[r][c + can + 1] -= can
	valid = [[False for _ in range(m)] for __ in range(n)]
	for r in range(n):
		curr = 0
		for c in range(m):
			curr += COLS[r][c]
			if curr > 0:
				valid[r][c] = True
	for c in range(m):
		curr = 0
		for r in range(n):
			curr += ROWS[r][c]
			if curr > 0:
				valid[r][c] = True
	for r in range(n):
		for c in range(m):
			if A[r][c] and (not valid[r][c]):
				print(-1)
				return
	print(stars)
	for (x, y, z) in res:
		print(x, y, z)
t = 1
while t:
	t -= 1
	solve()


(n, m) = input().strip().split(' ')
n = int(n)
m = int(m)
grid = []
for i in range(n):
	grid.append(input())
mask = [[0] * m for _ in range(n)]
stars = dict()
for i in range(n):
	for j in range(m):
		if grid[i][j] == '.':
			mask[i][j] = 1
		else:
			stars[i, j] = 1

def get_largest_star(i, j):
	for x in range(1, min(i, n - i - 1, j, m - j - 1) + 1):
		if grid[i + x][j] != '*' or grid[i - x][j] != '*' or grid[i][j - x] != '*' or (grid[i][j + x] != '*'):
			return x - 1
	return min(i, n - i - 1, j, m - j - 1)

def fill_map(i, j, x):
	global mask
	mask[i][j] = 1
	for y in range(1, x + 1):
		mask[i + y][j] = mask[i - y][j] = mask[i][j + y] = mask[i][j - y] = 1
num_stars = 0
my_stars = []
for star in stars:
	x = get_largest_star(star[0], star[1])
	if x > 0:
		num_stars += 1
		my_stars.append([star[0], star[1], x])
		fill_map(star[0], star[1], x)
possible = True
for i in range(n):
	for j in range(m):
		if mask[i][j] == 0:
			possible = False
			break
if not possible:
	print(-1)
else:
	print(num_stars)
	for star in my_stars:
		print(str(star[0] + 1) + ' ' + str(star[1] + 1) + ' ' + str(star[2]))


def main():
	(n, m) = map(int, input().split())
	grid = []
	for i in range(n):
		grid.append(input())
	visited = set()
	ans = {}
	for l in range(1, min(n, m)):
		for row in range(l, n - l):
			for col in range(l, m - l):
				new = set()
				found = True
				for col1 in range(col, col - l - 1, -1):
					new.add((row, col1))
					if grid[row][col1] != '*':
						found = False
						break
				if found:
					for col1 in range(col, col + l + 1):
						new.add((row, col1))
						if grid[row][col1] != '*':
							found = False
							break
				if found:
					for row1 in range(row, row - l - 1, -1):
						new.add((row1, col))
						if grid[row1][col] != '*':
							found = False
							break
				if found:
					for row1 in range(row, row + l + 1):
						new.add((row1, col))
						if grid[row1][col] != '*':
							found = False
							break
				if found:
					if (row + 1, col + 1) not in ans.keys():
						ans[row + 1, col + 1] = l
					else:
						ans[row + 1, col + 1] = max(ans[row + 1, col + 1], l)
					for i in new:
						visited.add(i)
	for row in range(n):
		for col in range(m):
			if grid[row][col] == '*' and (row, col) not in visited:
				print(-1)
				return
	print(len(ans))
	for i in ans.keys():
		print(i[0], i[1], ans[i])
main()


import sys
import math
import os.path
from copy import deepcopy
from functools import reduce
from pprint import pprint
from collections import Counter, ChainMap, defaultdict
from itertools import cycle, chain
from queue import Queue, PriorityQueue, deque
from heapq import heappush, heappop, heappushpop, heapify, heapreplace, nlargest, nsmallest
import bisect
from statistics import mean, mode, median, median_low, median_high
sys.setrecursionlimit(10 ** 9)

def log(*args, **kwargs):
	print(*args, file=sys.stderr, **kwargs)

def ni():
	return list(map(int, input().split()))

def nio(offset):
	return [int(x) + offset for x in input().split()]

def nia():
	return list(map(int, input().split()))

def toString(aList, sep=' '):
	return sep.join((str(x) for x in aList))

def toMapInvertIndex(aList):
	return {k: v for (v, k) in enumerate(aList)}

def sortId(arr):
	return sorted(list(range(len(arr))), key=lambda k: arr[k])
(n, m) = ni()
s = [0] * n
for i in range(n):
	ss = input()
	s[i] = ss
dd = [['.' for j in range(m)] for i in range(n)]
res = deque()
for i in range(n):
	for j in range(m):
		if s[i][j] == '*':
			k = 1
			while 0 <= i - k < n and 0 <= i + k < n and (0 <= j - k < m) and (0 <= j + k < m) and (s[i - k][j] == '*') and (s[i + k][j] == '*') and (s[i][j - k] == '*') and (s[i][j + k] == '*'):
				dd[i - k][j] = '*'
				dd[i + k][j] = '*'
				dd[i][j - k] = '*'
				dd[i][j + k] = '*'
				if k == 1:
					dd[i][j] = '*'
					res.append((i + 1, j + 1, k))
				else:
					res[-1] = (i + 1, j + 1, k)
				k += 1

def check():
	for i in range(n):
		for j in range(m):
			if s[i][j] != dd[i][j]:
				return False
	return True
if check():
	lres = len(res)
	print(lres)
	if lres > 0:
		print('\n'.join((' '.join((str(y) for y in x)) for x in res)))
else:
	print(-1)


from sys import stdin, stdout

def main():
	(n, m) = map(int, stdin.readline().split())
	A = [list(stdin.readline()[:-1]) for _ in range(n)]
	B = [[False for _ in range(m)] for __ in range(n)]

	def star(i, j, x):
		if i - x >= 0 and i + x < n and (j - x >= 0) and (j + x < m) and (A[i + x][j] == '*') and (A[i - x][j] == '*') and (A[i][j + x] == '*') and (A[i][j - x] == '*'):
			B[i + x][j] = True
			B[i - x][j] = True
			B[i][j + x] = True
			B[i][j - x] = True
			return True
		return False
	R = []
	for i in range(n):
		for j in range(m):
			if A[i][j] == '*':
				x = 1
				while star(i, j, x):
					x += 1
				if x > 1:
					B[i][j] = True
					R.append([str(i + 1), str(j + 1), str(x - 1)])
	for i in range(n):
		for j in range(m):
			if B[i][j] != (A[i][j] == '*'):
				stdout.write('-1')
				exit(0)
	stdout.write('{}\n'.format(len(R)))
	for X in R:
		stdout.write('{} {} {}\n'.format(X[0], X[1], X[2]))
main()


(n, m) = map(int, input().split())
S = [list(str(input())) for _ in range(n)]
L = [[0] * m for _ in range(n)]
R = [[0] * m for _ in range(n)]
U = [[0] * m for _ in range(n)]
D = [[0] * m for _ in range(n)]
for i in range(n):
	cnt = 0
	for j in range(m):
		if S[i][j] == '.':
			cnt = 0
		else:
			cnt += 1
			L[i][j] = cnt
	cnt = 0
	for j in reversed(range(m)):
		if S[i][j] == '.':
			cnt = 0
		else:
			cnt += 1
			R[i][j] = cnt
for j in range(m):
	cnt = 0
	for i in range(n):
		if S[i][j] == '.':
			cnt = 0
		else:
			cnt += 1
			U[i][j] = cnt
	cnt = 0
	for i in reversed(range(n)):
		if S[i][j] == '.':
			cnt = 0
		else:
			cnt += 1
			D[i][j] = cnt
T = [['.'] * m for _ in range(n)]
ans = []
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if S[i][j] == '.':
			continue
		l = L[i][j] - 1
		r = R[i][j] - 1
		u = U[i][j] - 1
		d = D[i][j] - 1
		s = min([l, r, u, d])
		if s == 0:
			continue
		ans.append((i + 1, j + 1, s))
		for p in range(i - s, i + s + 1):
			T[p][j] = '*'
		for q in range(j - s, j + s + 1):
			T[i][q] = '*'
for i in range(n):
	for j in range(m):
		if S[i][j] != T[i][j]:
			print(-1)
			exit()
else:
	print(len(ans))
	for i in range(len(ans)):
		print(*ans[i])


(n, m) = map(int, input().split())
s = list()
for i in range(n):
	s.append(list(map(lambda x: 0 if x == '.' else 1, *input().split())))
re = list()
check_re = [[0] * m for _ in range(n)]

def check(x, y, length):
	if x + length >= n or y + length >= m or x - length < 0 or (y - length < 0):
		if length > 1:
			re.append(['{} {} {}'.format(x + 1, y + 1, length - 1)])
		return
	tmp = s[x + length][y] + s[x - length][y] + s[x][y + length] + s[x][y - length]
	if tmp == 4:
		prin(x, y, length)
		check(x, y, length + 1)
	elif length > 1:
		re.append(['{} {} {}'.format(x + 1, y + 1, length - 1)])

def prin(x, y, i):
	check_re[x][y] = 1
	check_re[x + i][y] = 1
	check_re[x - i][y] = 1
	check_re[x][y + i] = 1
	check_re[x][y - i] = 1
for i in range(n):
	for j in range(m):
		if s[i][j] == 1:
			check(i, j, 1)
if s == check_re:
	print(len(re))
	for i in re:
		print(i[0])
else:
	print(-1)


(n, m) = map(int, input().split())
c = []
for j in range(n):
	d = []
	s = input()
	for i in s:
		d.append(i)
	c.append(d)
a = []
b = []
e = []
g = []
for j in range(n):
	k = [0] * m
	e.append(k)
for j in range(n):
	k = [0] * m
	g.append(k)
dpu = []
for j in range(n):
	k = [0] * m
	dpu.append(k)
dpd = []
for j in range(n):
	k = [0] * m
	dpd.append(k)
dpl = []
for j in range(n):
	k = [0] * m
	dpl.append(k)
dpr = []
for j in range(n):
	k = [0] * m
	dpr.append(k)
for i in range(n):
	for j in range(m):
		if c[i][j] == '*':
			if i > 0:
				dpu[i][j] += dpu[i - 1][j] + 1
			else:
				dpu[i][j] = 1
			if j > 0:
				dpl[i][j] = dpl[i][j - 1] + 1
			else:
				dpl[i][j] = 1
i = n - 1
while i >= 0:
	j = m - 1
	while j >= 0:
		if c[i][j] == '*':
			if i < n - 1:
				dpd[i][j] += dpd[i + 1][j] + 1
			else:
				dpd[i][j] = 1
			if j < m - 1:
				dpr[i][j] = dpr[i][j + 1] + 1
			else:
				dpr[i][j] = 1
		j += -1
	i += -1
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if c[i][j] == '*':
			k = min(dpd[i][j] - 1, dpu[i][j] - 1, dpr[i][j] - 1, dpl[i][j] - 1)
			if k == 0:
				pass
			elif k > 0:
				a.append([i + 1, j + 1, k])
				e[i - k][j] += 1
				if i + k < n - 1:
					e[i + k + 1][j] += -1
				g[i][j - k] += 1
				if j + k < m - 1:
					g[i][j + k + 1] += -1
for i in range(m):
	for j in range(1, n):
		if c[j - 1][i] == '*':
			e[j][i] += e[j - 1][i]
for i in range(n):
	for j in range(1, m):
		if c[i][j - 1] == '*':
			g[i][j] += g[i][j - 1]
f = 0
for i in range(n):
	for j in range(m):
		if c[i][j] == '*' and e[i][j] <= 0 and (g[i][j] <= 0):
			f = 1
			break
if f == 1:
	print(-1)
else:
	print(len(a))
	for j in a:
		print(*j)


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
import collections
from itertools import permutations
from collections import deque
import threading
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD
(n, m) = map(int, input().split())
a = list()
for i in range(n):
	b = input()
	a.append(b)
p = [['.' for i in range(m)] for j in range(n)]
r = list()
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if a[i][j] == '*':
			mn = 1000
			c = 0
			for k in range(i - 1, -1, -1):
				if a[k][j] == '*':
					c += 1
				else:
					break
			mn = min(mn, c)
			c = 0
			for k in range(i + 1, n):
				if a[k][j] == '*':
					c += 1
				else:
					break
			mn = min(mn, c)
			c = 0
			for k in range(j - 1, -1, -1):
				if a[i][k] == '*':
					c += 1
				else:
					break
			mn = min(mn, c)
			c = 0
			for k in range(j + 1, m):
				if a[i][k] == '*':
					c += 1
				else:
					break
			mn = min(mn, c)
			if mn > 0:
				p[i][j] = '*'
				r.append((i + 1, j + 1, mn))
				for k in range(i - 1, i - mn - 1, -1):
					p[k][j] = '*'
				for k in range(i + 1, i + mn + 1):
					p[k][j] = '*'
				for k in range(j - 1, j - mn - 1, -1):
					p[i][k] = '*'
				for k in range(j + 1, j + mn + 1):
					p[i][k] = '*'
ch = 1
for i in range(n):
	for j in range(m):
		if a[i][j] != p[i][j]:
			ch = 0
			break
if ch:
	print(len(r))
	for i in r:
		print(*i)
else:
	print(-1)


import sys
input = lambda : sys.stdin.readline().rstrip()
(h, w) = map(int, input().split())
s = [list('.' * (w + 2))] + [list('.' + input() + '.') for _ in range(h)] + [list('.' * (w + 2))]
b = [[0] * (w + 2) for _ in range(h + 2)]
c = [[0] * (w + 2) for _ in range(h + 2)]
for i in range(1, h + 2):
	for j in range(1, w + 2):
		if s[i][j] == '*':
			b[i][j] = b[i - 1][j] + 1
			c[i][j] = c[i][j - 1] + 1
for i in range(h, -1, -1):
	for j in range(w, -1, -1):
		if s[i][j] == '*':
			b[i][j] = min(b[i][j], b[i + 1][j] + 1)
			c[i][j] = min(c[i][j], c[i][j + 1] + 1)
ans = []
for i in range(1, h + 1):
	for j in range(1, w + 1):
		t = min(b[i][j], c[i][j]) - 1
		if t > 0:
			ans.append((i, j, t))
b = [[0] * (w + 2) for _ in range(h + 2)]
c = [[0] * (w + 2) for _ in range(h + 2)]
for (i, j, t) in ans:
	b[i - t][j] += 1
	b[i + t + 1][j] -= 1
	c[i][j - t] += 1
	c[i][j + t + 1] -= 1
for i in range(h + 1):
	for j in range(w + 1):
		b[i + 1][j] += b[i][j]
		c[i][j + 1] += c[i][j]
		if i != 0 and j != 0:
			if (b[i][j] + c[i][j] > 0) != (s[i][j] == '*'):
				print(-1)
				exit()
print(len(ans))
for i in ans:
	print(*i)


(n, m) = map(int, input().split())
arr = [input() for i in range(n)]
s1 = set()
s2 = set()
res = list()
for i in range(n):
	for j in range(m):
		if arr[i][j] == '*':
			s1.add((i, j))
			l = 1
			while True:
				if i - l >= 0 and i + l < n and (j - l >= 0) and (j + l < m):
					if arr[i - l][j] == arr[i + l][j] == arr[i][j - l] == arr[i][j + l] == '*':
						s2 |= {(i - l, j), (i + l, j), (i, j - l), (i, j + l)}
						l += 1
					else:
						break
				else:
					break
			l -= 1
			if l > 0:
				s2.add((i, j))
				res.append([i + 1, j + 1, l])
if len(s1 - s2) > 0:
	print(-1)
else:
	print(len(res))
	for x in res:
		print(*x)


import math
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction
import sys
mod = 10 ** 9 + 7
mod1 = 998244353
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class SegmentTree:

	def __init__(self, data, default=0, func=lambda a, b: a + b):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

def powm(a, n, m):
	if a == 1 or n == 0:
		return 1
	if n % 2 == 0:
		s = powm(a, n // 2, m)
		return s * s % m
	else:
		return a * powm(a, n - 1, m) % m

def sort_list(list1, list2):
	zipped_pairs = zip(list2, list1)
	z = [x for (_, x) in sorted(zipped_pairs)]
	return z

def product(l):
	por = 1
	for i in range(len(l)):
		por *= l[i]
	return por

def binarySearchCount(arr, n, key):
	left = 0
	right = n - 1
	count = 0
	while left <= right:
		mid = int((right + left) / 2)
		if arr[mid] < key:
			count = mid + 1
			left = mid + 1
		else:
			right = mid - 1
	return count

def countdig(n):
	c = 0
	while n > 0:
		n //= 10
		c += 1
	return c

def binary(x, length):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y

def countGreater(arr, n, k):
	l = 0
	r = n - 1
	leftGreater = n
	while l <= r:
		m = int(l + (r - l) / 2)
		if arr[m] >= k:
			leftGreater = m
			r = m - 1
		else:
			l = m + 1
	return n - leftGreater
(n, m) = map(int, input().split())
l = []
tot = []
done = [[0 for i in range(m)] for j in range(n)]
for i in range(n):
	l.append(input())
colsum = [[0 for i in range(m)] for j in range(n)]
rowsum = [[0 for i in range(m)] for j in range(n)]
col = [[0 for i in range(m)] for j in range(n)]
row = [[0 for i in range(m)] for j in range(n)]
for i in range(n):
	for j in range(m):
		if l[i][j] == '*':
			rowsum[i][j] = 1
			colsum[i][j] = 1
			row[i][j] = 1
			col[i][j] = 1
for i in range(n):
	for j in range(1, m):
		if l[i][j] == '.':
			continue
		rowsum[i][j] += rowsum[i][j - 1]
for i in range(n):
	for j in range(m - 2, -1, -1):
		if l[i][j] == '.':
			continue
		row[i][j] += row[i][j + 1]
for i in range(m):
	for j in range(n - 2, -1, -1):
		if l[j][i] == '.':
			continue
		col[j][i] += col[j + 1][i]
for i in range(m):
	for j in range(1, n):
		if l[j][i] == '.':
			continue
		colsum[j][i] += colsum[j - 1][i]

def check(x, y):
	i = x
	j = y
	ans = min(row[i][j], rowsum[i][j], colsum[i][j], col[i][j]) - 1
	if ans == 0:
		return []
	return [ans]
h = [[0 for i in range(m + 1)] for j in range(n)]
v = [[0 for i in range(m)] for j in range(n + 1)]
for i in range(n):
	for j in range(m):
		if l[i][j] == '*':
			ans = check(i, j)
			for j1 in ans:
				tot.append([i + 1, j + 1, j1])
				h[i][j - j1] += 1
				h[i][j + j1 + 1] -= 1
				v[i - j1][j] += 1
				v[i + j1 + 1][j] -= 1
for i in range(n):
	for j in range(1, m):
		h[i][j] += h[i][j - 1]
for i in range(m):
	for j in range(1, n):
		v[j][i] += v[j - 1][i]
for i in range(n):
	for j in range(m):
		if l[i][j] == '*' and h[i][j] == 0 and (v[i][j] == 0):
			print(-1)
			sys.exit(0)
print(len(tot))
for i in tot:
	print(*i)


(n, m) = map(int, input().split())
s = [input() for row in range(n)]
f = [[(column == '*') & 1 for column in row] for row in s]
vis = [[0 for i in range(0, m)] for j in range(0, n)]
result = []

def allvis(vis, f, n, m):
	sum1 = 0
	sum2 = 0
	for i in range(0, n):
		for j in range(0, m):
			sum1 += vis[i][j] == 1
			sum2 += f[i][j] == 1
	return sum1 == sum2
for row in range(0, n, 1):
	for column in range(0, m, 1):
		if f[row][column] == 1:
			cnt = 0
			for i in range(1, max(n, m)):
				if row - i >= 0 and column - i >= 0 and (row + i < n) and (column + i < m):
					if f[row - i][column] == f[row + i][column] == f[row][column + i] == f[row][column - i] == f[row][column]:
						vis[row - i][column] = 1
						vis[row + i][column] = 1
						vis[row][column - i] = 1
						vis[row][column + i] = 1
						vis[row][column] = 1
						cnt = i
					else:
						break
				else:
					break
			if cnt != 0:
				result.append([row + 1, column + 1, cnt])
if not allvis(vis, f, n, m):
	print(-1)
else:
	print(len(result))
	for i in range(0, len(result), 1):
		print(result[i][0], result[i][1], result[i][2])


def check_size(x_c, y_c):
	global n, m
	max_size = min(x_c, m - x_c - 1, y_c, n - y_c - 1)
	size = 1
	while size <= max_size and data[y_c][x_c + size] and data[y_c - size][x_c] and data[y_c][x_c - size] and data[y_c + size][x_c]:
		size += 1
	size -= 1
	return size

def check_stars():
	global n, m
	for y in range(n):
		for x in range(m):
			if data[y][x]:
				size = check_size(x, y)
				if size > 0:
					stars.append([x, y, size])

def check_field():
	global n, m
	for star in stars:
		x_c = star[0]
		y_c = star[1]
		size = star[2]
		for x in range(x_c - size, x_c + size + 1):
			data[y_c][x] = False
		for y in range(y_c - size, y_c + size + 1):
			data[y][x_c] = False
	for y in range(n):
		for x in range(m):
			if data[y][x]:
				return False
	return True
(n, m) = map(int, input().split())
data = [[False for j in range(m)] for i in range(n)]
for i in range(n):
	l = input()
	for j in range(m):
		data[i][j] = l[j] == '*'
stars = []
check_stars()
if check_field():
	print(len(stars))
	for star in stars:
		print(star[1] + 1, star[0] + 1, star[2])
else:
	print('-1')


import sys
input = sys.stdin.readline
(n, m) = map(int, input().split())
MAP = [list(input().strip()) for i in range(n)]
T0 = [[0] * (m + 1) for i in range(n + 1)]
T1 = [[0] * (m + 1) for i in range(n + 1)]
Y0 = [[0] * (m + 1) for i in range(n + 1)]
Y1 = [[0] * (m + 1) for i in range(n + 1)]
for i in range(n):
	for j in range(m):
		if MAP[i][j] == '*':
			T0[i][j] = T0[i - 1][j] + 1
			Y0[i][j] = Y0[i][j - 1] + 1
for i in range(n - 1, -1, -1):
	for j in range(m - 1, -1, -1):
		if MAP[i][j] == '*':
			T1[i][j] = T1[i + 1][j] + 1
			Y1[i][j] = Y1[i][j + 1] + 1
ANS = [[0] * m for i in range(n)]
for i in range(n):
	for j in range(m):
		score = min(T0[i][j], T1[i][j], Y0[i][j], Y1[i][j])
		if score >= 2:
			ANS[i][j] = score
T0 = [[0] * (m + 1) for i in range(n + 1)]
T1 = [[0] * (m + 1) for i in range(n + 1)]
Y0 = [[0] * (m + 1) for i in range(n + 1)]
Y1 = [[0] * (m + 1) for i in range(n + 1)]
for i in range(n):
	for j in range(m):
		T0[i][j] = max(ANS[i][j], T0[i - 1][j] - 1)
		Y0[i][j] = max(ANS[i][j], Y0[i][j - 1] - 1)
for i in range(n - 1, -1, -1):
	for j in range(m - 1, -1, -1):
		T1[i][j] = max(ANS[i][j], T1[i + 1][j] - 1)
		Y1[i][j] = max(ANS[i][j], Y1[i][j + 1] - 1)
SUF = [['.'] * m for i in range(n)]
for i in range(n):
	for j in range(m):
		if T0[i][j] or T1[i][j] or Y0[i][j] or Y1[i][j]:
			SUF[i][j] = '*'
if SUF != MAP:
	print(-1)
else:
	ANSLIST = []
	for i in range(n):
		for j in range(m):
			if ANS[i][j] != 0:
				ANSLIST.append((i + 1, j + 1, ANS[i][j] - 1))
	print(len(ANSLIST))
	for ans in ANSLIST:
		print(*ans)


(n, m) = map(int, input().split())
s = [list(input()) for i in range(n)]
dp = [['.' for i in range(m)] for j in range(n)]
ans = ''
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if s[i][j] == '*' and s[i + 1][j] == '*' and (s[i - 1][j] == '*') and (s[i][j - 1] == '*') and (s[i][j + 1] == '*'):
			x = 1
			while i - x > -1 and x + i < n and (j - x > -1) and (x + j < m) and (s[i + x][j] == '*') and (s[i - x][j] == '*') and (s[i][j - x] == '*') and (s[i][j + x] == '*'):
				(dp[i][j], dp[i + x][j], dp[i - x][j], dp[i][j - x], dp[i][j + x]) = ('*', '*', '*', '*', '*')
				x += 1
			ans += str(i + 1) + ' ' + str(j + 1) + ' ' + str(x - 1) + chr(10)
if dp != s:
	print(-1)
else:
	print(ans.count(chr(10)))
	print(ans)


(n, m) = map(int, input().split())
a = [[' ' for i in range(m)] for j in range(n)]
for i in range(n):
	a[i] = list(input())
check = [['.' for i in range(m)] for j in range(n)]
MAX_STAR_SIZE = min(n, m) // 2
ans = []

def valid_star(i, j, s):
	if s <= 0:
		return False
	if i - s < 0 or i + s >= n or j - s < 0 or (j + s >= m):
		return False
	if a[i + s][j] == '.' or a[i - s][j] == '.' or a[i][j + s] == '.' or (a[i][j - s] == '.'):
		return False
	return True

def place_star(x, y, sz):
	global check
	check[x][y] = '*'
	for i in range(1, sz + 1):
		check[x + i][y] = '*'
		check[x - i][y] = '*'
		check[x][y + i] = '*'
		check[x][y - i] = '*'

def star_complete():
	global check
	for i in range(n):
		for j in range(m):
			if a[i][j] != check[i][j]:
				return False
	return True
for i in range(n):
	for j in range(m):
		if a[i][j] != '*':
			continue
		sz = 0
		for s in range(1, MAX_STAR_SIZE + 1):
			if valid_star(i, j, s):
				sz = s
			else:
				break
		if sz != 0:
			place_star(i, j, sz)
			ans.append([i + 1, j + 1, sz])
if not star_complete():
	print(-1)
else:
	print(len(ans))
	for i in ans:
		print(*i, sep=' ')


R = lambda : map(int, input().split())
(n, m) = R()
g = [input() for _ in range(n)]
f = [[0 for j in range(m)] for i in range(n)]
res = []
for i in range(n):
	for j in range(m):
		if g[i][j] == '*':
			dd = 0
			for d in range(1, 101):
				if i >= d and i + d < n and (j >= d) and (j + d < m):
					if g[i - d][j] == '*' and g[i + d][j] == '*' and (g[i][j - d] == '*') and (g[i][j + d] == '*'):
						f[i][j] = 1
						f[i - d][j] = 1
						f[i + d][j] = 1
						f[i][j - d] = 1
						f[i][j + d] = 1
						dd = d
					else:
						break
				else:
					break
			if dd >= 1:
				res.append([i + 1, j + 1, dd])
for i in range(n):
	for j in range(m):
		if g[i][j] == '*' and f[i][j] == 0:
			print(-1)
			exit(0)
print(len(res))
for r in res:
	print(' '.join(map(str, r)))


R = lambda : map(int, input().split())
(n, m) = R()
g = [input() for _ in range(n)]
f = [[0] * m for i in range(n)]
res = []
for i in range(n):
	for j in range(m):
		if g[i][j] == '*':
			d = 1
			while i >= d and i + d < n and (j >= d) and (j + d < m) and (g[i - d][j] == g[i + d][j] == g[i][j - d] == g[i][j + d] == '*'):
				f[i][j] = f[i - d][j] = f[i + d][j] = f[i][j - d] = f[i][j + d] = 1
				d += 1
			d -= 1
			if d >= 1:
				res.append([i + 1, j + 1, d])
for i in range(n):
	for j in range(m):
		if g[i][j] == '*' and (not f[i][j]):
			print(-1)
			exit(0)
print(len(res))
for r in res:
	print(' '.join(map(str, r)))


import math
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction
import sys
mod = 10 ** 9 + 7
mod1 = 998244353
sys.setrecursionlimit(300000)
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192
sys.setrecursionlimit(300000)

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class TreeNode:

	def __init__(self, k, v):
		self.key = k
		self.value = v
		self.left = None
		self.right = None
		self.parent = None
		self.height = 1
		self.num_left = 1
		self.num_total = 1

class AvlTree:

	def __init__(self):
		self._tree = None

	def add(self, k, v):
		if not self._tree:
			self._tree = TreeNode(k, v)
			return
		node = self._add(k, v)
		if node:
			self._rebalance(node)

	def _add(self, k, v):
		node = self._tree
		while node:
			if k < node.key:
				if node.left:
					node = node.left
				else:
					node.left = TreeNode(k, v)
					node.left.parent = node
					return node.left
			elif node.key < k:
				if node.right:
					node = node.right
				else:
					node.right = TreeNode(k, v)
					node.right.parent = node
					return node.right
			else:
				node.value = v
				return

	@staticmethod
	def get_height(x):
		return x.height if x else 0

	@staticmethod
	def get_num_total(x):
		return x.num_total if x else 0

	def _rebalance(self, node):
		n = node
		while n:
			lh = self.get_height(n.left)
			rh = self.get_height(n.right)
			n.height = max(lh, rh) + 1
			balance_factor = lh - rh
			n.num_total = 1 + self.get_num_total(n.left) + self.get_num_total(n.right)
			n.num_left = 1 + self.get_num_total(n.left)
			if balance_factor > 1:
				if self.get_height(n.left.left) < self.get_height(n.left.right):
					self._rotate_left(n.left)
				self._rotate_right(n)
			elif balance_factor < -1:
				if self.get_height(n.right.right) < self.get_height(n.right.left):
					self._rotate_right(n.right)
				self._rotate_left(n)
			else:
				n = n.parent

	def _remove_one(self, node):
		replacement = node.left or node.right
		if node.parent:
			if AvlTree._is_left(node):
				node.parent.left = replacement
			else:
				node.parent.right = replacement
			replacement.parent = node.parent
			node.parent = None
		else:
			self._tree = replacement
			replacement.parent = None
		node.left = None
		node.right = None
		node.parent = None
		self._rebalance(replacement)

	def _remove_leaf(self, node):
		if node.parent:
			if AvlTree._is_left(node):
				node.parent.left = None
			else:
				node.parent.right = None
			self._rebalance(node.parent)
		else:
			self._tree = None
		node.parent = None
		node.left = None
		node.right = None

	def remove(self, k):
		node = self._get_node(k)
		if not node:
			return
		if AvlTree._is_leaf(node):
			self._remove_leaf(node)
			return
		if node.left and node.right:
			nxt = AvlTree._get_next(node)
			node.key = nxt.key
			node.value = nxt.value
			if self._is_leaf(nxt):
				self._remove_leaf(nxt)
			else:
				self._remove_one(nxt)
			self._rebalance(node)
		else:
			self._remove_one(node)

	def get(self, k):
		node = self._get_node(k)
		return node.value if node else -1

	def _get_node(self, k):
		if not self._tree:
			return None
		node = self._tree
		while node:
			if k < node.key:
				node = node.left
			elif node.key < k:
				node = node.right
			else:
				return node
		return None

	def get_at(self, pos):
		x = pos + 1
		node = self._tree
		while node:
			if x < node.num_left:
				node = node.left
			elif node.num_left < x:
				x -= node.num_left
				node = node.right
			else:
				return (node.key, node.value)
		raise IndexError('Out of ranges')

	@staticmethod
	def _is_left(node):
		return node.parent.left and node.parent.left == node

	@staticmethod
	def _is_leaf(node):
		return node.left is None and node.right is None

	def _rotate_right(self, node):
		if not node.parent:
			self._tree = node.left
			node.left.parent = None
		elif AvlTree._is_left(node):
			node.parent.left = node.left
			node.left.parent = node.parent
		else:
			node.parent.right = node.left
			node.left.parent = node.parent
		bk = node.left.right
		node.left.right = node
		node.parent = node.left
		node.left = bk
		if bk:
			bk.parent = node
		node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
		node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
		node.num_left = 1 + self.get_num_total(node.left)

	def _rotate_left(self, node):
		if not node.parent:
			self._tree = node.right
			node.right.parent = None
		elif AvlTree._is_left(node):
			node.parent.left = node.right
			node.right.parent = node.parent
		else:
			node.parent.right = node.right
			node.right.parent = node.parent
		bk = node.right.left
		node.right.left = node
		node.parent = node.right
		node.right = bk
		if bk:
			bk.parent = node
		node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
		node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
		node.num_left = 1 + self.get_num_total(node.left)

	@staticmethod
	def _get_next(node):
		if not node.right:
			return node.parent
		n = node.right
		while n.left:
			n = n.left
		return n

class SegmentTree1:

	def __init__(self, data, default=0, func=lambda a, b: max(a, b)):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class SegmentTree:

	def __init__(self, data, default=0, func=lambda a, b: a + b):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

def powm(a, n, m):
	if a == 1 or n == 0:
		return 1
	if n % 2 == 0:
		s = powm(a, n // 2, m)
		return s * s % m
	else:
		return a * powm(a, n - 1, m) % m

def sort_list(list1, list2):
	zipped_pairs = zip(list2, list1)
	z = [x for (_, x) in sorted(zipped_pairs)]
	return z

def product(l):
	por = 1
	for i in range(len(l)):
		por *= l[i]
	return por

def binarySearchCount(arr, n, key):
	left = 0
	right = n - 1
	count = 0
	while left <= right:
		mid = int((right + left) / 2)
		if arr[mid] < key:
			count = mid + 1
			left = mid + 1
		else:
			right = mid - 1
	return count

def countdig(n):
	c = 0
	while n > 0:
		n //= 10
		c += 1
	return c

def binary(x, length):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y

def countGreater(arr, n, k):
	l = 0
	r = n - 1
	leftGreater = n
	while l <= r:
		m = int(l + (r - l) / 2)
		if arr[m] >= k:
			leftGreater = m
			r = m - 1
		else:
			l = m + 1
	return n - leftGreater
(n, m) = map(int, input().split())
l = []
tot = []
done = [[0 for i in range(m)] for j in range(n)]
for i in range(n):
	l.append(input())

def check(x, y):
	cur = 0
	for i in range(x - 1, -1, -1):
		if l[i][y] == '*':
			cur += 1
		else:
			break
	ans = cur
	cur = 0
	for i in range(x + 1, n):
		if l[i][y] == '*':
			cur += 1
		else:
			break
	ans = min(ans, cur)
	cur = 0
	for i in range(y - 1, -1, -1):
		if l[x][i] == '*':
			cur += 1
		else:
			break
	ans = min(ans, cur)
	cur = 0
	for i in range(y + 1, m):
		if l[x][i] == '*':
			cur += 1
		else:
			break
	ans = min(ans, cur)
	if ans == 0:
		return []
	done[x][y] = 1
	for i in range(x - 1, x - ans - 1, -1):
		done[i][y] = 1
	for i in range(x + 1, x + ans + 1):
		done[i][y] = 1
	for i in range(y - 1, y - ans - 1, -1):
		done[x][i] = 1
	for i in range(y + 1, y + ans + 1):
		done[x][i] = 1
	ly = [ans]
	return ly
for i in range(n):
	for j in range(m):
		if l[i][j] == '*':
			ans = check(i, j)
			for j1 in ans:
				tot.append([i + 1, j + 1, j1])
for i in range(n):
	for j in range(m):
		if l[i][j] == '*' and done[i][j] == 0:
			print(-1)
			sys.exit(0)
print(len(tot))
for i in tot:
	print(*i)


import re
import sys
exit = sys.exit
from bisect import bisect_left as bsl, bisect_right as bsr
from collections import Counter, defaultdict as ddict, deque
from functools import lru_cache
cache = lru_cache(None)
from heapq import *
from itertools import *
from math import inf
from pprint import pprint as pp
enum = enumerate
ri = lambda : int(rln())
ris = lambda : list(map(int, rfs()))
rln = sys.stdin.readline
rl = lambda : rln().rstrip('\n')
rfs = lambda : rln().split()
mod = 1000000007
d4 = [(0, -1), (1, 0), (0, 1), (-1, 0)]
d8 = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]
(m, n) = ris()
(m, n) = (m + 2, n + 2)
grid = ['.' * n]
grid += ['.' + rl() + '.' for _ in range(m - 2)]
grid += ['.' * n]
up = [[0] * n for _ in range(m)]
dw = [[0] * n for _ in range(m)]
lf = [[0] * n for _ in range(m)]
rg = [[0] * n for _ in range(m)]
rs = [[0] * n for _ in range(m)]
cs = [[0] * n for _ in range(m)]
for i in range(1, m - 1):
	for j in range(1, n - 1):
		if grid[i][j] == '*':
			up[i][j] = 1 + up[i - 1][j]
			lf[i][j] = 1 + lf[i][j - 1]
for i in range(m - 1, 0, -1):
	for j in range(n - 1, 0, -1):
		if grid[i][j] == '*':
			dw[i][j] = 1 + dw[i + 1][j]
			rg[i][j] = 1 + rg[i][j + 1]
ans = []
for i in range(1, m - 1):
	for j in range(1, n - 1):
		if grid[i][j] == '.':
			continue
		s = min(up[i - 1][j], dw[i + 1][j], lf[i][j - 1], rg[i][j + 1])
		if s == 0:
			continue
		ans.append((i, j, s))
		rs[i - s][j] += 1
		rs[i + s + 1][j] -= 1
		cs[i][j - s] += 1
		cs[i][j + s + 1] -= 1
for i in range(1, m - 1):
	for j in range(1, n - 1):
		rs[i][j] += rs[i - 1][j]
		cs[i][j] += cs[i][j - 1]
for i in range(1, m - 1):
	for j in range(1, n - 1):
		if grid[i][j] == '.':
			continue
		if rs[i][j] == 0 and cs[i][j] == 0:
			print(-1)
			exit()
print(len(ans))
for (i, j, s) in ans:
	print(i, j, s)


import sys
input = sys.stdin.readline

def read():
	return list(map(int, input().split()))
(n, m) = read()
g = [input() for i in range(n)]
mrk = [[0 for j in range(m)] for i in range(n)]
ans = []
for i in range(n):
	for j in range(m):
		if g[i][j] == '*':
			cnt = [0, 0, 0, 0]
			k = i - 1
			while k >= 0 and g[k][j] == '*':
				k -= 1
				cnt[0] += 1
			k = i + 1
			while k < n and g[k][j] == '*':
				k += 1
				cnt[1] += 1
			k = j - 1
			while k >= 0 and g[i][k] == '*':
				k -= 1
				cnt[2] += 1
			k = j + 1
			while k < m and g[i][k] == '*':
				k += 1
				cnt[3] += 1
			mn = min(cnt)
			if mn:
				mrk[i][j] = 1
				for k in range(1, mn + 1):
					mrk[i - k][j] = 1
					mrk[i + k][j] = 1
					mrk[i][j - k] = 1
					mrk[i][j + k] = 1
				ans.append([i + 1, j + 1, mn])
for i in range(n):
	for j in range(m):
		if g[i][j] == '*' and (not mrk[i][j]):
			print(-1)
			quit()
print(len(ans))
for (a, b, c) in ans:
	print(a, b, c)


from copy import *
(r, c) = map(int, input().split())
arr1 = []
arr2 = []
for i in range(r):
	s = str(input())
	arrx = []
	for j in range(c):
		arrx.append(s[j])
	arr1.append(copy(arrx))
	arr2.append(copy(arrx))
ansarr = []
for i in range(r):
	for j in range(c):
		if i > 0 and i < r - 1 and (j > 0) and (j < c - 1):
			if arr1[i][j] == '*' and arr1[i - 1][j] == '*' and (arr1[i + 1][j] == '*') and (arr1[i][j - 1] == '*') and (arr1[i][j + 1] == '*'):
				count1 = 0
				count2 = 0
				count3 = 0
				count4 = 0
				k = i
				l = j
				while k >= 0:
					if arr1[k][j] == '*':
						count1 += 1
					else:
						break
					k -= 1
				k = i
				l = j
				while k <= r - 1:
					if arr1[k][j] == '*':
						count2 += 1
					else:
						break
					k += 1
				k = i
				l = j
				while l >= 0:
					if arr1[i][l] == '*':
						count3 += 1
					else:
						break
					l -= 1
				k = i
				l = j
				while l <= c - 1:
					if arr1[i][l] == '*':
						count4 += 1
					else:
						break
					l += 1
				count = min(count1, count2, count3, count4)
				ansarr.append([i + 1, j + 1, count - 1])
				x = 0
				while x < count:
					arr2[i - x][j] = '.'
					arr2[i + x][j] = '.'
					arr2[i][j - x] = '.'
					arr2[i][j + x] = '.'
					x += 1
flag = 0
for i in range(r):
	for j in range(c):
		if arr2[i][j] == '*':
			flag = 1
if flag == 1:
	print(-1)
else:
	print(len(ansarr))
	for i in range(len(ansarr)):
		print(*ansarr[i])


import sys
(n, m) = map(int, input().split())
s = [[*input()] for i in range(n)]
f = [[0 for i in range(m)] for i in range(n)]
ans = []
for i in range(n):
	for j in range(m):
		if s[i][j] == '.':
			f[i][j] = 1
			continue
		for k in range(1, min(n, m) + 1):
			if i + k < n and j + k < m and (i - k >= 0) and (j - k >= 0) and (s[i + k][j] == '*') and (s[i][j - k] == '*') and (s[i - k][j] == '*') and (s[i][j + k] == '*'):
				f[i][j] = 1
				f[i][j + k] = 1
				f[i][j - k] = 1
				f[i + k][j] = 1
				f[i - k][j] = 1
			else:
				if k > 1:
					ans.append((i + 1, j + 1, k - 1))
				break
for i in range(n):
	for j in range(m):
		if f[i][j] == 0:
			print(-1)
			sys.exit()
print(len(ans))
for i in ans:
	print(i[0], i[1], i[2])


def findStar(ar, i, j, n, m):
	size = 1
	newStars = 0
	while True:
		if j - size > -1 and j + size < m and (i - size > -1) and (i + size < n) and (ar[i][j - size] > 0) and (ar[i][j + size] > 0) and (ar[i - size][j] > 0) and (ar[i + size][j] > 0):
			if ar[i][j - size] == 1:
				newStars += 1
			ar[i][j - size] += 1
			if ar[i][j + size] == 1:
				newStars += 1
			ar[i][j + size] += 1
			if ar[i - size][j] == 1:
				newStars += 1
			ar[i - size][j] += 1
			if ar[i + size][j] == 1:
				newStars += 1
			ar[i + size][j] += 1
			if ar[i][j] == 1:
				newStars += 1
			ar[i][j] += 1
			size += 1
		else:
			return (ar, size - 1, newStars)
(n, m) = map(int, input().split())
mat = []
ar = []
for _ in range(n):
	l = list(input())
	mat.append(l)
	ar.append([0] * m)
starCount = 0
for i in range(n):
	for j in range(m):
		if mat[i][j] == '*':
			ar[i][j] = 1
			starCount += 1
out = []
countStars = 0
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if ar[i][j] > 0:
			(ar, vals, newStars) = findStar(ar, i, j, n, m)
			if vals > 0:
				out.append([i + 1, j + 1, vals])
				countStars += newStars
if starCount == countStars:
	print(len(out))
	for row in out:
		print(row[0], row[1], row[2])
else:
	print(-1)


(n, m) = map(int, input().split())
pole = []
metka = []
for i in range(n):
	pole.append([])
	metka.append([])
	s = input()
	for j in range(m):
		pole[i].append(s[j])
		if s[j] == '.':
			metka[i].append(0)
		else:
			metka[i].append(1)
k = 0
ans = []
for i in range(n):
	for j in range(m):
		if pole[i][j] == '*':
			e = 0
			while i - e - 1 >= 0 and j - e - 1 >= 0 and (i + e + 1 < n) and (j + e + 1 < m) and (pole[i - e - 1][j] == '*') and (pole[i][j - e - 1] == '*') and (pole[i + e + 1][j] == '*') and (pole[i][j + e + 1] == '*'):
				e = e + 1
				metka[i][j] = 0
				metka[i - e][j] = 0
				metka[i][j - e] = 0
				metka[i + e][j] = 0
				metka[i][j + e] = 0
			if e != 0:
				k = k + 1
				ans.append((i + 1, j + 1, e))
flag = True
for i in range(n):
	if 1 in metka[i]:
		flag = False
		break
if not flag:
	print(-1)
else:
	print(k)
	for i in range(k):
		print(ans[i][0], ans[i][1], ans[i][2], end='\n')


def main():
	(n, m) = map(int, input().split())
	S = [list(str(input())) for _ in range(n)]
	L = [[0] * m for _ in range(n)]
	R = [[0] * m for _ in range(n)]
	U = [[0] * m for _ in range(n)]
	D = [[0] * m for _ in range(n)]
	for i in range(n):
		cnt = 0
		for j in range(m):
			if S[i][j] == '.':
				cnt = 0
			else:
				cnt += 1
				L[i][j] = cnt
		cnt = 0
		for j in reversed(range(m)):
			if S[i][j] == '.':
				cnt = 0
			else:
				cnt += 1
				R[i][j] = cnt
	for j in range(m):
		cnt = 0
		for i in range(n):
			if S[i][j] == '.':
				cnt = 0
			else:
				cnt += 1
				U[i][j] = cnt
		cnt = 0
		for i in reversed(range(n)):
			if S[i][j] == '.':
				cnt = 0
			else:
				cnt += 1
				D[i][j] = cnt
	imosH = [[0] * (m + 1) for _ in range(n)]
	imosV = [[0] * m for _ in range(n + 1)]
	ans = []
	for i in range(1, n - 1):
		for j in range(1, m - 1):
			if S[i][j] == '.':
				continue
			l = L[i][j] - 1
			r = R[i][j] - 1
			u = U[i][j] - 1
			d = D[i][j] - 1
			s = min([l, r, u, d])
			if s == 0:
				continue
			ans.append((i + 1, j + 1, s))
			imosV[i - s][j] += 1
			imosV[i + s + 1][j] -= 1
			imosH[i][j - s] += 1
			imosH[i][j + s + 1] -= 1
	from itertools import accumulate
	for i in range(n):
		imosH[i] = list(accumulate(imosH[i]))
	for j in range(m):
		for i in range(1, n + 1):
			imosV[i][j] += imosV[i - 1][j]
	for i in range(n):
		for j in range(m):
			if S[i][j] == '*':
				if imosH[i][j] <= 0 and imosV[i][j] <= 0:
					print(-1)
					exit()
	else:
		print(len(ans))
		for i in range(len(ans)):
			print(*ans[i])
main()


import atexit, io, sys, collections, math, heapq, fractions, copy, os, functools
import sys
import random
import collections
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
(n, m) = map(int, input().split())
mat = []
for u in range(n):
	mat.append(list(input()))
dp = [[[0, 0, 0, 0] for j in range(m)] for i in range(n)]
for i in range(n):
	count = 0
	for j in range(m):
		if mat[i][j] == '*':
			count += 1
		else:
			count = 0
		dp[i][j][0] = count
	count = 0
	for j in range(m)[::-1]:
		if mat[i][j] == '*':
			count += 1
		else:
			count = 0
		dp[i][j][1] = count
for j in range(m):
	count = 0
	for i in range(n):
		if mat[i][j] == '*':
			count += 1
		else:
			count = 0
		dp[i][j][2] = count
	count = 0
	for i in range(n)[::-1]:
		if mat[i][j] == '*':
			count += 1
		else:
			count = 0
		dp[i][j][3] = count

def f(t, row, col):
	for i in range(len(t)):
		cumul = 0
		for j in range(len(t[0])):
			cumul += row[i][j]
			if cumul > 0:
				t[i][j] = '*'
	for j in range(len(t[0])):
		cumul = 0
		for i in range(len(t)):
			cumul += col[j][i]
			if cumul > 0:
				t[i][j] = '*'
r = []
t = [['.' for j in range(len(mat[0]))] for i in range(len(mat))]
row = {i: collections.Counter() for i in range(len(mat))}
col = {j: collections.Counter() for j in range(len(mat[0]))}
for i in range(len(mat)):
	for j in range(len(mat[0])):
		if mat[i][j] == '*':
			if min(dp[i][j]) > 1:
				t[i][j] = '*'
				gap = min(dp[i][j]) - 1
				row[i][j - gap] += 1
				row[i][j + gap + 1] -= 1
				col[j][i - gap] += 1
				col[j][i + gap + 1] -= 1
				r.append((i + 1, j + 1, min(dp[i][j]) - 1))
f(t, row, col)
if mat == t:
	print(len(r))
	for e in r:
		print('{} {} {}'.format(e[0], e[1], e[2]))
else:
	print(-1)


(n, m) = map(int, input().split())
c = []
for j in range(n):
	d = []
	s = input()
	for i in s:
		d.append(i)
	c.append(d)
a = []
b = []
for j in range(n):
	a.append([0] * m)
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if c[i][j] == '*':
			p = i - 1
			x = 0
			while p >= 0:
				if c[p][j] == '*':
					x += 1
				else:
					break
				p += -1
			p = i + 1
			y = 0
			while p < n:
				if c[p][j] == '*':
					y += 1
				else:
					break
				p += 1
			p = j + 1
			z = 0
			while p < m:
				if c[i][p] == '*':
					z += 1
				else:
					break
				p += 1
			p = j - 1
			e = 0
			while p >= 0:
				if c[i][p] == '*':
					e += 1
				else:
					break
				p += -1
			x = min(x, y, z, e)
			if x > 0:
				b.append([i + 1, j + 1, x])
				a[i][j] = 1
				p = i - 1
				while p >= i - x:
					a[p][j] = 1
					p += -1
				p = i + 1
				y = 0
				while p <= i + x:
					a[p][j] = 1
					p += 1
				p = j + 1
				z = 0
				while p <= j + x:
					a[i][p] = 1
					p += 1
				p = j - 1
				e = 0
				while p >= j - x:
					a[i][p] = 1
					p += -1
f = 0
for i in range(n):
	for j in range(m):
		if c[i][j] == '*' and a[i][j] == 0:
			f = 1
			break
if f == 1:
	print(-1)
else:
	print(len(b))
	for j in b:
		print(*j)


(n, m) = [int(x) for x in input().split()]
L = []
for _ in range(n):
	L.extend([i for i in input()])
for i in range(n * m):
	if L[i] == '.':
		L[i] = 0
	else:
		L[i] = 1
stars = []
for i in range(n * m):
	l = 0
	y = i // m
	x = i % m
	if L[i] == 1:
		while True:
			if y + l != n - 1 and y - l != 0 and (x - l != 0) and (x + l != m - 1):
				l += 1
				if L[i + l] * L[i - l] * L[i - l * m] * L[i + l * m] == 0:
					l -= 1
					break
			else:
				break
		if l > 0:
			stars.append((i, l))
T = [0] * (n * m)
for s in stars:
	T[s[0]] = 1
	for l in range(1, s[1] + 1):
		T[s[0] + l] = 1
		T[s[0] - l] = 1
		T[s[0] - l * m] = 1
		T[s[0] + l * m] = 1
if T == L:
	print(len(stars))
	for s in stars:
		print(1 + s[0] // m, 1 + s[0] % m, s[1])
else:
	print(-1)


(n, m) = input().split(' ')[:2]
n = int(n)
m = int(m)
orig = []
for _ in range(n):
	row = input()
	orig.append(row)
copy = [['.'] * m for _ in range(n)]
stars = []
for i in range(n):
	for j in range(m):
		curSymbol = orig[i][j]
		if curSymbol == '*':
			if i > 0 and i < n - 1 and (j > 0) and (j < m - 1) and (orig[i - 1][j] == '*') and (orig[i + 1][j] == '*') and (orig[i][j + 1] == '*') and (orig[i][j - 1] == '*'):
				copy[i][j] = '*'
				radius = 1
				while i > radius - 1 and i < n - radius and (j > radius - 1) and (j < m - radius) and (orig[i - radius][j] == '*') and (orig[i + radius][j] == '*') and (orig[i][j + radius] == '*') and (orig[i][j - radius] == '*'):
					copy[i - radius][j] = '*'
					copy[i + radius][j] = '*'
					copy[i][j + radius] = '*'
					copy[i][j - radius] = '*'
					radius += 1
				stars.append((i + 1, j + 1, radius - 1))
if all((orig[i][j] == copy[i][j] for i in range(n) for j in range(m))):
	print(len(stars))
	for star in stars:
		print(f'{star[0]} {star[1]} {star[2]}')
else:
	print(-1)


def possible(i, j):
	count = 0
	x = 10 ** 18
	for k in range(j + 1, m):
		if grid[i][k] == '*':
			count += 1
		else:
			break
	x = min(x, count)
	count = 0
	for k in range(j - 1, -1, -1):
		if grid[i][k] == '*':
			count += 1
		else:
			break
	x = min(x, count)
	count = 0
	for k in range(i + 1, n):
		if grid[k][j] == '*':
			count += 1
		else:
			break
	x = min(x, count)
	count = 0
	for k in range(i - 1, -1, -1):
		if grid[k][j] == '*':
			count += 1
		else:
			break
	x = min(x, count)
	if x == 0:
		return -1
	for k in range(i - x, i + x + 1):
		done[k, j] = 1
	for k in range(j - x, j + x + 1):
		done[i, k] = 1
	return x
(n, m) = map(int, input().split())
grid = []
l = {}
for i in range(n):
	grid.append(input())
	for j in range(m):
		if grid[-1][j] == '*':
			l[i, j] = 1
done = {}
c = {}
for i in range(n):
	for j in range(m):
		if grid[i][j] == '*':
			x = possible(i, j)
			if x != -1:
				c[i, j] = x
	if len(l) == len(done):
		break
if len(l) != len(done):
	print(-1)
	exit()
print(len(c))
for i in c:
	print(i[0] + 1, i[1] + 1, c[i])


(n, m) = map(int, input().split())
maze = []
for _ in range(n):
	maze.append(list(str(input())))
noa = 0
for i in range(n):
	for j in range(m):
		if maze[i][j] == '*':
			noa += 1
dp = [[0 for j in range(m)] for i in range(n)]
output = []
for i in range(1, n):
	for j in range(1, m - 1):
		if maze[i][j] == '*':
			for height in range(1, max(n, m)):
				if i - height < 0 or i + height > n - 1 or j - height < 0 or (j + height > m - 1):
					if height != 1:
						output.append((i + 1, j + 1, height - 1))
					break
				if maze[i - height][j] == '*' and maze[i + height][j] == '*' and (maze[i][j - height] == '*') and (maze[i][j + height] == '*'):
					dp[i - height][j] = 1
					dp[i + height][j] = 1
					dp[i][j - height] = 1
					dp[i][j + height] = 1
					dp[i][j] = 1
				else:
					if height != 1:
						output.append((i + 1, j + 1, height - 1))
					break
cp = 0
for i in range(n):
	for j in range(m):
		if dp[i][j] == 1:
			cp += 1
if cp == noa:
	print(len(output))
	for i in output:
		print(*i)
else:
	print(-1)


import sys
from math import *

def minp():
	return sys.stdin.readline().strip()

def mint():
	return int(minp())

def mints():
	return map(int, minp().split())

def main():
	(n, m) = mints()
	res = []
	a = [None] * n
	l = [None] * n
	r = [None] * n
	s = [0] * n
	for i in range(n):
		a[i] = list(minp())
		l[i] = [i for i in range(m)]
		r[i] = [i for i in range(m)]
		s[i] = [0] * m
	for i in range(n):
		j = 0
		b = a[i]
		ll = l[i]
		rr = r[i]
		while j < m:
			if b[j] == '*':
				jj = j + 1
				while jj < m and b[jj] == '*':
					jj += 1
				jj -= 1
				for k in range(j, jj + 1):
					ll[k] = j
					rr[k] = jj
				j = jj + 1
			else:
				j += 1
	for i in range(m):
		j = 0
		while j < n:
			if a[j][i] == '*':
				jj = j + 1
				while jj < n and a[jj][i] == '*':
					jj += 1
				jj -= 1
				for k in range(j, jj + 1):
					x = min(i - l[k][i], r[k][i] - i, k - j, jj - k)
					s[k][i] = x
					if x > 0:
						res.append((k + 1, i + 1, x))
				j = jj + 1
			else:
				j += 1
	for i in range(n):
		j = 0
		ss = s[i]
		rr = r[i]
		c = -1
		while j < m:
			if ss[j] > 0 and c < ss[j]:
				c = ss[j]
			if c >= 0:
				rr[j] = '*'
			else:
				rr[j] = '.'
			j += 1
			c -= 1
		j = m - 1
		c = -1
		while j >= 0:
			if ss[j] > 0 and c < ss[j]:
				c = ss[j]
			if c >= 0:
				rr[j] = '*'
			c -= 1
			j -= 1
	for i in range(m):
		j = 0
		c = -1
		while j < n:
			x = s[j][i]
			if x > 0 and c < x:
				c = x
			if c >= 0:
				r[j][i] = '*'
			j += 1
			c -= 1
		j = n - 1
		c = -1
		while j >= 0:
			x = s[j][i]
			if x > 0 and c < x:
				c = x
			if c >= 0:
				r[j][i] = '*'
			if r[j][i] != a[j][i]:
				print(-1)
				exit(0)
			c -= 1
			j -= 1
	print(len(res))
	for i in res:
		print(*i)
main()


(n, m) = map(int, input().split())
G = []
L = [[0 for x in range(m + 2)] for x in range(n + 2)]
R = [[0 for x in range(m + 2)] for x in range(n + 2)]
U = [[0 for x in range(m + 2)] for x in range(n + 2)]
D = [[0 for x in range(m + 2)] for x in range(n + 2)]
for i in range(n):
	s = input()
	G.append(s)
for i in range(n):
	nm = 0
	for j in range(m):
		if G[i][j] == '*':
			nm += 1
		else:
			nm = 0
		L[i][j] = nm
	nm = 0
	for j in range(m - 1, -1, -1):
		if G[i][j] == '*':
			nm += 1
		else:
			nm = 0
		R[i][j] = nm
for j in range(m):
	nm = 0
	for i in range(n):
		if G[i][j] == '*':
			nm += 1
		else:
			nm = 0
		U[i][j] = nm
	nm = 0
	for i in range(n - 1, -1, -1):
		if G[i][j] == '*':
			nm += 1
		else:
			nm = 0
		D[i][j] = nm
col = [[0 for x in range(m + 2)] for x in range(n + 2)]
row = [[0 for x in range(m + 2)] for x in range(n + 2)]
ANS = []
for i in range(n):
	for j in range(m):
		if G[i][j] == '.':
			continue
		ans = min(U[i][j], L[i][j], R[i][j], D[i][j]) - 1
		if ans <= 0:
			continue
		ANS.append([i + 1, j + 1, ans])
		row[i][j - ans] += 1
		row[i][j + ans + 1] -= 1
		col[i - ans][j] += 1
		col[i + ans + 1][j] -= 1
for i in range(n):
	for j in range(1, m):
		row[i][j] += row[i][j - 1]
for j in range(m):
	for i in range(1, n):
		col[i][j] += col[i - 1][j]
okay = True
for i in range(n):
	for j in range(m):
		if G[i][j] == '*' and row[i][j] == 0 and (col[i][j] == 0):
			okay = False
if okay:
	print(len(ANS))
	for x in ANS:
		print(x[0], x[1], x[2])
else:
	print(-1)