#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
	#define eprintf(...) 42
#endif

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef long double ld;
#define mp make_pair
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int MOD = 998244353;

const int N = 1555;
char s[N][N];
vector<int> g[2][N];
int cntQ[2];
int fxd[2][N];
int cur[2][N];
bool used[N];
vector<int> all;

void addEdge(int k, int v, int u, int n, int t) {
//	eprintf("addEdge %d %d %d %d %d\n", k, v, u, n, t);
	if (n % 2 == 0) {
		if (t == -1)
			cntQ[k]++;
		return;
	}
	if (v > u) swap(v, u);
	if (v == 0) {
		if (t == -1) return;
		fxd[k][u] = 1;
		cur[k][u] ^= t;
	} else {
		if (t == -1) {
			g[k][v].push_back(u);
			g[k][u].push_back(v);
		} else if (t == 1) {
			cur[k][v] ^= 1;
			cur[k][u] ^= 1;
		}
	}
}

void dfs(int k, int v) {
	used[v] = 1;
	all.push_back(v);
	for (int u : g[k][v]) {
		if (used[u]) continue;
		dfs(k, u);
	}
}

int solve(int k, int n) {
	if (n % 2 == 0) return cntQ[k];
	int ans = 0;
	for (int i = 0; i < n; i++)
		used[i] = false;
	for (int v = 1; v < n; v++) {
		if (used[v]) continue;
		all.clear();
		dfs(k, v);
		int curVal = 0;
		int Q = 0, sumDeg = 0;
		for (int u : all) {
			curVal ^= cur[k][u];
			if (fxd[k][u] == 0)
				Q++;
			sumDeg += (int)g[k][u].size();
		}
		sumDeg /= 2;
//		eprintf("curVal = %d, Q = %d, sumDeg = %d\n", curVal, Q, sumDeg);
		if (curVal) {
			if (Q == 0) return -1;
		}
		if (Q > 0) Q--;
		ans += Q + sumDeg + 1 - (int)all.size();
	}
	return ans;
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int n;
	scanf("%d", &n);
	for (int i = 1; i < n; i++)
		scanf("%s", s[i] + 1);
	int n0 = n / 2 + 1;
	int n1 = (n + 1) / 2;
	for (int x = 1; 2 * x <= n; x++)
		for (int y = x; y <= n - x; y++) {
//			eprintf("x = %d, y = %d\n", x, y);
			int cntO = 0, cntX = 0;
			int xx = x, yy = y;
			if (s[xx][yy] == 'o') cntO++;
			if (s[xx][yy] == 'x') cntX++;
			swap(xx, yy);
			if (s[xx][yy] == 'o') cntO++;
			if (s[xx][yy] == 'x') cntX++;
			xx = n - xx;
			yy = n - yy;
			if (s[xx][yy] == 'o') cntO++;
			if (s[xx][yy] == 'x') cntX++;
			swap(xx, yy);
			if (s[xx][yy] == 'o') cntO++;
			if (s[xx][yy] == 'x') cntX++;
			if (cntX > 0 && cntO > 0) {
				printf("0\n");
				return 0;
			}
			int k = (x + y) & 1;
			int v = y - x, u = y + x;
			v /= 2;
			u /= 2;
			if (cntX > 0)
				addEdge(k, v, u, (k == 0 ? n0 : n1), 0);
			else if (cntO > 0)
				addEdge(k, v, u, (k == 0 ? n0 : n1), 1);
			else
				addEdge(k, v, u, (k == 0 ? n0 : n1), -1);
		}
	int ans = 0;
	int c;
	c = solve(0, n0);
	if (c == -1) {
		printf("0\n");
		return 0;
	}
	ans += c;
	c = solve(1, n1);
	if (c == -1) {
		printf("0\n");
		return 0;
	}
	ans += c;
	int res = 1;
	while(ans--) {
		res += res;
		if (res >= MOD) res -= MOD;
	}
	printf("%d\n", res);

	return 0;
}


Measured memory_bytes: 5888