Ema built a quantum computer! Help her test its capabilities by solving the problem below.

Given a grid of size $n\times m$, each cell in the grid is either $good$ or $\boldsymbol{bad}$.

A valid plus is defined here as the crossing of two segments (horizontal and vertical) of equal lengths. These lengths must be odd, and the middle cell of its horizontal segment must cross the middle cell of its vertical segment. 

In the diagram below, the blue pluses are valid and the orange ones are not valid.

Find the two largest valid pluses that can be drawn on $good$ cells in the grid, and return an integer denoting the maximum product of their areas.  In the above diagrams, our largest pluses have areas of $5$ and $\mbox{9}$.  The product of their areas is $5\times9=45$.

Note: The two pluses cannot overlap, and the product of their areas should be maximal.

Function Description  

Complete the twoPluses function in the editor below.  It should return an integer that represents the area of the two largest pluses.

twoPluses has the following parameter(s):  

grid: an array of strings where each string represents a row and each character of the string represents a column of that row  

Input Format

The first line contains two space-separated integers, $n$ and $m$. 

Each of the next $n$ lines contains a string of $m$ characters where each character is either G ($good$) or B ($\boldsymbol{bad}$). These strings represent the rows of the grid.  If the $y^{th}$ character in the $x^{th}$ line is G, then $(x,y)$ is a $good$ cell.  Otherwise it's a $\boldsymbol{bad}$ cell.

Constraints

$2\leq n\leq15$

$2\leq m\leq15$

Output Format

Find $2$ pluses that can be drawn on $good$ cells of the grid, and return an integer denoting the maximum product of their areas.

Sample Input 0

5 6
GGGGGG
GBBBGB
GGGGGG
GGBBGB
GGGGGG

Sample Output 0

5

Sample Input 1

6 6
BGBBGB
GGGGGG
BGBBGB
GGGGGG
BGBBGB
BGBBGB

Sample Output 1

25

Explanation

Here are two possible solutions for Sample 0 (left) and Sample 1 (right):

Explanation Key:

Green: $good$ cell
Red: $\boldsymbol{bad}$ cell
Blue: possible $pluses$. 

For the explanation below, we will refer to a plus of length $\boldsymbol{i}$ as $P_i$.

Sample 0 

There is enough good space to color one $P_3$ plus and one $\mathbf{P_1}$ plus. $Area(P_3)=5\:units$, and $Area(P_1)=1\:\textit{unit}$. The product of their areas is $5\times1=5$.

Sample 1 

There is enough good space to color two $P_3$ pluses. $Area(P_3)=5\:units$. The product of the areas of our two $P_3$ pluses is $5\times5=25$.

Source: hackerrank | Difficulty: MEDIUM
Tags: Implementation


Solutions:
def solve(y, x, y1, x1, l):
	i = 0
	s = True
	t = True
	ans = []
	while True:
		if s:
			a = l[y + i][x] if y + i < len(l) else 'B'
			b = l[y - i][x] if 0 <= y - i else 'B'
			c = l[y][x - i] if 0 <= x - i else 'B'
			d = l[y][x + i] if x + i < len(l[0]) else 'B'
			if a == b == c == d == 'G':
				l[y + i][x] = 'B'
				l[y - i][x] = 'B'
				l[y][x - i] = 'B'
				l[y][x + i] = 'B'
			else:
				ans.append((i - 1) * 4 + 1)
				s = False
		if t:
			e = l[y1 + i][x1] if y1 + i < len(l) else 'B'
			f = l[y1 - i][x1] if 0 <= y1 - i else 'B'
			g = l[y1][x1 - i] if 0 <= x1 - i else 'B'
			h = l[y1][x1 + i] if x1 + i < len(l[0]) else 'B'
			if e == f == g == h == 'G':
				l[y1 + i][x1] = 'B'
				l[y1 - i][x1] = 'B'
				l[y1][x1 - i] = 'B'
				l[y1][x1 + i] = 'B'
			else:
				ans.append((i - 1) * 4 + 1)
				t = False
		i += 1
		if not s and (not t):
			break
	return max(0, ans[0] * ans[1])

def main():
	(n, m) = map(int, input().split())
	l = []
	for _ in range(n):
		l.append(list(input()))
	ans = 0
	for y in range(len(l)):
		for x in range(len(l[0])):
			for y1 in range(len(l)):
				for x1 in range(len(l[0])):
					if l[y][x] == 'B' or l[y1][x1] == 'B':
						continue
					t = []
					for i in l:
						t.append(i[:])
					if y == 1 and x == 1 and (y1 == 3) and (x1 == 4):
						kkkk = 0
					ans = max(ans, solve(y, x, y1, x1, t))
	print(ans)
main()


(n, m) = map(int, input().split())
s = [list(input()) for i in range(n)]
ans = 0

def star(i, j, c):
	s[i][j] = c
	for h in range(1, n):
		if i + h < n and i - h >= 0 and (j + h < m) and (j - h >= 0) and (s[i + h][j] == 'G') and (s[i - h][j] == 'G') and (s[i][j + h] == 'G') and (s[i][j - h] == 'G'):
			s[i + h][j] = s[i - h][j] = s[i][j + h] = s[i][j - h] = c
		else:
			break

def calc():
	t1 = t2 = 0
	for i in range(n):
		for j in range(m):
			if s[i][j] == 'B':
				continue
			if s[i][j] == '1':
				t1 += 1
			if s[i][j] == '2':
				t2 += 1
			s[i][j] = 'G'
	return t1 * t2

def check(i, j, ii, jj):
	if s[i][j] != 'G' or s[ii][jj] != 'G':
		return 0
	star(i, j, '1')
	star(ii, jj, '2')
	c1 = calc()
	star(ii, jj, '1')
	star(i, j, '2')
	c2 = calc()
	return c1 if c1 > c2 else c2
for k1 in range(n * m):
	for k2 in range(k1 + 1, n * m):
		ans = max(ans, check(k1 // m, k1 % m, k2 // m, k2 % m))
print(ans)


(n, m) = map(int, input().split())
t = []
for i in range(n):
	t += [[i for i in input()]]

def dessine(t, i, j):
	tt = []
	for x in t:
		tt += [[y for y in x]]
	tt[i][j] = 'B'
	a = 0
	while True:
		a += 1
		if i + a >= n or i - a < 0 or j + a >= m or (j - a < 0):
			break
		if tt[i + a][j] == 'B' or tt[i - a][j] == 'B' or tt[i][j + a] == 'B' or (tt[i][j - a] == 'B'):
			break
		tt[i + a][j] = 'B'
		tt[i - a][j] = 'B'
		tt[i][j + a] = 'B'
		tt[i][j - a] = 'B'
	return (tt, 4 * a - 3)

def best(t, nb):
	if nb == 0:
		maxi = 0
		for i in range(n):
			for j in range(m):
				if t[i][j] == 'G':
					(tt, v) = dessine(t, i, j)
					maxi = max(maxi, v)
		return maxi
	else:
		maxi = 0
		for i in range(n):
			for j in range(m):
				if t[i][j] == 'G':
					(tt, v) = dessine(t, i, j)
					maxi = max(maxi, v * best(tt, 0))
		return maxi
print(best(t, 1))


def increase(a, x, y, d, N, M):
	if x + d < N and 0 <= x - d and (y + d < M) and (0 <= y - d):
		if a[x + d][y] == 0 and a[x - d][y] == 0 and (a[x][y + d] == 0) and (a[x][y - d] == 0):
			a[x + d][y] = 1
			a[x - d][y] = 1
			a[x][y + d] = 1
			a[x][y - d] = 1
			return [True, d + 1]
		else:
			return [False, d]
	else:
		return [False, d]

def foo(a, x1, y1, x2, y2, N, M):
	if a[x1][y1] == 0 and a[x2][y2] == 0:
		a[x1][y1] = 1
		a[x2][y2] = 1
		i1 = True
		i2 = True
		d1 = 1
		d2 = 1
		while i1 or i2:
			if i1:
				(i1, d1) = increase(a, x1, y1, d1, N, M)
			if i2:
				(i2, d2) = increase(a, x2, y2, d2, N, M)
		return (1 + 4 * (d1 - 1)) * (1 + 4 * (d2 - 1))
	else:
		return 0

def copp(a, N, M):
	b = [[0] * M for i in range(N)]
	for i in range(N):
		for j in range(M):
			b[i][j] = a[i][j]
	return b
(N, M) = list(map(int, input().split()))
a = [[0] * M for i in range(N)]
for i in range(N):
	s = input()
	for j in range(M):
		if s[j] == 'B':
			a[i][j] = 1
res = 0
for x1 in range(N):
	for y1 in range(M):
		for x2 in range(N):
			for y2 in range(M):
				if x1 != x2 or y1 != y2:
					b = copp(a, N, M)
					res1 = foo(b, x1, y1, x2, y2, N, M)
					if res < res1:
						res = res1
print(res)


def bad(i, j):
	if i < 0 or i >= n or j < 0 or (j >= m):
		return True
	if grid[i][j] == 'B' or vis[i][j]:
		return True
	return False

def check(i, j, k):
	for a in range(0, k + 1):
		if bad(i, j + a) or bad(i, j - a) or bad(i + a, j) or bad(i - a, j):
			return False
	return True
(n, m) = map(int, input().split())
grid = []
vis = []
for i in range(n):
	grid.append(input())
	vis.append([False] * m)
ans = 0
for i in range(n):
	for j in range(m):
		for k in range(20):
			for a in range(n):
				for b in range(m):
					vis[a][b] = False
			if check(i, j, k):
				for a in range(0, k + 1):
					vis[i][j + a] = vis[i][j - a] = vis[i + a][j] = vis[i - a][j] = True
				for a in range(n):
					for b in range(m):
						for l in range(20):
							if check(a, b, l):
								ans = max(ans, (4 * k + 1) * (4 * l + 1))
print(ans)


def getarea(c1, c2):
	x1 = {c1[1]}
	for k in range(c1[0]):
		x1.add((c1[1][0] + (k + 1), c1[1][1]))
		x1.add((c1[1][0] - (k + 1), c1[1][1]))
		x1.add((c1[1][0], c1[1][1] + (k + 1)))
		x1.add((c1[1][0], c1[1][1] - (k + 1)))
	x2 = {c2[1]}
	for k in range(c2[0]):
		x2.add((c2[1][0] + (k + 1), c2[1][1]))
		x2.add((c2[1][0] - (k + 1), c2[1][1]))
		x2.add((c2[1][0], c2[1][1] + (k + 1)))
		x2.add((c2[1][0], c2[1][1] - (k + 1)))
	if c1[0] <= c2[0]:
		for cel in x1:
			if cel in x2:
				return 0
	else:
		for cel in x2:
			if cel in x1:
				return 0
	return (4 * c1[0] + 1) * (4 * c2[0] + 1)
(N, M) = [int(x) for x in input().split()]
board = []
ngood = 0
for n in range(N):
	linea = input().strip()
	ngood += linea.count('G')
	board.append([x for x in linea])
p = []
for i in range(1, N - 1):
	for j in range(1, M - 1):
		if board[i][j] != 'G':
			continue
		for k in range(1, min(i + 1, j + 1, N - i, M - j)):
			if board[i + k][j] != 'G':
				break
			if board[i - k][j] != 'G':
				break
			if board[i][j + k] != 'G':
				break
			if board[i][j - k] != 'G':
				break
			p.append([k, (i, j)])
ln = len(p)
if ln == 0:
	if ngood > 1:
		maxarea = 1
	else:
		maxarea = 0
elif ln == 1:
	if 4 * p[0][0] + 1 < ngood:
		maxarea = 4 * p[0][0] + 1
	else:
		maxarea = 0
else:
	maxarea = 0
	for i in range(ln - 1):
		area = 0
		for j in range(i + 1, ln):
			area = max(area, getarea(p[i], p[j]))
		if area == 0 and 4 * p[i][0] + 1 < ngood:
			area = 4 * p[i][0] + 1
		maxarea = max(area, maxarea)
print(maxarea)


from re import finditer
from copy import deepcopy

def findLargestProd(n, m, grid, biggest):
	largest = 0
	for size in range(biggest, -1, -1):
		if (4 * size + 1) ** 2 < largest:
			break
		centers = []
		for i in range(0 + size, n - size):
			potential = [m.start() + size for m in finditer('(?=' + 'G' * (2 * size + 1) + ')', grid[i])]
			for j in potential:
				found = True
				for k in range(size + 1):
					if grid[i + k][j] == 'B' or grid[i - k][j] == 'B':
						found = False
						break
				if found:
					centers.append((i, j))
		if len(centers) > 0:
			for c in centers:
				size2 = findLargestPlus(n, m, fillGrid(grid, size, c), biggest)
				if size2 != -1:
					prod = (4 * size + 1) * (4 * size2 + 1)
					if prod > largest:
						largest = prod
	return largest

def findLargestPlus(n, m, grid, biggest):
	for size in range(biggest, -1, -1):
		for i in range(0 + size, n - size):
			potential = [m.start() + size for m in finditer('(?=' + 'G' * (2 * size + 1) + ')', grid[i])]
			for j in potential:
				found = True
				for k in range(size + 1):
					if grid[i + k][j] == 'B' or grid[i - k][j] == 'B':
						found = False
						break
				if found:
					return size
	return -1

def fillGrid(grid, size, center):
	(i, j) = center
	g = deepcopy(grid)
	g[i] = g[i][:j - size] + 'B' * (2 * size + 1) + g[i][j + size + 1:]
	if size > 0:
		for s in range(1, size + 1):
			g[i - s] = g[i - s][:j] + 'B' + g[i - s][j + 1:]
			g[i + s] = g[i + s][:j] + 'B' + g[i + s][j + 1:]
	return g
(n, m) = map(int, input().strip().split())
grid = []
for i in range(n):
	grid.append(input().strip())
biggest = (lambda x: (x - 1) // 2)(min(n, m))
print(findLargestProd(n, m, grid, biggest))


import sys
from itertools import combinations, chain
(N, M) = map(int, input().split())
grid = [input().strip() for _ in range(N)]

def make_cross(grid, i, j):
	cross = set()
	crosses = []
	crosses.append(cross)
	if grid[i][j] != 'G':
		return crosses
	cross = set(cross)
	cross.add((i, j))
	crosses.append(cross)

	def can_extend_vert():
		(u, d) = (i - size, i + size)
		return u >= 0 and d < N and (grid[u][j] == 'G') and (grid[d][j] == 'G')

	def can_extend_horz():
		(l, r) = (j - size, j + size)
		return l >= 0 and r < M and (grid[i][l] == 'G') and (grid[i][r] == 'G')
	size = 1
	while can_extend_vert() and can_extend_horz():
		cross = set(cross)
		cross.add((i, j - size))
		cross.add((i, j + size))
		cross.add((i - size, j))
		cross.add((i + size, j))
		crosses.append(cross)
		size += 1
	return crosses
crosses = list(chain.from_iterable((make_cross(grid, i, j) for j in range(M) for i in range(N))))
assert all((len(c) == 0 or (len(c) - 1) % 4 == 0 for c in crosses))
for c in crosses:
	for cell in c:
		if grid[cell[0]][cell[1]] != 'G':
			sys.exit(1)
max_prod = 0
for (c1, c2) in combinations(crosses, 2):
	if c1.isdisjoint(c2):
		max_prod = max(max_prod, len(c1) * len(c2))
print(max_prod)


def get(x, y, gmap):
	if x < 0 or y < 0:
		return None
	try:
		return gmap[y][x]
	except:
		return None
(height, width) = (5, 6)
game_map = ['GGGGGG', 'GBBBGB', 'GGGGGG', 'GGBBGB', 'GGGGGG']
(height, width) = map(int, input().split())
game_map = []
for _ in range(height):
	game_map.append(input())

def find_other_bigger(gmap, aldone):
	other_best_score = 0
	for y in range(height):
		for x in range(width):
			if game_map[y][x] == 'B':
				continue
			else:
				done = [(x, y)]
				idx = 1
				while True:
					ok = True
					curr_done = []
					for l in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
						try:
							if get(x + idx * l[0], y + idx * l[1], game_map) == 'G' and (x + idx * l[0], y + idx * l[1]) not in aldone:
								curr_done.append((x + idx * l[0], y + idx * l[1]))
							else:
								ok = False
								break
						except:
							pass
					if not ok:
						break
					done = done + curr_done
					idx += 1
				if len(done) > other_best_score:
					other_best_score = len(done)
	return other_best_score

def run():
	best_score = 0
	for y in range(height):
		for x in range(width):
			if game_map[y][x] == 'B':
				continue
			poss = []
			idx = 1
			done = [(x, y)]
			while True:
				curr_score = len(done) * find_other_bigger(game_map, done)
				if curr_score > best_score:
					best_score = curr_score
				ok = True
				curr_done = []
				for l in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
					if get(x + idx * l[0], y + idx * l[1], game_map) == 'G':
						curr_done.append((x + idx * l[0], y + idx * l[1]))
					else:
						ok = False
						break
				if not ok:
					break
				done = done + curr_done
				idx += 1
	print(best_score)
run()


(N, M) = map(int, input().split())
grid = [list(input()) for _ in range(N)]
dx = [0, -1, 0, 1]
dy = [1, 0, -1, 0]

def can(l, x, y):
	for i in range(len(dx)):
		for dl in range(l):
			nx = x + dx[i] * dl
			ny = y + dy[i] * dl
			if nx < 0 or nx >= N or ny < 0 or (ny >= M) or (grid[nx][ny] == 'B'):
				return False
	return True

def draw(l, x, y, c):
	for i in range(len(dx)):
		for dl in range(l):
			nx = x + dx[i] * dl
			ny = y + dy[i] * dl
			grid[nx][ny] = c
res = 0
for l1 in range(1, 8 + 1):
	for x1 in range(0, N):
		for y1 in range(0, M):
			if can(l1, x1, y1):
				draw(l1, x1, y1, 'B')
				for l2 in range(1, 8 + 1):
					for x2 in range(0, N):
						for y2 in range(0, M):
							if can(l2, x2, y2):
								res = max(res, ((l1 * 2 - 1) * 2 - 1) * ((l2 * 2 - 1) * 2 - 1))
				draw(l1, x1, y1, 'G')
print(res)


(m, n) = map(int, input().strip().split())
c = [[i == 'G' for i in input().strip()] for _ in range(m)]
p = [(0, -1), (0, 1), (-1, 0), (1, 0)]
plus = {}

def col(c, i, j):
	if c[i][j]:
		count = 1
		r = min(i, j, m - i - 1, n - j - 1)
		if r == 0:
			return (0, 1)
		else:
			t = 0
			for t in range(1, r + 1):
				if all((c[i + t * q[0]][j + t * q[1]] for q in p)):
					count += 4
				else:
					t -= 1
					break
			return (t, count)
	else:
		return None
for i in range(m):
	for j in range(n):
		res = col(c, i, j)
		if res:
			plus[i, j] = res
ans = 0
for k in plus:
	d = [x[:] for x in c]
	(i, j) = k
	count = 1
	for t in range(plus[k][0] + 1):
		if t > 0:
			count += 4
		for q in p:
			d[i + t * q[0]][j + t * q[1]] = False
		for i0 in range(m):
			for j0 in range(n):
				res = col(d, i0, j0)
				if res:
					ans = max(ans, count * res[1])
print(ans)


def inside(x, y):
	return 0 <= x and x < n and (0 <= y) and (y < m)

def f(x, y):
	ret = 150
	for i in range(4):
		tmp = 0
		for j in range(20):
			(nx, ny) = (x + j * dx[i], y + j * dy[i])
			if inside(nx, ny) and s[nx][ny] == 'G':
				tmp = j
			else:
				break
		ret = min(ret, tmp)
	return ret

def ok(a, b, c, d, e, f):
	g = [[0 for i in range(m)] for i in range(n)]
	for i in range(4):
		for j in range(e + 1):
			g[a + j * dx[i]][b + j * dy[i]] = 1
	for i in range(4):
		for j in range(f + 1):
			if g[c + j * dx[i]][d + j * dy[i]] == 1:
				return False
	return True
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]
(n, m) = (int(_) for _ in input().split())
s = [input() for i in range(n)]
size = [[0 for i in range(m)] for i in range(n)]
for i in range(n):
	for j in range(m):
		size[i][j] = f(i, j)
ans = 0
for i in range(n):
	for j in range(m):
		for h in range(i, n):
			for k in range(m):
				(a, b) = (size[i][j], size[h][k])
				for x in range(a + 1):
					for y in range(b + 1):
						if ok(i, j, h, k, x, y):
							ans = max(ans, (1 + 4 * x) * (1 + 4 * y))
print(ans)


def crosssize(good, row, col):
	if not good[row][col]:
		return 0
	ans = 1
	for armlen in range(min(row, col, len(good) - 1 - row, len(good[0]) - 1 - col)):
		if good[row][col + ans] and good[row][col - ans] and good[row + ans][col] and good[row - ans][col]:
			ans += 1
		else:
			break
	return ans

def bestsizes(size1, size2, rowdiff, coldiff):
	(shortdiff, longdiff) = sorted([rowdiff, coldiff])
	if size1 > size2:
		(size1, size2) = (size2, size1)
	if shortdiff == 0:
		if size1 + size2 <= longdiff + 1:
			return (size1, size2)
		elif 2 * size1 <= longdiff + 1:
			return (size1, longdiff + 1 - size1)
		else:
			return ((longdiff + 1) // 2, (longdiff + 2) // 2)
	if shortdiff < size1 and longdiff < size2:
		if area(shortdiff) * area(size2) > area(size1) * area(longdiff):
			return (shortdiff, size2)
		else:
			return (size1, longdiff)
	else:
		return (size1, size2)
	return min(rowdiff, coldiff) < min(size1, size2) and max(rowdiff, coldiff) < max(size1, size2)

def area(size):
	if size == 0:
		return 0
	return 4 * (size - 1) + 1
(rows, cols) = map(int, input().split())
good = []
for _ in range(rows):
	good.append([cell == 'G' for cell in input()])
assert all((cols == len(row) for row in good))
size = [[crosssize(good, row, col) for col in range(cols)] for row in range(rows)]
ans = 0
for r1 in range(rows):
	for c1 in range(cols):
		for r2 in range(rows):
			for c2 in range(cols):
				sizes = bestsizes(size[r1][c1], size[r2][c2], abs(r1 - r2), abs(c1 - c2))
				ans = max(ans, area(sizes[0]) * area(sizes[1]))
print(ans)


(n, m) = input().strip().split(' ')
(n, m) = [int(n), int(m)]
maxSize = (min(n, m) + 1) // 2
grid = []
for i in range(n):
	grid.append([cell == 'G' for cell in input()])

def sizeToArea(size):
	if size == 0:
		return 0
	return (size - 1) * 4 + 1

def checkCell(x, y):
	if x < 0 or x >= n or y < 0 or (y >= m):
		return False
	return grid[x][y]

def getMaxPlus(x, y):
	if not checkCell(x, y):
		return 0
	size = 1
	valid = True
	while valid:
		check = [(1, 0), (0, 1), (-1, 0), (0, -1)]
		valid = False
		for (i, j) in check:
			if not checkCell(x + i * size, y + j * size):
				break
		else:
			valid = True
			size += 1
	return size

def isOverlapping(aPos, aSize, bPos, bSize):
	shorterDist = min(abs(aPos[0] - bPos[0]), abs(aPos[1] - bPos[1]))
	longerDist = max(abs(aPos[0] - bPos[0]), abs(aPos[1] - bPos[1]))
	if aPos[0] == bPos[0] or aPos[1] == bPos[1]:
		return longerDist < aSize + bSize - 1
	if aSize > longerDist:
		return bSize > shorterDist
	if bSize > longerDist:
		return aSize > shorterDist
	return False
order = []
for a in range(1, maxSize + 1):
	for b in range(1, a + 1):
		order.append((a, b))
order.sort(key=lambda x: sizeToArea(x[0]) * sizeToArea(x[1]), reverse=True)
pluses = [[] for x in range(maxSize + 1)]
for x in range(n):
	for y in range(m):
		result = getMaxPlus(x, y)
		pluses[result].append((x, y))
for i in reversed(range(maxSize)):
	pluses[i].extend(pluses[i + 1])
for (aSize, bSize) in order:
	for aPos in pluses[aSize]:
		for bPos in pluses[bSize]:
			if not isOverlapping(aPos, aSize, bPos, bSize):
				print(sizeToArea(aSize) * sizeToArea(bSize))
				exit()
else:
	print(0)


def find_max_plus(grid, n, m):
	max_plus = 0
	for i in range(n):
		for j in range(m):
			if grid[i][j] == 'G':
				plus = 0
				for (t, r, b, l) in zip(range(i, -1, -1), range(j, m), range(i, n), range(j, -1, -1)):
					if grid[t][j] == 'G' and grid[i][r] == 'G' and (grid[b][j] == 'G') and (grid[i][l] == 'G'):
						plus += 1
					else:
						break
				if plus > max_plus:
					max_plus = plus
	return max_plus

def find_max_plus_prod(grid, n, m):
	max_prod = 0
	for i in range(n):
		for j in range(m):
			if grid[i][j] == 'G':
				pcount = 0
				new_grid = [list(grid[k]) for k in range(n)]
				for (t, r, b, l) in zip(range(i, -1, -1), range(j, m), range(i, n), range(j, -1, -1)):
					if grid[t][j] == 'G' and grid[i][r] == 'G' and (grid[b][j] == 'G') and (grid[i][l] == 'G'):
						pcount += 1
						new_grid[t][j] = new_grid[i][r] = new_grid[b][j] = new_grid[i][l] = 'B'
						second_plus = find_max_plus(new_grid, n, m)
						prod = (4 * (pcount - 1) + 1) * (4 * (second_plus - 1) + 1)
						if prod > max_prod:
							max_prod = prod
					else:
						break
	return max_prod
(n, m) = map(int, input().split())
grid = [[] for i in range(n)]
for i in range(n):
	grid[i] = list(map(str, input()))
print(find_max_plus_prod(grid, n, m))


import sys
sol = []

def max_cross(grid, i, j, max_i, max_j, c):
	m = 1
	sol.append((2 * m - 1, c))
	continuer = True
	while continuer:
		if i - m >= 0 and j - m >= 0 and (i + m < max_i) and (j + m < max_j):
			if grid[i - m][j] == 'G' and grid[i + m][j] == 'G' and (grid[i][j - m] == 'G') and (grid[i][j + m] == 'G'):
				m += 1
				sol.append((2 * m - 1, c))
			else:
				continuer = False
		else:
			continuer = False
	return 2 * m - 1

def detect_cross(grid, c, t, nbc):
	(i, j) = (c // t, c % t)
	s = grid[i][j]
	if c == nbc - 1:
		if s != 'G':
			return (0, c)
		else:
			m = (max_cross(grid, i, j, n, t, c), c)
			return m
	elif s == 'G':
		m = (max_cross(grid, i, j, n, t, c), c)
		ret = max(m, detect_cross(grid, c + 1, t, nbc))
		if ret[0] > m[0]:
			return ret
		else:
			return m
	else:
		return detect_cross(grid, c + 1, t, nbc)
(n, m) = input().strip().split(' ')
(n, m) = [int(n), int(m)]
grid = []
for i in range(n):
	c = [c_temp for c_temp in input().strip()]
	grid.append(c)
nbc = n * m
c1 = detect_cross(grid, 0, m, nbc)
if c[0] != 0:
	sol.sort(reverse=True)
	aera = []
	for i in range(len(sol)):
		for j in range(i + 1, len(sol)):
			(x1, y1) = (sol[i][1] // m, sol[i][1] % m)
			(x2, y2) = (sol[j][1] // m, sol[j][1] % m)
			a = [(x1, y1)]
			for k in range(1, (sol[i][0] + 1) // 2):
				a += [(x1 - k, y1), (x1, y1 - k), (x1 + k, y1), (x1, y1 + k)]
			b = [(x2, y2)]
			for k in range(1, (sol[j][0] + 1) // 2):
				b += [(x2 - k, y2), (x2, y2 - k), (x2 + k, y2), (x2, y2 + k)]
			if not max([case in b for case in a]):
				aera.append((4 * (sol[i][0] // 2) + 1) * (4 * (sol[j][0] // 2) + 1))
	aera.sort(reverse=True)
	if aera != []:
		print(aera[0])
	else:
		print(0)
else:
	print(0)


(n, m) = map(int, input().split())
(g, p) = ([input() for i in range(n)], [])
for i in range(n):
	for j in range(m):
		(s, k) = (set(), 0)
		while True:
			sk = {(i + k, j), (i - k, j), (i, j + k), (i, j - k)}
			if any((x not in range(n) or y not in range(m) or g[x][y] == 'B' for (x, y) in sk)):
				break
			s |= sk
			p.append(set(s))
			k += 1
print(max((len(pi) * len(pj) for pi in p for pj in p if not pi & pj)))


def get_pluses(x, y, grid, width, height):
	pluses = []
	if grid[y][x]:
		dist = 0
		for i in range(0, max(width, height)):
			if y - i < 0 or not grid[y - i][x]:
				break
			if y + i >= height or not grid[y + i][x]:
				break
			if x - i < 0 or not grid[y][x - i]:
				break
			if x + i >= width or not grid[y][x + i]:
				break
			pluses.append((x, y, dist, dist * 4 + 1))
			dist += 1
	return pluses

def line_intersect(l1, l2):
	return l1[0] <= l2[2] and l1[2] >= l2[0] and (l1[1] <= l2[3]) and (l1[3] >= l2[1])

def intersect(p1, p2):
	if p1[0] == p2[0] and p1[1] == p2[1]:
		return True
	l1 = (p1[0] - p1[2], p1[1], p1[0] + p1[2], p1[1])
	l2 = (p1[0], p1[1] - p1[2], p1[0], p1[1] + p1[2])
	l3 = (p2[0] - p2[2], p2[1], p2[0] + p2[2], p2[1])
	l4 = (p2[0], p2[1] - p2[2], p2[0], p2[1] + p2[2])
	return line_intersect(l1, l3) or line_intersect(l1, l4) or line_intersect(l2, l3) or line_intersect(l2, l4)
(n, m) = map(int, input().strip().split(' '))
grid = []
for i in range(n):
	grid.append([True if x == 'G' else False for x in input().strip()])
pluses = []
for y in range(n):
	for x in range(m):
		pluses += get_pluses(x, y, grid, m, n)
if len(pluses) <= 1:
	print(0)
else:
	best = 0
	for i in range(len(pluses) - 1):
		for j in range(i + 1, len(pluses)):
			if not intersect(pluses[i], pluses[j]):
				best = max(best, pluses[i][3] * pluses[j][3])
	print(best)


from collections import namedtuple
from itertools import combinations
Point = namedtuple('Point', ['x', 'y'])
Cross = namedtuple('Cross', ['center', 'len'])
(N, M) = map(int, input().strip().split())
squares = [i * 4 + 1 for i in range(min(N, M))]
products = []
for i in range(min(N, M)):
	products.append([squares[i] * squares[j] for j in range(min(N, M))])
grid = []
centers = []
for i in range(N):
	line = []
	for (j, c) in enumerate(input().strip()):
		if c == 'G':
			line.append(True)
			centers.append(Point(i, j))
		else:
			line.append(False)
	grid.append(line)
crosses = []
for center in centers:
	arm = 0
	xm = center.x - arm
	ym = center.y - arm
	xp = center.x + arm
	yp = center.y + arm
	while xm >= 0 and ym >= 0 and (xp < N) and (yp < M) and grid[xm][center.y] and grid[xp][center.y] and grid[center.x][ym] and grid[center.x][yp]:
		arm += 1
		xm -= 1
		ym -= 1
		xp += 1
		yp += 1
		crosses.append(Cross(center, arm - 1))

def intersect(c1, c2):
	xdist = abs(c1.center.x - c2.center.x)
	ydist = abs(c1.center.y - c2.center.y)
	maxdist = max(xdist, ydist)
	mindist = min(xdist, ydist)
	maxlen = max(c1.len, c2.len)
	minlen = min(c1.len, c2.len)
	if mindist == 0:
		return maxdist <= minlen + maxlen
	return minlen >= mindist and maxlen >= maxdist
pairs = [products[c1.len][c2.len] for (c1, c2) in combinations(crosses, 2) if not intersect(c1, c2)]
if not pairs:
	print(0)
else:
	pairs.sort()
	print(pairs[-1])


def can_fit(arr, r, i, j):
	if arr[i][j]:
		return False
	steps = (r + 1) // 2
	for k in range(1, steps):
		if arr[i + k][j]:
			return False
		if arr[i - k][j]:
			return False
		if arr[i][j - k]:
			return False
		if arr[i][j + k]:
			return False
	return True

def set_plus(arr, r, i, j, b):
	arr[i][j] = b
	steps = (r + 1) // 2
	for k in range(1, steps):
		arr[i + k][j] = b
		arr[i - k][j] = b
		arr[i][j - k] = b
		arr[i][j + k] = b

def add_plus(arr, r, i, j):
	set_plus(arr, r, i, j, True)

def remove_plus(arr, r, i, j):
	set_plus(arr, r, i, j, False)

def next_rank(r, t, m):
	if r == t:
		return (r - 2, m)
	else:
		return (r, t - 2)

def solution(N, M, arr):
	max_rank = (min(N, M) - 1) // 2 * 2 + 1
	rank1 = rank2 = max_rank
	max_so_far = 0
	while rank1 > 0:
		fits = False
		dist2 = rank2 // 2
		for i in range(dist2, N - dist2):
			for j in range(dist2, M - dist2):
				if can_fit(arr, rank2, i, j):
					fits = True
					dist1 = rank1 // 2
					add_plus(arr, rank2, i, j)
					for n in range(dist1, N - dist1):
						for m in range(dist1, M - dist1):
							if can_fit(arr, rank1, n, m):
								max_so_far = max((2 * rank1 - 1) * (2 * rank2 - 1), max_so_far)
					remove_plus(arr, rank2, i, j)
		if not fits:
			max_rank = rank2 - 2
		(rank1, rank2) = next_rank(rank1, rank2, max_rank)
	return max_so_far
(N, M) = [int(x) for x in input().split()]
grid = []
for n in range(N):
	grid.append([])
	for m in input().strip():
		grid[n].append(m == 'B')
print(solution(N, M, grid))


import sys
import itertools
(n, m) = input().strip().split(' ')
(n, m) = [int(n), int(m)]
grid = []
possible = []
for i in range(n):
	grid.append(input().strip())
for r in range(n):
	for c in range(m):
		if grid[r][c] == 'B':
			continue
		possible.append((r, c, 0))
		for i in range(1, min(min(n - r - 1, r), min(m - c - 1, c)) + 1):
			if grid[r - i][c] == 'G' and grid[r][c - i] == 'G' and (grid[r + i][c] == 'G') and (grid[r][c + i] == 'G'):
				possible.append((r, c, i))
			else:
				break
product = 0
for (a, b) in itertools.combinations(possible, 2):
	if a[1] == b[1] and a[1] + a[2] >= b[1] - b[2] and (a[1] - a[2] <= b[1] + b[2]):
		continue
	if a[0] == b[0] and a[0] + a[2] >= b[0] - b[2] and (a[0] - a[2] <= b[0] + b[2]):
		continue
	a_r = a[0]
	a_c = a[1]
	a_i = a[2]
	b_r = b[0]
	b_c = b[1]
	b_i = b[2]
	if (a_r + a_i >= b_r and a_r - a_i <= b_r) and (b_c + b_i >= a_c and b_c - b_i <= a_c):
		continue
	if (b_r + b_i >= a_r and b_r - b_i <= a_r) and (a_c + a_i >= b_c and a_c - a_i <= b_c):
		continue
	product = max(product, (4 * a_i + 1) * (4 * b_i + 1))
print(product)


(n, m) = input().split(' ')
(n, m) = (int(n), int(m))
cells = []
for i in range(n):
	cells.append(list(input()))
pluses = []
for y in range(n):
	for x in range(m):
		if cells[y][x] == 'G':
			max_possible = min(m - 1 - x, x, y, n - 1 - y) + 1
			for l in range(max_possible):
				if cells[y - l][x] == 'G' and cells[y + l][x] == 'G' and (cells[y][x - l] == 'G') and (cells[y][x + l] == 'G'):
					pluses.append((l, x, y))
				else:
					break
pluses.sort(reverse=True)
max_area = 0
for cross in range(len(pluses)):
	cells_taken = set()
	(l, x, y) = pluses[cross]
	for length in range(l + 1):
		cells_taken.update({(x + length, y), (x - length, y), (x, y + length), (x, y - length)})
	for next_cross in range(cross + 1, len(pluses)):
		new_cells_taken = set()
		(l_new, x_new, y_new) = pluses[next_cross]
		for length in range(l_new + 1):
			new_cells_taken.update({(x_new + length, y_new), (x_new - length, y_new), (x_new, y_new + length), (x_new, y_new - length)})
		if not cells_taken & new_cells_taken:
			area = (l * 4 + 1) * (l_new * 4 + 1)
			max_area = max(area, max_area)
			break
	if max_area > (l * 4 + 1) ** 2:
		break
print(max_area)


(n, m) = tuple(map(int, input().strip().split()))
matriz = [input().strip() for i in range(n)]
matrizT = list(zip(*matriz))

def maxBuenos(lista, centro):
	if lista[centro] != 'G':
		return 0
	longitud = 1
	for i in range(1, min(centro + 1, len(lista) - centro)):
		if lista[centro + i] != 'G' or lista[centro - i] != 'G':
			break
		longitud += 2
	return longitud

def solapan(cruz1, cruz2):
	matriz = [[False for i in range(m)] for j in range(n)]
	lado1 = cruz1[0] // 2
	lado2 = cruz2[0] // 2
	for i in range(cruz1[0]):
		matriz[cruz1[1]][i + cruz1[2] - lado1] = True
		matriz[i + cruz1[1] - lado1][cruz1[2]] = True
	for i in range(cruz2[0]):
		if matriz[cruz2[1]][i + cruz2[2] - lado2] or matriz[i + cruz2[1] - lado2][cruz2[2]]:
			return True
	return False
cruces = []
for i in range(n):
	for j in range(m):
		dimension = min(maxBuenos(matriz[i], j), maxBuenos(matrizT[j], i))
		for k in range(1, dimension + 1, 2):
			cruces.append((k, i, j))
res = 0
cruces.sort(reverse=True)
for i in range(len(cruces) - 1):
	for cruz in cruces[i + 1:]:
		multAreas = (cruces[i][0] * 2 - 1) * (cruz[0] * 2 - 1)
		if multAreas <= res or solapan(cruces[i], cruz):
			continue
		res = max(res, multAreas)
print(res)


import copy
(N, M) = input().split()
(N, M) = (int(N), int(M))

def possiblePluses(iGrid):
	iN = len(iGrid)
	iM = len(iGrid[0])
	K = min(iN, iM)
	res = []
	for k in range(0, K // 2 + 1):
		res = res + possiblePlusesK(iGrid, k)
	return res

def possiblePlusesK(iGrid, k):
	iN = len(iGrid)
	iM = len(iGrid[0])
	res = []
	for i in range(k, iN - k):
		for j in range(k, iM - k):
			good = True
			for ik in range(i - k, i + k + 1):
				good = good and iGrid[ik][j] == 'G'
			for jk in range(j - k, j + k + 1):
				good = good and iGrid[i][jk] == 'G'
			if good:
				res.append([[i, j], k])
	return res

def updateGrid(iGrid, iPlus):
	updatedGrid = copy.deepcopy(iGrid)
	i = iPlus[0][0]
	j = iPlus[0][1]
	k = iPlus[1]
	for ik in range(i - k, i + k + 1):
		updatedGrid[ik][j] = 'B'
	for jk in range(j - k, j + k + 1):
		updatedGrid[i][jk] = 'B'
	return updatedGrid
grid = []
for a0 in range(N):
	grid.append(list(input()))
possi1 = possiblePluses(grid)
maxArea = -1
for p1 in possi1:
	grid2 = updateGrid(grid, p1)
	possi2 = possiblePluses(grid2)
	for p2 in possi2:
		maxAreaLoc = (p1[1] * 4 + 1) * (p2[1] * 4 + 1)
		maxArea = max(maxArea, maxAreaLoc)
print(maxArea)


class grid:

	def __init__(self, rows):
		self.rows = rows
		self.N = len(rows)
		self.M = len(rows[0])
		self.MIN_COLUMN = 0
		self.MIN_ROW = 0
		self.MAX_COLUMN = self.M - 1
		self.MAX_ROW = self.N - 1
		self.goodCells = self.getGoodCells()
		self.validCrosses = self.getValidCrosses()

	def __str__(self):
		name = ''
		for r in self.rows:
			name += r + '\n'
		return name

	def outOfBounds(self, x, y):
		if x < self.MIN_ROW:
			return True
		if y < self.MIN_COLUMN:
			return True
		if x > self.MAX_ROW:
			return True
		if y > self.MAX_COLUMN:
			return True
		return False

	def goodCell(self, x, y):
		if self.outOfBounds(x, y):
			return False
		return self.rows[x][y] == 'G'

	def getGoodCells(self):
		goodCells = []
		for row in range(self.N):
			for col in range(self.M):
				if self.goodCell(row, col):
					goodCells.append((row, col))
		return goodCells

	def getValidCrosses(self):
		validCrosses = []
		for c in self.goodCells:
			for armLength in range(min(c[0] + 1, c[1] + 1, self.N - c[0], self.M - c[1])):
				x = cross(c[0], c[1], armLength * 2 + 1)
				if x.isValid(self):
					validCrosses.append(x)
				else:
					break
		return validCrosses

class cross:

	def __init__(self, x, y, l):
		self.x = x
		self.y = y
		self.length = l
		self.armLength = int((l - 1) / 2)
		self.size = l * 2 - 1
		self.cells = self.getCells()

	def __str__(self):
		name = 'x:{}, y:{}, length:{}, size:{}'.format(self.x, self.y, self.length, self.size)
		return name

	def isValid(self, board):
		if not board.goodCell(self.x, self.y):
			return False
		for i in range(1, self.armLength + 1):
			if not board.goodCell(self.x + i, self.y):
				return False
			if not board.goodCell(self.x - i, self.y):
				return False
			if not board.goodCell(self.x, self.y + i):
				return False
			if not board.goodCell(self.x, self.y - i):
				return False
		return True

	def overlaps(self, ox):
		if self.x == ox.x and self.y == ox.y:
			return True
		if self.y == ox.y:
			if self.x + self.armLength >= ox.x - ox.armLength:
				return True
			if self.x - self.armLength >= ox.x + ox.armLength:
				return True
		if self.x == ox.x:
			if self.y + self.armLength >= ox.y - ox.armLength:
				return True
			if self.y - self.armLength >= ox.y + ox.armLength:
				return True
		return False

	def overlaps2(self, ox):
		for c in self.cells:
			if c in ox.cells:
				return True
		return False

	def getCells(self):
		cells = [(self.x, self.y)]
		for i in range(1, self.armLength + 1):
			cells.append((self.x - i, self.y))
			cells.append((self.x + i, self.y))
			cells.append((self.x, self.y - i))
			cells.append((self.x, self.y + i))
		return cells

def getInput():
	(N, M) = [int(x) for x in input().split()]
	board = []
	for _ in range(N):
		board.append(input())
	G = grid(board)
	return G

def Solution():
	G = getInput()
	maxProduct = 0
	if len(G.goodCells) == 0 or len(G.goodCells) == 1:
		print(0)
		return
	for (i, c) in enumerate(G.validCrosses):
		for x in G.validCrosses[i + 1:]:
			if not c.overlaps2(x):
				prod = c.size * x.size
				if prod > maxProduct:
					maxProduct = prod
	print(maxProduct)
Solution()


import pprint
from copy import deepcopy
pp = pprint.PrettyPrinter(indent=4)
DEBUG = False
(n, m) = input().strip().split(' ')
(dim1, dim2) = [int(n), int(m)]
max_size = min(dim1, dim2)
if max_size % 2 == 0:
	max_size -= 1

def is_g(arg):
	if arg == 'G':
		return 1
	else:
		return 0
grid = []
for _ in range(dim1):
	grid.append(list(map(is_g, list(input().strip()))))

def is_g(arg):
	if arg == 'G':
		return 1
	else:
		return 0

def get_sizes(minimum, maximum):
	if minimum % 2 == 0:
		minimum += 1
	if maximum % 2 == 0:
		maximum -= 1
	result = list(range(minimum, maximum + 1, 2))
	result.reverse()
	return result

def get_row_elements(row, size):
	results = []
	branch_size = size // 2
	for (idx, center) in enumerate(row[branch_size:len(row) - branch_size], branch_size):
		if center == 0:
			continue
		for branch in range(1, branch_size + 1):
			if row[idx + branch] != 1 or row[idx - branch] != 1:
				break
		else:
			results.append(idx)
	return results

def find_plus(grid, size):
	found_list = []
	branch_size = size // 2
	if DEBUG:
		print('\nfind_plus: looking for size {}, branch_size:{}'.format(size, branch_size))
	if DEBUG:
		print('starting with row:{} ending with row:{}'.format(branch_size, len(grid) - branch_size - 1))
	for (row_idx, row) in enumerate(grid[branch_size:len(grid) - branch_size], branch_size):
		row_candidates = get_row_elements(row, size)
		if DEBUG:
			print('row:{}:{} candidates: {}'.format(row_idx, row, row_candidates))
		for candidate in row_candidates:
			if DEBUG:
				print('r:{} checking candidate: {}'.format(row_idx, candidate))
			for branch in range(1, branch_size + 1):
				if DEBUG:
					print('r:{}, c:{}, checking branch: {}'.format(row_idx, candidate, branch))
				if grid[row_idx + branch][candidate] != 1 or grid[row_idx - branch][candidate] != 1:
					break
			else:
				if DEBUG:
					print('found plus at ({}, {})'.format(row_idx, candidate))
				found_list.append((row_idx, candidate))
	if DEBUG:
		print('size: {}, found_list:{}'.format(size, found_list))
	return found_list

def max_plus(grid, min_size=1, max_size=max_size):
	size_list = get_sizes(min_size, max_size)
	found_list = []
	for size in size_list:
		branch_size = size // 2
		if DEBUG:
			print('\nmax_plus: looking for size {}, branch_size:{}'.format(size, branch_size))
		if DEBUG:
			print('starting with row:{} ending with row:{}'.format(branch_size, len(grid) - branch_size - 1))
		for (row_idx, row) in enumerate(grid[branch_size:len(grid) - branch_size], branch_size):
			row_candidates = get_row_elements(row, size)
			if DEBUG:
				print('row:{}:{} candidates: {}'.format(row_idx, row, row_candidates))
			for candidate in row_candidates:
				if DEBUG:
					print('r:{} checking candidate: {}'.format(row_idx, candidate))
				for branch in range(1, branch_size + 1):
					if DEBUG:
						print('r:{}, c:{}, checking branch: {}'.format(row_idx, candidate, branch))
					if grid[row_idx + branch][candidate] != 1 or grid[row_idx - branch][candidate] != 1:
						break
				else:
					if DEBUG:
						print('found plus at ({}, {})'.format(row_idx, candidate))
					found_list.append((row_idx, candidate))
		if found_list:
			break
	if DEBUG:
		print('size: {}, found_list:{}'.format(size, found_list))
	return (size, found_list)

def clear_plus(center, size, grid):
	new_grid = deepcopy(grid)
	branch_size = size // 2
	(center_row, center_col) = center
	new_grid[center_row][center_col] = 0
	for branch in range(1, branch_size + 1):
		new_grid[center_row][center_col + branch] = 0
		new_grid[center_row][center_col - branch] = 0
		new_grid[center_row + branch][center_col] = 0
		new_grid[center_row - branch][center_col] = 0
	return new_grid
size_list = get_sizes(1, max_size)
solution = 0
for size in size_list:
	if DEBUG:
		print('\nMain: looking for size {}'.format(size))
	found_list = find_plus(grid, size)
	if DEBUG:
		print('Main: size:{}, found:{}'.format(size, found_list))
	for plus in found_list:
		if DEBUG:
			print('Main: current plus center:{}, size:{}'.format(plus, size))
		next_grid = clear_plus(plus, size, grid)
		(next_max, next_plus_list) = max_plus(next_grid, max_size=size)
		if DEBUG:
			print('next max_found:{}, list:{}'.format(next_max, next_plus_list))
		if next_plus_list:
			prod = (size * 2 - 1) * (next_max * 2 - 1)
			if prod > solution:
				if DEBUG:
					print('FOUND better solution: {} (size:{} x next_max:{})'.format(prod, size, next_max))
				solution = prod
print(solution)


from math import floor
from sys import stderr

def find_pluses(a, b, r, c, lines):
	found = []
	for i1 in range(r - a + 1):
		for j1 in range(c - a + 1):
			cok = all((lines[i1 + ci][j1 + floor(a / 2)] == 'G' for ci in range(a)))
			rok = lines[i1 + floor(a / 2)][j1:j1 + a] == ['G'] * a
			if cok and rok:
				new_lines = [list(l) for l in lines]
				for ci in range(a):
					new_lines[i1 + ci][j1 + floor(a / 2)] = 'B'
				new_lines[i1 + floor(a / 2)][j1:j1 + a] = ['B'] * a
				for i2 in range(r - b + 1):
					for j2 in range(c - b + 1):
						cok = all((new_lines[i2 + ci][j2 + floor(b / 2)] == 'G' for ci in range(b)))
						rok = new_lines[i2 + floor(b / 2)][j2:j2 + b] == ['G'] * b
						if cok and rok:
							found.append((2 * a - 1, 2 * b - 1))
	return found
(n, m) = [int(x) for x in input().strip().split(' ')]
rows = []
for _ in range(n):
	rows.append(list(input().strip()))
maxp = min(m, n) + 1
sofar = []
maxsofa = 0
for i in range(1, maxp + 1, 2):
	for j in range(1, i + 1, 2):
		for (p1, p2) in find_pluses(i, j, n, m, rows):
			maxsofa = max(p1 * p2, maxsofa)
print(maxsofa)


def findMaxA(N, M, agrid):
	maxA = maxA = [[-1 for j in range(M)] for i in range(N)]
	for i in range(N):
		for j in range(M):
			if agrid[i][j] == 'G':
				a = 0
				while i - a >= 0 and i + a <= N - 1 and (j - a >= 0) and (j + a <= M - 1) and (agrid[i][j - a] == 'G') and (agrid[i][j + a] == 'G') and (agrid[i - a][j] == 'G') and (agrid[i + a][j] == 'G'):
					a = a + 1
				maxA[i][j] = a - 1
	return maxA

def updateGrid(i, j, a, grid):
	newGrid = []
	for r in range(len(grid)):
		arr = [s for s in grid[r]]
		newGrid.append(arr)
	for d in range(a + 1):
		newGrid[i][j - d] = 'S'
		newGrid[i][j + d] = 'S'
		newGrid[i - d][j] = 'S'
		newGrid[i + d][j] = 'S'
	return newGrid

def main():
	[N, M] = [int(s) for s in input().strip().split(' ')]
	grid = []
	for i in range(N):
		arr = [s for s in input().strip()]
		grid.append(arr)
	maxA = findMaxA(N, M, grid)
	maxProd = 0
	for i in range(N):
		for j in range(M):
			area1 = 0
			if maxA[i][j] >= 0:
				for a in range(maxA[i][j] + 1):
					area1 = 1 + 4 * a
					newgrid = updateGrid(i, j, a, grid)
					newMaxA = findMaxA(N, M, newgrid)
					for x in range(N):
						for y in range(M):
							area2 = 0
							if x != i and y != j and (newMaxA[x][y] >= 0):
								for b in range(newMaxA[x][y] + 1):
									area2 = 1 + 4 * b
									if area1 * area2 > maxProd:
										maxProd = area1 * area2
	print(maxProd)
main()


import sys
from itertools import combinations
(n, m) = [int(x) for x in sys.stdin.readline().split()]
grid = []
total = 0

def trans(a):
	if a == 'G':
		return True
	else:
		return False
for line in sys.stdin:
	a = [trans(x) for x in line.strip()]
	total += len(a)
	grid.append(a)

def gprint(grid):
	for row in grid:
		for col in row:
			if col:
				print('G', end='')
			else:
				print('B', end='')
		print()

def is_cross(grid, start):
	mid = len(grid) // 2
	y = start[0]
	x = start[1]
	result = []
	for i in range(len(grid)):
		result += [(mid + y, i + x), (i + y, mid + x)]
		if not (grid[mid][i] and grid[i][mid]):
			return None
	return list(set(result))

def conflict(c1, c2):
	return len(set(c1) & set(c2))
sizes = [x for x in range(1, min(m, n) + 1) if x % 2 == 1]
crosses = []
for size in sizes:
	for col in range(m - size + 1):
		for row in range(n - size + 1):
			sub = []
			for r in range(size):
				sub.append(grid[row + r][col:col + size])
			cross = is_cross(sub, (row, col))
			if cross:
				crosses.append(cross)
pairs = combinations(crosses, 2)
scores = [(x, len(x[0]) * len(x[1]), conflict(x[0], x[1])) for x in pairs if not conflict(x[0], x[1])]
scores.sort(key=lambda x: x[1])
if len(scores) > 1:
	result = max(scores, key=lambda x: x[1])[1]
print(result)


(n, m) = map(int, input().split())
grid = []
grid.append([False] * (m + 2))
for _ in range(0, n):
	grid.append([False] + list(map(lambda x: 'G' == x, input())) + [False])
grid.append([False] * (m + 2))
numGood = sum(map(lambda l: sum(map(int, l)), grid))
max_area = 0

def plusValid(depth, grid, point):
	(r, c) = point
	return grid[r - depth][c] and grid[r + depth][c] and grid[r][c - depth] and grid[r][c + depth]

def markInvalid(depth, grid, point):
	(r, c) = point
	grid[r - depth][c] = False
	grid[r + depth][c] = False
	grid[r][c - depth] = False
	grid[r][c + depth] = False

def markValid(depth, grid, point):
	(r, c) = point
	grid[r - depth][c] = True
	grid[r + depth][c] = True
	grid[r][c - depth] = True
	grid[r][c + depth] = True

def getArea(pi, pj, grid):
	(di, dj) = (0, 0)
	markInvalid(di, grid, pi)
	markInvalid(dj, grid, pj)
	while plusValid(di + 1, grid, pi):
		di += 1
		markInvalid(di, grid, pi)
	while plusValid(dj + 1, grid, pj):
		dj += 1
	area = (4 * di + 1) * (4 * dj + 1)
	while di > 0:
		markValid(di, grid, pi)
		di -= 1
	markValid(0, grid, pi)
	markValid(0, grid, pj)
	return area
plusCentres = []
for i in range(1, n + 1):
	for j in range(1, m + 1):
		if plusValid(1, grid, (i, j)):
			plusCentres.append((i, j))
numCentres = len(plusCentres)
if numCentres == 0:
	max_area = 1 if numGood > 1 else 0
else:
	for i in range(0, numCentres):
		p = plusCentres[i]
		d = 0
		while plusValid(d + 1, grid, p):
			d += 1
		area = 4 * d + 1
		max_area = max(max_area, area if numGood > area else area - 4)
		for j in range(i + 1, numCentres):
			pi = plusCentres[i]
			pj = plusCentres[j]
			max_area = max(max_area, getArea(pi, pj, grid))
			max_area = max(max_area, getArea(pj, pi, grid))
print(max_area)


import sys
(n, m) = [int(x) for x in input().strip().split(' ')]
grid = []
for _ in range(n):
	grid.append([True if x == 'G' else False for x in input()])
pluses = []
for x in range(m):
	for y in range(n):
		sides = 0
		while x - sides >= 0 and x + sides < m and (y - sides >= 0) and (y + sides < n) and grid[y - sides][x] and grid[y + sides][x] and grid[y][x - sides] and grid[y][x + sides]:
			pluses.append((x, y, sides))
			sides += 1
pluses.sort(reverse=True, key=lambda i: i[2])
area = 0
plus_area = lambda p: 4 * p[2] + 1
while len(pluses) > 1:
	p1 = pluses.pop(0)
	cells1 = set([(x, p1[1]) for x in range(p1[0] - p1[2], p1[0] + p1[2] + 1)])
	cells1 |= set([(p1[0], y) for y in range(p1[1] - p1[2], p1[1] + p1[2] + 1)])
	for p2 in pluses:
		cells2 = set([(x, p2[1]) for x in range(p2[0] - p2[2], p2[0] + p2[2] + 1)])
		cells2 |= set([(p2[0], y) for y in range(p2[1] - p2[2], p2[1] + p2[2] + 1)])
		if not len(cells1.intersection(cells2)):
			area = max(area, plus_area(p1) * plus_area(p2))
print(area)


(h, l) = [int(e) for e in input().split(' ')]
matrix = []
for j in range(h):
	ligne = input()
	matrix.append(ligne)
mat = {}
for j in range(h):
	for i in range(l):
		if matrix[j][i] == 'G':
			mat[str(i) + ' ' + str(j)] = 1

def ha(mat, i, j):
	result = 0
	for k in range(j - 1, -1, -1):
		index = str(i) + ' ' + str(k)
		if index not in mat:
			break
		result += 1
	return result

def b(mat, i, j):
	result = 0
	for k in range(j + 1, h):
		index = str(i) + ' ' + str(k)
		if index not in mat:
			break
		result += 1
	return result

def g(mat, i, j):
	result = 0
	for k in range(i - 1, -1, -1):
		index = str(k) + ' ' + str(j)
		if index not in mat:
			break
		result += 1
	return result

def d(mat, i, j):
	result = 0
	for k in range(i + 1, l):
		index = str(k) + ' ' + str(j)
		if index not in mat:
			break
		result += 1
	return result

def plus(mat, i, j):
	patte = min(ha(mat, i, j), b(mat, i, j), g(mat, i, j), d(mat, i, j))
	return 1 + 4 * patte
surf = []
for j in range(1, h - 1):
	for i in range(1, l - 1):
		surface = plus(mat, i, j)
		if surface > 0:
			patte = 0
			surfP = 1 + patte * 4
			while surfP <= surface:
				surf.append([surfP, i, j])
				patte += 1
				surfP = 1 + patte * 4
surf.sort()

def rendPlus(surfi):
	dicoPlus1 = {}
	patte = (surfi[0] - 1) // 4
	i = surfi[1]
	j = surfi[2]
	dicoPlus1[str(i) + ' ' + str(j)] = 1
	for k in range(1, patte + 1):
		dicoPlus1[str(i - k) + ' ' + str(j)] = 1
		dicoPlus1[str(i + k) + ' ' + str(j)] = 1
		dicoPlus1[str(i) + ' ' + str(j - k)] = 1
		dicoPlus1[str(i) + ' ' + str(j + k)] = 1
	return dicoPlus1
maxi = []
if len(surf) < 2:
	print(0)
elif len(surf) == 2:
	print(surf[-1][0] * surf[0][0])
else:
	longSurf = len(surf)
	for k in range(longSurf - 1, 0, -1):
		dic1 = rendPlus(surf[k])
		for i in range(k - 1, -1, -1):
			dic2 = rendPlus(surf[i])
			indep = True
			for (cle, v) in dic2.items():
				if cle in dic1:
					indep = False
					break
			if indep:
				maxi.append(surf[i][0] * surf[k][0])
	maxi.sort()
	print(maxi[-1])


from itertools import combinations
(n, m) = input().strip().split(' ')
(n, m) = [int(n), int(m)]
grid = []
for _ in range(n):
	grid += [[1 if cell == 'G' else 0 for cell in input().strip()]]

def find_crosses(grid):
	crosses = []
	for i in range(n):
		for j in range(m):
			if grid[i][j] == 1:
				k = min(i, n - i - 1, j, m - j - 1)
				for l in range(k + 1):
					if grid[i - l][j] and grid[i + l][j] and grid[i][j - l] and grid[i][j + l]:
						crosses += [(i, j, l)]
					else:
						break
	return crosses

def check_disjoint(pair):
	(i1, j1, k1) = pair[0]
	(i2, j2, k2) = pair[1]
	idist = abs(i1 - i2)
	jdist = abs(j1 - j2)
	if i1 == i2 and jdist <= k1 + k2:
		return False
	if j1 == j2 and idist <= k1 + k2:
		return False
	if max(k1, k2) >= max(idist, jdist) and min(k1, k2) >= min(idist, jdist):
		return False
	return True

def solve(grid):
	max_area = 0
	crosses = find_crosses(grid)
	crosses.sort(key=lambda x: x[2])
	for pair in combinations(crosses, 2):
		area = (1 + 4 * pair[0][2]) * (1 + 4 * pair[1][2])
		if area <= max_area:
			continue
		elif check_disjoint(pair):
			max_area = area
	return max_area
print(solve(grid))


def isG(i, j):
	return matrix[i][j] == 'G'

def left(i, j):
	return j >= 0 and isG(i, j)

def right(i, j):
	return j < m and isG(i, j)

def up(i, j):
	return i >= 0 and isG(i, j)

def down(i, j):
	return i < n and isG(i, j)
(n, m) = map(int, input().strip().split(' '))
matrix = []
for i in range(n):
	matrix.append(input().strip())
crosses = []
for i in range(n):
	for j in range(m):
		if not isG(i, j):
			continue
		center = (i, j)
		cross = set([center])
		crosses.append(cross)
		step = 1
		while left(i, j - step) and right(i, j + step) and up(i - step, j) and down(i + step, j):
			cross = cross.copy()
			cross.add((i, j - step))
			cross.add((i, j + step))
			cross.add((i - step, j))
			cross.add((i + step, j))
			crosses.append(cross)
			step += 1
result = 0
for i in range(len(crosses)):
	for j in range(i + 1, len(crosses)):
		if not crosses[i].intersection(crosses[j]):
			result = max(result, len(crosses[i]) * len(crosses[j]))
print(result)


def max_plus(grid, row, column):
	grid_rows = len(grid)
	grid_columns = len(grid[0])
	max_size = min(min(row, grid_rows - row - 1), min(column, grid_columns - column - 1))
	up = row
	down = row
	left = column
	right = column
	max_pluses.append([(row, column)])
	previous = [(row, column)]
	for i in range(1, max_size + 1):
		up -= 1
		down += 1
		left -= 1
		right += 1
		if grid[up][column] == 'G' and grid[down][column] == 'G' and (grid[row][left] == 'G') and (grid[row][right] == 'G'):
			previous.append((up, column))
			previous.append((down, column))
			previous.append((row, left))
			previous.append((row, right))
			max_pluses.append(list(previous))
		else:
			return
	return
(rows, columns) = [int(x) for x in input().split()]
grid = []
max_pluses = []
for r in range(rows):
	grid.append(input().strip())
for row in range(rows):
	for column in range(columns):
		if grid[row][column] == 'G':
			max_plus(grid, row, column)
max_product = 0
for i in range(len(max_pluses)):
	for j in range(len(max_pluses)):
		if bool(set(max_pluses[i]) & set(max_pluses[j])) == False:
			current_product = len(max_pluses[i]) * len(max_pluses[j])
			if current_product > max_product:
				max_product = current_product
print(max_product)


def is_in(i, j, n, m, l):
	if i - l >= 0 and j - l >= 0 and (i + l < n) and (j + l < m):
		return True
	else:
		return False

def is_allgood(i, j, l, grid):
	if grid[i - l][j] == 'G' and grid[i + l][j] == 'G' and (grid[i][j - l] == 'G') and (grid[i][j + l] == 'G'):
		return True
	else:
		return False

def isnot_overlap(x1, y1, x2, y2, l1, l2):
	if abs(x1 - x2) <= l1 and abs(y1 - y2) <= l2:
		return False
	elif abs(x1 - x2) <= l2 and abs(y1 - y2) <= l1:
		return False
	elif x1 == x2 and abs(y1 - y2) <= l1 + l2:
		return False
	elif y1 == y2 and abs(x1 - x2) <= l1 + l2:
		return False
	else:
		return True
(n, m) = map(int, input().split())
grid = []
for i in range(n):
	grid.append(input())
max_l = int((min(n, m) - 1) / 2)
plus_list = [[] for i in range(max_l + 1)]
for i in range(n):
	for j in range(m):
		if grid[i][j] == 'G':
			l = 1
			plus_list[0].append((i, j))
			while is_in(i, j, n, m, l):
				if is_allgood(i, j, l, grid):
					plus_list[l].append((i, j))
					l += 1
				else:
					break
while True:
	if not plus_list[-1]:
		plus_list.pop()
		max_l -= 1
	else:
		break
combination = {}
for i in range(max_l + 1):
	for j in range(max_l + 1):
		combination[(4 * i + 1) * (4 * j + 1)] = (i, j)
finish = False
ans = 0
for (i, j) in sorted(combination.items(), reverse=True):
	(a, b) = j
	for c in plus_list[a]:
		for d in plus_list[b]:
			if isnot_overlap(c[0], c[1], d[0], d[1], a, b):
				ans = (4 * a + 1) * (4 * b + 1)
				finish = True
				break
		if finish:
			break
	if finish:
		break
print(ans)


def printMatrix(A, N, M):
	for i in range(N):
		print(''.join(map(str, A[i])))
(N, M) = map(int, input().split())
G = []
for i in range(N):
	G.append(input())
U = [[0 for x in range(M)] for x in range(N)]
D = [[0 for x in range(M)] for x in range(N)]
L = [[0 for x in range(M)] for x in range(N)]
R = [[0 for x in range(M)] for x in range(N)]
Q = [[0 for x in range(M)] for x in range(N)]
for i in range(1, N):
	for j in range(M):
		if G[i][j] == 'G' and G[i - 1][j] == 'G':
			U[i][j] = U[i - 1][j] + 1
for i in range(N - 2, -1, -1):
	for j in range(M):
		if G[i][j] == 'G' and G[i + 1][j] == 'G':
			D[i][j] = D[i + 1][j] + 1
for i in range(N):
	for j in range(1, M):
		if G[i][j] == 'G' and G[i][j - 1] == 'G':
			L[i][j] = L[i][j - 1] + 1
for i in range(N):
	for j in range(M - 2, -1, -1):
		if G[i][j] == 'G' and G[i][j + 1] == 'G':
			R[i][j] = R[i][j + 1] + 1
maxArea = 0
for i in range(N):
	for j in range(M):
		if G[i][j] != 'G':
			continue
		for k in range(N):
			for l in range(M):
				if G[k][l] != 'G':
					continue
				if i == k and j == l:
					continue
				c1w = min(L[i][j], R[i][j], U[i][j], D[i][j])
				Q[i][j] = 1
				for w in range(1, c1w + 1):
					Q[i + w][j] = 1
					Q[i - w][j] = 1
					Q[i][j + w] = 1
					Q[i][j - w] = 1
				c2w = min(L[k][l], R[k][l], U[k][l], D[k][l])
				while True:
					crossing = False
					for w in range(1, c2w + 1):
						if Q[k + w][l] == 1 or Q[k - w][l] == 1 or Q[k][l + w] == 1 or (Q[k][l - w] == 1):
							crossing = True
					if c2w == 0:
						break
					elif crossing:
						c2w = c2w - 1
					else:
						break
				Q[i][j] = 0
				for w in range(1, c1w + 1):
					Q[i + w][j] = 0
					Q[i - w][j] = 0
					Q[i][j + w] = 0
					Q[i][j - w] = 0
				maxArea = max(maxArea, (1 + 4 * c1w) * (1 + 4 * c2w))
print(maxArea)


from copy import deepcopy

def find_cross(cells, i, j, n, m):
	cross_size = 1
	area = 1
	limit = min(i, j, n - 1 - i, m - 1 - j)
	for k in range(1, limit + 1):
		if cells[i + k][j] == 'G' and cells[i - k][j] == 'G' and (cells[i][j + k] == 'G') and (cells[i][j - k] == 'G'):
			cross_size += 1
			area += 4
		else:
			break
	return (cross_size, area)
(n, m) = map(int, input().split())
cells = []
for i in range(n):
	cells.append(list(input()))
max_prod = 0
for i in range(n):
	for j in range(m):
		if cells[i][j] == 'B':
			continue
		(cross_size1, area1) = find_cross(cells, i, j, n, m)
		cells_mod = deepcopy(cells)
		max_cross2 = 0
		for k in range(cross_size1):
			cells_mod[i + k][j] = cells_mod[i - k][j] = cells_mod[i][j + k] = cells_mod[i][j - k] = 'B'
		for k in range(n):
			for l in range(m):
				if cells[k][l] == 'B':
					continue
				(cross_size2, area2) = find_cross(cells_mod, k, l, n, m)
				max_cross2 = max(area2, max_cross2)
		max_prod = max(max_cross2 * area1, max_prod)
print(max_prod)


if 1 == 2:
	f = open('in.txt')
	fkt = f.readline
else:
	fkt = input
from collections import Counter
import sys, math
(N, M) = map(int, fkt().strip().split(' '))
C = []
for n in range(N):
	C.append(list(fkt().strip()))
G = 'G'
B = 'B'
pluses = []
for n in range(N):
	for m in range(M):
		if C[n][m] == G:
			plus = set([(n, m)])
			pluses.append(plus.copy())
			i = 1
			while n - i > -1 and n + i < N and (m - i > -1) and (m + i < M) and (C[n][m - i] == G) and (C[n][m + i] == G) and (C[n - i][m] == G) and (C[n + i][m] == G):
				plus |= set([(n, m - i), (n, m + i), (n - i, m), (n + i, m)])
				i += 1
				pluses.append(plus.copy())
m = 0
for p1 in pluses:
	for p2 in pluses:
		if len(p1.intersection(p2)) == 0:
			m = max(len(p1) * len(p2), m)
print(m)


def maxPlus(i, j):
	if grid[i][j] == 'B':
		return 0
	lim = min(i, r - 1 - i, j, c - 1 - j)
	d = 0
	while d <= lim:
		if grid[i - d][j] == 'B' or grid[i + d][j] == 'B' or grid[i][j - d] == 'B' or (grid[i][j + d] == 'B'):
			break
		d += 1
	return d

def isDisjoint(l1, x, y, l2, u, v):
	if x == u and y == v:
		return False
	(u1, u2, v1, v2) = (u - l1, u + l1, v - l1, v + l1)
	(x1, x2, y1, y2) = (x - l2, x + l2, y - l2, y + l2)
	overlap = x == u and (y1 <= v1 <= y2 or y1 <= v2 <= y2) or (y == v and (x1 <= u1 <= x2 or x1 <= u2 <= x2)) or (x1 <= u <= x2 and v1 <= y <= v2) or (y1 <= v <= y2 and u1 <= x <= u2)
	return not overlap
(r, c) = map(int, input().strip().split())
grid = [input() for _ in range(r)]
Plus = []
for i in range(r):
	for j in range(c):
		size = maxPlus(i, j)
		if size:
			Plus.append((size - 1, i, j))
product = 0
for (l, x1, y1) in Plus:
	for l1 in range(l + 1):
		for (l2, x2, y2) in Plus:
			if isDisjoint(l1, x1, y1, l2, x2, y2):
				product = max(product, (l1 * 4 + 1) * (l2 * 4 + 1))
print(product)


(n, m) = [int(x) for x in input().strip().split(' ')]
grid = []
ps = []
for c in range(n):
	row = list(input().strip())
	grid.append(row)

class plus(object):

	def __init__(self, rown, coln, diam):
		self.row = rown
		self.col = coln
		self.diam = diam
		self.arml = (diam - 1) // 2
		self.area = diam * 2 - 1

	def __repr__(self):
		return str(self.row) + ' ' + str(self.col) + ' ' + str(self.diam)

	def checkol(self, plus2):
		rowdiff = abs(self.row - plus2.row)
		coldiff = abs(self.col - plus2.col)
		box1row = rowdiff <= self.arml
		box1col = coldiff <= self.arml
		box2row = rowdiff <= plus2.arml
		box2col = coldiff <= plus2.arml
		samerow = self.row == plus2.row and rowdiff <= self.arml + plus2.arml
		samecol = self.col == plus2.col and coldiff <= self.arml + plus2.arml
		return box1row + box1col + box2row + box2col + samerow + samecol >= 3

def checkols(plus):
	for pl in ps:
		if not pl.checkol(plus):
			return pl.area
	return 0

def gogo():
	maxa = 0
	for c in range(n - int(not n % 2), 0, -2):
		arml = (c - 1) // 2
		for rown in range(arml + 1, n - arml + 1):
			l = 0
			row = grid[rown - 1]
			for coln in range(1, m + 1):
				if row[coln - 1] == 'G':
					l += 1
					if l >= c:
						for v in range(c):
							if grid[rown - arml + v - 1][coln - arml - 1] == 'B':
								break
							elif v == c - 1:
								newplus = plus(rown, coln - arml, c)
								a = checkols(newplus)
								maxa = max(a * newplus.area, maxa)
								ps.append(newplus)
				else:
					l = 0
		if c == 1:
			break
	return maxa
print(gogo())


def getPlus(c, r):
	ps = {(c, r)}
	pl = [set(ps)]
	s = 1
	while True:
		if c + s >= M or c - s < 0 or r + s >= N or (r - s < 0):
			break
		if grid[r][c + s] == 'B' or grid[r][c - s] == 'B' or grid[r + s][c] == 'B' or (grid[r - s][c] == 'B'):
			break
		ps.update({(c + s, r), (c - s, r), (c, r + s), (c, r - s)})
		pl.append(set(ps))
		s += 1
	return pl
(N, M) = map(int, input().strip().split())
grid = []
plus = []
maxp = 0
for n in range(N):
	grid.append(input().strip())
for col in range(M):
	for row in range(N):
		if grid[row][col] == 'G':
			plus += getPlus(col, row)
for p1 in plus:
	for p2 in plus:
		if p1.isdisjoint(p2):
			product = len(p1) * len(p2)
			maxp = max(maxp, product)
print(maxp)


import copy

def check_plus(A, i, j):
	if A[i][j] == 0:
		return 0
	k = 1
	try:
		while True:
			if i - k >= 0 and j - k >= 0 and A[i + k][j] and A[i - k][j] and A[i][j + k] and A[i][j - k]:
				k += 1
			else:
				break
	finally:
		return -3 + 4 * k

def check_second(A, i, j, k):
	B = copy.deepcopy(A)
	p = (k + 3) // 4 - 1
	s = 0
	c = []
	while s <= p:
		B[i + s][j] = B[i - s][j] = B[i][j + s] = B[i][j - s] = 0
		s += 1
	for i in range(n):
		for j in range(m):
			c.append(check_plus(B, i, j))
	return max(c) * k
(n, m) = [int(i) for i in input().split()]
A = []
c = []
for i in range(n):
	A.append(list(map(lambda x: 1 if x == 'G' else 0, list(input()))))
for i in range(n):
	for j in range(m):
		z = check_plus(A, i, j)
		if z >= 1:
			c.append(check_second(A, i, j, z))
print(max(c))


(n, m) = [int(x) for x in input().strip().split(' ')]
grid = [[x == 'G' for x in input().strip()] for _ in range(n)]
plus = []
for r in range(n):
	for c in range(m):
		if grid[r][c]:
			plus.append((r, c, 0))
plus_last = plus
while len(plus_last) > 0:
	plus_new = []
	for p in plus_last:
		v = True
		for rm in (-1, 1):
			r = rm * (p[2] + 1) + p[0]
			c = p[1]
			v &= r >= 0 and r < n and grid[r][c]
		for cm in (-1, 1):
			r = p[0]
			c = cm * (p[2] + 1) + p[1]
			v &= c >= 0 and c < m and grid[r][c]
		if v:
			plus_new.append((p[0], p[1], p[2] + 1))
	plus.extend(plus_new)
	plus_last = plus_new
plus.reverse()
best = 0
for i in range(len(plus)):
	(r0, c0, s0) = plus[i]
	for j in range(i + 1, len(plus)):
		(r1, c1, s1) = plus[j]
		p = (1 + s0 * 4) * (1 + s1 * 4)
		if p > best:
			if r0 == r1 and abs(c0 - c1) <= s0 + s1:
				continue
			elif c0 == c1 and abs(r0 - r1) <= s0 + s1:
				continue
			elif abs(c0 - c1) <= s1 and abs(r0 - r1) <= s0:
				continue
			elif abs(c0 - c1) <= s0 and abs(r0 - r1) <= s1:
				continue
			else:
				best = p
				if s0 == s1:
					break
print(best)


def get_max_size(grid, i, j, n, m):
	size = 1
	for k in range(1, 8):
		if i + k < n and i - k >= 0 and (j + k < m) and (j - k >= 0) and (grid[i + k][j] == 'G') and (grid[i - k][j] == 'G') and (grid[i][j + k] == 'G') and (grid[i][j - k] == 'G'):
			size = size + 2
		else:
			return size
	return size

def area(size):
	return 2 * size - 1

def intersect(grid, i1, j1, s1, i2, j2, s2):
	if j1 == j2 and s1 // 2 + s2 // 2 >= i2 - i1 or (i1 == i2 and s1 // 2 + s2 // 2 >= j2 - j1):
		return 1
	if j1 == j2 or i1 == i2:
		return 0
	if j2 < j1:
		if i2 - s2 // 2 <= i1 and j1 - s1 // 2 <= j2 or (j2 + s2 // 2 >= j1 and i1 + s1 // 2 >= i2):
			return 1
		return 0
	if i1 + s1 // 2 >= i2 and j2 - s2 // 2 <= j1 or (j1 + s1 // 2 >= j2 and i2 - s2 // 2 <= i1):
		return 1
	return 0
(n, m) = input().strip().split(' ')
(n, m) = (int(n), int(m))
grid = []
for i in range(n):
	grid.append(list(input().strip()))
mx = 1
pmx = 1
for i1 in range(n - 1):
	for j1 in range(m):
		if grid[i1][j1] != 'G':
			continue
		ms1 = get_max_size(grid, i1, j1, n, m)
		for i2 in range(i1, n):
			for j2 in range(m):
				if grid[i2][j2] != 'G' or (i1 == i2 and j2 <= j1 + 1) or (j1 == j2 and i2 == i1 + 1):
					continue
				ms2 = get_max_size(grid, i2, j2, n, m)
				inter = intersect(grid, i1, j1, ms1, i2, j2, ms2)
				if inter == 0:
					if area(ms1) * area(ms2) > mx:
						mx = area(ms1) * area(ms2)
					continue
				if i1 == i2:
					m1t = ms1
					m2t = ms2
					cut = ms1 // 2 + ms2 // 2 - (j2 - j1 - 1)
					if ms1 > ms2:
						m1t = ms1 - 2 * cut
					else:
						m2t = ms2 - 2 * cut
					if area(m1t) * area(m2t) > mx:
						mx = area(m1t) * area(m2t)
					continue
				if j1 == j2:
					m1t = ms1
					m2t = ms2
					cut = ms1 // 2 + ms2 // 2 - (i2 - i1 - 1)
					if ms1 > ms2:
						m1t = ms1 - 2 * cut
					else:
						m2t = ms2 - 2 * cut
					if area(m1t) * area(m2t) > mx:
						mx = area(m1t) * area(m2t)
					continue
				m1t = ms1
				m2t = ms2
				while intersect(grid, i1, j1, m1t, i2, j2, m2t) != 0:
					m1t = m1t - 1
				if area(m2t) * area(m1t) > mx:
					mx = area(m2t) * area(m1t)
				m1t = ms1
				while intersect(grid, i1, j1, m1t, i2, j2, m2t) != 0:
					m2t = m2t - 1
				if area(m1t) * area(m2t) > mx:
					mx = area(m1t) * area(m2t)
print(mx)


import re

def prepare_matcher(c, size):
	if size == 0:
		return 'G'
	regex = 'G[\\s\\S]{%d}' * size % tuple([c] * (size - 1) + [c - size])
	regex += 'G{%d})G(?=G{%d}' % (size, size)
	regex += '[\\s\\S]{%d}G' * size % tuple([c - size] + [c] * (size - 1))
	return '(?<=' + regex + ')'

def row_range(row, c):
	if c['row'] == row:
		return set(range(c['col'] - c['size'], c['col'] + c['size'] + 1))
	elif c['row'] - c['size'] <= row <= c['row'] + c['size']:
		return {c['col']}
	else:
		return {}

def row_collide(row, c1, c2):
	r1 = row_range(row, c1)
	for i in row_range(row, c2):
		if i in r1:
			return True
	return False

def intersect(c1, c2):
	for row in range(c2['row'] - c2['size'], c2['row'] + c2['size'] + 1):
		if row_collide(row, c1, c2):
			return True
	return False

def first_diff(c, cs):
	for c2 in cs:
		if not intersect(c, c2):
			return c2

def to_plus(m, s, ncol):
	center = m.span()[0]
	row = center // (ncol + 1)
	col = center - row * (ncol + 1)
	return {'row': row, 'col': col, 'size': s}

def max_prod(c1, centers):
	c2 = first_diff(c1, centers)
	return (1 + c1['size'] * 4) * (1 + c2['size'] * 4) if c2 else 0

def two_pluses(r, c, grid):
	smax = min(r, c) // 2
	centers = [to_plus(m, s, c) for s in range(smax, -1, -1) for m in re.finditer(prepare_matcher(c, s), grid)]
	return max((max_prod(c1, centers[i + 1:]) for (i, c1) in enumerate(centers)))
(r, c) = [int(i) for i in input().split()]
grid = '|'.join([input() for _ in range(r)])
print(two_pluses(r, c, grid))


import math
GRID = []
OP = list(map(int, input().strip().split(' ')))
r = OP[0]
c = OP[1]
PLUS = {}
for d in range(r):
	GRID.append(input())
for i in range(0, r):
	for j in range(0, c):
		if GRID[i][j] == 'G':
			if 1 not in PLUS:
				PLUS[1] = []
			PLUS[1].append([i, j])
			d = 1
			lookable = True
			while lookable == True:
				if i + d < r and i - d >= 0 and (j + d < c) and (j - d >= 0):
					if GRID[i + d][j] == 'G' and GRID[i - d][j] == 'G' and (GRID[i][j - d] == 'G') and (GRID[i][j + d] == 'G'):
						if d * 2 + 1 not in PLUS:
							PLUS[d * 2 + 1] = []
						PLUS[d * 2 + 1].append([i, j])
						d += 1
					else:
						lookable = False
				else:
					lookable = False
AREA = 0
HOLD = [[15, 15], [15, 13], [13, 13], [15, 11], [13, 11], [15, 9], [11, 11], [13, 9], [15, 7], [11, 9], [13, 7], [9, 9], [11, 7], [15, 5], [13, 5], [9, 7], [11, 5], [7, 7], [9, 5], [15, 3], [13, 3], [7, 5], [11, 3], [9, 3], [5, 5], [7, 3], [5, 3], [15, 1], [13, 1], [3, 3], [11, 1], [9, 1], [7, 1], [5, 1], [3, 1], [1, 1]]
for pr in HOLD:
	M = pr[0]
	N = pr[1]
	if M in PLUS and N in PLUS:
		for bg in PLUS[M]:
			bgc = []
			bgc.append([bg[0], bg[1]])
			d = 1
			while d <= int(math.floor(M / 2)):
				bgc.append([bg[0], bg[1] + d])
				bgc.append([bg[0] + d, bg[1]])
				bgc.append([bg[0], bg[1] - d])
				bgc.append([bg[0] - d, bg[1]])
				d += 1
			for ltl in PLUS[N]:
				collision = False
				d = 0
				while d <= int(math.floor(N / 2)) and collision == False:
					if [ltl[0] + d, ltl[1]] in bgc:
						collision = True
					if [ltl[0], ltl[1] + d] in bgc:
						collision = True
					if [ltl[0] - d, ltl[1]] in bgc:
						collision = True
					if [ltl[0], ltl[1] - d] in bgc:
						collision = True
					d += 1
				if collision == False:
					AREA = (M + M - 1) * (N + N - 1)
				if AREA > 0:
					break
			if AREA > 0:
				break
		if AREA > 0:
			break
	if AREA > 0:
		break
print(AREA)


def setMaxPlus(G, i, j):
	a = 0
	while G[i - a][j] == 'G' and G[i + a][j] == 'G' and (G[i][j - a] == 'G') and (G[i][j + a] == 'G'):
		G[i - a][j] = 'B'
		G[i + a][j] = 'B'
		G[i][j - a] = 'B'
		G[i][j + a] = 'B'
		a += 1
	return a * 4 - 3

def removePlus(G, i, j, a):
	a = (a + 3) // 4
	for k in range(a):
		G[i - k][j] = 'G'
		G[i + k][j] = 'G'
		G[i][j - k] = 'G'
		G[i][j + k] = 'G'
	return a

def solve(G):
	G_ = [['B'] * (len(G[0]) + 2)] + [['B'] + r + ['B'] for r in G] + [['B'] * (len(G[0]) + 2)]
	best = 0
	for i in range(1, len(G_) - 1):
		for j in range(1, len(G_[i]) - 1):
			if G_[i][j] == 'B':
				continue
			a = setMaxPlus(G_, i, j)
			for k in range(i, len(G_) - 1):
				for l in range(1, len(G_[k]) - 1):
					b = setMaxPlus(G_, k, l)
					if a * b > best:
						best = a * b
					removePlus(G_, k, l, b)
			removePlus(G_, i, j, a)
	return best
(N, M) = map(int, input().split())
G = list((list(input()) for _ in range(N)))
print(solve(G))


(rows, cols) = [int(s) for s in input().strip().split()]
allowed = set()
for r in range(rows):
	row_str = input().strip()
	for (c, ch) in enumerate(row_str):
		if ch == 'G':
			allowed.add((r, c))
max_so_far = 0
for (r, c) in allowed:
	used = set()
	used.add((r, c))
	width = 1
	while True:
		if (r + width, c) in allowed and (r - width, c) in allowed and ((r, c + width) in allowed) and ((r, c - width) in allowed):
			used.update([(r + width, c), (r - width, c), (r, c + width), (r, c - width)])
			width += 1
		else:
			width -= 1
			break
	first_size = 4 * width + 1
	remain = allowed - used
	for (r, c) in remain:
		width = 1
		while True:
			if (r + width, c) in remain and (r - width, c) in remain and ((r, c + width) in remain) and ((r, c - width) in remain):
				width += 1
			else:
				width -= 1
				break
		second_size = 4 * width + 1
		max_so_far = max(first_size * second_size, max_so_far)
print(max_so_far)


import itertools

def find_plus(board, r, c, rows, cols):
	if board[r][c] != 'G':
		return None
	items = {(r, c)}
	for i in itertools.count(1):
		coords = [(r, c + i), (r, c - i), (r + i, c), (r - i, c)]
		for (rt, ct) in coords:
			if not (0 <= rt < rows and 0 <= ct < cols) or board[rt][ct] != 'G':
				return (items, (r, c))
		items.update(coords)
	return (items, (r, c))

def options(pluses):
	for ((plus1, (cr1, cc1)), (plus2, (cr2, cc2))) in itertools.combinations(pluses, 2):
		intersect = plus1 & plus2
		if not intersect:
			yield (len(plus1) * len(plus2))
			continue
		if cr1 == cr2 or cc1 == cc2:
			center = ((cr1 + cr2) / 2, (cc1 + cc2) / 2)
			split = min(intersect, key=lambda r_c: abs(r_c[0] - center[0]) + abs(r_c[1] - center[1]))
			d1 = abs(cr1 - split[0]) + abs(cc1 - split[1])
			d2 = abs(cr2 - split[0]) + abs(cc2 - split[1])
			(d1, d2) = sorted([d1, d2])
			d1 -= 1
			yield ((d1 * 4 + 1) * (d2 * 4 + 1))
		else:
			distances = [(abs(cr1 - ir) + abs(cc1 - ic), abs(cr2 - ir) + abs(cc2 - ic)) for (ir, ic) in intersect]
			(d1, d2) = map(min, zip(*distances))
			if d2:
				v = len(plus1) * (d2 * 4 - 3)
				yield (len(plus1) * (d2 * 4 - 3))
			if d1:
				v = (d1 * 4 - 3) * len(plus2)
				yield ((d1 * 4 - 3) * len(plus2))
(rows, cols) = map(int, input().split())
board = [input() for _ in range(rows)]
pluses = []
for (r, row) in enumerate(board):
	for (c, elem) in enumerate(row):
		plus = find_plus(board, r, c, rows, cols)
		if plus:
			pluses.append(plus)
print(max(options(pluses)))


def findpluses(start):
	(x, y) = start
	flag = True
	l = 0
	pluse = []
	nextpuzzle = [(x, y)]
	while flag:
		if x + l >= n or x - l < 0 or y + l >= m or (y - l < 0):
			return pluse
		for (i, j) in nextpuzzle:
			if graph[i][j] != 'G':
				return pluse
		if len(pluse) > 0:
			pluse.append(pluse[-1] + nextpuzzle)
		else:
			pluse.append(nextpuzzle)
		l += 1
		nextpuzzle = [(x + l, y), (x - l, y), (x, y + l), (x, y - l)]
(n, m) = list(map(int, input().strip().split()))
graph = [list(input().strip()) for _ in range(n)]
pss = []
for i in range(n):
	for j in range(m):
		pluse = findpluses([i, j])
		if len(pluse) > 0:
			pss.append(pluse)
pss.sort(key=lambda x: -len(x))
pluses = set()
ans = 0
lp = len(pss)
from itertools import combinations
for (i, j) in combinations(range(lp), 2):
	a = pss[i]
	b = pss[j]
	for k in a:
		for l in b:
			x = len(k)
			y = len(l)
			its = set(k).intersection(set(l))
			if len(its) == 0:
				ans = max(ans, x * y)
print(ans)


import copy
(n, m) = list(map(int, input().split()))
new_grid = [[c for c in input()] for i in range(n)]
result = []
answer = False

def max_cross_size(n, m):
	if min(n, m) % 2 == 0:
		return min(n, m) - 1
	else:
		return min(n, m)
for k in range(max_cross_size(n, m) // 2):
	if answer == False:
		for big in range(max_cross_size(n, m), 1, -2):
			grid = copy.deepcopy(new_grid)
			area = 1
			possible_crosses = []
			combinations = []
			while big > 1:
				start = big // 2
				r_m_r = m - big
				c_m_r = n - big
				for i in range(k, c_m_r + 1):
					for j in range(r_m_r + 1):
						scan = grid[start + i][start + j]
						valid = -1
						if scan == 'G':
							for a in range(-start, start + 1):
								segment = grid[start + i + a][start + j]
								if segment == 'G':
									valid += 1
							for b in range(-start, start + 1):
								segment = grid[start + i][start + j + b]
								if segment == 'G':
									valid += 1
							if valid == big * 2 - 1:
								area *= big * 2 - 1
								possible_crosses.append(area)
								area = 1
								for a in range(-start, start + 1):
									segment = grid[start + i + a][start + j]
									if segment == 'G':
										grid[start + i + a][start + j] = 'B'
								for b in range(-start, start + 1):
									segment = grid[start + i][start + j + b]
									if segment == 'G':
										grid[start + i][start + j + b] = 'B'
				for i in range(c_m_r + 1):
					for j in range(k, r_m_r + 1):
						scan = grid[start + i][start + j]
						valid = -1
						if scan == 'G':
							for a in range(-start, start + 1):
								segment = grid[start + i + a][start + j]
								if segment == 'G':
									valid += 1
							for b in range(-start, start + 1):
								segment = grid[start + i][start + j + b]
								if segment == 'G':
									valid += 1
							if valid == big * 2 - 1:
								area *= big * 2 - 1
								possible_crosses.append(area)
								area = 1
								for a in range(-start, start + 1):
									segment = grid[start + i + a][start + j]
									if segment == 'G':
										grid[start + i + a][start + j] = 'B'
								for b in range(-start, start + 1):
									segment = grid[start + i][start + j + b]
									if segment == 'G':
										grid[start + i][start + j + b] = 'B'
				big -= 2
			if len(possible_crosses) == 1:
				if result:
					print(max(result))
				else:
					print(possible_crosses[0])
				answer = True
				break
			elif len(possible_crosses) == 0:
				print(1)
				answer = True
				break
			else:
				for i in range(len(possible_crosses)):
					for j in range(len(possible_crosses)):
						if i != j:
							combinations.append(possible_crosses[i] * possible_crosses[j])
				max_seq = max(combinations)
				result.append(max_seq)
if answer == False:
	print(max(result))


def find_max_plus(grid, n, m):
	max_plus = 0
	for i in range(n):
		for j in range(m):
			if grid[i][j] == 'G':
				plus = 0
				for (t, r, b, l) in zip(range(i, -1, -1), range(j, m), range(i, n), range(j, -1, -1)):
					if grid[t][j] == 'G' and grid[i][r] == 'G' and (grid[b][j] == 'G') and (grid[i][l] == 'G'):
						plus += 1
					else:
						break
				if plus > max_plus:
					max_plus = plus
	return max_plus

def find_max_plus_prod(grid, n, m):
	max_prod = 0
	for i in range(n):
		for j in range(m):
			if grid[i][j] == 'G':
				pcount = 0
				new_grid = [list(grid[k]) for k in range(n)]
				for (t, r, b, l) in zip(range(i, -1, -1), range(j, m), range(i, n), range(j, -1, -1)):
					if grid[t][j] == 'G' and grid[i][r] == 'G' and (grid[b][j] == 'G') and (grid[i][l] == 'G'):
						pcount += 1
						new_grid[t][j] = new_grid[i][r] = new_grid[b][j] = new_grid[i][l] = 'B'
						second_plus = find_max_plus(new_grid, n, m)
						prod = (4 * (pcount - 1) + 1) * (4 * (second_plus - 1) + 1)
						if prod > max_prod:
							max_prod = prod
					else:
						break
	return max_prod
(n, m) = map(int, input().split())
grid = [[] for i in range(n)]
for i in range(n):
	grid[i] = list(map(str, input()))
print(find_max_plus_prod(grid, n, m))


(n, m) = [int(x) for x in input().strip().split()]
f = []
for row in range(n):
	f.append([['G', 'B'].index(x) for x in list(input().strip())])

def set_cell(f, row, col, value):
	if row in range(n) and col in range(m):
		f[row][col] = value

def check_two_crosses(cross1, cross2):
	(col1, row1, size1) = cross1
	(col2, row2, size2) = cross2
	if abs(col1 - col2) < max(size1, size2) and abs(row1 - row2) < min(size1, size2) or (abs(col1 - col2) < min(size1, size2) and abs(row1 - row2) < max(size1, size2)) or (col1 == col2 and abs(row1 - row2) < size1 + size2 - 1) or (row1 == row2 and abs(col1 - col2) < size1 + size2 - 1):
		return 0
	else:
		return (size1 * 4 - 3) * (size2 * 4 - 3)

def get_cross_size(row, col):
	i = 0
	while i <= row and i <= col and (i + row < n) and (i + col < m) and (f[row - i][col] == f[row + i][col] == f[row][col - i] == f[row][col + i] == 0):
		i += 1
	return i

def find_all_crosses():
	crosses = []
	for row in range(n):
		for col in range(m):
			cross_size = get_cross_size(row, col)
			if cross_size > 0:
				for i in range(1, cross_size + 1):
					crosses.append([row, col, i])
	return crosses
crosses = find_all_crosses()
max_area_size = 0
crosses = sorted(crosses, key=lambda x: x[2], reverse=True)
mc1 = []
mc2 = []
for (i, c1) in enumerate(crosses):
	for c2 in crosses[i + 1:]:
		tmp = check_two_crosses(c1, c2)
		if tmp > max_area_size:
			max_area_size = tmp
			mc1 = c1
			mc2 = c2
print(max_area_size)


import sys

def get_m():
	(n, _) = map(int, input().split())
	m = []
	for _ in range(n):
		s = input()
		m.append(tuple(map(lambda c: c == 'G', s)))
	return tuple(m)

def solve(m):

	def cross_size(r, c):
		if not m[r][c]:
			return 0
		sz = 0
		while True:
			(c1, c2) = (c - sz, c + sz)
			(r1, r2) = (r - sz, r + sz)
			if c1 < 0 or c2 >= len(m[0]) or r1 < 0 or (r2 >= len(m)):
				break
			if not m[r][c1] or not m[r][c2] or (not m[r1][c]) or (not m[r2][c]):
				break
			sz += 1
		return sz

	def intersect(cr1, cr2):
		(r1, c1, sz1) = cr1
		(r2, c2, sz2) = cr2
		(s1, s2) = (set(), set())
		for (s, r, c, sz) in ((s1, r1, c1, sz1), (s2, r2, c2, sz2)):
			for i in range(sz):
				s.add((r, c - i))
				s.add((r, c + i))
				s.add((r - i, c))
				s.add((r + i, c))
		s = s1 & s2
		return len(s) > 0

	def area(cr):
		(_, _, sz) = cr
		return sz * 4 - 3
	cc = []
	for r in range(len(m)):
		for c in range(len(m[r])):
			s = cross_size(r, c)
			for sz in range(1, s + 1):
				cc.append((r, c, sz))
				if sz > 1:
					print('r=%d c=%d size=%d' % (r, c, sz), file=sys.stderr)
	rval = 0
	for (i, cr1) in enumerate(cc):
		for cr2 in cc[i + 1:]:
			if not intersect(cr1, cr2):
				v = area(cr1) * area(cr2)
				rval = max(v, rval)
				if cr1[-1] > 1 and cr2[-1] > 1:
					print(cr1, cr2, file=sys.stderr)
	return rval
m = get_m()
print(solve(m))


(N, M) = map(int, input().split())
G = []
for i in range(N):
	G.append(input().strip())
pats = []
for i in range(N):
	for j in range(M):
		if G[i][j] == 'G':
			pat = {}
			pat[i * M + j] = 1
			pats.append(dict(pat))
			for k in range(1, M):
				t = j - k
				if t < 0 or G[i][t] != 'G':
					break
				pat[i * M + t] = 1
				t = j + k
				if t >= M or G[i][t] != 'G':
					break
				pat[i * M + t] = 1
				t = i - k
				if t < 0 or G[t][j] != 'G':
					break
				pat[t * M + j] = 1
				t = i + k
				if t >= N or G[t][j] != 'G':
					break
				pat[t * M + j] = 1
				pats.append(dict(pat))
pats.sort(key=len, reverse=True)
best = 0
for i in range(len(pats)):
	p1 = pats[i]
	for j in range(i + 1, len(pats)):
		p2 = pats[j]
		prod = len(p1) * len(p2)
		if prod <= best:
			break
		for x in p1:
			if x in p2:
				break
		else:
			best = prod
			break
print(best)


from copy import deepcopy
(n, m) = [int(x) for x in input().split()]
a = []
z = []
for b in range(n):
	a.append([c for c in input()])
for b in range(len(a)):
	for c in range(len(a[b])):
		if a[b][c] == 'G':
			z.append([[b, c]])
			for i in range(1, max(n, m) + 1):
				if not (b + i < n and b - i > -1 and (c + i < m) and (c - i > -1)):
					break
				if a[b + i][c] == 'G' and a[b - i][c] == 'G' and (a[b][c + i] == 'G') and (a[b][c - i] == 'G'):
					z.append(deepcopy(z[-1]))
					z[-1].append([b + i, c])
					z[-1].append([b - i, c])
					z[-1].append([b, c + i])
					z[-1].append([b, c - i])
				else:
					break
w = []
for x in range(len(z) - 1):
	for y in range(x + 1, len(z)):
		valid = True
		for v in z[x]:
			if v in z[y]:
				valid = False
				break
		if valid:
			w.append(len(z[x]) * len(z[y]))
print(max(w))


import sys
from operator import itemgetter

def findgoods(m, rows, cols, x=0, y=0, visited=set(), res=set()):
	if (x, y) not in visited:
		visited.add((x, y))
		if m[x][y] == 'G':
			res.add((x, y))
		if x < rows - 1:
			findgoods(m, rows, cols, x + 1, y, visited, res)
		if y < cols - 1:
			findgoods(m, rows, cols, x, y + 1, visited, res)
		return res

def printplus(goods, cords, area=1):
	if (cords[0] + area, cords[1]) in goods and (cords[0] - area, cords[1]) in goods and ((cords[0], cords[1] + area) in goods) and ((cords[0], cords[1] - area) in goods):
		return printplus(goods, cords, area + 1)
	else:
		return area

def getneighbour(cords, layers):
	res = set([cords])
	if layers > 1:
		for layer in range(1, layers):
			res.add((cords[0] + layer, cords[1]))
			res.add((cords[0] - layer, cords[1]))
			res.add((cords[0], cords[1] + layer))
			res.add((cords[0], cords[1] - layer))
	return res

def getareas(goods):
	areas = []
	for good in goods:
		size = printplus(goods, good)
		for unit in range(1, size + 1):
			areas.append([unit, getneighbour(good, unit)])
	areas = sorted(areas, key=itemgetter(0), reverse=True)
	return areas

def getpluses(areas):
	pluses = []
	for x in range(len(areas)):
		(layers, cords) = (areas[x][0], areas[x][1])
		for y in range(len(areas) - x - 1):
			if not cords.intersection(areas[y + 1][1]):
				res = ((areas[x][0] - 1) * 4 + 1) * ((areas[y + 1][0] - 1) * 4 + 1)
				pluses.append(res)
				break
	return max(pluses)
inp = sys.stdin.read().splitlines()
(r, c) = map(int, inp[0].split())
mtx = list(map(lambda x: [_ for _ in x], [x for x in inp[1:]]))
goods = findgoods(mtx, r, c)
areas = getareas(goods)
pluses = getpluses(areas)
print(pluses)


(n, m) = [int(x) for x in input().split()]
cells = [[False for x in range(m)] for y in range(n)]
for _n in range(n):
	line = input()
	for (i, letter) in enumerate(line):
		if letter == 'G':
			cells[_n][i] = True
boards = [cells]
for i in range(1, 8):
	if i * 2 + 1 <= n and i * 2 + 1 <= m:
		board = [[False for x in range(m)] for y in range(n)]
		for row in range(i, n - i):
			for col in range(i, m - i):
				if boards[-1][row][col]:
					if boards[0][row - i][col] and boards[0][row + i][col] and boards[0][row][col - i] and boards[0][row][col + i]:
						board[row][col] = True
		boards.append(board)

def findSecondLargest(margin, rowPicked, colPicked, boards):
	for i in reversed(range(margin + 1)):
		for row in range(i, n - i):
			for col in range(i, m - i):
				if boards[i][row][col]:
					if row == rowPicked or col == colPicked:
						if abs(rowPicked - row) + abs(colPicked - col) > margin + i:
							return i
					elif abs(rowPicked - row) > i and abs(colPicked - col) > i:
						return i
					elif abs(rowPicked - row) > margin or abs(colPicked - col) > margin:
						return i
largest = 0
for i in reversed(range(len(boards))):
	for row in range(i, n - i):
		for col in range(i, m - i):
			if boards[i][row][col]:
				largest = max(largest, (i * 4 + 1) * (findSecondLargest(i, row, col, boards) * 4 + 1))
print(largest)


class Grid(object):

	def __init__(self, rows, cols):
		self.rows = rows
		self.cols = cols
		self.curr_row = 0
		self.grid = []
		self.plusses = {}
		for i in range(1, 4 * min((rows, cols)), 4):
			self.plusses[i] = set()

	def add_row(self, row_str):
		row = []
		for i in range(len(row_str)):
			row.append(Cell(self.curr_row, i, row_str[i]))
		self.grid.append(row)
		self.curr_row += 1

	def find_plusses(self):
		for row in self.grid:
			for cell in row:
				cell.add_plusses(self.grid, self.plusses, self.rows, self.cols)
		l = list(self.plusses.keys())
		for key in l:
			if len(self.plusses[key]) == 0:
				del self.plusses[key]

	def find_max_plusses(self):
		max_prod = 0
		size_list = sorted(self.plusses.keys(), reverse=True)
		for size1 in size_list:
			if size1 == 1 and max_prod > 0:
				break
			for plus1 in self.plusses[size1]:
				found_plus = False
				for size2 in size_list:
					if size2 > size1:
						continue
					for plus2 in self.plusses[size2]:
						if plus1 == plus2:
							continue
						if not plus1.cells.isdisjoint(plus2.cells):
							continue
						found_plus = True
						max_prod = max(max_prod, plus1.size * plus2.size)
						break
					if found_plus:
						break
		return max_prod

class Cell(object):

	def __init__(self, row, col, good):
		self.row = row
		self.col = col
		self.plusses = {}
		if good == 'G':
			self.good = True
		else:
			self.good = False

	def add_plusses(self, grid, plusses, rows, cols):
		(row, col) = (self.row, self.col)
		(up, down, left, right) = ([row, col], [row, col], [row, col], [row, col])
		size = 1
		done = False
		edges = set()
		while True:
			for (row, col) in (up, down, left, right):
				if row in range(rows) and col in range(cols) and grid[row][col].good:
					edges.add(grid[row][col])
				else:
					done = True
					break
			if done:
				break
			plusses[size].add(Plus(self, size, set(edges)))
			size += 4
			up[0] -= 1
			down[0] += 1
			left[1] -= 1
			right[1] += 1

	def __repr__(self):
		if self.good:
			return 'G'
		else:
			return 'B'

class Plus(object):

	def __init__(self, center, size, cells):
		self.center = center
		self.size = size
		self.cells = cells

	def __repr__(self):
		return str((self.center.row, self.center.col))
(rows, cols) = map(int, input().split())
g = Grid(rows, cols)
for row in range(rows):
	g.add_row(input())
g.find_plusses()
print(g.find_max_plusses())


(N, M) = [int(n) for n in input().split()]
rows = []
for _ in range(N):
	rows.append(list(input()))
foundDict = {}
for r in range(N):
	for c in range(M):
		size = 1
		while c + size // 2 - 1 < M:
			found = True
			if not (c >= size // 2 and c < M - size // 2):
				found = False
			if not (r - size // 2 >= 0 and r + size // 2 < N):
				found = False
			if found:
				for n in range(0 - size // 2, size // 2 + 1):
					if rows[r][c + n] != 'G' or rows[r + n][c] != 'G':
						found = False
						break
			if found:
				if size in foundDict:
					foundDict[size].append((r, c))
				else:
					foundDict[size] = [(r, c)]
			size += 2
sizePairs = []
keyList = sorted(foundDict.keys(), reverse=True)
for a in range(len(keyList)):
	aVal = keyList[a]
	if len(foundDict[keyList[a]]) > 1:
		sizePairs.append((aVal, aVal))
	for b in range(a + 1, len(keyList)):
		bVal = keyList[b]
		sizePairs.append((aVal, bVal))
sizePairs.sort(key=lambda x: x[0] * x[1], reverse=True)
found = False
for (a, b) in sizePairs:
	if found:
		break
	for (r, c) in foundDict[a]:
		if found:
			break
		coords = {(r, c)}
		for n in range(0 - a // 2, a // 2 + 1):
			coords.add((r, c + n))
			coords.add((r + n, c))
		for (r2, c2) in foundDict[b]:
			found = True
			for n in range(0 - b // 2, b // 2 + 1):
				if (r2, c2 + n) in coords:
					found = False
					break
				if (r2 + n, c2) in coords:
					found = False
					break
			if found:
				print((a + a - 1) * (b + b - 1))
				break
if not found:
	print(0)


import itertools

def crossesIntersect(r1, c1, s1, r2, c2, s2, grid):
	dr = abs(r1 - r2)
	dc = abs(c1 - c2)
	if r1 == r2:
		return s1 + s2 >= dc
	if c1 == c2:
		return s1 + s2 >= dr
	return s1 >= dc and s2 >= dr or (s2 >= dc and s1 >= dr)
(N, M) = map(int, input().strip().split())
grid = [input() for _ in range(N)]
points = [x for x in itertools.product(range(N), range(M))]
maxCross = {}
for (r, c) in points:
	if grid[r][c] == 'B':
		continue
	s = 1
	while s <= min(r, c, N - r - 1, M - c - 1):
		if grid[r - s][c] == 'B' or grid[r + s][c] == 'B' or grid[r][c - s] == 'B' or (grid[r][c + s] == 'B'):
			break
		s += 1
	maxCross[r, c] = s - 1
maxProd = 0
for i in range(len(points)):
	(r1, c1) = points[i]
	if grid[r1][c1] == 'B':
		continue
	for j in range(i + 1, len(points)):
		(r2, c2) = points[j]
		if grid[r2][c2] == 'B':
			continue
		for s1 in range(maxCross[r1, c1] + 1):
			for s2 in range(maxCross[r2, c2] + 1):
				if not crossesIntersect(r1, c1, s1, r2, c2, s2, grid):
					p = (4 * s1 + 1) * (4 * s2 + 1)
					if p > maxProd:
						maxProd = p
print(maxProd)


def find_all_pluses(grid, size):

	def is_plus_sign(grid, r, c, half_size):
		exists = grid[r][c] == 'G'
		if exists:
			for i in range(1, half_size + 1):
				exists = exists and grid[r + i][c] == grid[r - i][c] == 'G'
			for i in range(1, half_size + 1):
				exists = exists and grid[r][c + i] == grid[r][c - i] == 'G'
		return exists
	positions = []
	if size <= min(len(grid), len(grid[0])):
		offset = size // 2
		for r in range(offset, len(grid) - offset):
			for c in range(offset, len(grid[r]) - offset):
				if is_plus_sign(grid, r, c, offset):
					positions.append((r, c))
	return positions

def overlaps(p1, s1, p2, s2):
	h_s1 = s1 // 2
	h_s2 = s2 // 2
	overlaps = False
	cells1 = set([(p1[0], p1[1])] + [(r, p1[1]) for r in range(p1[0] - h_s1, p1[0] + h_s1 + 1)] + [(p1[0], c) for c in range(p1[1] - h_s1, p1[1] + h_s1 + 1)])
	cells2 = set([(p2[0], p2[1])] + [(r, p2[1]) for r in range(p2[0] - h_s2, p2[0] + h_s2 + 1)] + [(p2[0], c) for c in range(p2[1] - h_s2, p2[1] + h_s2 + 1)])
	while not overlaps and cells1:
		overlaps = cells1.pop() in cells2
	return overlaps
(n, m) = map(int, input().strip().split(' '))
grid = [list(input().strip()) for _ in range(n)]
max_len_for_plus_sign = min(len(grid), len(grid[0]))
if max_len_for_plus_sign % 2 == 0:
	max_len_for_plus_sign -= 1
all_plus_signs = []
for k in range(max_len_for_plus_sign, 0, -2):
	for (i, j) in find_all_pluses(grid, k):
		all_plus_signs.append((i, j, k, k // 2 * 4 + 1))
max_product = 0
for (i, (r1, c1, size1, area1)) in enumerate(all_plus_signs[:-1]):
	for (r2, c2, size2, area2) in all_plus_signs[i + 1:]:
		if area1 * area2 > max_product and (not overlaps((r1, c1), size1, (r2, c2), size2)):
			max_product = area1 * area2
print(max_product)


(m, n) = [int(x) for x in input().split()]
l = []
for i in range(m):
	l.append(input())
	l[i] = l[i].replace('G', '+', n)
	l[i] = l[i].replace('B', ' ', n)
	l[i] = list(l[i])
points = []
for i in range(0, m):
	for j in range(0, n):
		if l[i][j] == '+':
			if i > 0 and j > 0 and (i < m - 1) and (j < n - 1):
				if l[i - 1][j] is '+' and l[i + 1][j] is '+' and (l[i][j - 1] is '+') and (l[i][j + 1] is '+'):
					points.append([i, j, 'C'])
				else:
					points.append([i, j, 'N'])
			else:
				points.append([i, j, 'N'])
CrossLen = []
for p in points:
	(x, y, poi) = p
	(u, d, lf, r) = [0, 0, 0, 0]
	path = {(x, y)}
	if poi is 'C':
		CrossLen.append([x, y, min(u, d, lf, r), set(path), len(path)])
		while x - 1 - u >= 0 and l[x - 1 - u][y] == '+' and (x + 1 + d < m) and (l[x + 1 + d][y] == '+') and (y - 1 - lf >= 0) and (l[x][y - 1 - lf] == '+') and (y + 1 + r < n) and (l[x][y + 1 + r] == '+'):
			path.add((x - 1 - u, y))
			path.add((x + 1 + d, y))
			path.add((x, y - 1 - lf))
			path.add((x, y + 1 + r))
			r += 1
			lf += 1
			d += 1
			u += 1
			CrossLen.append([x, y, u, set(path), len(path)])
	else:
		CrossLen.append([x, y, u, path, len(path)])
i = 0
n = len(CrossLen)
prods = []
while i < n:
	j = 0
	while j < n:
		if i != j:
			if len(set.intersection(CrossLen[i][3], CrossLen[j][3])) is 0:
				prods.append(CrossLen[i][4] * CrossLen[j][4])
		j += 1
	i += 1
print(max(prods))


import copy
import itertools

def evalcomb(m, t1, t2):
	(i, j) = t1[1:3]
	for x in range(t1[0]):
		m[i + x][j] = 'X'
		m[i - x][j] = 'X'
		m[i][j + x] = 'X'
		m[i][j - x] = 'X'
	ok = True
	(i, j) = t2[1:3]
	for x in range(t2[0]):
		if m[i + x][j] != 'G' or m[i - x][j] != 'G' or m[i][j - x] != 'G' or (m[i][j + x] != 'G'):
			ok = False
			break
	if not ok:
		return -1
	return t1[-1] * t2[-1]
(n, k) = map(int, input().strip().split(' '))
m = []
for i in range(n):
	m += [list(input().strip())]
f = {1: []}
c = 0
for i in range(n):
	for j in range(k):
		if m[i][j] == 'B':
			continue
		d = 1
		f[d] += [(i, j)]
		while True:
			if i - d < 0 or i + d > n - 1 or j - d < 0 or (j + d > k - 1):
				break
			if m[i - d][j] != 'G' or m[i + d][j] != 'G' or m[i][j - d] != 'G' or (m[i][j + d] != 'G'):
				break
			d += 1
			if d in f:
				f[d] += [(i, j)]
			else:
				f[d] = [(i, j)]
opt = []
for d in reversed(sorted(f.keys())):
	for (i, j) in f[d]:
		opt += [(d, i, j, 4 * d - 3)]
maxa = 0
for x1 in range(len(opt) - 1):
	for x2 in range(x1 + 1, len(opt)):
		if opt[x1][-1] * opt[x2][-1] < maxa:
			break
		a = evalcomb(copy.deepcopy(m), opt[x1], opt[x2])
		maxa = max(a, maxa)
print(maxa)


(n, m) = list(map(int, input().strip().split(' ')))
mat = []
for i in range(n):
	mat.append(list(input().strip()))
stars = {}
for row in range(1, n - 1):
	for column in range(1, m - 1):
		if mat[row][column] == 'B':
			continue
		radius = 1
		while True:
			if row - radius < 0 or row + radius > n - 1 or column - radius < 0 or (column + radius > m - 1):
				break
			if mat[row - radius][column] != 'B' and mat[row + radius][column] != 'B' and (mat[row][column - radius] != 'B') and (mat[row][column + radius] != 'B'):
				key = '%d,%d' % (row, column)
				if key in stars.keys():
					stars[key].append(4 * radius + 1)
				else:
					stars[key] = [4 * radius + 1]
				radius += 1
			else:
				break
		radius -= 1

def doOverlap(stars, s1, r1, s2, r2):
	(x1, y1) = list(map(int, s1.split(',')))
	(x2, y2) = list(map(int, s2.split(',')))
	s1coords = ['%d,%d' % (x1, y1)]
	for i in range(1, r1):
		s1coords.append('%d,%d' % (x1 - i, y1))
		s1coords.append('%d,%d' % (x1 + i, y1))
		s1coords.append('%d,%d' % (x1, y1 - i))
		s1coords.append('%d,%d' % (x1, y1 + i))
	s2coords = ['%d,%d' % (x2, y2)]
	for i in range(1, r2):
		s2coords.append('%d,%d' % (x2 - i, y2))
		s2coords.append('%d,%d' % (x2 + i, y2))
		s2coords.append('%d,%d' % (x2, y2 - i))
		s2coords.append('%d,%d' % (x2, y2 + i))
	for i in s1coords:
		if i in s2coords:
			return True
	return False
for i in stars.keys():
	stars[key] = sorted(stars[key], reverse=True)
maxValue = 0
if len(stars) > 2:
	for i in stars.keys():
		for j in stars.keys():
			if i == j:
				continue
			for ilen in stars[i]:
				for jlen in stars[j]:
					r1 = int((ilen - 1) / 4) + 1
					r2 = int((jlen - 1) / 4) + 1
					if doOverlap(stars, i, r1, j, r2):
						continue
					elif maxValue < ilen * jlen:
						maxValue = ilen * jlen
elif len(stars) == 1:
	maxValue = stars[list(stars.keys())[0]][0]
elif len(stars) == 2:
	if stars[list(stars.keys())[0]] > stars[list(stars.keys())[1]]:
		maxValue = stars[list(stars.keys())[0]][0]
	else:
		maxValue = stars[list(stars.keys())[1]][0]
elif len(stars) == 0:
	maxValue = 1
print(maxValue)


import sys

class Plus:

	def __init__(self, i, j, size):
		self.i = i
		self.j = j
		self.size = size

	def intersects(self, p):
		return len(self.points().intersection(p.points())) > 0

	def points(self):
		points = set()
		points.add((self.i, self.j))
		reach = 1
		while reach <= (self.size - 1) / 2:
			points.add((self.i + reach, self.j))
			points.add((self.i - reach, self.j))
			points.add((self.i, self.j + reach))
			points.add((self.i, self.j - reach))
			reach += 1
		return points

	def area(self):
		return 2 * self.size - 1

class Board:

	def __init__(self, array):
		self.A = array
		if len(array) == 0:
			self.J_MAX = 0
		else:
			self.J_MAX = len(array[0])
		self.I_MAX = len(array)

	def possiblePluses(self):
		pluses = []
		i = 0
		while i < self.I_MAX:
			j = 0
			while j < self.J_MAX:
				pluses += self.possiblePlusesForPoint(i, j)
				j += 1
			i += 1
		return pluses

	def possiblePlusesForPoint(self, i, j):
		pluses = []
		reach = 0
		while True:
			if self.outOfBounds(i + reach, j) or self.outOfBounds(i - reach, j) or self.outOfBounds(i, j + reach) or self.outOfBounds(i, j - reach):
				break
			if self.good(i + reach, j) and self.good(i - reach, j) and self.good(i, j + reach) and self.good(i, j - reach):
				pluses.append(Plus(i, j, reach * 2 + 1))
			else:
				break
			reach += 1
		return pluses

	def outOfBounds(self, i, j):
		return i < 0 or i >= self.I_MAX or j < 0 or (j >= self.J_MAX)

	def good(self, i, j):
		return self.A[i][j] == 'G'
sys.stdin.readline()
array = []
for line in sys.stdin:
	array.append(line.strip())
b = Board(array)
pluses = b.possiblePluses()
max = 0
i = 0
while i < len(pluses):
	j = i
	while j < len(pluses):
		if not pluses[i].intersects(pluses[j]):
			val = pluses[i].area() * pluses[j].area()
			if val > max:
				max = val
		j += 1
	i += 1
if len(pluses) == 1:
	max = pluses[0].area()
print(max)


MAX_S = 8
(n, m) = [int(i) for i in input().split()]
a = []
for i in range(n):
	a.append([True if x == 'G' else False for x in input()])
table = []

def fill_table(table, a, i, j):
	if not a[i][j]:
		return
	table.append((i, j, 0))
	for x in range(1, MAX_S):
		if i + x >= n or j + x >= m or i - x < 0 or (j - x < 0):
			return
		if a[i + x][j] and a[i - x][j] and a[i][j + x] and a[i][j - x]:
			table.append((i, j, x))
		else:
			return

def not_collide(x, y):
	(i1, j1, p1) = x
	(i2, j2, p2) = y
	s = set()
	s.add((i1, j1))
	for k in range(p1 + 1):
		s.add((i1 + k, j1))
		s.add((i1 - k, j1))
		s.add((i1, j1 + k))
		s.add((i1, j1 - k))
	for k in range(p2 + 1):
		if (i2, j2) in s or (i2 + k, j2) in s or (i2 - k, j2) in s or ((i2, j2 + k) in s) or ((i2, j2 - k) in s):
			return False
	return True
for i in range(n):
	for j in range(m):
		fill_table(table, a, i, j)
ps = [i * 4 + 1 for i in range(MAX_S)]
max_p = 0
for (i1, j1, p1) in table:
	for (i2, j2, p2) in table:
		if i1 == i2 and j1 == j2:
			continue
		if not_collide((i1, j1, p1), (i2, j2, p2)) and ps[p1] * ps[p2] > max_p:
			max_p = ps[p1] * ps[p2]
print(max_p)


from itertools import combinations, product

def find_max_cross(grid, x, y):
	rows = len(grid)
	cols = len(grid[0])
	radius = 1
	while True:
		right = x + radius < cols and grid[y][x + radius] == 'G'
		left = x - radius >= 0 and grid[y][x - radius] == 'G'
		top = y - radius >= 0 and grid[y - radius][x] == 'G'
		bottom = y + radius < rows and grid[y + radius][x] == 'G'
		if right and left and top and bottom:
			radius += 1
		else:
			break
	return radius

def find_crosses(grid):
	rows = len(grid)
	cols = len(grid[0])
	crosses = []
	for y in range(rows):
		for x in range(cols):
			if grid[y][x] == 'G':
				radius = find_max_cross(grid, x, y)
				crosses.append((x, y, radius))
	crosses.sort(key=lambda x: x[2], reverse=True)
	return crosses

def no_overlap(cross1, cross2):
	(x1, y1, r1) = cross1
	(x2, y2, r2) = cross2
	coords1 = set()
	coords1.update([(x, y1) for x in range(x1 - r1 + 1, x1 + r1)])
	coords1.update([(x1, y) for y in range(y1 - r1 + 1, y1 + r1)])
	coords2 = set()
	coords2.update([(x, y2) for x in range(x2 - r2 + 1, x2 + r2)])
	coords2.update([(x2, y) for y in range(y2 - r2 + 1, y2 + r2)])
	return not coords1.intersection(coords2)

def area(r):
	return (r - 1) * 4 + 1

def optimum_pair(grid):
	crosses = find_crosses(grid)
	pairs = sorted(combinations(crosses, 2), key=lambda x: area(x[0][2]) * area(x[1][2]), reverse=True)
	max_area = 0
	for pair in pairs:
		if area(pair[0][2]) * area(pair[1][2]) < max_area:
			break
		radlist = product(range(pair[0][2], 0, -1), range(pair[1][2], 0, -1))
		for rads in sorted(radlist, key=lambda x: area(x[0]) * area(x[1]), reverse=True):
			pair_area = area(rads[0]) * area(rads[1])
			if pair_area > max_area:
				if no_overlap((pair[0][0], pair[0][1], rads[0]), (pair[1][0], pair[1][1], rads[1])):
					max_area = pair_area
					break
			else:
				break
	return max_area
(rows, cols) = map(int, input().split())
grid = []
for _ in range(rows):
	grid.append(list(input().strip()))
print(optimum_pair(grid))


class plus(object):

	def __init__(self, x, y, size):
		if size == 1:
			self.points = [(x, y)]
		else:
			self.points = [(int(x + size / 2), q) for q in range(y, y + size)] + [(p, int(y + size / 2)) for p in range(x, x + size)]
		self.area = size * 2 - 1

def is_plus(grid):
	N = len(grid)
	m = int(N / 2)
	for n in range(N):
		if grid[m][n] != 'G':
			return False
	for n in range(N):
		if grid[n][m] != 'G':
			return False
	return True

def overlap(plus1, plus2):
	for a in plus1.points:
		for b in plus2.points:
			if a == b:
				return True
	return False
(N, M) = [int(v) for v in input().split(' ')]
grid = []
for n in range(N):
	row = [c for c in input()]
	grid.append(row)
n = 1
plus_list = []
add = True
while n <= min(N, M):
	add = False
	for i in range(N - n + 1):
		for j in range(M - n + 1):
			grid_to_check = [subgrid[j:j + n] for subgrid in grid[i:i + n]]
			if is_plus(grid_to_check) == True:
				plus_list.append(plus(i, j, n))
	n += 2
max_product = 0
while len(plus_list) > 0:
	last = plus_list.pop()
	for p in plus_list:
		if overlap(last, p) == False:
			temp_max = last.area * p.area
			if temp_max > max_product:
				max_product = temp_max
print(max_product)


(n, m) = map(int, input().split())
s = [list(input()) for i in range(n)]
ans = 0

def star(i, j, c):
	s[i][j] = c
	for h in range(1, n):
		if i + h < n and i - h >= 0 and (j + h < m) and (j - h >= 0) and (s[i + h][j] == 'G') and (s[i - h][j] == 'G') and (s[i][j + h] == 'G') and (s[i][j - h] == 'G'):
			s[i + h][j] = s[i - h][j] = s[i][j + h] = s[i][j - h] = c
		else:
			break

def calc():
	t1 = t2 = 0
	for i in range(n):
		for j in range(m):
			if s[i][j] == 'B':
				continue
			if s[i][j] == '1':
				t1 += 1
			if s[i][j] == '2':
				t2 += 1
			s[i][j] = 'G'
	return t1 * t2

def check(i, j, ii, jj):
	if s[i][j] != 'G' or s[ii][jj] != 'G':
		return 0
	star(i, j, '1')
	star(ii, jj, '2')
	c1 = calc()
	star(ii, jj, '1')
	star(i, j, '2')
	c2 = calc()
	return c1 if c1 > c2 else c2
for k1 in range(n * m):
	for k2 in range(k1 + 1, n * m):
		ans = max(ans, check(k1 // m, k1 % m, k2 // m, k2 % m))
print(ans)


def plusesProduct(matrix, m, n):
	maxProduct = 0
	for i in range(m):
		for j in range(n):
			if matrix[i][j] == 'G':
				fst = helper(matrix, i, j, m, n)
				setTo(matrix, fst, i, j, 'B')
				secd = largePlus(matrix, m, n)
				setTo(matrix, fst, i, j, 'G')
				maxProduct = max(maxProduct, (fst * 2 - 1) * (secd * 2 - 1))
	return maxProduct

def largePlus(matrix, m, n):
	fst = 0
	for i in range(m):
		for j in range(n):
			if matrix[i][j] == 'G':
				d = helper(matrix, i, j, m, n)
				if d > fst:
					fst = d
	return fst

def setTo(matrix, fst, i, j, target):
	n = (fst - 1) // 2
	for t in range(n + 1):
		matrix[i - t] = matrix[i - t][:j] + target + matrix[i - t][j + 1:]
		matrix[i + t] = matrix[i + t][:j] + target + matrix[i + t][j + 1:]
		matrix[i] = matrix[i][:j - t] + target + matrix[i][j - t + 1:]
		matrix[i] = matrix[i][:j + t] + target + matrix[i][j + t + 1:]

def helper(matrix, i, j, m, n):
	d = 1
	t = 1
	while i - t > -1 and i + t < m and (j - t > -1) and (j + t < n) and (matrix[i - t][j] == 'G') and (matrix[i + t][j] == 'G') and (matrix[i][j - t] == 'G') and (matrix[i][j + t] == 'G'):
		d += 2
		t += 1
	return d
(m, n) = list(map(int, input().strip().split()))
matrix = []
for _ in range(m):
	matrix.append(input().strip())
print(plusesProduct(matrix, m, n))


class Pos:
	x = 0
	y = 0

	def __init__(self, i, j):
		self.x = i
		self.y = j

def initFlag(flag):
	for i in range(0, len(flag)):
		for j in range(0, len(flag)):
			flag[i][j] = False

def isValid(i, j, length, grid, flag):
	if grid[i][j] != 'G' or flag[i][j] == True:
		return False
	for k in range(i - length // 2, i + length // 2 + 1):
		if grid[k][j] != 'G' or flag[k][j] == True:
			return False
	for k in range(j - length // 2, j + length // 2 + 1):
		if grid[i][k] != 'G' or flag[i][k] == True:
			return False
	return True

def mark(i, j, length, flag):
	for k in range(i - length // 2, i + length // 2 + 1):
		flag[k][j] = True
	for k in range(j - length // 2, j + length // 2 + 1):
		flag[i][k] = True

def search(length, n, m, flag, grid):
	start = (length - 1) // 2
	iend = n - 1 - (length - 1) // 2
	jend = m - 1 - (length - 1) // 2
	validPos = []
	for i in range(start, iend + 1):
		for j in range(start, jend + 1):
			if isValid(i, j, length, grid, flag):
				mypos = Pos(i, j)
				validPos.append(mypos)
	return validPos

def solve(n, m, grid, flag):
	longest = min(n, m)
	if longest % 2 == 0:
		longest -= 1
	ret = 1
	for i in range(longest, 0, -2):
		initFlag(flag)
		fstPos = search(i, n, m, flag, grid)
		if len(fstPos) != 0:
			for iPos in range(0, len(fstPos)):
				initFlag(flag)
				mark(fstPos[iPos].x, fstPos[iPos].y, i, flag)
				for j in range(longest, 0, -2):
					search_j = search(j, n, m, flag, grid)
					if len(search_j) != 0:
						ret = max(ret, (2 * i - 1) * (2 * j - 1))
						break
	return ret
(n, m) = [int(x) for x in input().strip().split()]
grid = []
for grid_i in range(n):
	grid.append([x for x in list(input().strip())])
flag = [[False for i in range(16)] for j in range(16)]
result = solve(n, m, grid, flag)
print(result)


(n, m) = [int(s) for s in input().split()]
grid = [input() for s in range(n)]

class Plus:

	def __init__(self, x, y, size):
		(self.x, self.y) = (x, y)
		self.size = size
		self.area = size * 2 - 1
		t = size // 2
		self.points = set(((i, y) for i in range(x - t, x + t + 1)))
		self.points |= set(((x, i) for i in range(y - t, y + t + 1)))

	@classmethod
	def at_coord(cls, grid, x, y, size):
		(x, y) = (y, x)
		t = size // 2
		ty = y - t
		lx = x - t
		if ty < 0 or lx < 0:
			return False
		try:
			h = (grid[i][y] == 'G' for i in range(lx, lx + size))
			v = (grid[x][i] == 'G' for i in range(ty, ty + size))
			return all(h) and all(v)
		except IndexError:
			return False

	def overlaps(self, other):
		return not self.points.isdisjoint(other.points)

	def __repr__(self):
		return 'Plus({s.x},{s.y},{s.size})'.format(s=self)
mps = min(n, m)
mps = mps if mps % 2 else mps - 1
plusses = []
for size in range(1, mps + 2, 2):
	for y in range(n):
		for x in range(m):
			p = Plus.at_coord(grid, x, y, size)
			if p:
				plusses.append(Plus(x, y, size))
area = 1
for p1 in plusses:
	for p2 in plusses:
		if not p1.overlaps(p2):
			area = max(area, p1.area * p2.area)
print(area)


def checkMaxPlus(max, ab, l):
	abOld = ab
	if max <= l:
		ab = []
		totalFound = False
		for i in range(max, n - max):
			for j in range(max, m - max):
				found = True
				for k in range(max + 1):
					if ar[i + k][j] == 'B':
						found = False
						break
					if ar[i - k][j] == 'B':
						found = False
						break
					if ar[i][j + k] == 'B':
						found = False
						break
					if ar[i][j - k] == 'B':
						found = False
						break
				if found:
					totalFound = True
					ab.append([i, j])
		if totalFound:
			return checkMaxPlus(max + 1, ab, l)
	return [max - 1, abOld, l]
aux = input().split(' ')
n = int(aux[0])
m = int(aux[1])
ar2 = []
for i in range(n):
	ar2.append(list(input()))
result = 0
limit = min([n, m]) / 2
area1 = 1
area2 = 0
while area1 > area2:
	ar = []
	for i in range(n):
		ar.append([])
		for j in range(m):
			ar[i].append(ar2[i][j])
	max = checkMaxPlus(0, [[-1, -1]], limit)
	area1 = 1 + max[0] * 4
	for ab in max[1]:
		ar = []
		for i in range(n):
			ar.append([])
			for j in range(m):
				ar[i].append(ar2[i][j])
		i = ab[0]
		j = ab[1]
		for k in range(max[0] + 1):
			ar[i + k][j] = 'B'
			ar[i - k][j] = 'B'
			ar[i][j + k] = 'B'
			ar[i][j - k] = 'B'
		max2 = checkMaxPlus(0, [[-1, -1]], limit)
		area2 = 1 + max2[0] * 4
		resParc = area1 * area2
		if resParc > result:
			result = resParc
	limit = max[0] - 1
print(result)


def check(i, j, r, c):
	if 0 <= i < r and 0 <= j < c:
		return grid[i][j] == 'G'
	else:
		return False

def check_plus(i, j, r, c, rad):
	res = True
	res &= check(i + rad, j, r, c)
	res &= check(i - rad, j, r, c)
	res &= check(i, j + rad, r, c)
	res &= check(i, j - rad, r, c)
	return res

def overlap(ia, ja, a, ib, jb, b):
	if abs(jb - ja) >= min(a, b) and abs(ib - ia) >= min(a, b):
		return False
	elif abs(jb - ja) == 0 and abs(ib - ia) <= a + b - 2:
		return True
	elif abs(ib - ia) == 0 and abs(jb - ja) <= a + b - 2:
		return True
	elif abs(jb - ja) >= max(a, b) or abs(ib - ia) >= max(a, b):
		return False
	else:
		return True
(r, c) = [int(i) for i in input().split()]
grid = [input() for _ in range(r)]
plus_list = {}
for i in range(r):
	for j in range(c):
		if grid[i][j] == 'G':
			size = 0
			while check_plus(i, j, r, c, size) == True:
				size += 1
			plus_list[i, j] = size
plus_list = sorted(plus_list.items(), key=lambda x: (x[1], x[0]), reverse=True)
prod = 0
for i in range(len(plus_list)):
	size_max_1 = plus_list[i][1]
	(p1_x, p1_y) = (plus_list[i][0][0], plus_list[i][0][1])
	for size1 in range(1, size_max_1 + 1):
		for j in range(i + 1, len(plus_list)):
			size_max_2 = plus_list[j][1]
			(p2_x, p2_y) = (plus_list[j][0][0], plus_list[j][0][1])
			for size2 in range(1, size_max_2 + 1):
				if not overlap(p1_x, p1_y, size1, p2_x, p2_y, size2):
					if ((size1 - 1) * 4 + 1) * ((size2 - 1) * 4 + 1) > prod:
						prod = ((size1 - 1) * 4 + 1) * ((size2 - 1) * 4 + 1)
						break
print(prod)


(h, w) = input().strip().split()
(h, w) = [int(h), int(w)]
grid = []
area = 1
lst = []
for i in range(h):
	tmp = input().strip()
	grid.append(list(tmp))
co = 0
for u in range(h):
	co += grid[u].count('G')
if co < 2:
	print(0)
	exit()
for i in range(h):
	for j in range(w):
		if grid[i][j] == 'G':
			hu = hd = i
			wl = wr = j
			finding = True
			clst = [(i, j)]
			lst.append([(i, j)])
			while finding:
				hu -= 1
				hd += 1
				wl -= 1
				wr += 1
				up = 'B' if hu == -1 else grid[hu][j]
				down = 'B' if hd == h else grid[hd][j]
				left = 'B' if wl == -1 else grid[i][wl]
				right = 'B' if wr == w else grid[i][wr]
				if up == down == left == right == 'G':
					clst.append((hu, j))
					clst.append((hd, j))
					clst.append((i, wl))
					clst.append((i, wr))
					clst2 = [itm for itm in clst]
					lst = lst + [clst2]
				else:
					finding = False
l = len(lst)
mxa = 1
area = 0
for p in range(l):
	for q in range(p, l):
		if not any((x in lst[p] for x in lst[q])):
			a = len(lst[p])
			b = len(lst[q])
			a = 1 if a == 2 else a
			b = 1 if b == 2 else b
			mxa = a * b
			area = max(area, mxa)
print(area)


import sys
import re
import math

def search_for_crosses(arena, size):
	halfsize = math.floor(size / 2)
	horizontal_matches = []
	for y in range(halfsize, N - halfsize):
		row = ''.join(arena[y])
		for a in re.finditer('G(?=' + 'G' * (size - 1) + ')', row):
			horizontal_match = {}
			horizontal_match['y'] = y
			horizontal_match['size'] = size
			horizontal_match['x'] = a.start() + halfsize
			horizontal_matches += [horizontal_match]
	crosses = []
	for h in horizontal_matches:
		is_cross = True
		for v in range(size):
			if arena[h['y'] + v - halfsize][h['x']] != 'G':
				is_cross = False
				break
		if is_cross:
			crosses += [h]
	return crosses

def pprint(arena):
	for y in range(N):
		for x in range(M):
			print(arena[y][x], end='')
		print('')
	print('')

def overlay(arena, cross):
	copy_arena = [row[:] for row in arena]
	halfsize = math.floor(cross['size'] / 2)
	for i in range(cross['size']):
		copy_arena[cross['y'] + i - halfsize][cross['x']] = 'x'
		copy_arena[cross['y']][cross['x'] + i - halfsize] = 'x'
	return copy_arena

def cross_area(size):
	return size * 2 - 1
(N, M) = [int(i) for i in input().strip().split(' ')]
arena = []
for row in range(N):
	arena += [list(input().strip())]
max_size = min(N, M)
if max_size % 2 == 0:
	max_size -= 1
max_product = 1
for size_1 in range(max_size, 0, -2):
	for size_2 in range(size_1, 0, -2):
		if cross_area(size_1) * cross_area(size_2) <= max_product:
			break
		crosses = search_for_crosses(arena, size_1)
		for cross in crosses:
			second_crosses = search_for_crosses(overlay(arena, cross), size_2)
			if len(second_crosses) > 0:
				max_product = max(max_size, cross_area(size_1) * cross_area(size_2))
print(max_product)


import sys
(n, m) = [int(x) for x in input().split(' ')]
mat = [list(line.strip()) for line in sys.stdin.readlines()]

def discover_plus(i, j):
	plus = []
	k = 0
	while 'G' == mat[i][j - k] == mat[i][j + k] == mat[i - k][j] == mat[i + k][j]:
		if k == 0:
			plus = [(i, j)]
		else:
			delta = [(i, j - k), (i, j + k), (i - k, j), (i + k, j)]
			plus.extend(delta)
		k += 1
		if i - k < 0 or j - k < 0 or i + k >= n or (j + k >= m):
			break
	return plus

def shrink_plus(plus):
	return plus[:-4]

def do_overlap(p1, p2):
	p1_reach = len(p1) // 4
	p1_center_y = p1[0][0]
	p1_center_x = p1[0][1]
	p2_reach = len(p2) // 4
	p2_center_y = p2[0][0]
	p2_center_x = p2[0][1]
	dx = abs(p1_center_x - p2_center_x)
	dy = abs(p1_center_y - p2_center_y)
	if dx == 0 and dy <= p1_reach + p2_reach:
		return True
	if dy == 0 and dx <= p1_reach + p2_reach:
		return True
	if dx <= p1_reach and dy <= p2_reach:
		return True
	if dx <= p2_reach and dy <= p1_reach:
		return True
	return False
all_pluses = []
for i in range(n):
	for j in range(m):
		all_pluses.append(discover_plus(i, j))
all_pluses = [x for x in all_pluses if x]
all_pluses.sort(key=lambda k: len(k), reverse=True)
max_area = 0
for i in range(len(all_pluses)):
	this = all_pluses[i]
	for j in range(i):
		that = all_pluses[j]
		while do_overlap(this, that):
			if len(that) == 1:
				that = []
				break
			that = shrink_plus(that)
			if len(this) * len(that) < max_area:
				break
		area = len(this) * len(that)
		if area > max_area:
			max_area = area
print(max_area)


def get_item(grid, position):
	return grid[position[0]][position[1]]

def set_item(grid, position, s='U'):
	grid[position[0]][position[1]] = s

def get_positions(grid, position, offset_amt=1):
	positions = []
	positions.append(get_position(grid, position, 'up', offset_amt))
	positions.append(get_position(grid, position, 'down', offset_amt))
	positions.append(get_position(grid, position, 'left', offset_amt))
	positions.append(get_position(grid, position, 'right', offset_amt))
	return positions

def get_position(grid, position, offset, offset_amt=1):
	(posr, posc) = position
	if offset == 'up':
		posr -= offset_amt
	elif offset == 'left':
		posc -= offset_amt
	elif offset == 'down':
		posr += offset_amt
	elif offset == 'right':
		posc += offset_amt
	if (posr < 0 or posr > len(grid) - 1) or (posc < 0 or posc > len(grid[0]) - 1):
		return None
	return (posr, posc)

def compare_positions(positions_1, positions_2):
	for position in positions_1:
		if position in positions_2:
			return True
	return False
(n, m) = [int(x) for x in input().strip().split(' ')]
grid = []
for row in range(n):
	grid.append(list(input().strip()))
valid_pluses = []
for row in range(1, n - 1):
	for column in range(1, m - 1):
		current_position = (row, column)
		if get_item(grid, current_position) == 'B':
			continue
		offset_amt = 1
		positions_queue = []
		while True:
			positions = get_positions(grid, current_position, offset_amt)
			if None in positions:
				break
			items = [get_item(grid, position) for position in positions]
			if 'B' in items:
				break
			positions_queue.extend(positions)
			valid_pluses.append((offset_amt * 4 + 1, positions_queue + [current_position]))
			offset_amt += 1
if not valid_pluses:
	count_g = 0
	for row in grid:
		count_g += row.count('G')
	print(1) if count_g >= 2 else print(0)
elif len(valid_pluses) == 1:
	print(valid_pluses[0][0])
else:
	valid_pluses = list(reversed(sorted(valid_pluses)))
	products = []
	for i in range(len(valid_pluses)):
		current_plus = valid_pluses[i]
		comparison_pluses = valid_pluses[i + 1:]
		for comparison_plus in comparison_pluses:
			if compare_positions(current_plus[1], comparison_plus[1]) != True:
				products.append(current_plus[0] * comparison_plus[0])
				break
		else:
			products.append(current_plus[0] * 1)
	print(max(products))


def isValid(coor):
	if coor[0] < n and coor[0] >= 0 and (coor[1] < m) and (coor[1] >= 0):
		if grid[coor[0]][coor[1]] == 'G':
			return True
	return False

def generatePoints(plus):
	s = set()
	l = int((plus[2] - 1) / 4)
	for i in range(l + 1):
		s = s.union({(plus[0] + i, plus[1]), (plus[0] - i, plus[1]), (plus[0], plus[1] + i), (plus[0], plus[1] - i)})
	return s

def notOverlaping(plus1, plus2):
	set1 = generatePoints(plus1)
	set2 = generatePoints(plus2)
	if set1.isdisjoint(set2):
		return True
	else:
		return False
(n, m) = map(int, input().strip().split(' '))
grid = []
for i in range(n):
	row = input().strip()
	grid.append(row)
pluses = []
for i in range(n):
	for j in range(m):
		if grid[i][j] == 'G':
			area = -3
			(left, right, up, down) = ((i, j), (i, j), (i, j), (i, j))
			while isValid(left) and isValid(right) and isValid(up) and isValid(down):
				area += 4
				left = (left[0], left[1] - 1)
				right = (right[0], right[1] + 1)
				up = (up[0] - 1, up[1])
				down = (down[0] + 1, down[1])
				pluses.append((i, j, area))
pluses.sort(key=lambda x: x[2], reverse=True)
max_area = 0
for i in range(len(pluses)):
	for j in range(i + 1, len(pluses)):
		if notOverlaping(pluses[i], pluses[j]):
			area = pluses[i][2] * pluses[j][2]
			if area > max_area:
				max_area = area
print(max_area)


DEBUG = False
inp = ['GBGB', 'BBGB', 'GGGG', 'BBGB']

class SuperComp:

	def __init__(self):
		if not DEBUG:
			(self.rows, self.cols) = [int(x) for x in input().split()]
		else:
			(self.rows, self.cols) = (len(inp), len(inp[0]))
		self.field = []
		for _ in range(self.rows):
			if not DEBUG:
				tmp = [x == 'G' for x in input()]
			else:
				tmp = [x == 'G' for x in inp[_]]
			self.field.append(tmp)
		if DEBUG:
			for line in inp:
				print(line)
		self._fieldToPointList()

	def _fieldToPointList(self):
		self.pointList = []
		for row in range(self.rows):
			for col in range(self.cols):
				if self.field[row][col]:
					self.pointList.append([row, col])

	def findMax(self):
		totMax = -1
		for (p0, idx) in self._buildRange():
			for p1 in self._buildRange(idx):
				currMax = self._calcMaxArea(p0, p1)
				if currMax > totMax:
					totMax = currMax
		self.totMax = totMax
		if DEBUG:
			print('max prod. of area:', totMax)
		else:
			print(totMax)

	def _buildRange(self, idx=-1):
		if idx == -1:
			return zip(self.pointList[:-1], range(len(self.pointList) - 1))
		else:
			return self.pointList[idx + 1:]

	def _calcMaxArea(self, p0, p1):
		(row0, col0) = p0
		(row1, col1) = p1
		d0 = self._distBorder(p0)
		d1 = self._distBorder(p1)
		(len0, len1) = (0, 0)
		while len0 < d0:
			if self._checkGoodBad(p0, len0):
				len0 += 1
			else:
				break
		while len1 < d1:
			if self._checkGoodBad(p1, len1):
				len1 += 1
			else:
				break
		if not self._checkOverlap(p0, len0, p1, len1):
			return self._calcProdAreas(len0, len1)
		else:
			maxProd = 0
			for len0tmp in range(len0, -1, -1):
				for len1tmp in range(len1, -1, -1):
					if not self._checkOverlap(p0, len0tmp, p1, len1tmp):
						maxProdTmp = self._calcProdAreas(len0tmp, len1tmp)
						if maxProdTmp > maxProd:
							maxProd = maxProdTmp
			return maxProd

	def _calcProdAreas(self, len0, len1):
		area0 = 4 * len0 + 1
		area1 = 4 * len1 + 1
		return area0 * area1

	def _checkOverlap(self, p0, len0, p1, len1):
		(row0, col0) = p0
		(row1, col1) = p1
		if row0 == row1:
			distMax = abs(col1 - col0) - 1
			dist = len0 + len1
			if distMax < dist:
				return True
			else:
				return False
		if col0 == col1:
			distMax = abs(row1 - row0) - 1
			dist = len0 + len1
			if distMax < dist:
				return True
			else:
				return False
		pTmp = [row1, col0]
		if self._checkOverlap(pTmp, 0, p0, len0) and self._checkOverlap(pTmp, 0, p1, len1):
			return True
		pTmp = [row0, col1]
		if self._checkOverlap(pTmp, 0, p0, len0) and self._checkOverlap(pTmp, 0, p1, len1):
			return True
		return False

	def _checkGoodBad(self, pX, lenX):
		f = self.field
		(row, col) = pX
		d = lenX + 1
		if f[row + d][col] and f[row - d][col] and f[row][col + d] and f[row][col - d]:
			return True
		else:
			return False

	def _distBorder(self, p):
		(row, col) = p
		top = row
		bot = self.rows - row - 1
		left = col
		right = self.cols - col - 1
		return min(top, bot, left, right)
emas = SuperComp()
emas.findMax()


class ValidPlus:

	def __init__(self, x_origin, y_origin, occupied_cells):
		self.cells = set(occupied_cells)
		self.x_origin = x_origin
		self.y_origin = y_origin

	@property
	def area(self):
		return len(self.cells)

	def __str__(self):
		return '{}'.format(self.cells)

	def __repr__(self):
		return self.__str__()

	def __eq__(self, other):
		return self.cells == other.cells

def generate_valid_pluses(x_origin, y_origin, grid):
	if grid[x_origin][y_origin] == 0:
		raise ValueError('origin of pluses must be good')
	plus_list = []
	occupied_cells = [(x_origin, y_origin)]
	plus_list.append(ValidPlus(x_origin, y_origin, occupied_cells))
	radius = 1
	while _is_radius_valid(x_origin, y_origin, radius, grid):
		occupied_cells.extend(_get_valid_radius_cells(x_origin, y_origin, radius, grid))
		plus_list.append(ValidPlus(x_origin, y_origin, occupied_cells))
		radius += 1
	return plus_list

def _get_valid_radius_cells(x, y, radius, grid):
	(n, m) = (len(grid), len(grid[0]))
	valid_cells = []
	new_x = x - radius
	new_y = y
	if new_x >= 0 and grid[new_x][new_y] == 1:
		valid_cells.append((new_x, new_y))
	new_x = x
	new_y = y + radius
	if new_y < m and grid[new_x][new_y] == 1:
		valid_cells.append((new_x, new_y))
	new_x = x + radius
	new_y = y
	if new_x < n and grid[new_x][new_y] == 1:
		valid_cells.append((new_x, new_y))
	new_x = x
	new_y = y - radius
	if new_y >= 0 and grid[new_x][new_y] == 1:
		valid_cells.append((new_x, new_y))
	return valid_cells

def _is_radius_valid(x, y, radius, grid):
	return len(_get_valid_radius_cells(x, y, radius, grid)) == 4

def get_max_pair_area(grid):
	pluses = []
	for x in range(n):
		for y in range(m):
			if grid[x][y] == 1:
				pluses.extend(generate_valid_pluses(x, y, grid))
	max_area = 0
	for p1 in pluses:
		for p2 in pluses:
			if p1 != p2 and len(p1.cells & p2.cells) == 0:
				pair_area = p1.area * p2.area
				if pair_area > max_area:
					max_area = pair_area
	return max_area
(n, m) = [int(x) for x in input().strip().split(' ')]
grid = [[0 for i in range(m)] for j in range(n)]
for i in range(n):
	row = input().strip()
	for (j, c) in enumerate(row):
		if c == 'G':
			grid[i][j] = 1
print(get_max_pair_area(grid))


from itertools import repeat, chain, combinations
(N, M) = [int(x) for x in input().strip().split(' ')]
grid = [[c == 'G' for c in input().strip()] for _ in range(N)]

def all_plusses(i0, j0):
	return chain([[(i0, j0)]], zip(zip(range(i0 + 1, N), repeat(j0)), zip(reversed(range(0, i0)), repeat(j0)), zip(repeat(i0), range(j0 + 1, M)), zip(repeat(i0), reversed(range(0, j0)))))

def valid_plusses(i0, j0):
	coords = set()
	for edge in all_plusses(i0, j0):
		if all((grid[i][j] for (i, j) in edge)):
			coords.update(edge)
			yield frozenset(coords)
		else:
			return
poss_plusses = chain.from_iterable((valid_plusses(i, j) for i in range(N) for j in range(M)))
max_size = -1
for (p1, p2) in combinations(poss_plusses, 2):
	if not p1 & p2:
		max_size = max(max_size, len(p1) * len(p2))
print(max_size)


def length(g, i, j):
	n = len(g)
	m = len(g[0]) if g != [] else 0
	res = [[]]
	k = 0
	while i - k >= 0 and i + k < n and (j - k >= 0) and (j + k < m) and (g[i - k][j] == 'G') and (g[i + k][j] == 'G') and (g[i][j - k] == 'G') and (g[i][j + k] == 'G'):
		res += [res[-1] + [(i - k, j), (i + k, j), (i, j - k), (i, j + k)]]
		k += 1
	return res

def overlap(l1, l2):
	s1 = set(l1)
	s2 = set(l2)
	return s1 & s2 != set()

def area(l):
	return len(set(l))
(n, m) = map(int, input().split())
g = [input().strip() for _ in range(n)]
alls = []
for i in range(n):
	for j in range(m):
		ls = length(g, i, j)
		for x in ls:
			alls.append(x)
res = 0
for i in range(len(alls)):
	for j in range(i + 1, len(alls)):
		if not overlap(alls[i], alls[j]):
			res = max(res, area(alls[i]) * area(alls[j]))
print(res)


def find_plus_size(mat, i, j, n, m, size):
	if i - size >= 0 and i + size < n and (j - size >= 0) and (j + size < m):
		if mat[i - size][j] == 'G' and mat[i + size][j] == 'G' and (mat[i][j - size] == 'G') and (mat[i][j + size] == 'G'):
			return True
		else:
			return False
	else:
		return False

def check_plus_not_overlap(p1, p2):
	(l1, l2) = (list(), list())
	l1.append((p1[0], p1[1]))
	for i in range(1, p1[2]):
		l1.append((p1[0], p1[1] + i))
		l1.append((p1[0], p1[1] - i))
		l1.append((p1[0] + i, p1[1]))
		l1.append((p1[0] - i, p1[1]))
	l2.append((p2[0], p2[1]))
	for i in range(1, p2[2]):
		l2.append((p2[0], p2[1] + i))
		l2.append((p2[0], p2[1] - i))
		l2.append((p2[0] + i, p2[1]))
		l2.append((p2[0] - i, p2[1]))
	if len(set(l1) & set(l2)) == 0:
		return True
	else:
		return False

def find_max_area(p1, p2, level1, level2):
	if p1[2] - level1 == 1:
		return p2[3] - 4 * level2
	elif p2[2] - level2 == 1:
		return p1[3] - 4 * level1
	elif check_plus_not_overlap([p1[0], p1[1], p1[2] - level1, p1[3]], [p2[0], p2[1], p2[2] - level2, p2[3]]):
		return max((p1[3] - 4 * level1) * (p2[3] - 4 * level2), find_max_area(p1, p2, level1 + 1, level2), find_max_area(p1, p2, level1, level2 + 1))
	else:
		return max(find_max_area(p1, p2, level1 + 1, level2), find_max_area(p1, p2, level1, level2 + 1))
(row, col) = [int(i) for i in input().strip().split(' ')]
mat = list()
for i in range(row):
	mat.append(list(input().strip()))
plusmap = list()
for i in range(row):
	for j in range(col):
		if mat[i][j] == 'G':
			size = 1
			while True:
				if find_plus_size(mat, i, j, row, col, size):
					size += 1
				else:
					break
			plusmap.append([i, j, size, 2 * (2 * size - 1) - 1])
f_plusmap = [i for i in plusmap if i[2] > 1]
if len(f_plusmap) == 0:
	max_p = 1
else:
	max_p = max(f_plusmap, key=lambda x: x[3])[3]
for i in range(len(f_plusmap)):
	for j in range(i + 1, len(f_plusmap)):
		max_p = max(max_p, find_max_area(f_plusmap[i], f_plusmap[j], 0, 0))
print(max_p)


import sys
gdata = {}

def findP2(grid, r, c):
	for i in range(r):
		for j in range(c):
			if grid[i][j] == 'G':
				plus = 1
				(xt, xb, yl, yr) = (i, i, j, j)
				while (yr + 1 <= c - 1 and grid[i][yr + 1] == 'G') and (yl - 1 >= 0 and grid[i][yl - 1] == 'G') and (xb + 1 <= r - 1 and grid[xb + 1][j] == 'G') and (xt - 1 >= 0 and grid[xt - 1][j] == 'G'):
					plus += 1
					xt -= 1
					xb += 1
					yr += 1
					yl -= 1
				for k in range(plus, 0, -1):
					gdata.setdefault(k, [])
					gdata[k].append((i, j))

def check(p1, t1, p2, t2l):
	grid = [['B' for i in range(c)] for j in range(r)]
	grid[t1[0]][t1[1]] = 'G'
	(x, y) = (t1[0], t1[1])
	(xt, xb, yl, yr) = (t1[0], t1[0], t1[1], t1[1])
	for i in range(p1 - 1):
		(grid[x][yr + 1], grid[x][yl - 1], grid[xb + 1][y], grid[xt - 1][y]) = ('G', 'G', 'G', 'G')
		xt -= 1
		xb += 1
		yr += 1
		yl -= 1
	for t in t2l:
		(x, y) = (t[0], t[1])
		(xt, xb, yl, yr) = (t[0], t[0], t[1], t[1])
		if grid[x][y] == 'B':
			if p2 == 1:
				return True
			isMax = True
			for i in range(p2 - 1):
				if grid[x][yr + 1] == 'B' and grid[x][yl - 1] == 'B' and (grid[xb + 1][y] == 'B') and (grid[xt - 1][y] == 'B'):
					xt -= 1
					xb += 1
					yr += 1
					yl -= 1
				else:
					isMax = False
					break
			if isMax == True:
				return True
	return False
(r, c) = map(int, input().split())
m = []
for i in range(r):
	m.append(list(input())[0:c])
findP2(m, r, c)
pluses = sorted(gdata)[::-1]
maxArea = 0
for p1 in range(len(pluses)):
	for t in gdata[pluses[p1]]:
		for p2 in range(p1, len(pluses)):
			isMax = check(pluses[p1], t, pluses[p2], gdata[pluses[p2]])
			if isMax == True:
				area = (4 * pluses[p1] - 3) * (4 * pluses[p2] - 3)
				if maxArea < area:
					maxArea = area
print(maxArea)


from copy import copy, deepcopy
(rows, cols) = input().split(' ')
(rows, cols) = (int(rows), int(cols))

def makeGrid(rows, cols):
	grid = []
	for i in range(rows):
		s = input()
		row = []
		for l in s:
			if l == 'B':
				row.append(1)
			else:
				row.append(0)
		grid.append(row)
	return grid

def testGood(grid, row, col, size):
	rows = len(grid)
	cols = len(grid[0])
	if row - size < 0:
		return False
	if col - size < 0:
		return False
	if row + size >= rows:
		return False
	if col + size >= cols:
		return False
	if grid[row + size][col] == 1:
		return False
	if grid[row - size][col] == 1:
		return False
	if grid[row][col + size] == 1:
		return False
	if grid[row][col - size] == 1:
		return False
	return True

def maxPlus(grid, row, col):
	size = -1
	while True:
		if testGood(grid, row, col, size + 1):
			size += 1
		else:
			break
	return size

def fillGrid(grid, row, col, size):
	newGrid = deepcopy(grid)
	for i in range(size + 1):
		newGrid[row - i][col] = 1
		newGrid[row + i][col] = 1
		newGrid[row][col - i] = 1
		newGrid[row][col + i] = 1
	return newGrid

def maxPlusInGrid(grid):
	rows = len(grid)
	cols = len(grid[0])
	value = -1
	row = 0
	col = 0
	for i in range(rows):
		for j in range(cols):
			tmp = maxPlus(grid, i, j)
			if tmp > value:
				value = tmp
				row = i
				col = j
	return (row, col, value)

def maxProductGrid(grid):
	maxProduct = 0
	rows = len(grid)
	cols = len(grid[0])
	for i in range(rows):
		for j in range(cols):
			size = maxPlus(grid, i, j)
			if size > -1:
				tmpGrid = fillGrid(grid, i, j, size)
				size2 = maxPlusInGrid(tmpGrid)[2]
				product = areaFromSize(size) * areaFromSize(size2)
				if product > maxProduct:
					maxProduct = product
	return maxProduct

def areaFromSize(size):
	return 1 + size * 4
grid = makeGrid(rows, cols)
print(maxProductGrid(grid))


def area(x):
	return x * 4 + 1

def cross(p0, p1):
	(p0x, p0y, p0k) = p0
	(p1x, p1y, p1k) = p1
	plus0 = set()
	for k in range(-1 * p0k, p0k + 1, 1):
		plus0.add((p0x + k, p0y))
		plus0.add((p0x, p0y + k))
	for k in range(-1 * p1k, p1k + 1, 1):
		if (p1x + k, p1y) in plus0:
			return True
		if (p1x, p1y + k) in plus0:
			return True
	return False

def get_size(x, y):
	k = 1
	while x + k < n and x - k >= 0 and (y + k < m) and (y - k >= 0):
		if g[x + k][y] == 'G' and g[x - k][y] == 'G' and (g[x][y + k] == 'G') and (g[x][y - k] == 'G'):
			k += 1
		else:
			break
	return k - 1
(n, m) = [int(i) for i in input().split()]
g = [[c for c in input().strip()] for _ in range(n)]
pluses = []
for i in range(n):
	for j in range(m):
		if g[i][j] == 'G':
			poss_size = get_size(i, j)
			for s in range(0, poss_size + 1):
				pluses += [(i, j, s)]
pluses.sort(key=lambda p: p[2], reverse=True)
result = 0
for i in range(len(pluses) - 1):
	for j in range(i + 1, len(pluses)):
		if not cross(pluses[i], pluses[j]):
			result = max(result, area(pluses[i][2]) * area(pluses[j][2]))
print(result)


(N, M) = (int(x) for x in input().strip().split())
grid = [list(input().strip()) for n in range(N)]

def get_area(size):
	return 4 * size + 1

def do_cross(c1, s1, c2, s2):
	(min_s, max_s) = sorted((s1, s2))
	(min_d, max_d) = sorted((abs(d) for d in (c2[0] - c1[0], c2[1] - c1[1])))
	if min_d == 0:
		return max_d <= min_s + max_s
	return max_d <= max_s and min_d <= min_s
good_cells = tuple(((n, m) for n in range(N) for m in range(M) if grid[n][m] == 'G'))
all_cross_centers = [good_cells]
while len(all_cross_centers[-1]) > 0:
	size = len(all_cross_centers)
	cross_centers = []
	for (n, m) in all_cross_centers[-1]:
		for (n2, m2) in ((n - size, m), (n + size, m), (n, m - size), (n, m + size)):
			if n2 < 0 or m2 < 0 or N <= n2 or (M <= m2):
				break
			if grid[n2][m2] == 'B':
				break
		else:
			cross_centers.append((n, m))
	all_cross_centers.append(tuple(cross_centers))
all_cross_centers.pop()
area = 0
size_pairs = ((i, j, get_area(i) * get_area(j)) for i in range(len(all_cross_centers)) for j in range(i, len(all_cross_centers)))
size_pairs = sorted(size_pairs, key=lambda p: p[2], reverse=True)
for (s1, s2, curr_area) in size_pairs:
	for c1 in all_cross_centers[s1]:
		for c2 in all_cross_centers[s2]:
			if not do_cross(c1, s1, c2, s2):
				area = curr_area
			if area != 0:
				break
		if area != 0:
			break
	if area != 0:
		break
print(area)


def get_item(grid, position):
	return grid[position[0]][position[1]]

def get_positions(grid, position, offset_amt=1):
	positions = []
	positions.append(get_position(grid, position, 'up', offset_amt))
	positions.append(get_position(grid, position, 'down', offset_amt))
	positions.append(get_position(grid, position, 'left', offset_amt))
	positions.append(get_position(grid, position, 'right', offset_amt))
	return positions

def get_position(grid, position, offset, offset_amt=1):
	(posr, posc) = position
	if offset == 'up':
		posr -= offset_amt
	elif offset == 'left':
		posc -= offset_amt
	elif offset == 'down':
		posr += offset_amt
	elif offset == 'right':
		posc += offset_amt
	if (posr < 0 or posr > len(grid) - 1) or (posc < 0 or posc > len(grid[0]) - 1):
		return None
	return (posr, posc)

def compare_positions(positions_1, positions_2):
	for position in positions_1:
		if position in positions_2:
			return True
	return False
(n, m) = [int(x) for x in input().strip().split(' ')]
grid = []
for row in range(n):
	grid.append(list(input().strip()))
valid_pluses = []
for row in range(1, n - 1):
	for column in range(1, m - 1):
		current_position = (row, column)
		if get_item(grid, current_position) == 'B':
			continue
		offset_amt = 1
		positions_queue = []
		while True:
			positions = get_positions(grid, current_position, offset_amt)
			if None in positions:
				break
			items = [get_item(grid, position) for position in positions]
			if 'B' in items:
				break
			positions_queue.extend(positions)
			valid_pluses.append((offset_amt * 4 + 1, positions_queue + [current_position]))
			offset_amt += 1
if not valid_pluses:
	count_g = 0
	for row in grid:
		count_g += row.count('G')
	print(1) if count_g >= 2 else print(0)
elif len(valid_pluses) == 1:
	print(valid_pluses[0][0])
else:
	valid_pluses = list(reversed(sorted(valid_pluses)))
	products = []
	for i in range(len(valid_pluses)):
		current_plus = valid_pluses[i]
		comparison_pluses = valid_pluses[i + 1:]
		for comparison_plus in comparison_pluses:
			if compare_positions(current_plus[1], comparison_plus[1]) != True:
				products.append(current_plus[0] * comparison_plus[0])
				break
		else:
			products.append(current_plus[0] * 1)
	print(max(products))


from itertools import repeat, chain, combinations
(N, M) = [int(x) for x in input().strip().split(' ')]
grid = [[c == 'G' for c in input().strip()] for _ in range(N)]

def all_plusses(i0, j0):
	return chain([[(i0, j0)]], zip(zip(range(i0 + 1, N), repeat(j0)), zip(reversed(range(0, i0)), repeat(j0)), zip(repeat(i0), range(j0 + 1, M)), zip(repeat(i0), reversed(range(0, j0)))))

def valid_plusses(i0, j0):
	coords = set()
	for edge in all_plusses(i0, j0):
		if all((grid[i][j] for (i, j) in edge)):
			coords.update(edge)
			yield frozenset(coords)
		else:
			return
poss_plusses = chain.from_iterable((valid_plusses(i, j) for i in range(N) for j in range(M)))
max_size = -1
for (p1, p2) in combinations(poss_plusses, 2):
	if not p1 & p2:
		max_size = max(max_size, len(p1) * len(p2))
print(max_size)


(n, m) = input().strip().split(' ')
(n, m) = (int(n), int(m))
grid = []
for i in range(n):
	grid.append(list(input().strip()))

def computeLimit(x, y, rows, columns):
	horizontal_limit = min(y, columns - y - 1)
	vertical_limit = min(x, rows - x - 1)
	return min(horizontal_limit, vertical_limit)

def coordinates(x, y):
	points = [(x, y)]
	output = [set(points)]
	limit = computeLimit(x, y, n, m)
	for k in range(1, limit + 1):
		if 'B' in [grid[x - k][y], grid[x + k][y], grid[x][y - k], grid[x][y + k]]:
			break
		else:
			points += [(x - k, y), (x + k, y), (x, y - k), (x, y + k)]
			output.append(set(points))
	return output
pluses = []
for r in range(n):
	for c in range(m):
		if grid[r][c] == 'G':
			for element in coordinates(r, c):
				pluses.append(element)
pluses.sort(key=lambda x: -1 * len(x))
max_area = 0
(i, j) = (0, len(pluses))
while i + 1 <= j - 1:
	for k in range(i + 1, j):
		if pluses[i].isdisjoint(pluses[k]):
			area = len(pluses[i]) * len(pluses[k])
			if area > max_area:
				max_area = area
			break
	i += 1
	j = k
print(max_area)


def get_item(grid, position):
	return grid[position[0]][position[1]]

def get_positions(grid, position, offset_amt=1):
	positions = []
	positions.append(get_position(grid, position, 'up', offset_amt))
	positions.append(get_position(grid, position, 'down', offset_amt))
	positions.append(get_position(grid, position, 'left', offset_amt))
	positions.append(get_position(grid, position, 'right', offset_amt))
	return positions

def get_position(grid, position, offset, offset_amt=1):
	(posr, posc) = position
	if offset == 'up':
		posr -= offset_amt
	elif offset == 'left':
		posc -= offset_amt
	elif offset == 'down':
		posr += offset_amt
	elif offset == 'right':
		posc += offset_amt
	if (posr < 0 or posr > len(grid) - 1) or (posc < 0 or posc > len(grid[0]) - 1):
		return None
	return (posr, posc)

def compare_positions(positions_1, positions_2):
	for position in positions_1:
		if position in positions_2:
			return True
	return False
(n, m) = [int(x) for x in input().strip().split(' ')]
grid = []
for row in range(n):
	grid.append(list(input().strip()))
valid_pluses = []
for row in range(1, n - 1):
	for column in range(1, m - 1):
		current_position = (row, column)
		if get_item(grid, current_position) == 'B':
			continue
		offset_amt = 1
		positions_queue = []
		while True:
			positions = get_positions(grid, current_position, offset_amt)
			if None in positions:
				break
			items = [get_item(grid, position) for position in positions]
			if 'B' in items:
				break
			positions_queue.extend(positions)
			valid_pluses.append((offset_amt * 4 + 1, positions_queue + [current_position]))
			offset_amt += 1
if not valid_pluses:
	count_g = 0
	for row in grid:
		count_g += row.count('G')
	print(1) if count_g >= 2 else print(0)
elif len(valid_pluses) == 1:
	print(valid_pluses[0][0])
else:
	valid_pluses = list(reversed(sorted(valid_pluses)))
	products = []
	for i in range(len(valid_pluses)):
		current_plus = valid_pluses[i]
		comparison_pluses = valid_pluses[i + 1:]
		for comparison_plus in comparison_pluses:
			if compare_positions(current_plus[1], comparison_plus[1]) != True:
				products.append(current_plus[0] * comparison_plus[0])
				break
		else:
			products.append(current_plus[0] * 1)
	print(max(products))


def get_item(grid, position):
	return grid[position[0]][position[1]]

def get_positions(grid, position, offset_amt=1):
	positions = []
	positions.append(get_position(grid, position, 'up', offset_amt))
	positions.append(get_position(grid, position, 'down', offset_amt))
	positions.append(get_position(grid, position, 'left', offset_amt))
	positions.append(get_position(grid, position, 'right', offset_amt))
	return positions

def get_position(grid, position, offset, offset_amt=1):
	(posr, posc) = position
	if offset == 'up':
		posr -= offset_amt
	elif offset == 'left':
		posc -= offset_amt
	elif offset == 'down':
		posr += offset_amt
	elif offset == 'right':
		posc += offset_amt
	if (posr < 0 or posr > len(grid) - 1) or (posc < 0 or posc > len(grid[0]) - 1):
		return None
	return (posr, posc)

def compare_positions(positions_1, positions_2):
	for position in positions_1:
		if position in positions_2:
			return True
	return False
(n, m) = [int(x) for x in input().strip().split(' ')]
grid = []
for row in range(n):
	grid.append(list(input().strip()))
valid_pluses = []
for row in range(1, n - 1):
	for column in range(1, m - 1):
		current_position = (row, column)
		if get_item(grid, current_position) == 'B':
			continue
		offset_amt = 1
		positions_queue = []
		while True:
			positions = get_positions(grid, current_position, offset_amt)
			if None in positions:
				break
			items = [get_item(grid, position) for position in positions]
			if 'B' in items:
				break
			positions_queue.extend(positions)
			valid_pluses.append((offset_amt * 4 + 1, positions_queue + [current_position]))
			offset_amt += 1
if not valid_pluses:
	count_g = 0
	for row in grid:
		count_g += row.count('G')
	print(1) if count_g >= 2 else print(0)
elif len(valid_pluses) == 1:
	print(valid_pluses[0][0])
else:
	valid_pluses = list(reversed(sorted(valid_pluses)))
	products = []
	for i in range(len(valid_pluses)):
		current_plus = valid_pluses[i]
		comparison_pluses = valid_pluses[i + 1:]
		for comparison_plus in comparison_pluses:
			if compare_positions(current_plus[1], comparison_plus[1]) != True:
				products.append(current_plus[0] * comparison_plus[0])
				break
		else:
			products.append(current_plus[0] * 1)
	print(max(products))


def get_item(grid, position):
	return grid[position[0]][position[1]]

def get_positions(grid, position, offset_amt=1):
	positions = []
	positions.append(get_position(grid, position, 'up', offset_amt))
	positions.append(get_position(grid, position, 'down', offset_amt))
	positions.append(get_position(grid, position, 'left', offset_amt))
	positions.append(get_position(grid, position, 'right', offset_amt))
	return positions

def get_position(grid, position, offset, offset_amt=1):
	(posr, posc) = position
	if offset == 'up':
		posr -= offset_amt
	elif offset == 'left':
		posc -= offset_amt
	elif offset == 'down':
		posr += offset_amt
	elif offset == 'right':
		posc += offset_amt
	if (posr < 0 or posr > len(grid) - 1) or (posc < 0 or posc > len(grid[0]) - 1):
		return None
	return (posr, posc)

def compare_positions(positions_1, positions_2):
	for position in positions_1:
		if position in positions_2:
			return True
	return False
(n, m) = [int(x) for x in input().strip().split(' ')]
grid = []
for row in range(n):
	grid.append(list(input().strip()))
valid_pluses = []
for row in range(1, n - 1):
	for column in range(1, m - 1):
		current_position = (row, column)
		if get_item(grid, current_position) == 'B':
			continue
		offset_amt = 1
		positions_queue = []
		while True:
			positions = get_positions(grid, current_position, offset_amt)
			if None in positions:
				break
			items = [get_item(grid, position) for position in positions]
			if 'B' in items:
				break
			positions_queue.extend(positions)
			valid_pluses.append((offset_amt * 4 + 1, positions_queue + [current_position]))
			offset_amt += 1
if not valid_pluses:
	count_g = 0
	for row in grid:
		count_g += row.count('G')
	print(1) if count_g >= 2 else print(0)
elif len(valid_pluses) == 1:
	print(valid_pluses[0][0])
else:
	valid_pluses = list(reversed(sorted(valid_pluses)))
	products = []
	for i in range(len(valid_pluses)):
		current_plus = valid_pluses[i]
		comparison_pluses = valid_pluses[i + 1:]
		for comparison_plus in comparison_pluses:
			if compare_positions(current_plus[1], comparison_plus[1]) != True:
				products.append(current_plus[0] * comparison_plus[0])
				break
		else:
			products.append(current_plus[0] * 1)
	print(max(products))


def get_max_area_product(grid, r1, c1, r2, c2):
	center_of_plus2 = {(r2, c2)}
	plus1 = max_plus(grid, r1, c1, center_of_plus2)
	plus2 = max_plus(grid, r2, c2, plus1)
	return len(plus1) * len(plus2)

def max_plus(grid, r, c, region_to_avoid):
	rows = len(grid)
	cols = len(grid[0])
	plus = {(r, c)}
	size = 0
	legit = True
	while legit:
		size += 1
		test_set = {(r + size, c), (r - size, c), (r, c + size), (r, c - size)}
		for cell in test_set:
			if cell[0] >= rows or cell[0] < 0 or cell[1] >= cols or (cell[1] < 0) or (grid[cell[0]][cell[1]] == 'B') or (cell in region_to_avoid):
				legit = False
				break
		if legit:
			plus = plus | test_set
	return plus
(n, m) = map(int, input().split())
grid = list()
for row in range(n):
	grid.append(list(input()))
max_area_product = 0
for r1 in range(n):
	for c1 in range(m):
		if grid[r1][c1] == 'B':
			continue
		for r2 in range(n):
			for c2 in range(m):
				if r1 == r2 and c1 == c2 or grid[r2][c2] == 'B':
					continue
				area_product = get_max_area_product(grid, r1, c1, r2, c2)
				if area_product > max_area_product:
					max_area_product = area_product
print(max_area_product)


import sys

class Plus:

	def __init__(self, r, c, size):
		self.r = r
		self.c = c
		self.size = size

def getItem(board, r, c):
	return board[str(r) + '-' + str(c)]

def setItem(board, r, c, item):
	board[str(r) + '-' + str(c)] = item

def isGood(board, r, c, cr, cc):
	if cr < r and cr >= 0 and (cc < c) and (cc >= 0):
		if getItem(board, cr, cc) == 'G' or getItem(board, cr, cc) == 'N':
			return True
	return False

def getPlusSize(board, r, c, cr, cc):
	isValid = True
	size = 0
	while isValid:
		if isGood(board, r, c, cr + size + 1, cc) and isGood(board, r, c, cr - size - 1, cc) and isGood(board, r, c, cr, cc + size + 1) and isGood(board, r, c, cr, cc - size - 1):
			size += 1
		else:
			isValid = False
	return size

def discardPlus(board, r, c, plus):
	board = dict(board)
	setItem(board, plus.r, plus.c, 'N')
	return board

def choosePlus(board, r, c, plus):
	board = dict(board)
	for cr in range(plus.r - plus.size, plus.r + plus.size + 1):
		setItem(board, cr, plus.c, 'B')
	for cc in range(plus.c - plus.size, plus.c + plus.size + 1):
		setItem(board, plus.r, cc, 'B')
	return board

def findLargestPlus(board, r, c):
	largest_size = -1
	largest_r = -1
	largest_c = -1
	for cr in range(0, r):
		for cc in range(0, c):
			if getItem(board, cr, cc) == 'G':
				size = getPlusSize(board, r, c, cr, cc)
				if size > largest_size:
					largest_size = size
					largest_r = cr
					largest_c = cc
	if largest_size == -1:
		return None
	else:
		return Plus(largest_r, largest_c, largest_size)

def solve(board, r, c, depth):
	largest = findLargestPlus(board, r, c)
	if largest == None or largest.size == 0 or depth == 0:
		return 1
	sizesChosen = []
	for s in range(largest.size, 0, -1):
		sizesChosen.append((4 * s + 1) * solve(choosePlus(board, r, c, Plus(largest.r, largest.c, s)), r, c, depth - 1))
	sizesChosen.append(solve(discardPlus(board, r, c, largest), r, c, depth))
	return max(sizesChosen)

def print_board(board, r, c):
	for cr in range(0, r):
		for cc in range(0, c):
			print(getItem(board, cr, cc), end='')
		print('')
(r, c) = map(int, input().split(' '))
board = {}
for cr in range(0, r):
	items = str(input())
	for cc in range(0, c):
		setItem(board, cr, cc, items[cc])
print(solve(board, r, c, 2))