You are given a grid having N rows and M columns. A grid square can either be blocked or empty. Blocked squares are represented by a '#' and empty squares are represented by '.'. Find the number of ways to tile the grid using L shaped bricks. A L brick has one side of length three units while other of length 2 units. All empty squares in the grid should be covered by exactly one of the L shaped tiles, and blocked squares should not be covered by any tile. The bricks can be used in any orientation (they can be rotated or flipped).

Input Format

The first line contains the number of test cases T. T test cases follow. Each test case contains N and M on the first line, followed by N lines describing each row of the grid.

Constraints

1 <= T <= 50 

1 <= N <= 20 

1 <= M <= 8 

Each grid square will be either '.' or '#'.

Output Format

Output the number of ways to tile the grid. Output each answer modulo 1000000007.

Sample Input
3  
2 4  
....  
....  
3 3  
...  
.#.  
...  
2 2  
##  
##

Sample Output
2  
4  
1

Explanation

NOTE: 

If all points in the grid are blocked the number of ways is 1, as in the last sample testcase.

Source: hackerrank | Difficulty: MEDIUM_HARD
Tags: Dynamic programming


Solutions:
def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


P = 10 ** 9 + 7
moves = (((0, 0), (1, 0), (1, 1), (1, 2)), ((0, 0), (1, 0), (1, -1), (1, -2)), ((0, 0), (1, 0), (2, 0), (2, 1)), ((0, 0), (1, 0), (2, 0), (2, -1)), ((0, 0), (0, 1), (1, 0), (2, 0)), ((0, 0), (0, 1), (1, 1), (2, 1)), ((0, 0), (0, 1), (0, 2), (1, 0)), ((0, 0), (0, 1), (0, 2), (1, 2)))

def try_place(grid, num_cols, y, x, move, full_row):
	for (dy, dx) in move:
		nx = x + dx
		if nx < 0 or nx >= num_cols:
			return False
		bit = 1 << nx
		if grid[y + dy] & bit:
			return False
		grid[y + dy] |= bit
	return True

def solve(grid, num_rows, num_cols, y, x, cache=None):
	if cache is None:
		cache = dict()
	full_row = 2 ** num_cols - 1
	key = (y, grid[y], grid[y + 1] if y + 1 < len(grid) else full_row, grid[y + 2] if y + 2 < len(grid) else full_row)
	if key in cache:
		return cache[key]
	if y == num_rows - 1:
		res = int(grid[y] == full_row)
		cache[key] = res
		return res
	if grid[y] == full_row:
		res = solve(grid, num_rows, num_cols, y + 1, 0, cache)
		cache[key] = res
		return res
	bit = 1 << x
	if grid[y] & bit:
		return solve(grid, num_rows, num_cols, y, x + 1, cache)
	num_ways = 0
	backup = grid[y:y + 3]
	for move in moves:
		check = try_place(grid, num_cols, y, x, move, full_row)
		if check:
			num_ways = (num_ways + solve(grid, num_rows, num_cols, y, x + 1, cache)) % P
		grid[y:y + 3] = backup
	cache[key] = num_ways
	return num_ways
T = int(input())
for i in range(T):
	(N, M) = map(int, input().split())
	full_row = 2 ** M - 1
	grid = [list(input().strip()) for _ in range(N)]
	for y in range(N):
		grid[y] = int(''.join(['0' if c == '.' else '1' for c in grid[y]]), 2)
	grid.extend([full_row, full_row])
	print(solve(grid, N, M, 0, 0))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


import math
import os
import random
import re
import sys

def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


from collections import defaultdict
from collections import deque
import copy
from functools import lru_cache
from sys import stdin
MOD = int(1000000000.0 + 7)

def return_first(grid):
	for i in range(len(grid[0])):
		if grid[0][i] == '.':
			return i
	return None

def attempt(num, grid, first):
	row_col_list = []
	for i in range(3):
		if num < 3:
			row_col_list.append((i, first))
			if i == 2:
				if num == 0:
					row_col_list.append((i, first + 1))
				elif num == 1:
					row_col_list.append((0, first + 1))
				else:
					row_col_list.append((i, first - 1))
		elif num < 4:
			row_col_list.append((i, first + 1))
			if i == 2:
				row_col_list.append((0, first))
		elif num < 6:
			row_col_list.append((0, first + i))
			if i == 2:
				if num == 4:
					row_col_list.append((1, first))
				else:
					row_col_list.append((1, first + i))
		elif num == 6:
			row_col_list.append((1, first + i))
			if i == 2:
				row_col_list.append((0, first))
		else:
			row_col_list.append((1, first - i))
			if i == 2:
				row_col_list.append((0, first))
	return check_coord_return_new_grid(row_col_list, grid)

def check_coord_return_new_grid(coord_list, grid):
	for (row, col) in coord_list:
		if row < 0 or row >= len(grid) or col < 0 or (col >= len(grid[0])) or (grid[row][col] != '.'):
			return None
	length = min(3, len(grid))
	new_grid = [list(grid[i]) for i in range(length)]
	for (row, col) in coord_list:
		new_grid[row][col] = '#'
	grid2 = []
	for i in range(length):
		grid2.append(tuple(new_grid[i]))
	grid2.extend(grid[length:])
	return tuple(grid2)

@lru_cache(None)
def sp(grid):
	ans = 0
	if not grid:
		return 1
	first = return_first(grid)
	if first is None:
		return sp(grid[1:])
	for i in range(8):
		r = attempt(i, grid, first)
		if r is None:
			continue
		ans = (ans + sp(r)) % MOD
	return ans
t = int(stdin.readline().strip())
for i in range(t):
	(n, m) = [int(x) for x in stdin.readline().split()]
	grid = []
	for j in range(n):
		grid.append(tuple(stdin.readline().strip()))
	print(sp(tuple(grid)))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	ghhggf = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == ghhggf:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	kalk = {}

	def chocc(*lorg):
		if lorg not in kalk:
			kalk[lorg] = func(*lorg)
		return kalk[lorg]
	return chocc
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(rrr, kgf) = map(int, input().split())
	tooofan = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(rrr)]
	tooofan = tooofan + 3 * [0]
	puraa = (1 << kgf) - 1

	@memoize
	def rec(suchii, first, second, third):
		if suchii == rrr:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == puraa:
			return rec(suchii + 1, second, third, tooofan[suchii + 3])

		def can_fit(rows, shape, sudhee_xx):
			res = rows[:]
			for (sudhee, suchii) in shape:
				sudhee += sudhee_xx
				if sudhee < 0 or sudhee >= kgf or suchii < 0 or (suchii >= rrr):
					return None
				if res[suchii] & 1 << sudhee != 0:
					return None
				res[suchii] |= 1 << sudhee
			return res
		pukad = 0
		while first & 1 << pukad != 0:
			pukad += 1
		rows = [first | 1 << pukad, second, third]
		sollu = 0
		for shape in shapes:
			comeon = can_fit(rows, shape, pukad)
			if comeon != None:
				sollu = (sollu + rec(suchii, *comeon)) % mod
		return sollu
	print(rec(0, tooofan[0], tooofan[1], tooofan[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def remember(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
design = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@remember
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in design:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def naveen(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return naveen
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(M, N) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(M)]
	mx = mx + 3 * [0]
	full = (1 << N) - 1

	@memoize
	def rec(n, first, second, third):
		if n == M:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(n + 1, second, third, mx[n + 3])

		def can_fit(rows, shape, m_offset):
			res = rows[:]
			for (m, n) in shape:
				m += m_offset
				if m < 0 or m >= N or n < 0 or (n >= M):
					return None
				if res[n] & 1 << m != 0:
					return None
				res[n] |= 1 << m
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(n, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


import math
import os
import random
import re
import sys

def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))


def memoize(func):
	pool = {}

	def wrapper(*arg):
		if arg not in pool:
			pool[arg] = func(*arg)
		return pool[arg]
	return wrapper
mod = 1000000007
shapes = (((1, 0), (2, 0), (2, 1)), ((0, 1), (0, 2), (-1, 2)), ((0, 1), (1, 1), (2, 1)), ((1, 0), (0, 1), (0, 2)), ((0, 1), (-1, 1), (-2, 1)), ((0, 1), (0, 2), (1, 2)), ((1, 0), (2, 0), (0, 1)), ((1, 0), (1, 1), (1, 2)))
for case in range(int(input())):
	(Y, X) = map(int, input().split())
	mx = [int(''.join(('0' if c == '.' else '1' for c in input().rstrip())), 2) for i in range(Y)]
	mx = mx + 3 * [0]
	full = (1 << X) - 1

	@memoize
	def rec(y, first, second, third):
		if y == Y:
			return 1 if first == second and second == third and (third == 0) else 0
		if first == full:
			return rec(y + 1, second, third, mx[y + 3])

		def can_fit(rows, shape, x_offset):
			res = rows[:]
			for (x, y) in shape:
				x += x_offset
				if x < 0 or x >= X or y < 0 or (y >= Y):
					return None
				if res[y] & 1 << x != 0:
					return None
				res[y] |= 1 << x
			return res
		free = 0
		while first & 1 << free != 0:
			free += 1
		rows = [first | 1 << free, second, third]
		ans = 0
		for shape in shapes:
			nrows = can_fit(rows, shape, free)
			if nrows != None:
				ans = (ans + rec(y, *nrows)) % mod
		return ans
	print(rec(0, mx[0], mx[1], mx[2]))