The only difference between the easy and hard versions is that tokens of type O do not appear in the input of the easy version.

Errichto gave Monogon the following challenge in order to intimidate him from taking his top contributor spot on Codeforces.

In a Tic-Tac-Toe grid, there are $n$ rows and $n$ columns. Each cell of the grid is either empty or contains a token. There are two types of tokens: X and O. If there exist three tokens of the same type consecutive in a row or column, it is a winning configuration. Otherwise, it is a draw configuration.

The patterns in the first row are winning configurations. The patterns in the second row are draw configurations.

In an operation, you can change an X to an O, or an O to an X. Let $k$ denote the total number of tokens in the grid. Your task is to make the grid a draw in at most $\lfloor \frac{k}{3}\rfloor$ (rounding down) operations.

You are not required to minimize the number of operations.


-----Input-----

The first line contains a single integer $t$ ($1\le t\le 100$) — the number of test cases.

The first line of each test case contains a single integer $n$ ($1\le n\le 300$) — the size of the grid.

The following $n$ lines each contain a string of $n$ characters, denoting the initial grid. The character in the $i$-th row and $j$-th column is '.' if the cell is empty, or it is the type of token in the cell: 'X' or 'O'.

It is guaranteed that not all cells are empty.

In the easy version, the character 'O' does not appear in the input.

The sum of $n$ across all test cases does not exceed $300$.


-----Output-----

For each test case, print the state of the grid after applying the operations.

We have proof that a solution always exists. If there are multiple solutions, print any.


-----Examples-----

Input
3
3
.X.
XXX
.X.
6
XX.XXX
XXXXXX
XXX.XX
XXXXXX
XX.X.X
XXXXXX
5
XXX.X
.X..X
XXX.X
..X..
..X..
Output
.X.
XOX
.X.
XX.XXO
XOXXOX
OXX.XX
XOOXXO
XX.X.X
OXXOXX
XOX.X
.X..X
XXO.O
..X..
..X..


-----Note-----

In the first test case, there are initially three 'X' consecutive in the second row and the second column. By changing the middle token to 'O' we make the grid a draw, and we only changed $1\le \lfloor 5/3\rfloor$ token.

In the second test case, we change only $9\le \lfloor 32/3\rfloor$ tokens, and there does not exist any three 'X' or 'O' consecutive in a row or column, so it is a draw.

In the third test case, we change only $3\le \lfloor 12/3\rfloor$ tokens, and the resulting grid is a draw.

Source: codeforces | Difficulty: HARD
Tags: Mathematics

Constructive algorithms


Solutions:
t = int(input())
for _ in range(t):
	n = int(input())
	mat = []
	for i in range(n):
		mat.append(list(input()))
	score = []
	for i in range(n):
		score.append([0] * n)
	for i in range(n):
		for j in range(n):
			if mat[i][j] != '.':
				for di in [-2, -1, 0]:
					if 0 <= i + di and i + di + 2 < n:
						trio = True
						if mat[i + di][j] != 'X' or mat[i + di + 1][j] != 'X' or mat[i + di + 2][j] != 'X':
							trio = False
						if trio:
							score[i][j] += 1
				for dj in [-2, -1, 0]:
					if 0 <= j + dj and j + dj + 2 < n:
						trio = True
						if mat[i][j + dj] != 'X' or mat[i][j + dj + 1] != 'X' or mat[i][j + dj + 2] != 'X':
							trio = False
						if trio:
							score[i][j] += 1
	oo = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if score[i][j] > 0:
				oo[(i + j) % 3] += 1
	m = 0
	if oo[1] < oo[m]:
		m = 1
	if oo[2] < oo[m]:
		m = 2
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == m:
				if score[i][j] > 0:
					mat[i][j] = 'O'
	for i in range(n):
		print(''.join(mat[i]))


import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__

def printGrid(grid):
	for row in grid:
		for cell in row:
			print(cell, end='')
		print('')

def changeBoard(board, n, idx):
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == idx and board[i][j] == 'X':
				board[i][j] = 'O'
t = int(input())
for test in range(t):
	n = int(input())
	board = []
	for i in range(n):
		board.append(list(map(str, input())))
	counts = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			cell = board[i][j]
			if cell == 'X':
				counts[(i + j) % 3] = counts[(i + j) % 3] + 1
	minIdx = 0
	for i in range(3):
		if counts[minIdx] > counts[i]:
			minIdx = i
	changeBoard(board, n, minIdx)
	printGrid(board)


(z, zz) = (input, lambda : list(map(int, z().split())))
fast = lambda : stdin.readline().strip()
zzz = lambda : [int(i) for i in fast().split()]
(szz, graph, mod, szzz) = (lambda : sorted(zz()), {}, 10 ** 9 + 7, lambda : sorted(zzz()))
from string import *
from re import *
from collections import *
from queue import *
from sys import *
from collections import *
from math import *
from heapq import *
from itertools import *
from bisect import *
from collections import Counter as cc
from math import factorial as f
from bisect import bisect as bs
from bisect import bisect_left as bsl
from itertools import accumulate as ac

def lcd(xnum1, xnum2):
	return xnum1 * xnum2 // gcd(xnum1, xnum2)

def prime(x):
	p = ceil(x ** 0.5) + 1
	for i in range(2, p):
		if x % i == 0 and x != 2 or x == 0:
			return 0
	return 1

def dfs(u, visit, graph):
	visit[u] = 1
	for i in graph[u]:
		if not visit[i]:
			dfs(i, visit, graph)
num = int(z())
for _ in range(num):
	n = int(z())
	lst = []
	ans = [0] * 3
	for _ in range(n):
		lst.append(list(fast()))
	for i in range(n):
		for j in range(n):
			if lst[i][j] == 'X':
				ans[(i + j) % 3] += 1
	res = ans.index(min(ans))
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == res:
				if lst[i][j] == 'X':
					lst[i][j] = 'O'
	for i in lst:
		print(''.join(i))


import sys
input = sys.stdin.readline

def main():
	n = int(input())
	tizu = [list(input().strip()) for _ in range(n)]
	cnt = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if tizu[i][j] == 'X':
				cnt[(i + j) % 3] += 1
	min_ = min(cnt)
	pos = cnt.index(min_)
	change = 0
	for i in range(n):
		for j in range(n):
			if tizu[i][j] == 'X' and (i + j) % 3 == pos:
				tizu[i][j] = 'O'
				change += 1
	for row in tizu:
		print(''.join(row))
for _ in range(int(input())):
	main()


from collections import defaultdict
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

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

def func(n: int, arr: list, count: list):
	if n < 3:
		return '\n'.join([''.join(i) for i in arr])
	for i in range(n):
		for j in range(n):
			if arr[i][j] == 'X':
				count[(i + j) % 3] += 1
	what = count.index(min(count))
	min_mod = what
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == min_mod and arr[i][j] == 'X':
				arr[i][j] = 'O'
	return '\n'.join([''.join(i) for i in arr])

def main():
	t = int(input())
	for _ in range(t):
		n = int(input())
		arr = [['.'] * n for _ in range(n)]
		count = [0] * 3
		for i in range(n):
			s = input()
			for j in range(n):
				if s[j] != '.':
					arr[i][j] = 'X'
					count[(i + j) % 3] += 1
		print(func(n, arr, count))
	return
main()


t = int(input())
while t > 0:
	t -= 1
	m = n = int(input())
	grid = []
	have = [0, 0, 0]
	for i in range(n):
		row = input()
		grid += [row]
		for j in range(m):
			if row[j] == 'X':
				have[(i + j) % 3] += 1
	selected = have.index(min(have))
	for i in range(n):
		for j in range(m):
			if (i + j) % 3 == selected and grid[i][j] == 'X':
				grid[i] = grid[i][:j] + 'O' + grid[i][j + 1:]
	print('\n'.join(grid))


for i in range(int(input())):
	n = int(input())
	a = []
	for i in range(n):
		l = list(input())
		a.append(l)
	r = []
	g = []
	b = []
	for i in range(n):
		for j in range(n):
			if a[i][j] == 'X':
				if (i + j) % 3 == 0:
					r.append([i, j])
				elif (i + j) % 3 == 1:
					g.append([i, j])
				elif (i + j) % 3 == 2:
					b.append([i, j])
	mini = min(len(r), len(g), len(b))
	if mini == len(r):
		for i in r:
			a[i[0]][i[1]] = 'O'
	elif mini == len(g):
		for i in g:
			a[i[0]][i[1]] = 'O'
	elif mini == len(b):
		for i in b:
			a[i[0]][i[1]] = 'O'
	for i in range(n):
		for j in range(n):
			print(a[i][j], end='')
		print()


t = int(input())
for i in range(t):
	n = int(input())
	arr = []
	for i in range(n):
		arr.append(list(input().strip(' ')))
	d = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if arr[i][j] == 'X':
				d[(i + j) % 3] += 1
	dmin = min(d)
	ind = d.index(dmin)
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == ind and arr[i][j] == 'X':
				arr[i][j] = 'O'
	for i in range(n):
		print(''.join(arr[i]))


def main():
	t = int(input())
	while t > 0:
		t -= 1
		n = int(input())
		mp = [''] * n
		X = [0] * 3
		O = [0] * 3
		for i in range(n):
			mp[i] = list(input().strip())
			for j in range(n):
				if mp[i][j] == 'X':
					X[(i + j) % 3] += 1
				elif mp[i][j] == 'O':
					O[(i + j) % 3] += 1
		tp = [0, 1]
		mins = X[0] + O[1]
		for i in range(3):
			for j in range(3):
				if i == j:
					continue
				if mins > X[i] + O[j]:
					mins = X[i] + O[j]
					tp = [i, j]
		for i in range(n):
			for j in range(n):
				k = (i + j) % 3
				if k == tp[0] and mp[i][j] == 'X':
					mp[i][j] = 'O'
				elif k == tp[1] and mp[i][j] == 'O':
					mp[i][j] = 'X'
		for i in range(n):
			print(''.join(mp[i]))
main()


from sys import stdin
t = int(stdin.readline())
for _ in range(t):
	n = int(stdin.readline())
	ori_board = []
	tiles = 0
	for i in range(n):
		ori_board.append(list(stdin.readline()[:-1]))
		tiles += n - ori_board[-1].count('.')
	for m in range(3):
		count = 0
		board = []
		for i in range(n):
			board.append(ori_board[i].copy())
		for i in range(n):
			j = 0
			while j < n - 2:
				if board[i][j] == board[i][j + 1] == board[i][j + 2] == 'X':
					board[i][j + (m - i - j) % 3] = 'O'
					count += 1
				j += 1
		board = list((list((board[i][j] for i in range(n))) for j in range(n)))
		for i in range(n):
			j = 0
			while j < n - 2:
				if board[i][j] == board[i][j + 1] == board[i][j + 2] == 'X':
					board[i][j + (m - i - j) % 3] = 'O'
					count += 1
				j += 1
		if count <= tiles // 3:
			board = list((list((board[i][j] for i in range(n))) for j in range(n)))
			for item in board:
				print(''.join(item))
			break


import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__

def gift():
	for _ in range(t):
		n = int(input())
		s = []
		for i in range(n):
			array = list(input())
			s.append(array)
		f = [0] * 3
		for (i, r) in enumerate(s):
			for (j, c) in enumerate(r):
				if c == 'X':
					f[(i + j) % 3] += 1
		rKey = min(range(3), key=lambda x: f[x])
		for (i, r) in enumerate(s):
			for (j, c) in enumerate(r):
				if c == 'X' and (i + j) % 3 == rKey:
					s[i][j] = 'O'
			yield ''.join(s[i])
t = int(input())
ans = gift()
print(*ans, sep='\n')


import math

def tic_toe():
	for _ in range(int(input())):
		n = int(input())
		arr = [[x for x in input()] for _ in range(n)]
		x_marks = [0] * 3
		o_marks = [0] * 3
		for i in range(n):
			for j in range(n):
				x_marks[(i + j) % 3] += 1 if arr[i][j] == 'X' else 0
				o_marks[(i + j) % 3] += 1 if arr[i][j] == 'O' else 0
		cnt_marks = math.floor((sum(x_marks) + sum(o_marks)) / 3)
		decision_x = -1
		decision_o = -1
		for i in range(3):
			for j in range(3):
				if i != j and x_marks[i] + o_marks[j] <= cnt_marks:
					decision_x = i
					decision_o = j
		for i in range(n):
			for j in range(n):
				if arr[i][j] == 'X' and (i + j) % 3 == decision_x:
					print('O', end='')
				elif arr[i][j] == 'O' and (i + j) % 3 == decision_o:
					print('X', end='')
				else:
					print(arr[i][j], end='')
			print()
		print()
tic_toe()


from math import *
from sys import *
from bisect import *
t = int(stdin.readline())
for _ in range(t):
	n = int(stdin.readline())
	m = []
	for i in range(n):
		a = list(input())
		m.append(a)
	d = {0: 0, 1: 0, 2: 0}
	for i in range(n):
		for j in range(n):
			if m[i][j] == 'X':
				d[(i + j) % 3] += 1
	f = -1
	if min(d.values()) == d[0]:
		f = 0
	elif min(d.values()) == d[1]:
		f = 1
	elif min(d.values()) == d[2]:
		f = 2
	for i in range(n):
		for j in range(n):
			if m[i][j] == 'X' and (i + j) % 3 == f:
				print('O', end='')
			else:
				print(m[i][j], end='')
		print()


import math, sys

def yes():
	print('YES')

def no():
	print('NO')

def I():
	return int(sys.stdin.readline())

def In():
	return map(int, sys.stdin.readline().split())

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

def dict(a):
	d = {}
	for x in a:
		if d.get(x, -1) != -1:
			d[x] += 1
		else:
			d[x] = 1
	return d

def find_gt(a, x):
	i = bi.bisect_left(a, x)
	if i != len(a):
		return i
	else:
		return -1

def main():
	try:
		n = I()
		cnt = [0, 0, 0]
		l = []
		for i in range(n):
			l.append(list(Sn()))
			for j in range(n):
				if l[i][j] == 'X':
					cnt[(i + j) % 3] += 1
		z = min(cnt)
		for x in range(3):
			if z == cnt[x]:
				v = x
				break
		for i in range(n):
			for j in range(n):
				if l[i][j] == 'X' and (i + j) % 3 == v:
					l[i][j] = 'O'
		for x in l:
			sys.stdout.write(''.join(x) + '\n')
	except:
		pass
M = 998244353
P = 1000000007
for _ in range(I()):
	main()


for _ in range(int(input())):
	n = int(input())
	b = [0] * n
	for i in range(n):
		b[i] = input()
	d = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			k = i + j
			if k % 3 == 0 and b[i][j] == 'X':
				d[0] += 1
			elif k % 3 == 1 and b[i][j] == 'X':
				d[1] += 1
			elif k % 3 == 2 and b[i][j] == 'X':
				d[2] += 1
	mx = min(d)
	for i in range(3):
		if d[i] == mx:
			ind = i
			break
	for i in range(n):
		print('')
		for j in range(n):
			k = i + j
			if k % 3 == ind and b[i][j] == 'X':
				print('O', end='')
			else:
				print(b[i][j], end='')


t = int(input())
for case in range(t):
	n = int(input())
	grid = []
	for row in range(n):
		grid.append(list(input()))
	m = float('inf')
	s = 0
	for k in range(3):
		c = 0
		for i in range(n):
			for j in range(n):
				if (i + j) % 3 == k:
					if grid[i][j] == 'X':
						c += 1
		if c < m:
			m = c
			s = k
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == s:
				if grid[i][j] == 'X':
					grid[i][j] = 'O'
	for row in grid:
		print(''.join(row))


import sys
import math
import operator
from collections import defaultdict, deque
input = sys.stdin.readline

def inar():
	return [int(el) for el in input().split()]

def main():
	t = int(input())
	for _ in range(t):
		n = int(input())
		matrix = []
		for i in range(n):
			matrix.append(list(input().strip()))
		dic = {0: 0, 1: 0, 2: 0}
		for i in range(n):
			for j in range(n):
				if matrix[i][j] == 'X':
					dic[(i + j) % 3] += 1
		dic = dict(sorted(dic.items(), key=operator.itemgetter(1)))
		val = 0
		for (key, val) in dic.items():
			val = key
			break
		for i in range(n):
			for j in range(n):
				if matrix[i][j] == 'X' and (i + j) % 3 == val:
					matrix[i][j] = 'O'
		for i in range(n):
			print(''.join(matrix[i]))
main()


import sys, collections, math, itertools, random
INF = sys.maxsize

def get_ints():
	return map(int, sys.stdin.readline().strip().split())

def get_array():
	return list(map(int, sys.stdin.readline().strip().split()))

def input():
	return sys.stdin.readline().strip()
mod = 1000000007
for _ in range(int(input())):
	n = int(input())
	arr = []
	cnt = [0, 0, 0]
	for i in range(n):
		arr.append(list(input()))
	for i in range(n):
		for j in range(n):
			if arr[i][j] == 'X':
				cnt[(i + j) % 3] += 1
	idx = cnt.index(min(cnt))
	for i in range(n):
		for j in range(n):
			if arr[i][j] == 'X' and (i + j) % 3 == idx:
				arr[i][j] = 'O'
	for i in range(n):
		for ele in arr[i]:
			print(ele, end='')
		print()


for _ in range(int(input())):
	a = []
	n = int(input())
	for i in range(n):
		a.append(list(str(input())))
	c = [0] * 3
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == 0 and a[i][j] == 'X':
				c[0] += 1
			elif (i + j) % 3 == 1 and a[i][j] == 'X':
				c[1] += 1
			elif (i + j) % 3 == 2 and a[i][j] == 'X':
				c[2] += 1
	c1 = c.index(min(c))
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == c1 and a[i][j] == 'X':
				a[i][j] = 'O'
		print(''.join(map(str, a[i])))


t = int(input())
while t:
	t -= 1
	n = int(input())
	a = [input() for i in range(n)]
	cnt = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if a[i][j] == 'X':
				cnt[(i + j) % 3] += 1
	mc = min(cnt)
	for k in range(3):
		if mc == cnt[k]:
			for i in range(n):
				for j in range(n):
					if a[i][j] == 'X' and (i + j) % 3 == k:
						print('O', end='')
					else:
						print(a[i][j], end='')
				print()
			break


t = int(input())
for _ in range(t):
	n = int(input())
	grid = []
	for i in range(n):
		temp = list(input())
		grid.append(temp)
	count = [0] * 3
	for x in range(n):
		for y in range(n):
			r = (x + y) % 3
			if grid[x][y] == 'X':
				count[r] += 1
	r = 0
	for i in range(3):
		if count[i] <= count[r]:
			r = i
	for x in range(n):
		for y in range(n):
			if (x + y) % 3 == r and grid[x][y] == 'X':
				grid[x][y] = 'O'
	for i in range(n):
		print(*grid[i], sep='')


for _ in ' ' * int(input()):
	(n, lst, rr) = (int(input()), [], [0, 0, 0])
	for i in range(n):
		a = input()
		for j in range(n):
			if a[j] == 'X':
				rr[(i + j) % 3] += 1
		lst.append(list(a))
	mn = rr.index(min(rr))
	for i in range(n):
		for j in range(n):
			if lst[i][j] == 'X' and (i + j) % 3 == mn:
				lst[i][j] = 'O'
		print(''.join(lst[i]))


for i in range(int(input())):
	(n, lst, r) = (int(input()), [], [0, 0, 0])
	for i in range(n):
		a = input()
		for j in range(n):
			if a[j] == 'X':
				r[(i + j) % 3] += 1
		lst.append(list(a))
	m = r.index(min(r))
	for i in range(n):
		for j in range(n):
			print('O' if lst[i][j] == 'X' and (i + j) % 3 == m else lst[i][j], end='')
		print()


gans = []
for _ in range(int(input())):
	n = int(input())
	u = []
	u0 = []
	cnt0 = 0
	for i in range(n):
		u.append(list(input()))
		u0.append(u[-1][:])
		for j in range(n):
			if u[i][j] == 'X':
				cnt0 += 1
	cnt = 0
	for i in range(n):
		for j in range(n):
			if u[i][j] == 'X' and (i - j) % 3 == 0:
				u[i][j] = 'O'
				cnt += 1
	if cnt * 3 <= cnt0:
		for i in range(n):
			gans.append(''.join(u[i]))
		continue
	for i in range(n):
		for j in range(n):
			u[i][j] = u0[i][j]
	cnt = 0
	for i in range(n):
		for j in range(n):
			if u[i][j] == 'X' and (i - j) % 3 == 1:
				u[i][j] = 'O'
				cnt += 1
	if cnt * 3 <= cnt0:
		for i in range(n):
			gans.append(''.join(u[i]))
		continue
	for i in range(n):
		for j in range(n):
			u[i][j] = u0[i][j]
	cnt = 0
	for i in range(n):
		for j in range(n):
			if u[i][j] == 'X' and (i - j) % 3 == 2:
				u[i][j] = 'O'
				cnt += 1
	if cnt * 3 <= cnt0:
		for i in range(n):
			gans.append(''.join(u[i]))
		continue
print('\n'.join(gans))


try:
	inp = open('file.txt').readline
except:
	inp = input
t = int(inp().strip())
for _ in range(t):
	n = int(inp().strip())
	rows = []
	for __ in range(n):
		arr = list(inp().strip())
		rows.append(arr)
	box = [[], [], []]
	for i in range(n):
		for j in range(n):
			if rows[i][j] == 'X':
				box[(i + j) % 3].append((i, j))
	l0 = len(box[0])
	l1 = len(box[1])
	l2 = len(box[2])
	mi = min(l0, l1, l2)
	ans = []
	if mi == l0:
		ans = box[0]
	elif mi == l1:
		ans = box[1]
	else:
		ans = box[2]
	for a in ans:
		(i, j) = a
		rows[i][j] = 'O'
	for row in rows:
		print(''.join(row))


def solve(a):
	c = [0, 0, 0]
	for i in range(len(a)):
		for j in range(len(a)):
			if a[i][j] == 'X':
				c[(i + j) % 3] += 1
	Min = float('inf')
	for i in range(len(c)):
		if c[i] < Min:
			Min = c[i]
			idx = i
	for i in range(len(a)):
		for j in range(len(a)):
			if a[i][j] == 'X' and (i + j) % 3 == idx:
				a[i][j] = 'O'
	return a
t = int(input())
ans = []
tp = ''
while t > 0:
	n = int(input(''))
	a = []
	for i in range(n):
		x = input('')
		a.append(list(x))
	a = solve(a)
	for i in range(len(a)):
		for j in range(len(a)):
			tp += a[i][j]
		tp += '\n'
	t -= 1
print(tp.strip())


import os
import sys
from io import BytesIO, IOBase
import math

def print_grid(grid):
	for el in grid:
		print(''.join(el))

def get_sol(grid):
	works = [[], [], []]
	for i in range(len(grid)):
		for j in range(len(grid[i])):
			if grid[i][j] == 'X':
				works[(i + j) % 3].append([i, j])
	mx = min(len(works[0]), len(works[1]), len(works[2]))
	for point in works[[len(works[0]), len(works[1]), len(works[2])].index(mx)]:
		if grid[point[0]][point[1]] == 'X':
			grid[point[0]][point[1]] = 'O'
	print_grid(grid)

def main():
	for t in range(int(input())):
		n = int(input())
		grid = []
		for i in range(n):
			grid.append(list(input()))
		get_sol(grid)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

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


import sys
input = lambda : sys.stdin.readline().rstrip('\r\n')
for _ in range(int(input())):
	n = int(input())
	a = []
	for i in range(n):
		a.append(list(input()))
	b = []
	for i in range(n):
		b.append([])
		for j in range(n):
			b[i].append(a[i][j])
	total = 0
	for i in a:
		total += i.count('X')
	i = 0
	count = 0
	while i < n:
		j = i % 3
		while j < n:
			if a[i][j] == 'X':
				if j + 2 < n and a[i][j + 1] == 'X' and (a[i][j + 2] == 'X'):
					b[i][j] = 'O'
				elif i + 2 < n and a[i + 1][j] == 'X' and (a[i + 2][j] == 'X'):
					b[i][j] = 'O'
				elif i - 2 >= 0 and a[i - 2][j] == 'X' and (a[i - 1][j] == 'X'):
					b[i][j] = 'O'
				elif j - 2 >= 0 and a[i][j - 1] == 'X' and (a[i][j - 2] == 'X'):
					b[i][j] = 'O'
				elif j - 1 >= 0 and j + 1 < n and (a[i][j - 1] == 'X') and (a[i][j + 1] == 'X'):
					b[i][j] = 'O'
				elif i - 1 >= 0 and i + 1 < n and (a[i + 1][j] == 'X') and (a[i - 1][j] == 'X'):
					b[i][j] = 'O'
			if b[i][j] == 'O':
				count += 1
			j += 3
		i += 1
	if count <= total // 3:
		for i in b:
			for j in i:
				print(j, end='')
			print()
	else:
		count = 0
		b = []
		for i in range(n):
			b.append([])
			for j in range(n):
				b[i].append(a[i][j])
		i = 0
		while i < n:
			j = (i + 1) % 3
			while j < n:
				if a[i][j] == 'X':
					if j + 2 < n and a[i][j + 1] == 'X' and (a[i][j + 2] == 'X'):
						b[i][j] = 'O'
					elif i + 2 < n and a[i + 1][j] == 'X' and (a[i + 2][j] == 'X'):
						b[i][j] = 'O'
					elif i - 2 >= 0 and a[i - 2][j] == 'X' and (a[i - 1][j] == 'X'):
						b[i][j] = 'O'
					elif j - 2 >= 0 and a[i][j - 1] == 'X' and (a[i][j - 2] == 'X'):
						b[i][j] = 'O'
					elif j - 1 >= 0 and j + 1 < n and (a[i][j - 1] == 'X') and (a[i][j + 1] == 'X'):
						b[i][j] = 'O'
					elif i - 1 >= 0 and i + 1 < n and (a[i + 1][j] == 'X') and (a[i - 1][j] == 'X'):
						b[i][j] = 'O'
				if b[i][j] == 'O':
					count += 1
				j += 3
			i += 1
		if count <= total // 3:
			for i in b:
				for j in i:
					print(j, end='')
				print()
		else:
			count = 0
			b = []
			for i in range(n):
				b.append([])
				for j in range(n):
					b[i].append(a[i][j])
			i = 0
			while i < n:
				j = (i + 2) % 3
				while j < n:
					if a[i][j] == 'X':
						if j + 2 < n and a[i][j + 1] == 'X' and (a[i][j + 2] == 'X'):
							b[i][j] = 'O'
						elif i + 2 < n and a[i + 1][j] == 'X' and (a[i + 2][j] == 'X'):
							b[i][j] = 'O'
						elif i - 2 >= 0 and a[i - 2][j] == 'X' and (a[i - 1][j] == 'X'):
							b[i][j] = 'O'
						elif j - 2 >= 0 and a[i][j - 1] == 'X' and (a[i][j - 2] == 'X'):
							b[i][j] = 'O'
						elif j - 1 >= 0 and j + 1 < n and (a[i][j - 1] == 'X') and (a[i][j + 1] == 'X'):
							b[i][j] = 'O'
						elif i - 1 >= 0 and i + 1 < n and (a[i + 1][j] == 'X') and (a[i - 1][j] == 'X'):
							b[i][j] = 'O'
					if b[i][j] == 'O':
						count += 1
					j += 3
				i += 1
			if count <= total // 3:
				for i in b:
					for j in i:
						print(j, end='')
					print()


import sys, os, io
T = int(input())
ans = [0] * T
for t in range(T):
	n = int(input())
	S = [list(input()) for _ in range(n)]
	lis = [[0] * 3 for _ in range(2)]
	for i in range(n):
		for j in range(n):
			if S[i][j] == 'O':
				lis[0][(i + j) % 3] += 1
			elif S[i][j] == 'X':
				lis[1][(i + j) % 3] += 1
	total = sum(lis[0]) + sum(lis[1])
	for k in range(3):
		for l in range(3):
			if k == l:
				continue
			if lis[0][k] + lis[1][l] <= total // 3:
				for i in range(n):
					for j in range(n):
						if S[i][j] == 'O' and (i + j) % 3 == k:
							S[i][j] = 'X'
						elif S[i][j] == 'X' and (i + j) % 3 == l:
							S[i][j] = 'O'
				break
		else:
			continue
		break
	for s in S:
		print(''.join(s))


nbTests = int(input())
for i in range(nbTests):
	taille = int(input())
	grille = [list(input()) for _ in range(taille)]
	mini = 100000000000000
	meilleur = -1
	for k in range(3):
		nb = 0
		for i in range(taille):
			for j in range(taille):
				if (i + j) % 3 == k and grille[i][j] == 'X':
					nb += 1
		if nb < mini:
			mini = nb
			meilleur = k
	for i in range(taille):
		for j in range(taille):
			if (i + j) % 3 == meilleur and grille[i][j] == 'X':
				grille[i][j] = 'O'
	for i in range(taille):
		print(''.join(grille[i]))


t = int(input())
for _ in range(t):
	n = int(input())
	s = []
	for i in range(n):
		r = list(input())
		s.append(r)
	cnt = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if s[i][j] == 'X':
				cnt[(i + j) % 3] += 1
	m = 2 ** 32
	index = -3
	for i in range(3):
		if cnt[i] < m:
			index = i
			m = cnt[i]
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == index and s[i][j] == 'X':
				s[i][j] = 'O'
	for i in s:
		print(''.join(i))


def countMap(grid):
	map_v = []
	n = len(grid[0])
	for i in range(n):
		map_v.append(n * [0])
	for i in range(n):
		for j in range(1, n - 1):
			a = ''.join([grid[i][j - 1], grid[i][j + 0], grid[i][j + 1]])
			if a == 'XXX':
				map_v[i][j - 1] += 1
				map_v[i][j + 0] += 1
				map_v[i][j + 1] += 1
	for i in range(1, n - 1):
		for j in range(n):
			a = ''.join([grid[i - 1][j], grid[i + 0][j], grid[i + 1][j]])
			if a == 'XXX':
				map_v[i - 1][j] += 1
				map_v[i + 0][j] += 1
				map_v[i + 1][j] += 1
	return map_v

def comp(i, j, t):
	if t == 0:
		return (i + j - 0) % 3
	if t == 1:
		return (i + j - 1) % 3
	else:
		return (i + j - 2) % 3

def deepcopy(A):
	rt = []
	for elem in A:
		if isinstance(elem, list):
			rt.append(deepcopy(elem))
		else:
			rt.append(elem)
	return rt

def fill_o(grid_, map_v, n, t):
	num_o = 0
	grid = deepcopy(grid_)
	for i in range(n):
		for j in range(n):
			if not comp(i, j, t):
				if grid[i][j] != '.':
					grid[i][j] = 'O'
					num_o += 1
	return (grid, num_o)

def main():
	n_tests = int(input())
	for test in range(n_tests):
		n = int(input())
		grid = []
		max_tries = 0
		for i in range(n):
			row = list(input())
			for j in range(n):
				if row[j] == 'X':
					max_tries += 1
			grid.append(row)
		max_tries = max_tries // 3
		map_v = countMap(grid)
		(grid_1, num_o) = fill_o(grid, map_v, n, 0)
		if num_o > max_tries:
			(grid_1, num_o) = fill_o(grid, map_v, n, 1)
		if num_o > max_tries:
			(grid_1, num_o) = fill_o(grid, map_v, n, 2)
		for i in range(n):
			print(''.join(grid_1[i]))
main()


import sys
input = sys.stdin.readline
import math
for _ in range(int(input())):
	n = int(input())
	arr = []
	for i in range(n):
		temp = input().rstrip()
		arr.append([])
		for c in temp:
			arr[i].append(c)
	diag1 = diag2 = diag3 = 0
	for i in range(n):
		for j in range(n):
			if i % 3 == j % 3 and arr[i][j] == 'X':
				diag1 += 1
			if i % 3 == (j + 1) % 3 and arr[i][j] == 'X':
				diag2 += 1
			if i % 3 == (j + 2) % 3 and arr[i][j] == 'X':
				diag3 += 1
	for i in range(n):
		for j in range(n):
			if diag1 <= diag2 and diag1 <= diag3:
				if i % 3 == j % 3 and arr[i][j] == 'X':
					arr[i][j] = 'O'
			elif diag2 <= diag3:
				if i % 3 == (j + 1) % 3 and arr[i][j] == 'X':
					arr[i][j] = 'O'
			elif i % 3 == (j + 2) % 3 and arr[i][j] == 'X':
				arr[i][j] = 'O'
	for i in range(n):
		for j in range(n):
			print(arr[i][j], end='')
		print()


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

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

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def members(self, x):
		root = self.find(x)
		return [i for i in range(self.n) if self.find(i) == root]

	def roots(self):
		return [i for (i, x) in enumerate(self.parents) if x < 0]

	def group_count(self):
		return len(self.roots())

	def all_group_members(self):
		return {r: self.members(r) for r in self.roots()}

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
t = int(input())
for _ in range(t):
	n = int(input())
	grid = []
	for i in range(n):
		s = input()
		grid.append([])
		for j in range(n):
			grid[-1].append(s[j])
	uf = UnionFind(n * n)
	for i in range(n):
		for j in range(n):
			if i < n - 1:
				if grid[i][j] == 'X' and grid[i + 1][j] == 'X':
					uf.union(i * n + j, (i + 1) * n + j)
			if j < n - 1:
				if grid[i][j] == 'X' and grid[i][j + 1] == 'X':
					uf.union(i * n + j, i * n + j + 1)
	for root in uf.roots():
		if uf.size(root) >= 3:
			count = [0, 0, 0]
			for member in uf.members(root):
				x = member % n
				y = member // n
				count[(x + y) % 3] += 1
			if count[0] <= count[1] and count[0] <= count[2]:
				for member in uf.members(root):
					x = member % n
					y = member // n
					if (x + y) % 3 == 0:
						grid[member // n][member % n] = 'O'
			elif count[1] <= count[2] and count[1] <= count[0]:
				for member in uf.members(root):
					x = member % n
					y = member // n
					if (x + y) % 3 == 1:
						grid[member // n][member % n] = 'O'
			else:
				for member in uf.members(root):
					x = member % n
					y = member // n
					if (x + y) % 3 == 2:
						grid[member // n][member % n] = 'O'
	for i in range(n):
		print(''.join(grid[i]))


import sys
input = lambda : sys.stdin.readline().rstrip()
T = int(input())
for _ in range(T):
	N = int(input())
	X = [[a for a in input()] for _ in range(N)]
	C = [0] * 3
	for i in range(N):
		for j in range(N):
			if X[i][j] == 'X':
				C[(i + j) % 3] += 1
	for k in range(3):
		if C[k] <= sum(C) // 3:
			for i in range(N):
				for j in range(N):
					if (i + j) % 3 == k:
						if X[i][j] == 'X':
							X[i][j] = 'O'
			break
	for x in X:
		print(''.join(x))


t = int(input())
for z in range(t):
	n = int(input())
	arr = []
	count = [0, 0, 0]
	for i in range(n):
		arr.append(list(input()))
	for i in range(n):
		for j in range(n):
			if arr[i][j] == 'X':
				count[(i + j) % 3] += 1
	k = count.index(min(count))
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == k and arr[i][j] == 'X':
				arr[i][j] = 'O'
		arr[i] = ''.join(arr[i])
	for s in arr:
		print(s)


def solve():
	n = int(input())
	g = []
	for _ in range(n):
		s = input()
		g.append(s)
	mod0 = 0
	mod1 = 0
	mod2 = 0
	for i in range(n):
		for j in range(n):
			if g[i][j] == 'X':
				if (i + j) % 3 == 0:
					mod0 += 1
				elif (i + j) % 3 == 1:
					mod1 += 1
				else:
					mod2 += 1
	min_ope = min(mod0, mod1, mod2)
	if min_ope == mod0:
		for i in range(n):
			ans = ''
			for j in range(n):
				if (i + j) % 3 == 0 and g[i][j] == 'X':
					ans += 'O'
				else:
					ans += g[i][j]
			print(ans)
	elif min_ope == mod1:
		for i in range(n):
			ans = ''
			for j in range(n):
				if (i + j) % 3 == 1 and g[i][j] == 'X':
					ans += 'O'
				else:
					ans += g[i][j]
			print(ans)
	elif min_ope == mod2:
		for i in range(n):
			ans = ''
			for j in range(n):
				if (i + j) % 3 == 2 and g[i][j] == 'X':
					ans += 'O'
				else:
					ans += g[i][j]
			print(ans)
t = int(input())
for _ in range(t):
	solve()


from sys import stdin
ip = stdin.readline
for _ in range(int(ip())):
	n = int(ip())
	a = [list(ip().strip()) for _ in range(n)]
	x = [0, 0, 0]
	o = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			(v, p) = (a[i][j], (i + j) % 3)
			if v == 'X':
				x[p] += 1
			elif v == 'O':
				o[p] += 1
	(p, q) = (-1, -1)
	mn = float('inf')
	for i in range(3):
		for j in range(3):
			sm = x[i] + o[j]
			if not i == j and sm < mn:
				(p, q) = (i, j)
				mn = sm
	for i in range(n):
		for j in range(n):
			(v, pt) = (a[i][j], (i + j) % 3)
			if pt == p and v == 'X':
				a[i][j] = 'O'
			elif pt == q and v == 'O':
				a[i][j] = 'X'
	print(*[''.join(i) for i in a], sep='\n')


from sys import stdin, stdout
from collections import deque
import bisect
R = lambda : stdin.readline().strip()
RL = lambda f=None: list(map(f, R().split(' '))) if f else list(R().split(' '))
output = lambda x: stdout.write(str(x) + '\n')
output_list = lambda x: output(' '.join(map(str, x)))
T = int(R())
for _ in range(T):
	n = int(R())
	tic = []
	count = [0, 0, 0]
	for i in range(n):
		s = list(input())
		tic.append(s)
		for j in range(n):
			if s[j] == 'X':
				count[(i + j) % 3] += 1
	mi = min(count)
	for i in range(3):
		if count[i] == mi:
			ind = i
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == ind and tic[i][j] == 'X':
				tic[i][j] = 'O'
	for i in range(n):
		print(''.join(tic[i]))


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

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
t = int(input())
for i in range(t):
	n = int(input())
	l = []
	k = 0
	for j in range(n):
		s = list(input())
		k += s.count('X')
		l.append(s)
	p = permutations([0, 1, 2])
	for a in p:
		c = 0
		l1 = []
		for j in range(n):
			s = l[j][:]
			if j % 3 == 0:
				for kk in range(a[0], n, 3):
					if s[kk] == 'X':
						s[kk] = 'O'
						c += 1
			elif j % 3 == 1:
				for kk in range(a[1], n, 3):
					if s[kk] == 'X':
						s[kk] = 'O'
						c += 1
			else:
				for kk in range(a[2], n, 3):
					if s[kk] == 'X':
						s[kk] = 'O'
						c += 1
			prev = ''.join(s)
			l1.append(prev)
		if c <= k // 3:
			for kk in l1:
				print(kk)
			break


for _ in range(int(input())):
	n = int(input())
	matrix = []
	clrscnt = [0] * 3
	colors = [[0 for x in range(n)] for y in range(n)]
	for i in range(n):
		s = list(input())
		matrix.append(s)
		for j in range(n):
			colors[i][j] = (i + j) % 3
			if s[j] == 'X':
				clrscnt[(i + j) % 3] += 1
	if clrscnt[0] == min(clrscnt):
		ans = 0
	elif clrscnt[1] == min(clrscnt):
		ans = 1
	else:
		ans = 2
	for i in range(n):
		for j in range(n):
			if matrix[i][j] == 'X' and colors[i][j] == ans:
				matrix[i][j] = 'O'
	for row in matrix:
		print(''.join(row))


for _ in range(int(input())):
	l = []
	n = int(input())
	for i in range(n):
		s = str(input())
		s1 = list(s)
		l.append(s1)
	if n < 3:
		for i in range(n):
			for j in range(n):
				print(l[i][j], end='')
			print()
	else:
		lc = [0] * 3
		for i in range(n):
			for j in range(n):
				if l[i][j] == 'X':
					lc[(i + j) % 3] += 1
		mn = min(lc)
		val = lc.index(mn)
		for i in range(n):
			for j in range(n):
				if (i + j) % 3 == val and l[i][j] == 'X':
					l[i][j] = 'O'
				print(l[i][j], end='')
			print()


t = int(input())
for _ in range(t):
	n = int(input())
	r = []
	b = []
	c = []
	k = 0
	for i in range(n):
		s = str(input())
		r.append(list(s))
		b.append(list(s))
		c.append(list(s))
		k += s.count('X')
	total = 0
	for i in range(n):
		m = (i + 1) % 3
		for j in range(n):
			if m == 0 and r[j][i] == 'X':
				r[j][i] = 'O'
				total += 1
			m += 1
			m = m % 3
	if total <= k // 3:
		for i in range(n):
			for j in range(n):
				print(r[i][j], end='')
			print()
	else:
		total = 0
		for i in range(n):
			m = (i + 2) % 3
			for j in range(n):
				if m == 0 and b[j][i] == 'X':
					b[j][i] = 'O'
					total += 1
				m += 1
				m = m % 3
		if total <= k // 3:
			for i in range(n):
				for j in range(n):
					print(b[i][j], end='')
				print()
		else:
			total = 0
			for i in range(n):
				m = i % 3
				for j in range(n):
					if m == 0 and c[j][i] == 'X':
						c[j][i] = 'O'
						total += 1
					m += 1
					m = m % 3
			for i in range(n):
				for j in range(n):
					print(c[i][j], end='')
				print()


def solve(mat, n):
	z = 0
	o = 0
	t = 0
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == 0 and mat[i][j] == 'X':
				z += 1
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == 1 and mat[i][j] == 'X':
				o += 1
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == 2 and mat[i][j] == 'X':
				t += 1
	p = min(o, z, t)
	if p == o:
		for i in range(n):
			for j in range(n):
				if (i + j) % 3 == 1 and mat[i][j] == 'X':
					mat[i][j] = 'O'
		return mat
	if p == z:
		for i in range(n):
			for j in range(n):
				if (i + j) % 3 == 0 and mat[i][j] == 'X':
					mat[i][j] = 'O'
		return mat
	if p == t:
		for i in range(n):
			for j in range(n):
				if (i + j) % 3 == 2 and mat[i][j] == 'X':
					mat[i][j] = 'O'
		return mat
	return mat
for _ in range(int(input())):
	n = int(input())
	mat = []
	for i in range(n):
		l = list(input())
		mat.append(l)
	result = solve(mat, n)
	for j in result:
		print(*j, sep='')


from collections import defaultdict
import sys
input = sys.stdin.readline
for _ in range(int(input())):
	n = int(input())
	grid = []
	for i in range(n):
		grid.append(list(input().strip()))
	arr = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if grid[i][j] == 'X':
				arr[(i + j) % 3] += 1
	mini = arr.index(min(arr))
	for i in range(n):
		for j in range(n):
			if grid[i][j] == 'X' and (i + j) % 3 == mini:
				grid[i][j] = 'O'
	for i in grid:
		print(''.join(i))


def disti(b, ind):
	a = []
	for i in b:
		h = []
		for j in i:
			h.append(j)
		a.append(h)
	ans = 0
	id = 0
	for i in range(n):
		start = ind[id % 3]
		id += 1
		for j in range(start, n, 3):
			left = ''
			right = ''
			up = ''
			down = ''
			mid1 = ''
			mid2 = ''
			if j - 2 >= 0:
				left = a[i][j - 2] + a[i][j - 1] + a[i][j]
			if j + 2 < n:
				right = a[i][j + 2] + a[i][j + 1] + a[i][j]
			if i + 2 < n:
				down = a[i + 2][j] + a[i + 1][j] + a[i][j]
			if i - 2 >= 0:
				up = a[i - 2][j] + a[i - 1][j] + a[i][j]
			if i + 1 < n and i - 1 >= 0:
				mid1 = a[i - 1][j] + a[i][j] + a[i + 1][j]
			if j + 1 < n and j - 1 >= 0:
				mid2 = a[i][j - 1] + a[i][j] + a[i][j + 1]
			ok = False
			for k in (left, right, up, down, mid1, mid2):
				if k == 'XXX' or k == 'OOO':
					ok = True
			if ok and a[i][j] == 'X':
				a[i][j] = 'O'
				ans += 1
	return (a, ans)

def P(b):
	for i in b:
		print(*i, sep='')
for _ in range(int(input())):
	n = int(input())
	a = []
	tot = 0
	for i in range(n):
		s = list(input())
		a.append(s)
		tot += n - s.count('.')
	(b1, s1) = disti(a, [1, 0, 2])
	(b2, s2) = disti(a, [2, 1, 0])
	(b3, s3) = disti(a, [0, 2, 1])
	if s1 * 3 <= tot:
		P(b1)
	elif s2 * 3 <= tot:
		P(b2)
	elif s3 * 3 <= tot:
		P(b3)


for _ in range(int(input())):
	n = int(input())
	arrC = []
	w = 0
	for i in range(n):
		data = list(input())
		w += data.count('X')
		arrC.append(data)
	change = [(-1, 0), (0, 1), (1, 0), (0, -1)]
	for d in range(3):
		arr = []
		for i in range(n):
			arr.append(arrC[i][:])
		counted = 0
		for i in range(n):
			for g in range((i + d) % 3, n, 3):
				if arr[i][g] != 'X':
					continue
				counted += 1
				arr[i][g] = 'O'
		if counted <= w // 3:
			for i in range(n):
				print(*arr[i], sep='')
			break


from queue import LifoQueue

def print_sol(c, sol):
	print('Case #{}: {}'.format(c, sol))

def rd_int():
	return int(input())

def rd_str():
	return input()

def rd_str_lst():
	return input().split(' ')

def sp_str_lst():
	return list(input())

def rd_int_lst():
	return [int(i) for i in rd_str_lst()]

def sp_int_lst():
	return [int(i) for i in sp_str_lst()]

def dfs(g, i, v):
	v[i] = True
	for j in g[i]:
		if not v[j]:
			dfs(g, j, v)
	print(i)

def dfs_iter(g, i, n):
	v = [False] * n
	stack = LifoQueue()
	stack.put(i)
	while stack.not_empty:
		u = stack.get()
		v[u] = True
		print(u)
		for i in g[u]:
			if not v[i]:
				stack.put(i)

def happiness(g, i, v, p, h, f):
	au = p[i]
	gv = 0
	v[i] = True
	for j in g[i]:
		if not v[j]:
			(av, gvi, f) = happiness(g, j, v, p, h, f)
			au += av
			gv += gvi
	if not (au + h[i]) % 2 == 0:
		f = False
	gu = (au + h[i]) // 2
	if not 0 <= gu <= au:
		f = False
	if not gu >= gv:
		f = False
	return (au, gu, f)

def main():
	t = rd_int()
	for c in range(1, t + 1):
		n = rd_int()
		board = [list(rd_str()) for i in range(n)]
		count = [0, 0, 0]
		for i in range(n):
			for j in range(n):
				if board[i][j] == 'X':
					count[(i + j) % 3] += 1
		min_i = count.index(min(count))
		for i in range(n):
			for j in range(n):
				if (i + j) % 3 == min_i and board[i][j] == 'X':
					board[i][j] = 'O'
		for row in board:
			print(*row, sep='')
main()


from os import path
import sys
from math import ceil, floor, gcd, log
from collections import defaultdict, Counter
maxx = float('inf')
if path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
	I = lambda : int(sys.stdin.buffer.readline())
	tup = lambda : map(int, sys.stdin.buffer.readline().split())
	lint = lambda : [int(x) for x in sys.stdin.buffer.readline().split()]
	S = lambda : sys.stdin.readline().replace('\n', '').strip()
	stpr = lambda x: sys.stdout.write(f'{x}' + '\n')
	star = lambda x: print(' '.join(map(str, x)))
else:
	I = lambda : int(sys.stdin.buffer.readline())
	tup = lambda : map(int, sys.stdin.buffer.readline().split())
	lint = lambda : [int(x) for x in sys.stdin.buffer.readline().split()]
	S = lambda : sys.stdin.readline().replace('\n', '').strip()
	stpr = lambda x: sys.stdout.write(f'{x}' + '\n')
	star = lambda x: print(' '.join(map(str, x)))
t = int(input())
for _ in range(t):
	n = int(input())
	ar = [list(input()) for _ in range(n)]
	a = [0] * 3
	for i in range(n):
		for j in range(n):
			if ar[i][j] == 'X':
				a[(i + j) % 3] += 1
	m = a.index(min(a))
	for i in range(n):
		for j in range(n):
			if ar[i][j] == 'X' and (i + j) % 3 == m:
				ar[i][j] = 'O'
	for i in ar:
		print(*i, sep='')


import sys
input = sys.stdin.readline
t = int(input())
for tests in range(t):
	n = int(input())
	MAP = [list(input().strip()) for i in range(n)]
	B = [0, 0, 0]
	W = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if MAP[i][j] == 'X':
				B[(i + j) % 3] += 1
			elif MAP[i][j] == 'O':
				W[(i + j) % 3] += 1
	MAX = 1 << 30
	MAXb = -1
	MAXw = -1
	for i in range(3):
		for j in range(3):
			if i == j:
				continue
			if B[i] + W[j] < MAX:
				MAX = B[i] + W[j]
				MAXb = i
				MAXw = j
	for i in range(n):
		for j in range(n):
			if MAP[i][j] != '.':
				if (i + j) % 3 == MAXb:
					MAP[i][j] = 'O'
				if (i + j) % 3 == MAXw:
					MAP[i][j] = 'X'
	for m in MAP:
		print(''.join(m))


import sys
from math import floor
input = sys.stdin.readline

def solve(l):
	buf = [[0, 0] for i in range(3)]
	k = 0
	s = []
	for i in range(n):
		s.append(list(map(str, input())))
		for j in range(n):
			c = s[i][j]
			val = (i + j) % 3
			if c == 'X':
				buf[val][0] += 1
				k += 1
			elif c == 'O':
				buf[val][1] += 1
				k += 1
	for d in range(3):
		for d2 in range(3):
			if d == d2:
				continue
			if buf[d][0] + buf[d2][1] <= floor(k / 3):
				for i in range(n):
					for j in range(n):
						if (i + j) % 3 == d and s[i][j] == 'X':
							s[i][j] = 'O'
						elif (i + j) % 3 == d2 and s[i][j] == 'O':
							s[i][j] = 'X'
					print(''.join((p for p in s[i])))
				return
for _ in range(int(input())):
	n = int(input())
	solve(n)


t = int(input())
for _ in range(t):
	n = int(input())
	grid = [list(input()) for _ in range(n)]
	total = {0: 0, 1: 0, 2: 0}
	for i in range(n):
		for j in range(n):
			if grid[i][j] == 'X':
				total[(i + j) % 3] += 1
	k = min(total, key=total.get)
	for i in range(n):
		for j in range(n):
			if grid[i][j] == 'X' and (i + j) % 3 == k:
				grid[i][j] = 'O'
	for row in grid:
		print(''.join(row))


for t in range(int(input())):
	n = int(input())
	store = []
	count = [0, 0, 0]
	for i in range(n):
		val = list(input())
		for j in range(n):
			if val[j] == 'X':
				count[(i + j) % 3] += 1
		store.append(val)
	mini_value = count[0]
	mini_index = 0
	for i in range(3):
		if count[i] < mini_value:
			mini_value = count[i]
			mini_index = i
	for i in range(n):
		for j in range(n):
			if store[i][j] == 'X' and (i + j) % 3 == mini_index:
				store[i][j] = 'O'
		print(''.join(map(str, store[i])))


import itertools
for _ in range(int(input())):
	n = int(input())
	A = [list(input()) for _ in range(n)]
	(cntx, cnto) = ([0] * 3, [0] * 3)
	for i in range(n):
		for j in range(n):
			if A[i][j] == 'X':
				cntx[(i + j) % 3] += 1
			elif A[i][j] == 'O':
				cnto[(i + j) % 3] += 1
	num = float('inf')
	for (i, j) in itertools.permutations(range(3), 2):
		if cntx[i] + cnto[j] < num:
			num = cntx[i] + cnto[j]
			idx = (i, j)
	for i in range(n):
		for j in range(n):
			if A[i][j] == 'X' and (i + j) % 3 == idx[0]:
				A[i][j] = 'O'
			elif A[i][j] == 'O' and (i + j) % 3 == idx[1]:
				A[i][j] = 'X'
	for a in A:
		print(''.join(a))


from os import path
from io import BytesIO, IOBase
import sys
from heapq import heappush, heappop
from functools import cmp_to_key as ctk
from collections import deque, Counter, defaultdict as dd
from bisect import bisect, bisect_left, bisect_right, insort, insort_left, insort_right
from itertools import permutations
from datetime import datetime
from math import ceil, sqrt, log, gcd

def ii():
	return int(input())

def si():
	return input().rstrip()

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

def li():
	return list(mi())
abc = 'abcdefghijklmnopqrstuvwxyz'
mod = 998244353
inf = float('inf')
vow = ['a', 'e', 'i', 'o', 'u']
(dx, dy) = ([-1, 1, 0, 0], [0, 0, 1, -1])

def bo(i):
	return ord(i) - ord('0')
file = 1

def ceil(a, b):
	return (a + b - 1) // b

def solve():
	for _ in range(ii()):
		n = ii()
		a = []
		for i in range(n):
			a.append(list(si()))
		x = [0, 0, 0]
		o = [0, 0, 0]
		k = 0
		for i in range(n):
			for j in range(n):
				if a[i][j] == 'X':
					k += 1
					x[(i + j) % 3] += 1
				if a[i][j] == 'O':
					k += 1
					o[(i + j) % 3] += 1
		ok = 0
		for i in range(3):
			for j in range(3):
				if i != j and x[i] + o[j] <= k // 3:
					for r in range(n):
						for c in range(n):
							if a[r][c] == 'X' and (r + c) % 3 == i:
								a[r][c] = 'O'
							if a[r][c] == 'O' and (r + c) % 3 == j:
								a[r][c] = 'X'
					ok = 1
					break
			if ok:
				break
		for i in a:
			print(''.join(i))
if file:
	if path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	else:
		input = sys.stdin.readline
solve()


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

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

def RL():
	return map(int, sys.stdin.readline().split())

def RLL():
	return list(map(int, sys.stdin.readline().split()))

def N():
	return int(input())

def print_list(l):
	print(' '.join(map(str, l)))
for _ in range(N()):
	n = N()
	g = []
	m = [0, 0, 0]
	for i in range(n):
		row = list(input().strip())
		g.append(row)
		for j in range(n):
			if row[j] == 'X':
				m[(i + j) % 3] += 1
	key = m.index(min(m))
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == key and g[i][j] == 'X':
				g[i][j] = 'O'
	for row in g:
		print(''.join(row))


t = int(input())
for i in range(t):
	n = int(input())
	a = []
	for j in range(n):
		a.append([])
		b = input()
		for k in range(n):
			a[j].append(b[k])
	c = n ** 2
	d = 0
	for l in range(3):
		o = 0
		f = a
		for j in range(n):
			for k in range(n):
				if f[j][k] == 'X':
					if (k + l - j % 3) % 3 == 0:
						o += 1
		if o < c:
			c = o
			d = l
	for j in range(n):
		for k in range(n):
			if a[j][k] == 'X':
				if (k + d - j % 3) % 3 == 0:
					a[j][k] = 'O'
	for j in range(n):
		e = ''
		for k in range(n):
			e += a[j][k]
		print(e)


for _ in range(int(input())):
	n = int(input())
	mat = []
	for _ in range(n):
		row = list(input())
		mat.append(row)
	dic = {0: 0, 1: 0, 2: 0}
	for i in range(n):
		for j in range(n):
			if mat[i][j] == 'X':
				dic[(i + j) % 3] += 1
	ch = ''
	if min(dic.values()) == dic[0]:
		ch = 0
	elif min(dic.values()) == dic[1]:
		ch = 1
	else:
		ch = 2
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == ch and mat[i][j] == 'X':
				print('O', end='')
			else:
				print(mat[i][j], end='')
		print()


for _ in range(0, int(input())):
	n = int(input())
	mat = [[ch for ch in input()] for _ in range(0, n)]
	cnt = [0, 0, 0]
	for i in range(0, n):
		for j in range(0, n):
			if mat[i][j] == 'X':
				cnt[(i + j) % 3] += 1
	ans = min(zip(cnt, [0, 1, 2]))
	for i in range(0, n):
		for j in range(0, n):
			if mat[i][j] == 'X' and (i + j) % 3 == ans[1]:
				mat[i][j] = 'O'
	for i in range(0, n):
		print(''.join(mat[i]))


from __future__ import division, print_function
import os, sys
from io import BytesIO, IOBase
if sys.version_info[0] < 3:
	from __builtin__ import xrange as range
	from future_builtins import ascii, filter, hex, map, oct, zip

def ii():
	return int(input())

def si():
	return input()

def mi():
	return map(int, input().strip().split(' '))

def msi():
	return map(str, input().strip().split(' '))

def li():
	return list(mi())

def dmain():
	sys.setrecursionlimit(1000000)
	threading.stack_size(1024000)
	thread = threading.Thread(target=main)
	thread.start()
abc = 'abcdefghijklmnopqrstuvwxyz'
abd = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25}
mod = 1000000007
inf = float('inf')
vow = ['a', 'e', 'i', 'o', 'u']
(dx, dy) = ([-1, 1, 0, 0], [0, 0, 1, -1])

def getKey(item):
	return item[1]

def sort2(l):
	return sorted(l, key=getKey, reverse=True)

def d2(n, m, num):
	return [[num for x in range(m)] for y in range(n)]

def isPowerOfTwo(x):
	return x and (not x & x - 1)

def decimalToBinary(n):
	return bin(n).replace('0b', '')

def ntl(n):
	return [int(i) for i in str(n)]

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(max(n - r, 1)))

def ceil(x, y):
	if x % y == 0:
		return x // y
	else:
		return x // y + 1

def powerMod(x, y, p):
	res = 1
	x %= p
	while y > 0:
		if y & 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def gcd(x, y):
	while y:
		(x, y) = (y, x % y)
	return x

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True

def read():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')

def main():
	for _ in range(ii()):
		n = ii()
		s = []
		for i in range(n):
			s.append(list(si()))
		if n == 1 or n == 2:
			for i in range(n):
				for j in range(n):
					print(s[i][j], end='')
				print()
			continue
		cnt = 0
		for i in range(n):
			for j in range(n):
				if s[i][j] != '.':
					cnt += 1
		k = -1
		ff = 0
		m = [x[:] for x in s]
		while True:
			s = [x[:] for x in m]
			f = d2(n, n, 0)
			j = 0
			k = ff
			ff += 1
			for i in range(n):
				j = k
				while j < n:
					f[i][j] = 1
					j += 3
				k += 1
				k %= 3
			c = 0
			for i in range(n):
				for j in range(n):
					if s[i][j] != '.':
						if f[i][j]:
							if j > 0 and j < n - 1:
								if s[i][j - 1] == s[i][j] and s[i][j + 1] == s[i][j] and (s[i][j] != '.'):
									c += 1
									s[i][j] = 'O'
									continue
								elif j + 2 < n and s[i][j + 2] == s[i][j] and (s[i][j + 1] == s[i][j]) and (s[i][j] != '.'):
									c += 1
									s[i][j] = 'O'
									continue
								elif j - 2 > -1 and s[i][j - 2] == s[i][j] and (s[i][j - 1] == s[i][j]) and (s[i][j] != '.'):
									c += 1
									s[i][j] = 'O'
									continue
							elif j == 0:
								if j + 2 < n and s[i][j + 2] == s[i][j] and (s[i][j + 1] == s[i][j]) and (s[i][j] != '.'):
									c += 1
									s[i][j] = 'O'
									continue
							elif j == n - 1:
								if j - 2 > -1 and s[i][j - 2] == s[i][j] and (s[i][j - 1] == s[i][j]) and (s[i][j] != '.'):
									c += 1
									s[i][j] = 'O'
									continue
							if i > 0 and i < n - 1:
								if s[i - 1][j] == s[i][j] and s[i + 1][j] == s[i][j] and (s[i][j] != '.'):
									c += 1
									s[i][j] = 'O'
									continue
								elif i + 2 < n and s[i + 2][j] == s[i][j] and (s[i + 1][j] == s[i][j]) and (s[i][j] != '.'):
									c += 1
									s[i][j] = 'O'
									continue
								elif i - 2 > -1 and s[i - 2][j] == s[i][j] and (s[i - 1][j] == s[i][j]) and (s[i][j] != '.'):
									c += 1
									s[i][j] = 'O'
									continue
							elif i == 0:
								if i + 2 < n and s[i + 2][j] == s[i][j] and (s[i + 1][j] == s[i][j]) and (s[i][j] != '.'):
									c += 1
									s[i][j] = 'O'
									continue
							elif i == n - 1:
								if i - 2 > -1 and s[i - 2][j] == s[i][j] and (s[i - 1][j] == s[i][j]) and (s[i][j] != '.'):
									c += 1
									s[i][j] = 'O'
									continue
			if c > cnt // 3:
				continue
			for i in range(n):
				for j in range(n):
					print(s[i][j], end='')
				print()
			break
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


t = int(input())
for _ in range(t):
	n = int(input())
	g = [input() for _ in range(n)]
	grille = [[[g[i][j] for j in range(n)] for i in range(n)] for _ in range(3)]
	best = n * n
	ibest = 0
	for h in range(3):
		count = 0
		for i in range(n):
			for j in range(n):
				if (i + j + h) % 3 == 0:
					if g[i][j] == 'X':
						grille[h][i][j] = 'O'
						count += 1
		if best > count:
			ibest = h
			best = count
	for l in grille[ibest]:
		mot = ''
		for ll in l:
			mot += ll
		print(mot)


for nt in range(int(input())):
	n = int(input())
	a = []
	for i in range(n):
		a.append(list(input()))
	c = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if a[i][j] == 'X':
				c[(i + j) % 3] += 1
	r = c.index(min(c))
	for i in range(n):
		for j in range(n):
			if a[i][j] == 'X' and (i + j) % 3 == r:
				a[i][j] = 'O'
	for i in a:
		print(''.join(i))


for __ in range(int(input())):
	n = int(input())
	ar = []
	kek = 0
	for i in range(n):
		ar.append(list(input()))
	for i in range(n):
		for j in range(n):
			if ar[i][j] != '.':
				kek += 1
	flag = 0
	num = 0
	chi = []
	for i in range(n):
		ha = []
		for j in range(n):
			ha.append(ar[i][j])
		chi.append(ha)
	for i in range(n):
		for j in range(n):
			if ar[i][j] == 'X' and (flag + j) % 3 == 2:
				chi[i][j] = 'O'
				num += 1
			elif ar[i][j] == 'O' and (flag + j) % 3 != 2:
				chi[i][j] = 'X'
				num += 1
		flag += 1
	if num <= kek // 3:
		for elem in chi:
			print(''.join(elem))
	else:
		flag = 1
		num = 0
		chi = []
		for i in range(n):
			ha = []
			for j in range(n):
				ha.append(ar[i][j])
			chi.append(ha)
		for i in range(n):
			for j in range(n):
				if ar[i][j] == 'X' and (flag + j) % 3 == 2:
					chi[i][j] = 'O'
					num += 1
				elif ar[i][j] == 'O' and (flag + j) % 3 != 2:
					chi[i][j] = 'X'
					num += 1
			flag += 1
		if num <= kek // 3:
			for elem in chi:
				print(''.join(elem))
		else:
			flag = 2
			num = 0
			chi = []
			for i in range(n):
				ha = []
				for j in range(n):
					ha.append(ar[i][j])
				chi.append(ha)
			for i in range(n):
				for j in range(n):
					if ar[i][j] == 'X' and (flag + j) % 3 == 2:
						chi[i][j] = 'O'
						num += 1
					elif ar[i][j] == 'O' and (flag + j) % 3 != 2:
						chi[i][j] = 'X'
						num += 1
				flag += 1
			if num <= kek // 3:
				for elem in chi:
					print(''.join(elem))
			else:
				flag = 0
				num = 0
				chi = []
				for i in range(n):
					ha = []
					for j in range(n):
						ha.append(ar[i][j])
					chi.append(ha)
				for i in range(n):
					for j in range(n):
						if ar[i][j] == 'X' and (flag + j) % 3 != 2:
							chi[i][j] = 'O'
							num += 1
						elif ar[i][j] == 'O' and (flag + j) % 3 == 2:
							chi[i][j] = 'X'
							num += 1
					flag += 1
				if num <= kek // 3:
					for elem in chi:
						print(''.join(elem))
				else:
					flag = 1
					num = 0
					chi = []
					for i in range(n):
						ha = []
						for j in range(n):
							ha.append(ar[i][j])
						chi.append(ha)
					for i in range(n):
						for j in range(n):
							if ar[i][j] == 'X' and (flag + j) % 3 != 2:
								chi[i][j] = 'O'
								num += 1
							elif ar[i][j] == 'O' and (flag + j) % 3 == 2:
								chi[i][j] = 'X'
								num += 1
						flag += 1
					if num <= kek // 3:
						for elem in chi:
							print(''.join(elem))
					else:
						flag = 2
						num = 0
						chi = []
						for i in range(n):
							ha = []
							for j in range(n):
								ha.append(ar[i][j])
							chi.append(ha)
						for i in range(n):
							for j in range(n):
								if ar[i][j] == 'X' and (flag + j) % 3 != 2:
									chi[i][j] = 'O'
									num += 1
								elif ar[i][j] == 'O' and (flag + j) % 3 == 2:
									chi[i][j] = 'X'
									num += 1
							flag += 1
						if num <= kek // 3:
							for elem in chi:
								print(''.join(elem))


import math
import bisect
from collections import defaultdict
from collections import OrderedDict
for _ in range(int(input())):
	n = int(input())
	mat = []
	for i in range(n):
		tmp = list(input())
		mat.append(tmp)
	k = 0
	count = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if mat[i][j] == 'X':
				count[(i + j) % 3] += 1
	p = count.index(min(count))
	for i in range(n):
		for j in range(n):
			if mat[i][j] == 'X' and (i + j) % 3 == p:
				mat[i][j] = 'O'
	for i in mat:
		for j in i:
			print(j, end='')
		print()


from sys import stdin, stdout
input = stdin.readline
t = int(input())
for _ in range(t):
	n = int(input())
	mat = [[0 for x in range(n)] for y in range(n)]
	for i in range(n):
		s = input()
		for j in range(n):
			mat[i][j] = s[j]
	d1 = {0: 0, 1: 0, 2: 0}
	d2 = {0: 0, 1: 0, 2: 0}
	d = {0: 0, 1: 0, 2: 0}
	for i in range(n):
		for j in range(n):
			if mat[i][j] == 'X':
				d[(i + j) % 3] += 1
				d1[(i + j) % 3] += 1
			elif mat[i][j] == 'O':
				d[(i + j) % 3] += 1
				d2[(i + j) % 3] += 1
	d = dict(sorted(d.items(), key=lambda item: item[1]))
	r = list(d.keys())[0]
	g = list(d.keys())[1]
	if d1[r] + d2[g] < d1[g] + d2[r]:
		for i in range(n):
			for j in range(n):
				if (i + j) % 3 == r and mat[i][j] == 'X':
					mat[i][j] = 'O'
				elif (i + j) % 3 == g and mat[i][j] == 'O':
					mat[i][j] = 'X'
	else:
		for i in range(n):
			for j in range(n):
				if (i + j) % 3 == g and mat[i][j] == 'X':
					mat[i][j] = 'O'
				elif (i + j) % 3 == r and mat[i][j] == 'O':
					mat[i][j] = 'X'
	for i in range(n):
		for j in range(n):
			stdout.write(mat[i][j])
		stdout.write('\n')


BUFSIZE = 8192
import os
import sys
import math
from io import BytesIO, IOBase
from bisect import bisect_left
from bisect import bisect_right

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
for _ in range(int(input())):
	n = int(input())
	a = []
	d = {}
	d[0] = 0
	d[1] = 0
	d[2] = 0
	for i in range(n):
		a.append(input())
		for j in range(n):
			if a[i][j] == 'X':
				d[(i + j) % 3] += 1
	if d[0] == min(d[0], d[1], d[2]):
		p = 0
	elif d[1] == min(d[0], d[1], d[2]):
		p = 1
	else:
		p = 2
	for i in range(n):
		s = ''
		for j in range(n):
			if (i + j) % 3 == p and a[i][j] == 'X':
				s += 'O'
			else:
				s += a[i][j]
		print(s)


def solve(arr):
	n = len(arr)
	k = 0
	for a in arr:
		for i in range(n):
			if a[i] == 'X':
				k += 1
	arr1 = []
	arr2 = []
	arr3 = []
	arr4 = []
	arr5 = []
	arr6 = []
	for i in range(n):
		temp1 = ''
		temp2 = ''
		temp3 = ''
		for j in range(n):
			if (i + j) % 3 == 0:
				temp1 += 'O'
				temp2 += 'X'
				temp3 += 'X'
			if (i + j) % 3 == 1:
				temp1 += 'X'
				temp2 += 'O'
				temp3 += 'X'
			if (i + j) % 3 == 2:
				temp1 += 'X'
				temp2 += 'X'
				temp3 += 'O'
		arr1.append(temp1)
		arr2.append(temp2)
		arr3.append(temp3)
		arr4.append(temp1[::-1])
		arr5.append(temp2[::-1])
		arr6.append(temp3[::-1])
	count1 = 0
	count2 = 0
	count3 = 0
	count4 = 0
	count5 = 0
	count6 = 0
	ans1 = arr.copy()
	ans2 = arr.copy()
	ans3 = arr.copy()
	ans4 = arr.copy()
	ans5 = arr.copy()
	ans6 = arr.copy()
	for i in range(n):
		for j in range(n):
			if ans1[i][j] == 'X' and arr1[i][j] == 'O':
				ans1[i] = ans1[i][:j] + 'O' + ans1[i][j + 1:]
				count1 += 1
			if ans2[i][j] == 'X' and arr2[i][j] == 'O':
				ans2[i] = ans2[i][:j] + 'O' + ans2[i][j + 1:]
				count2 += 1
			if ans3[i][j] == 'X' and arr3[i][j] == 'O':
				ans3[i] = ans3[i][:j] + 'O' + ans3[i][j + 1:]
				count3 += 1
			if ans4[i][j] == 'X' and arr4[i][j] == 'O':
				ans4[i] = ans4[i][:j] + 'O' + ans4[i][j + 1:]
				count4 += 1
			if ans5[i][j] == 'X' and arr5[i][j] == 'O':
				ans5[i] = ans5[i][:j] + 'O' + ans5[i][j + 1:]
				count5 += 1
			if ans6[i][j] == 'X' and arr6[i][j] == 'O':
				ans6[i] = ans6[i][:j] + 'O' + ans6[i][j + 1:]
				count6 += 1
	if count1 <= k // 3:
		return ans1
	if count2 <= k // 3:
		return ans2
	if count3 <= k // 3:
		return ans3
	if count4 <= k // 3:
		return ans4
	if count5 <= k // 3:
		return ans5
	if count6 <= k // 3:
		return ans6
t = int(input())
while t:
	t -= 1
	n = int(input())
	arr = []
	for i in range(n):
		s = str(input())
		arr.append(s)
	ans = solve(arr)
	for a in ans:
		print(a)


from sys import stdin, stdout
input = stdin.readline
t = int(input())
for _ in range(t):
	n = int(input())
	mat = [[0 for x in range(n)] for y in range(n)]
	for i in range(n):
		s = input()
		for j in range(n):
			mat[i][j] = s[j]
	d = {0: 0, 1: 0, 2: 0}
	for i in range(n):
		for j in range(n):
			if mat[i][j] == 'X':
				d[(i + j) % 3] += 1
	m = float('inf')
	x = -1
	for i in d:
		if d[i] < m:
			m = d[i]
			x = i
	for i in range(n):
		for j in range(n):
			if mat[i][j] == 'X' and (i + j) % 3 == x:
				mat[i][j] = 'O'
	for i in range(n):
		for j in range(n):
			stdout.write(mat[i][j])
		stdout.write('\n')


from bisect import *
from collections import *
from math import gcd, ceil, sqrt, floor, inf
from heapq import *
from itertools import *
from operator import add, mul, sub, xor, truediv, floordiv
from functools import *
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

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

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
farr = [1]
ifa = []

def fact(x, mod=0):
	if mod:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr) % mod)
	else:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr))
	return farr[x]

def ifact(x, mod):
	global ifa
	ifa.append(pow(farr[-1], mod - 2, mod))
	for i in range(x, 0, -1):
		ifa.append(ifa[-1] * i % mod)
	ifa = ifa[::-1]

def per(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return fact(i) // fact(i - j)
	return farr[i] * ifa[i - j] % mod

def com(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return per(i, j) // fact(j)
	return per(i, j, mod) * ifa[j] % mod

def catalan(n):
	return com(2 * n, n) // (n + 1)

def isprime(n):
	for i in range(2, int(n ** 0.5) + 1):
		if n % i == 0:
			return False
	return True

def lowbit(n):
	return n & -n

def inverse(a, m):
	a %= m
	if a <= 1:
		return a
	return (1 - inverse(m, a) * m) // a % m

class BIT:

	def __init__(self, arr):
		self.arr = arr
		self.n = len(arr) - 1

	def update(self, x, v):
		while x <= self.n:
			self.arr[x] += v
			x += x & -x

	def query(self, x):
		ans = 0
		while x:
			ans += self.arr[x]
			x &= x - 1
		return ans

class DSU:

	def __init__(self, n):
		self.c = [-1] * n

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def find(self, x):
		if self.c[x] < 0:
			return x
		self.c[x] = self.find(self.c[x])
		return self.c[x]

	def union(self, u, v):
		(u, v) = (self.find(u), self.find(v))
		if u == v:
			return False
		if self.c[u] < self.c[v]:
			(u, v) = (v, u)
		self.c[u] += self.c[v]
		self.c[v] = u
		return True

	def size(self, x):
		return -self.c[self.find(x)]

class UFS:

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.ranks = [0] * n

	def find(self, x):
		if x != self.parent[x]:
			self.parent[x] = self.find(self.parent[x])
		return self.parent[x]

	def union(self, u, v):
		(pu, pv) = (self.find(u), self.find(v))
		if pu == pv:
			return False
		if self.ranks[pu] >= self.ranks[pv]:
			self.parent[pv] = pu
			if self.ranks[pv] == self.ranks[pu]:
				self.ranks[pu] += 1
		else:
			self.parent[pu] = pv

def Prime(n):
	c = 0
	prime = []
	flag = [0] * (n + 1)
	for i in range(2, n + 1):
		if not flag[i]:
			prime.append(i)
			c += 1
		for j in range(c):
			if i * prime[j] > n:
				break
			flag[i * prime[j]] = prime[j]
			if i % prime[j] == 0:
				break
	return flag

def dij(s, graph):
	d = {}
	d[s] = 0
	heap = [(0, s)]
	seen = set()
	while heap:
		(dis, u) = heappop(heap)
		if u in seen:
			continue
		for v in graph[u]:
			if v not in d or d[v] > d[u] + graph[u][v]:
				d[v] = d[u] + graph[u][v]
				heappush(heap, (d[v], v))
	return d

def GP(it):
	return [[ch, len(list(g))] for (ch, g) in groupby(it)]

class DLN:

	def __init__(self, val):
		self.val = val
		self.pre = None
		self.next = None

def nb(i, j):
	for (ni, nj) in [[i + 1, j], [i - 1, j], [i, j - 1], [i, j + 1]]:
		if 0 <= ni < n and 0 <= nj < m:
			yield (ni, nj)

@bootstrap
def gdfs(r, p):
	if len(g[r]) == 1 and p != -1:
		yield None
	for ch in g[r]:
		if ch != p:
			yield gdfs(ch, r)
	yield None
t = N()
for i in range(t):
	n = N()
	a = []
	for i in range(n):
		a.append(input())
	res = [0] * 3
	for i in range(n):
		for j in range(n):
			if a[i][j] == 'X':
				res[(i + j) % 3] += 1
	k = sum(res)
	for i in range(3):
		if res[i] <= k // 3:
			break
	ans = ['' for i in range(n)]
	for r in range(n):
		for c in range(n):
			if a[r][c] == 'X' and (r + c) % 3 == i:
				ans[r] += 'O'
			else:
				ans[r] += a[r][c]
	for i in range(n):
		print(ans[i])


import sys
import math

def II():
	return int(sys.stdin.readline())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def MI():
	return map(int, sys.stdin.readline().split())

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

def FACT(n, mod):
	s = 1
	facts = [1]
	for i in range(1, n + 1):
		s *= i
		s %= mod
		facts.append(s)
	return facts[n]

def C(n, k, mod):
	return FACT(n, mod) * pow(FACT(k, mod) * FACT(n - k, mod) % mod, mod - 2, mod) % mod
t = II()
for q in range(t):
	n = II()
	l = []
	l1 = []
	l2 = []
	k = 0
	for i in range(n):
		temp = list(SI())
		l.append(temp[:])
		l1.append(temp[:])
		l2.append(temp[:])
	c = 0
	c1 = 0
	c2 = 0
	for i in range(n):
		for j in range(n):
			if l[i][j] == 'X':
				k += 1
				if (i + j) % 3 == 0:
					l[i][j] = 'O'
					c += 1
				elif (i + j) % 3 == 1:
					l1[i][j] = 'O'
					c1 += 1
				else:
					l2[i][j] = 'O'
					c2 += 1
	if c <= k // 3:
		ans = l
	elif c1 <= k // 3:
		ans = l1
	else:
		ans = l2
	for i in ans:
		print(''.join(i))


import sys
input = sys.stdin.readline

def prog():
	for _ in range(int(input())):
		n = int(input())
		k = 0
		grid = [list(input().strip()) for i in range(n)]
		locs = [[[], []] for i in range(3)]
		for i in range(n):
			for j in range(n):
				if grid[i][j] == 'O':
					locs[(i + j) % 3][0].append([i, j])
					k += 1
				elif grid[i][j] == 'X':
					locs[(i + j) % 3][1].append([i, j])
					k += 1
		found = False
		for i in range(3):
			for j in range(3):
				if i == j:
					continue
				if len(locs[i][0]) + len(locs[j][1]) <= k // 3:
					for loc in locs[i][0]:
						grid[loc[0]][loc[1]] = 'X'
					for loc in locs[j][1]:
						grid[loc[0]][loc[1]] = 'O'
					found = True
					break
			if found:
				break
		for row in grid:
			print(''.join(row))
prog()


from sys import stdin as inp
from sys import stdout as out
import math
for _ in range(int(inp.readline())):
	n = int(inp.readline())
	matrix = [list(inp.readline()) for _ in range(n)]
	check = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if matrix[i][j] == 'X':
				check[(i + j) % 3] += 1
	index = check.index(min(check))
	for i in range(n):
		for j in range(n):
			if matrix[i][j] == 'X' and (i + j) % 3 == index:
				matrix[i][j] = 'O'
	for row in matrix:
		print(*row, sep='', end='')


t = int(input())
for _ in range(t):
	n = int(input())
	d = []
	for j in range(n):
		d.append(list(input()))
	a = [0, 0, 0]
	for j in range(n):
		for i in range(n):
			if d[j][i] == 'X':
				a[(i + j) % 3] += 1
	if a[0] <= min(a[1], a[2]):
		for i in range(n):
			for j in range(n):
				if (i + j) % 3 == 0 and d[i][j] == 'X':
					d[i][j] = 'O'
	elif a[1] <= a[2]:
		for i in range(n):
			for j in range(n):
				if (i + j) % 3 == 1 and d[i][j] == 'X':
					d[i][j] = 'O'
	else:
		for i in range(n):
			for j in range(n):
				if (i + j) % 3 == 2 and d[i][j] == 'X':
					d[i][j] = 'O'
	for j in range(n):
		print(''.join(d[j]))


t = int(input())
for q in range(t):
	n = int(input())
	a1 = 0
	a2 = 0
	a3 = 0
	mass = list()
	for i in range(n):
		s = [x for x in input()]
		for j in range(n):
			if s[j] == 'X':
				if (i + j) % 3 == 0:
					a1 += 1
				elif (i + j) % 3 == 1:
					a2 += 1
				else:
					a3 += 1
		mass.append(s)
	zn = 0
	if a1 == min(a1, a2, a3):
		zn = 0
	elif a2 == min(a1, a2, a3):
		zn = 1
	else:
		zn = 2
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == zn and mass[i][j] == 'X':
				mass[i][j] = 'O'
		print(''.join(mass[i]))


EMPTY = '.'
X = 'X'
O = 'O'

def inverse(char):
	if char == X:
		result = O
	else:
		assert char == O
		result = X
	return result

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

def f(matrix, x_offset):
	cost = 0
	matrix = list(map(list, matrix))
	for i_row in range(len(matrix)):
		for i_col in range(len(matrix[0])):
			if matrix[i_row][i_col] != EMPTY and (i_row - x_offset) % 3 == i_col % 3:
				matrix[i_row][i_col] = inverse(matrix[i_row][i_col])
				cost += 1
	return (list(map(''.join, matrix)), cost)
(t_n,) = read_ints()
for i_t in range(t_n):
	(n,) = read_ints()
	matrix = [input() for i_row in range(n)]
	(best_result, best_cost) = min((f(matrix, x_offset) for x_offset in range(3)), key=lambda pair: pair[1])
	print('\n'.join(best_result))


for _ in range(int(input())):
	n = int(input())
	ar = [[x for x in input()] for _ in range(n)]
	c = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if ar[i][j] == 'X':
				c[(i + j) % 3] += 1
	e = c.index(min(c))
	for i in range(n):
		for j in range(n):
			if ar[i][j] == 'X' and (i + j) % 3 == e:
				ar[i][j] = 'O'
	for e in ar:
		print(''.join(e))


from collections import defaultdict
for _ in range(int(input())):
	n = int(input())
	a = []
	for i in range(n):
		b = []
		a.append(input())
	dp = [[0] * n for i in range(n)]
	coun = 0
	dic = {1: 0, 2: 0, 3: 0}
	for i in range(n):
		coun = coun % 3 + 1
		temp = coun
		for j in range(n):
			dp[i][j] = temp
			if a[i][j] == 'X':
				dic[temp] += 1
			temp = temp % 3 + 1
	mi = min(dic.values())
	yo = 0
	for i in dic:
		if dic[i] == mi:
			yo = i
			break
	for i in range(n):
		for j in range(n):
			if dp[i][j] == yo and a[i][j] == 'X':
				print('O', end='')
			else:
				print(a[i][j], end='')
		print()


from sys import *
input = stdin.readline
INF = 10 ** 9

def solve():
	t = int(input())
	for _ in range(t):
		n = int(input())
		k = 0
		s = ['_' for i in range(n)]
		for i in range(n):
			s[i] = input()
			for j in range(n):
				if s[i][j] != '.':
					k += 1
		min_value = INF
		(who_x, who_y) = (0, 0)
		for x in range(3):
			for y in range(3):
				if x != y:
					count = 0
					for i in range(n):
						for j in range(n):
							if (i + j) % 3 == x and s[i][j] == 'O':
								count += 1
							elif (i + j) % 3 == y and s[i][j] == 'X':
								count += 1
					if min_value > count:
						(min_value, who_x, who_y) = (count, x, y)
		assert min_value <= k // 3
		ans = []
		for i in range(n):
			result = ''
			for j in range(n):
				if (i + j) % 3 == who_x and s[i][j] == 'O':
					result += 'X'
				elif (i + j) % 3 == who_y and s[i][j] == 'X':
					result += 'O'
				else:
					result += s[i][j]
			ans.append(result)
		for i in range(n):
			print(ans[i])
solve()


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush
from math import *
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
import copy
import time
starttime = time.time()
mod = int(pow(10, 9) + 7)
mod2 = 998244353

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

def out(*var, end='\n'):
	sys.stdout.write(' '.join(map(str, var)) + end)

def L():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]
try:
	sys.stdin = open('input.txt', 'r')
except:
	pass
for _ in range(L()[0]):
	n = L()[0]
	A = [list(input()) for i in range(n)]
	B = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			B[(i + j) % 3] += 1 if A[i][j] == 'X' else 0
	cnt = 0
	last = 0
	rem = B.index(min(B))
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == rem and A[i][j] == 'X':
				A[i][j] = 'O'
	for ele in A:
		print(''.join(ele))
endtime = time.time()


import os
from io import BytesIO, IOBase
import sys
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
t = int(input())
import copy
for _ in range(t):
	n = int(input())
	parts_grid = []
	grid = []
	for i in range(n):
		grid.append([x for x in input()])
		parts_grid.append([0 for x in range(n)])
	orig_grid = copy.deepcopy(grid)
	for u in range(3):
		grid = copy.deepcopy(orig_grid)
		k = 0
		changes = 0
		for i in range(n):
			for j in range(n):
				if grid[i][j] == 'X':
					k += 1
				if not (i + j) % 3 == u:
					continue
				if i > 0 and grid[i - 1][j] == 'X' and (i < n - 1) and (grid[i + 1][j] == 'X') and (grid[i][j] == 'X'):
					grid[i][j] = 'O'
				elif j > 0 and grid[i][j - 1] == 'X' and (j < n - 1) and (grid[i][j + 1] == 'X') and (grid[i][j] == 'X'):
					grid[i][j] = 'O'
				elif i > 1 and grid[i - 1][j] == 'X' and (grid[i - 2][j] == 'X') and (grid[i][j] == 'X'):
					grid[i][j] = 'O'
				elif j > 1 and grid[i][j - 1] == 'X' and (grid[i][j - 2] == 'X') and (grid[i][j] == 'X'):
					grid[i][j] = 'O'
				elif i < n - 2 and grid[i + 1][j] == 'X' and (grid[i + 2][j] == 'X') and (grid[i][j] == 'X'):
					grid[i][j] = 'O'
				elif j < n - 2 and grid[i][j + 1] == 'X' and (grid[i][j + 2] == 'X') and (grid[i][j] == 'X'):
					grid[i][j] = 'O'
				if grid[i][j] == 'O':
					changes += 1
		if changes > k // 3:
			continue
		else:
			break
	for x in grid:
		print(''.join(x))


for _ in range(int(input())):
	n = int(input())
	arr = [list(input()) for i in range(n)]
	ar2 = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if arr[i][j] != 'X':
				continue
			ar2[abs(i + j) % 3] += 1
	ii = ar2.index(min(ar2))
	for i in range(n):
		for j in range(n):
			if arr[i][j] != 'X' or abs(i + j) % 3 != ii:
				continue
			arr[i][j] = 'O'
	for r in arr:
		print(''.join(r))


q = int(input())
for _ in range(q):
	n = int(input())
	mat = [list(input()[:n]) for i in range(n)]
	licz = [0] * 3
	wsumie = 0
	for i in range(n):
		for j in range(n):
			licz[(i + j) % 3] += mat[i][j] == 'X'
	wsumie = sum(licz)
	if licz[0] <= wsumie // 3:
		for i in range(n):
			for j in range(n):
				if mat[i][j] == 'X' and (i + j) % 3 == 0:
					mat[i][j] = 'O'
	elif licz[1] <= wsumie // 3:
		for i in range(n):
			for j in range(n):
				if mat[i][j] == 'X' and (i + j) % 3 == 1:
					mat[i][j] = 'O'
	elif licz[2] <= wsumie // 3:
		for i in range(n):
			for j in range(n):
				if mat[i][j] == 'X' and (i + j) % 3 == 2:
					mat[i][j] = 'O'
	for i in mat:
		print(''.join(i))


import sys, math, bisect
inf = float('inf')
mod = 10 ** 9 + 7

def lcm(a, b):
	return int(a / math.gcd(a, b) * b)

def gcd(a, b):
	return int(math.gcd(a, b))

def tobinary(n):
	return bin(n)[2:]

def binarySearch(a, x):
	i = bisect.bisect_left(a, x)
	if i != len(a) and a[i] == x:
		return i
	else:
		return -1

def lowerBound(a, x):
	i = bisect.bisect_left(a, x)
	if i:
		return i - 1
	else:
		return -1

def upperBound(a, x):
	i = bisect.bisect_right(a, x)
	if i != len(a) + 1 and a[i - 1] == x:
		return i - 1
	else:
		return -1

def SieveOfEratosthenes(n):
	ans = []
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	for p in range(2, n + 1):
		if prime[p]:
			ans.append(p)
	return ans
for _ in range(int(input())):
	n = int(input())
	arr = []
	for _ in range(n):
		arr.append(list(input()))
	r = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if arr[i][j] == 'X':
				r[(i + j) % 3] += 1
	x = r.index(min(r))
	for i in range(n):
		for j in range(n):
			if arr[i][j] == 'X' and (i + j) % 3 == x:
				arr[i][j] = 'O'
	for i in arr:
		print(''.join(i))


import math
t = int(input())
for test in range(t):
	n = int(input())
	board = [list(input()) for i in range(n)]
	x = [0, 0, 0]
	o = [0, 0, 0]
	for row in range(n):
		for col in range(n):
			cur = (row + col) % 3
			if board[row][col] == 'X':
				x[cur] += 1
			if board[row][col] == 'O':
				o[cur] += 1
	total = sum(x) + sum(o)
	for xite in range(3):
		for oite in range(3):
			if xite != oite and x[xite] + o[oite] <= math.floor(total / 3):
				xit = xite
				oit = oite
	for row in range(n):
		for col in range(n):
			cur = (row + col) % 3
			if board[row][col] == 'X' and cur == xit:
				board[row][col] = 'O'
			if board[row][col] == 'O' and cur == oit:
				board[row][col] = 'X'
	for i in range(n):
		print(''.join(board[i]))


for _ in range(int(input())):
	n = int(input())
	ml = []
	for i in range(n):
		s = list(input())
		ml.append(s)
	(a, b, c) = (0, 0, 0)
	for i in range(n):
		for j in range(n):
			if ml[i][j] == 'X':
				if (i + j) % 3 == 0:
					a += 1
				if (i + j) % 3 == 1:
					b += 1
				if (i + j) % 3 == 2:
					c += 1
	if min(a, b, c) == a:
		for i in range(n):
			for j in range(n):
				if ml[i][j] == 'X':
					if (i + j) % 3 == 0:
						ml[i][j] = 'O'
	elif min(a, b, c) == b:
		for i in range(n):
			for j in range(n):
				if ml[i][j] == 'X':
					if (i + j) % 3 == 1:
						ml[i][j] = 'O'
	elif min(a, b, c) == c:
		for i in range(n):
			for j in range(n):
				if ml[i][j] == 'X':
					if (i + j) % 3 == 2:
						ml[i][j] = 'O'
	for i in range(n):
		for j in range(n):
			print(ml[i][j], end='')
		print()


def solve(n, grid):
	x = [0 for i in range(3)]
	o = [0 for i in range(3)]
	for i in range(n):
		for j in range(n):
			if grid[i][j] == 'O':
				o[(i + j) % 3] += 1
			elif grid[i][j] == 'X':
				x[(i + j) % 3] += 1
	k = (sum(x) + sum(o)) // 3
	if k == 0:
		for i in range(n):
			print(grid[i])
		return
	for i in range(3):
		for j in range(3):
			if i != j and x[i] + o[j] <= k:
				(cx, co) = (i, j)
	for i in range(n):
		s = ''
		for j in range(n):
			if (i + j) % 3 == cx and grid[i][j] == 'X':
				s += 'O'
			elif (i + j) % 3 == co and grid[i][j] == 'O':
				s += 'X'
			else:
				s += grid[i][j]
		print(s)
t = int(input())
for i in range(t):
	n = int(input())
	grid = []
	for j in range(n):
		grid.append(input())
	solve(n, grid)


import io
import os
from collections import Counter, defaultdict, deque

def solve(N, grid):
	K = 0
	for r in range(N):
		for c in range(N):
			if grid[r][c] != '.':
				K += 1
	gridOriginal = [list(row) for row in grid]
	for start in range(3):
		changed = 0
		grid = [list(row) for row in gridOriginal]
		for d in range(start, 2 * N, 3):
			for r in range(N):
				c = d - r
				if 0 <= c < N:
					need = False
					for offset in range(3):
						if r + offset - 2 >= 0 and r + offset < N and (grid[r + offset - 2][c] == grid[r + offset - 1][c] == grid[r + offset][c] == 'X'):
							need = True
						if c + offset - 2 >= 0 and c + offset < N and (grid[r][c + offset - 2] == grid[r][c + offset - 1] == grid[r][c + offset] == 'X'):
							need = True
					if need:
						grid[r][c] = 'O'
						changed += 1
		if changed <= K // 3:
			return '\n'.join((''.join(row) for row in grid))
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
TC = int(input())
for tc in range(1, TC + 1):
	(N,) = [int(x) for x in input().split()]
	grid = [list(input().decode().rstrip()) for i in range(N)]
	ans = solve(N, grid)
	print(ans)


from __future__ import division, print_function
from fractions import Fraction
import sys
import os
from io import BytesIO, IOBase
from itertools import *
import bisect
from heapq import *
from math import ceil, floor
from copy import *
from collections import deque, defaultdict
from collections import Counter as counter
from itertools import combinations
from itertools import permutations as permutate
from bisect import bisect_left as bl
from operator import *
from bisect import bisect_right as br
from bisect import bisect
BUFSIZE = 8192
from sys import stderr

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
from types import GeneratorType

def iterative(f, stack=[]):

	def wrapped_func(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		to = f(*args, **kwargs)
		while True:
			if type(to) is GeneratorType:
				stack.append(to)
				to = next(to)
				continue
			stack.pop()
			if not stack:
				break
			to = stack[-1].send(to)
		return to
	return wrapped_func

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))
mod = 1000000007

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def fsep():
	return map(float, inp().split())

def nextline():
	out('\n')

def testcase(t):
	for p in range(t):
		solve()

def pow(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res
from functools import reduce

def factors(n):
	return set(reduce(list.__add__, ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))

def gcd(a, b):
	if a == b:
		return a
	while b > 0:
		(a, b) = (b, a % b)
	return a

def prefix_sum(ar):
	return list(accumulate(ar))

def suffix_sum(ar):
	return list(accumulate(ar[::-1]))[::-1]

def N():
	return int(inp())
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]

def YES():
	print('YES')

def NO():
	print('NO')

def Yes():
	print('Yes')

def No():
	print('No')
from collections import defaultdict

def numberOfSetBits(i):
	i = i - (i >> 1 & 1431655765)
	i = (i & 858993459) + (i >> 2 & 858993459)
	return ((i + (i >> 4) & 252645135) * 16843009 & 4294967295) >> 24

class MergeFind:

	def __init__(self, n):
		self.parent = list(range(n))
		self.size = [1] * n
		self.num_sets = n

	def find(self, a):
		to_update = []
		while a != self.parent[a]:
			to_update.append(a)
			a = self.parent[a]
		for b in to_update:
			self.parent[b] = a
		return self.parent[a]

	def merge(self, a, b):
		a = self.find(a)
		b = self.find(b)
		if a == b:
			return
		if self.size[a] < self.size[b]:
			(a, b) = (b, a)
		self.num_sets -= 1
		self.parent[b] = a
		self.size[a] += self.size[b]

	def set_size(self, a):
		return self.size[self.find(a)]

	def __len__(self):
		return self.num_sets

def lcm(a, b):
	return abs(a // gcd(a, b) * b)

def f(s):
	ar = []
	for i in s:
		if i == 'X':
			ar.append('X')
		if i == '.':
			ar.append('.')
	return ar

def solve():
	n = N()
	arr = [f(inp()) for _ in range(n)]
	m = 0
	d = defaultdict(int)

	def isvalid(i, j):
		if 0 <= i < n and 0 <= j < n and (arr[i][j] == 'X'):
			return 1
		return 0
	for i in range(n):
		for j in range(n):
			if arr[i][j] == 'X':
				d[(i + j) % 3] += 1
	maxx = min(d.values())
	for i in d.keys():
		if d[i] == maxx:
			founder = i
	for i in range(n):
		for j in range(n):
			if arr[i][j] == '.' or (i + j) % 3 != founder:
				continue
			if isvalid(i - 1, j) and isvalid(i + 1, j):
				arr[i][j] = 'O'
				m += 1
				continue
			if isvalid(i, j - 1) and isvalid(i, j + 1):
				arr[i][j] = 'O'
				m += 1
				continue
			if isvalid(i + 2, j) and isvalid(i + 1, j):
				arr[i][j] = 'O'
				m += 1
				continue
			if isvalid(i, j + 2) and isvalid(i, j + 1):
				arr[i][j] = 'O'
				m += 1
				continue
			if isvalid(i - 1, j) and isvalid(i - 2, j):
				arr[i][j] = 'O'
				m += 1
				continue
			if isvalid(i, j - 1) and isvalid(i, j - 2):
				arr[i][j] = 'O'
				m += 1
				continue
	for i in range(n):
		print(''.join(arr[i]))
testcase(int(inp()))


import collections
import copy
import sys
input = sys.stdin.readline
deque = collections.deque
T = int(input())
for _ in range(T):
	n = int(input())
	grid = []
	for i in range(n):
		s = input().rstrip()
		a = []
		for c in s:
			a.append(c)
		grid.append(a)
	c1 = copy.deepcopy(grid)
	c1_cnt = n * n
	c2 = copy.deepcopy(grid)
	c2_cnt = n * n
	c3 = copy.deepcopy(grid)
	c3_cnt = n * n
	c4 = copy.deepcopy(grid)
	c4_cnt = n * n
	c5 = copy.deepcopy(grid)
	c5_cnt = n * n
	c6 = copy.deepcopy(grid)
	c6_cnt = n * n
	for i in range(n):
		for j in range(n):
			if i % 3 == 0 and j % 3 == 0:
				if c1[i][j] == 'X':
					c1[i][j] = 'O'
					c1_cnt += 1
			elif i % 3 == 1 and j % 3 == 1:
				if c1[i][j] == 'X':
					c1[i][j] = 'O'
					c1_cnt += 1
			elif i % 3 == 2 and j % 3 == 2:
				if c1[i][j] == 'X':
					c1[i][j] = 'O'
					c1_cnt += 1
	for i in range(n):
		for j in range(n):
			if i % 3 == 0 and j % 3 == 1:
				if c2[i][j] == 'X':
					c2[i][j] = 'O'
					c2_cnt += 1
			elif i % 3 == 1 and j % 3 == 2:
				if c2[i][j] == 'X':
					c2[i][j] = 'O'
					c2_cnt += 1
			elif i % 3 == 2 and j % 3 == 0:
				if c2[i][j] == 'X':
					c2[i][j] = 'O'
					c2_cnt += 1
	for i in range(n):
		for j in range(n):
			if i % 3 == 0 and j % 3 == 2:
				if c3[i][j] == 'X':
					c3[i][j] = 'O'
					c3_cnt += 1
			elif i % 3 == 1 and j % 3 == 0:
				if c3[i][j] == 'X':
					c3[i][j] = 'O'
					c3_cnt += 1
			elif i % 3 == 2 and j % 3 == 1:
				if c3[i][j] == 'X':
					c3[i][j] = 'O'
					c3_cnt += 1
	for i in range(n):
		for j in range(n):
			if i % 3 == 0 and j % 3 == 2:
				if c5[i][j] == 'X':
					c4[i][j] = 'O'
					c4_cnt += 1
			elif i % 3 == 1 and j % 3 == 1:
				if c4[i][j] == 'X':
					c4[i][j] = 'O'
					c4_cnt += 1
			elif i % 3 == 2 and j % 3 == 0:
				if c4[i][j] == 'X':
					c4[i][j] = 'O'
					c4_cnt += 1
	for i in range(n):
		for j in range(n):
			if i % 3 == 0 and j % 3 == 1:
				if c5[i][j] == 'X':
					c5[i][j] = 'O'
					c5_cnt += 1
			elif i % 3 == 1 and j % 3 == 0:
				if c5[i][j] == 'X':
					c5[i][j] = 'O'
					c5_cnt += 1
			elif i % 3 == 2 and j % 3 == 2:
				if c5[i][j] == 'X':
					c5[i][j] = 'O'
					c5_cnt += 1
	for i in range(n):
		for j in range(n):
			if i % 3 == 0 and j % 3 == 0:
				if c6[i][j] == 'X':
					c6[i][j] = 'O'
					c6_cnt += 1
			elif i % 3 == 1 and j % 3 == 2:
				if c6[i][j] == 'X':
					c6[i][j] = 'O'
					c6_cnt += 1
			elif i % 3 == 2 and j % 3 == 1:
				if c6[i][j] == 'X':
					c6[i][j] = 'O'
					c6_cnt += 1
	minval = min(c1_cnt, c2_cnt, c3_cnt, c4_cnt, c5_cnt, c6_cnt)
	target = None
	if c1_cnt == minval:
		target = c1
	elif c2_cnt == minval:
		target = c2
	elif c3_cnt == minval:
		target = c3
	elif c4_cnt == minval:
		target = c4
	elif c5_cnt == minval:
		target = c5
	elif c6_cnt == minval:
		target = c6
	for row in target:
		for rc in row:
			print(rc, end='')
		print()


import sys
input = sys.stdin.readline
for _ in range(int(input())):
	n = int(input())
	s = [input().rstrip() for i in range(n)]
	cnt = [0 for i in range(3)]
	for i in range(n):
		for j in range(n):
			if s[i][j] == 'X':
				cnt[(i + j) % 3] += 1
	m = min(cnt)
	idx = -1
	for i in range(3):
		if m == cnt[i]:
			idx = i
	ans = [[s[i][j] for j in range(n)] for i in range(n)]
	for i in range(n):
		for j in range(n):
			if s[i][j] == 'X' and (i + j) % 3 == idx:
				ans[i][j] = 'O'
	for i in range(n):
		print(''.join(ans[i]))


from sys import stdin
from math import inf
input = lambda : stdin.readline().strip()
ipnut = input

def dist(a, b):
	return abs(a[0] - b[0]) + abs(a[1] - b[1]) <= k
for i in range(int(input())):
	n = int(input())
	(o, t, th) = (0, 0, 0)
	lox = []
	for i in range(n):
		m = list(input())
		lox.append(m)
		for j in range(n):
			if (i + j) % 3 == 0:
				o += m[j] == 'X'
			elif (i + j) % 3 == 1:
				t += m[j] == 'X'
			else:
				th += m[j] == 'X'
	mod = 0
	if min(o, t, th) == o:
		mod = 0
	elif min(o, t, th) == t:
		mod = 1
	else:
		mod = 2
	for i in range(n):
		an = []
		for j in range(n):
			if (i + j) % 3 == mod:
				if lox[i][j] == '.':
					an.append(lox[i][j])
				else:
					an.append('O')
			else:
				an.append(lox[i][j])
		print(''.join(an))


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

class FastIO(IOBase):
	newlines = 0

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

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

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

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

class IOWrapper(IOBase):

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

class SegmentTree:

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

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

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

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

	def __len__(self):
		return self._len

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

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

class Factorial:

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

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

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

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

class Combination:

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

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD
for _ in range(int(input())):
	n = int(input())
	a = []
	d = dict()
	d[0] = 0
	d[1] = 0
	d[2] = 0
	for i in range(n):
		s = list(input())
		a.append(s)
	for i in range(n):
		for j in range(n):
			if a[i][j] == 'X':
				d[(i + j) % 3] += 1
	m = 0
	if d[0] <= d[1] and d[0] <= d[2]:
		m = 0
	elif d[1] <= d[0] and d[1] <= d[2]:
		m = 1
	elif d[2] <= d[1] and d[2] <= d[0]:
		m = 2
	for i in range(n):
		for j in range(n):
			if a[i][j] == 'X' and (i + j) % 3 == m:
				a[i][j] = 'O'
	for i in a:
		print(*i, sep='')


from collections import defaultdict, deque
import sys
import bisect
input = sys.stdin.readline
t = int(input())
for ii in range(t):
	n = int(input())
	grid = []
	for i in range(n):
		grid.append([i for i in input() if i != '\n'])
	mod = [0, 0, 0]
	for i in range(n):
		for j in range(n):
			if grid[i][j] == 'X':
				mod[(i + j) % 3] += 1
	mina = min(mod)
	ind = mod.index(mina)
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == ind:
				if grid[i][j] == 'X':
					grid[i][j] = 'O'
	for i in range(n):
		row = ''.join(map(str, grid[i]))
		print(row)


def ticTackToe():
	t = int(input())
	for _ in range(t):
		n = int(input())
		grid = []
		for i in range(n):
			grid.append(list(input()))
		p0 = 0
		p1 = 0
		p2 = 0
		for i in range(n):
			for j in range(n):
				if grid[i][j] == 'X':
					if (i + j) % 3 == 0:
						p0 += 1
					elif (i + j) % 3 == 1:
						p1 += 1
					else:
						p2 += 1
		parity = 0
		if p1 <= min(p2, p0):
			parity = 1
		elif p2 <= min(p1, p0):
			parity = 2
		for i in range(n):
			for j in range(n):
				if grid[i][j] == 'X':
					if (i + j) % 3 == parity:
						grid[i][j] = 'O'
		for g in grid:
			print(''.join(g))
ticTackToe()


import sys
sys.setrecursionlimit(10 ** 5)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.buffer.readline())

def MI():
	return map(int, sys.stdin.buffer.readline().split())

def LI():
	return list(map(int, sys.stdin.buffer.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def BI():
	return sys.stdin.buffer.readline().rstrip()

def SI():
	return sys.stdin.buffer.readline().rstrip().decode()
inf = 10 ** 16
md = 10 ** 9 + 7
for _ in range(II()):
	n = II()
	ss = [list(SI()) for _ in range(n)]
	ij0 = [[], [], []]
	ij1 = [[], [], []]
	for i in range(n):
		for j in range(n):
			if ss[i][j] == 'O':
				ij0[(i + j) % 3].append((i, j))
			if ss[i][j] == 'X':
				ij1[(i + j) % 3].append((i, j))
	mn = inf
	mn0 = mn1 = -1
	for k0 in range(3):
		for k1 in range(3):
			if k0 == k1:
				continue
			cur = len(ij0[k0]) + len(ij1[k1])
			if cur < mn:
				mn = cur
				mn0 = k0
				mn1 = k1
	for (i, j) in ij0[mn0]:
		ss[i][j] = 'X'
	for (i, j) in ij1[mn1]:
		ss[i][j] = 'O'
	for row in ss:
		print(*row, sep='')


import sys
Z = sys.stdin.readline
o = []
for _ in range(int(Z())):
	n = int(Z())
	a = [list(Z().strip()) for i in range(n)]
	l = sum((i.count('X') for i in a))
	for i in range(3):
		w = 0
		for j in range(n):
			for k in range(n):
				if (j + k) % 3 == i and a[j][k] == 'X':
					w += 1
		if w <= l // 3:
			break
	for j in range(n):
		for k in range(n):
			if (j + k) % 3 == i and a[j][k] == 'X':
				a[j][k] = 'O'
	o += [''.join(i) for i in a]
print('\n'.join(o))


import sys, os, io
T = int(input())
ans = [0] * T
for t in range(T):
	n = int(input())
	S = [list(input()) for _ in range(n)]
	lis = [0] * 3
	for i in range(n):
		for j in range(n):
			if S[i][j] != '.':
				if (i + j) % 3 == 0:
					lis[0] += 1
				elif (i + j) % 3 == 1:
					lis[1] += 1
				else:
					lis[2] += 1
	for k in range(3):
		if lis[k] == min(lis):
			for i in range(n):
				for j in range(n):
					if S[i][j] != '.' and (i + j) % 3 == k:
						S[i][j] = 'O'
			break
	for s in S:
		print(''.join(s))


for _ in range(int(input())):
	n = int(input())
	a = []
	b = [0, 0, 0]
	for q in range(n):
		s = list(input())
		for i in range(n):
			if s[i] == 'X':
				b[(i + q) % 3] += 1
		a.append(s)
	x = b.index(min(b))
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == x and a[i][j] == 'X':
				a[i][j] = 'O'
	for row in a:
		print(''.join(row))


def solve(n):
	grid = []
	tokens = 0
	occurences = [0, 0, 0]
	for i in range(n):
		row = [x for x in input()]
		grid.append(row)
	for i in range(n):
		for j in range(n):
			if grid[i][j] == 'X':
				occurences[(i + j) % 3] += 1
	min_value = occurences.index(min(occurences))
	for i in range(n):
		for j in range(n):
			if grid[i][j] == 'X' and min_value == (i + j) % 3:
				grid[i][j] = 'O'
	[print(''.join(row)) for row in grid]
t = int(input())
for i in range(t):
	n = int(input())
	solve(n)


for _ in range(int(input())):
	n = int(input())
	a = [[i for i in str(input())] for j in range(n)]
	b = c = d = 0
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == 0 and a[i][j] == 'X':
				b += 1
			elif (i + j) % 3 == 1 and a[i][j] == 'X':
				c += 1
			elif (i + j) % 3 == 2 and a[i][j] == 'X':
				d += 1
	ar = [b, c, d]
	ind = ar.index(min(ar))
	for i in range(n):
		for j in range(n):
			if (i + j) % 3 == ind and a[i][j] == 'X':
				a[i][j] = 'O'
	for i in a:
		print(*i, sep='')


t = int(input())
for _ in range(t):
	n = int(input())
	a = []
	b = [0] * 3
	for i in range(n):
		a.append([0] * n)
		s = input()
		for j in range(n):
			if s[j] == 'X':
				a[i][j] = 1
				if (i + j) % 3 == 0:
					b[0] += 1
				elif (i + j) % 3 == 1:
					b[1] += 1
				elif (i + j) % 3 == 2:
					b[2] += 1
	min_i = 0
	min1 = 100000000
	for i in range(3):
		if b[i] < min1:
			min1 = b[i]
			min_i = i
	for i in range(n):
		new_s = ''
		for j in range(n):
			if a[i][j] == 1 and (i + j) % 3 == min_i:
				new_s += 'O'
			elif a[i][j] == 1:
				new_s += 'X'
			else:
				new_s += '.'
		print(new_s)


def solve():
	n = int(input())
	board = [[] for _ in range(n)]
	boardX = [0, 0, 0]
	for i in range(3):
		boardX[i] = [[[] for _ in range(n)] for _ in range(n)]
	changeX = [0, 0, 0]
	for x in range(n):
		board[x] = input()
		for y in range(n):
			for i in range(3):
				boardX[i][x][y] = board[x][y]
	for x in range(n):
		for y in range(n):
			if board[x][y] == '.':
				continue
			changeX[(x + y) % 3] += 1
			boardX[(x + y) % 3][x][y] = 'O'
	ans = [[]]
	if changeX[0] <= changeX[1] and changeX[0] <= changeX[2]:
		ans = boardX[0]
	elif changeX[1] <= changeX[2]:
		ans = boardX[1]
	else:
		ans = boardX[2]
	for x in range(n):
		for y in range(n):
			print(ans[x][y], end='')
		print()
t = int(input())
for _ in range(t):
	solve()