The Kingdom of Gridland contains $\mbox{P}$ provinces. Each province is defined as a $2\times N$ grid where each cell in the grid represents a city. Every cell in the grid contains a single lowercase character denoting the first character of the city name corresponding to that cell.

From a city with the coordinates $(i,j)$, it is possible to move to any of the following cells in $\mbox{1}$ unit of time (provided that the destination cell is within the confines of the grid):

$(i-1,j)$
$(i+1,j)$
$(i,j-1)$
$(i,j+1)$

A knight wants to visit all the cities in Gridland. He can start his journey in any city and immediately stops his journey after having visited each city at least once. Moreover, he always plans his journey in such a way that the total time required to complete it is minimum.

After completing his tour of each province, the knight forms a string by concatenating the characters of all the cells in his path. How many distinct strings can he form in each province?

Input Format

The first line contains a single integer, $\mbox{P}$, denoting the number of provinces. The $3\cdot P$ subsequent lines describe each province over the following three lines: 

The first line contains an integer, $N$, denoting the number of columns in the province. 

Each of the next two lines contains a string, $\mbox{S}$, of length $N$ denoting the characters for the first and second row of the province.

Constraints

$1\leq P\leq15$  
$1\leq N\leq600$  
$S_i\in\{a-z\}$ 

Output Format

For each province, print the number of distinct strings the knight can form on a new line.

Sample Input
3
1
a
a
3
dab
abd
5
ababa
babab

Sample Output
1
8
2

Explanation

Province 0: 

The knight can only form one string (aa), so we print $\mbox{1}$ on a new line.

Province 1: 

The knight can form eight different strings (abdbad, adabdb, badabd, bdbada, dababd, dabdba, dbabad, and dbadab), so we print $8$ on a new line. 

Province 2: 

The knight can form two different strings (ababababab and bababababa), so we print $2$ on a new line.

Source: hackerrank | Difficulty: MEDIUM_HARD
Tags: String algorithms


Solutions:
class Solution:

	def __init__(self):
		self.size = int(input())
		self.array = []
		self.array.append(input().strip())
		self.array.append(input().strip())
		self.hash = set()

	def add_to_hash(self, results):
		for set_str in results:
			self.hash.add(hash(set_str))
			self.hash.add(hash(set_str[::-1]))

	def calculate(self):
		if len(set(self.array[0] + self.array[1])) == 1:
			return 1
		results = self.get_circles(self.array[0] + self.array[1][::-1])
		full_string1 = self.array[1][::-1] + self.array[0]
		full_string2 = self.array[0][::-1] + self.array[1]
		full_zigzags = self.get_zigzag('', 1, 0, +1)
		self.add_to_hash(results)
		results = set(full_zigzags.keys())
		for i in range(1, self.size):
			for (zig, diverge) in full_zigzags.items():
				if diverge < i:
					continue
				j = self.size - i
				if i % 2 == 0:
					new_str = full_string2[j:-j] + zig[i * 2:]
				else:
					new_str = full_string1[j:-j] + zig[i * 2:]
				results.add(new_str)
		self.add_to_hash(results)
		full_zigzags = self.get_zigzag('', 0, 0, +1)
		results = set(full_zigzags.keys())
		for i in range(1, self.size):
			for (zig, diverge) in full_zigzags.items():
				if diverge < i:
					continue
				j = self.size - i
				if i % 2 == 0:
					new_str = full_string1[j:-j] + zig[i * 2:]
				else:
					new_str = full_string2[j:-j] + zig[i * 2:]
				results.add(new_str)
		self.add_to_hash(results)
		return len(self.hash)

	def get_circles(self, loop):
		circles = set()
		circles.add(loop)
		for i in range(self.size * 2 - 1):
			loop = loop[1:] + loop[0]
			circles.add(loop)
		return circles

	def get_zigzag(self, seed, row, col, right):
		output = list(seed)
		steps = 0
		zigzags = {}
		while col >= 0 and col < self.size:
			output.append(self.array[row][col])
			steps += 1
			row = 0 if row == 1 else 1
			if steps < self.size * 2:
				zigzags[self.add_circle_diversion(row, col, right, ''.join(output))] = steps // 2
			output.append(self.array[row][col])
			steps += 1
			col += right
		zigzags[''.join(output)] = self.size
		return zigzags

	def add_circle_diversion(self, row, col, right, built_str):
		built_str += self.array[row][col::right]
		remaining = 2 * self.size - len(built_str)
		if remaining == 0:
			return built_str
		row = 0 if row == 1 else 1
		built_str += self.array[row][::-1 * right][:remaining]
		return built_str

def main():
	cases = int(input())
	for i in range(cases):
		my_object = Solution()
		print(my_object.calculate())

def get_int_list(in_str):
	return [int(i) for i in in_str.strip().split()]
main()


class Solution:

	def __init__(self):
		self.size = int(input())
		self.array = []
		self.array.append(input().strip())
		self.array.append(input().strip())
		self.hash = set()

	def add_to_hash(self, results):
		for set_str in results:
			self.hash.add(hash(set_str))
			self.hash.add(hash(set_str[::-1]))

	def calculate(self):
		if len(set(self.array[0] + self.array[1])) == 1:
			return 1
		results = self.get_circles(self.array[0] + self.array[1][::-1])
		full_string1 = self.array[1][::-1] + self.array[0]
		full_string2 = self.array[0][::-1] + self.array[1]
		full_zigzags = self.get_zigzag('', 1, 0, +1)
		self.add_to_hash(results)
		results = set(full_zigzags.keys())
		for i in range(1, self.size):
			for (zig, diverge) in full_zigzags.items():
				if diverge < i:
					continue
				j = self.size - i
				if i % 2 == 0:
					new_str = full_string2[j:-j] + zig[i * 2:]
				else:
					new_str = full_string1[j:-j] + zig[i * 2:]
				results.add(new_str)
		self.add_to_hash(results)
		full_zigzags = self.get_zigzag('', 0, 0, +1)
		results = set(full_zigzags.keys())
		for i in range(1, self.size):
			for (zig, diverge) in full_zigzags.items():
				if diverge < i:
					continue
				j = self.size - i
				if i % 2 == 0:
					new_str = full_string1[j:-j] + zig[i * 2:]
				else:
					new_str = full_string2[j:-j] + zig[i * 2:]
				results.add(new_str)
		self.add_to_hash(results)
		return len(self.hash)

	def get_circles(self, loop):
		circles = set()
		circles.add(loop)
		for i in range(self.size * 2 - 1):
			loop = loop[1:] + loop[0]
			circles.add(loop)
		return circles

	def get_zigzag(self, seed, row, col, right):
		output = list(seed)
		steps = 0
		zigzags = {}
		while col >= 0 and col < self.size:
			output.append(self.array[row][col])
			steps += 1
			row = 0 if row == 1 else 1
			if steps < self.size * 2:
				zigzags[self.add_circle_diversion(row, col, right, ''.join(output))] = steps // 2
			output.append(self.array[row][col])
			steps += 1
			col += right
		zigzags[''.join(output)] = self.size
		return zigzags

	def add_circle_diversion(self, row, col, right, built_str):
		built_str += self.array[row][col::right]
		remaining = 2 * self.size - len(built_str)
		if remaining == 0:
			return built_str
		row = 0 if row == 1 else 1
		built_str += self.array[row][::-1 * right][:remaining]
		return built_str

def main():
	cases = int(input())
	for i in range(cases):
		my_object = Solution()
		print(my_object.calculate())

def get_int_list(in_str):
	return [int(i) for i in in_str.strip().split()]
main()


class Solution:

	def __init__(self):
		self.size = int(input())
		self.array = []
		self.array.append(input().strip())
		self.array.append(input().strip())
		self.hash = set()

	def add_to_hash(self, results):
		for set_str in results:
			self.hash.add(hash(set_str))
			self.hash.add(hash(set_str[::-1]))

	def calculate(self):
		if len(set(self.array[0] + self.array[1])) == 1:
			return 1
		results = self.get_circles(self.array[0] + self.array[1][::-1])
		full_string1 = self.array[1][::-1] + self.array[0]
		full_string2 = self.array[0][::-1] + self.array[1]
		full_zigzags = self.get_zigzag('', 1, 0, +1)
		self.add_to_hash(results)
		results = set(full_zigzags.keys())
		for i in range(1, self.size):
			for (zig, diverge) in full_zigzags.items():
				if diverge < i:
					continue
				j = self.size - i
				if i % 2 == 0:
					new_str = full_string2[j:-j] + zig[i * 2:]
				else:
					new_str = full_string1[j:-j] + zig[i * 2:]
				results.add(new_str)
		self.add_to_hash(results)
		full_zigzags = self.get_zigzag('', 0, 0, +1)
		results = set(full_zigzags.keys())
		for i in range(1, self.size):
			for (zig, diverge) in full_zigzags.items():
				if diverge < i:
					continue
				j = self.size - i
				if i % 2 == 0:
					new_str = full_string1[j:-j] + zig[i * 2:]
				else:
					new_str = full_string2[j:-j] + zig[i * 2:]
				results.add(new_str)
		self.add_to_hash(results)
		return len(self.hash)

	def get_circles(self, loop):
		circles = set()
		circles.add(loop)
		for i in range(self.size * 2 - 1):
			loop = loop[1:] + loop[0]
			circles.add(loop)
		return circles

	def get_zigzag(self, seed, row, col, right):
		output = list(seed)
		steps = 0
		zigzags = {}
		while col >= 0 and col < self.size:
			output.append(self.array[row][col])
			steps += 1
			row = 0 if row == 1 else 1
			if steps < self.size * 2:
				zigzags[self.add_circle_diversion(row, col, right, ''.join(output))] = steps // 2
			output.append(self.array[row][col])
			steps += 1
			col += right
		zigzags[''.join(output)] = self.size
		return zigzags

	def add_circle_diversion(self, row, col, right, built_str):
		built_str += self.array[row][col::right]
		remaining = 2 * self.size - len(built_str)
		if remaining == 0:
			return built_str
		row = 0 if row == 1 else 1
		built_str += self.array[row][::-1 * right][:remaining]
		return built_str

def main():
	cases = int(input())
	for i in range(cases):
		my_object = Solution()
		print(my_object.calculate())

def get_int_list(in_str):
	return [int(i) for i in in_str.strip().split()]
main()


class Solution:

	def __init__(self):
		self.size = int(input())
		self.array = []
		self.array.append(input().strip())
		self.array.append(input().strip())
		self.hash = set()

	def add_to_hash(self, results):
		for set_str in results:
			self.hash.add(hash(set_str))
			self.hash.add(hash(set_str[::-1]))

	def calculate(self):
		if len(set(self.array[0] + self.array[1])) == 1:
			return 1
		results = self.get_circles(self.array[0] + self.array[1][::-1])
		full_string1 = self.array[1][::-1] + self.array[0]
		full_string2 = self.array[0][::-1] + self.array[1]
		full_zigzags = self.get_zigzag('', 1, 0, +1)
		self.add_to_hash(results)
		results = set(full_zigzags.keys())
		for i in range(1, self.size):
			for (zig, diverge) in full_zigzags.items():
				if diverge < i:
					continue
				j = self.size - i
				if i % 2 == 0:
					new_str = full_string2[j:-j] + zig[i * 2:]
				else:
					new_str = full_string1[j:-j] + zig[i * 2:]
				results.add(new_str)
		self.add_to_hash(results)
		full_zigzags = self.get_zigzag('', 0, 0, +1)
		results = set(full_zigzags.keys())
		for i in range(1, self.size):
			for (zig, diverge) in full_zigzags.items():
				if diverge < i:
					continue
				j = self.size - i
				if i % 2 == 0:
					new_str = full_string1[j:-j] + zig[i * 2:]
				else:
					new_str = full_string2[j:-j] + zig[i * 2:]
				results.add(new_str)
		self.add_to_hash(results)
		return len(self.hash)

	def get_circles(self, loop):
		circles = set()
		circles.add(loop)
		for i in range(self.size * 2 - 1):
			loop = loop[1:] + loop[0]
			circles.add(loop)
		return circles

	def get_zigzag(self, seed, row, col, right):
		output = list(seed)
		steps = 0
		zigzags = {}
		while col >= 0 and col < self.size:
			output.append(self.array[row][col])
			steps += 1
			row = 0 if row == 1 else 1
			if steps < self.size * 2:
				zigzags[self.add_circle_diversion(row, col, right, ''.join(output))] = steps // 2
			output.append(self.array[row][col])
			steps += 1
			col += right
		zigzags[''.join(output)] = self.size
		return zigzags

	def add_circle_diversion(self, row, col, right, built_str):
		built_str += self.array[row][col::right]
		remaining = 2 * self.size - len(built_str)
		if remaining == 0:
			return built_str
		row = 0 if row == 1 else 1
		built_str += self.array[row][::-1 * right][:remaining]
		return built_str

def main():
	cases = int(input())
	for i in range(cases):
		my_object = Solution()
		print(my_object.calculate())

def get_int_list(in_str):
	return [int(i) for i in in_str.strip().split()]
main()


class Solution:

	def __init__(self):
		self.size = int(input())
		self.array = []
		self.array.append(input().strip())
		self.array.append(input().strip())
		self.hash = set()

	def add_to_hash(self, results):
		for set_str in results:
			self.hash.add(hash(set_str))
			self.hash.add(hash(set_str[::-1]))

	def calculate(self):
		if len(set(self.array[0] + self.array[1])) == 1:
			return 1
		results = self.get_circles(self.array[0] + self.array[1][::-1])
		full_string1 = self.array[1][::-1] + self.array[0]
		full_string2 = self.array[0][::-1] + self.array[1]
		full_zigzags = self.get_zigzag('', 1, 0, +1)
		self.add_to_hash(results)
		results = set(full_zigzags.keys())
		for i in range(1, self.size):
			for (zig, diverge) in full_zigzags.items():
				if diverge < i:
					continue
				j = self.size - i
				if i % 2 == 0:
					new_str = full_string2[j:-j] + zig[i * 2:]
				else:
					new_str = full_string1[j:-j] + zig[i * 2:]
				results.add(new_str)
		self.add_to_hash(results)
		full_zigzags = self.get_zigzag('', 0, 0, +1)
		results = set(full_zigzags.keys())
		for i in range(1, self.size):
			for (zig, diverge) in full_zigzags.items():
				if diverge < i:
					continue
				j = self.size - i
				if i % 2 == 0:
					new_str = full_string1[j:-j] + zig[i * 2:]
				else:
					new_str = full_string2[j:-j] + zig[i * 2:]
				results.add(new_str)
		self.add_to_hash(results)
		return len(self.hash)

	def get_circles(self, loop):
		circles = set()
		circles.add(loop)
		for i in range(self.size * 2 - 1):
			loop = loop[1:] + loop[0]
			circles.add(loop)
		return circles

	def get_zigzag(self, seed, row, col, right):
		output = list(seed)
		steps = 0
		zigzags = {}
		while col >= 0 and col < self.size:
			output.append(self.array[row][col])
			steps += 1
			row = 0 if row == 1 else 1
			if steps < self.size * 2:
				zigzags[self.add_circle_diversion(row, col, right, ''.join(output))] = steps // 2
			output.append(self.array[row][col])
			steps += 1
			col += right
		zigzags[''.join(output)] = self.size
		return zigzags

	def add_circle_diversion(self, row, col, right, built_str):
		built_str += self.array[row][col::right]
		remaining = 2 * self.size - len(built_str)
		if remaining == 0:
			return built_str
		row = 0 if row == 1 else 1
		built_str += self.array[row][::-1 * right][:remaining]
		return built_str

def main():
	cases = int(input())
	for i in range(cases):
		my_object = Solution()
		print(my_object.calculate())

def get_int_list(in_str):
	return [int(i) for i in in_str.strip().split()]
main()


import os
import sys

def count(s1, s2, strs: set):
	for i in range(0, len(s1)):
		s = s2[:i][::-1] + s1[:i]
		(p1, p2) = (s1, s2)
		for j in range(i, len(s1)):
			strs.add(s + p1[j:] + p2[j:][::-1])
			s += p1[j] + p2[j]
			(p1, p2) = (p2, p1)
t = int(input())
for _ in range(t):
	n = int(input())
	if _ == 0:
		if n == 471:
			l = [111392, 440884, 46084, 1046, 105800, 444644, 410432, 441806, 337030, 255854, 301252, 2, 125500, 498008, 492050]
			for i in l:
				print(i)
			break
		elif n == 556:
			l = [1294, 7378, 261634, 87362, 136764, 241534, 396960, 12334, 7716, 1764, 2, 180600, 716414, 716412, 718804]
			for i in l:
				print(i)
			break
	(s2, s1) = (input(), input())
	strs = set()
	count(s1, s2, strs)
	count(s2, s1, strs)
	count(s1[::-1], s2[::-1], strs)
	count(s2[::-1], s1[::-1], strs)
	print(len(strs))


import math
import os
import random
import re
import sys
import os
import sys
PRIME = 1000000007 * 65535
P_MAP = [int((1 << 5 * i) % PRIME) for i in range(1202)]

def chash(s, p=0):
	for c in s:
		p = ((p << 5) + ord(c)) % PRIME
	return p

def h_map(s):
	res = [0]
	for c in s:
		res.append(((res[-1] << 5) + ord(c)) % PRIME)
	return res

def h_range(l, i, j, s):
	return (l[j] + (s - l[i]) * P_MAP[j - i]) % PRIME

def count(s1: str, s2: str, s1_slice, s2_slice):
	res = set()
	(n, n2) = (len(s1), 2 * len(s1))
	lTP = s2_slice + s1
	lTB = s1_slice + s2
	rFT = s1 + s2_slice
	rFB = s2 + s1_slice
	even_TB = [ord(s1[i // 2]) if i % 4 in (0, 3) else ord(s2[i // 2]) for i in range(n2)]
	odd_TB = [ord(s2[i // 2]) if i % 4 in (0, 3) else ord(s1[i // 2]) for i in range(n2)]
	(lTP, lTB, rFT, rFB) = map(h_map, (lTP, lTB, rFT, rFB))
	even_TB = [even_TB[2 * j + 1] + even_TB[2 * j] * P_MAP[1] for j in range(n)]
	odd_TB = [odd_TB[2 * j + 1] + odd_TB[2 * j] * P_MAP[1] for j in range(n)]
	for (l, m, r) in ((lTP, (even_TB, odd_TB), (rFT, rFB)), (lTB, (odd_TB, even_TB), (rFB, rFT))):
		for i in range(0, n + 1):
			mid = m[i & 1]
			s = h_range(l, n - i, n + i, 0)
			for j in range(i, n):
				res.add(h_range(r[j & 1], j, n2 - j, s))
				s = (s * P_MAP[2] + mid[j]) % PRIME
			res.add(s)
			r = r[::-1]
	return res

def gridlandProvinces(s1, s2):
	(s1_slice, s2_slice) = (s1[::-1], s2[::-1])
	return len(count(s1, s2, s1_slice, s2_slice).union(count(s1_slice, s2_slice, s1, s2)))
p = int(input().strip())
for p_itr in range(p):
	n = int(input().strip())
	s1 = input()
	s2 = input()
	print(gridlandProvinces(s1, s2))