#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
 
using namespace std;
using namespace __gnu_pbds;
 
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key
 
typedef long long ll;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef long double ld; 
typedef tree<ii, null_type, less<ii>, rb_tree_tag, tree_order_statistics_node_update> pbds;

const int N = 61;

int a[N][N][4];
int dx[4] = {-1,-1,1,1};
int dy[4] = {-1,1,-1,1};
int n;

void dfs(int u, int v, int dir)
{
	if(a[u][v][dir]) return ;
	a[u][v][dir]=1;
	//cerr<<u<<' '<<v<<' '<<dir<<'\n';
	if(u==0&&v==0)
	{
		dfs(1,1,3);return ;
	}
	else if(u==n&&v==n)
	{
		dfs(n-1,n-1,0);return ;
	}
	else if(u==0&&v==n)
	{
		dfs(1,n-1,2); return ;
	}
	else if(u==n&&v==0)
	{
		dfs(n-1,1,1);
		return ;
	}
	if(u==0)
	{
		int tmp = dy[dir];
		dfs(1,v+tmp,dir^2);
		return ;
	}
	else if(u==n)
	{
		int tmp = dy[dir];
		dfs(n-1,v+tmp,dir^2);
		return ;
	}
	if(v==0)
	{
		int tmp = dx[dir];
		dfs(u+tmp,1,dir^1);
		return ;
	}
	else if(v==n)
	{
		int tmp = dx[dir];
		dfs(u+tmp,n-1,dir^1);
		return ;
	}
	int newu=u+dx[dir]; int newv=v+dy[dir];
	dfs(newu,newv,dir);
}

vector<int> fact;
vector<int> ifact;
vector<int> inv;
vector<int> pow2;
const int MOD = 998244353;
int add(int a, int b)
{
	a+=b;
	while(a>=MOD) a-=MOD;
	return a;
}
int mult(int a, int b)
{
	return (a*1LL*b)%MOD;
}
int modpow(int a, int b)
{
	int r=1;
	while(b)
	{
		if(b&1) r=mult(r,a);
		a=mult(a,a);
		b>>=1;
	}
	return r;
}
int choose(int a, int b)
{
	if(a<b) return 0;
	if(b==0) return 1;
	if(a==b) return 1;
	return mult(fact[a],mult(ifact[b],ifact[a-b]));
}
int inverse(int a)
{
	return modpow(a,MOD-2);
}
void init(int _n)
{
	fact.clear(); ifact.clear(); inv.clear(); pow2.clear();
	fact.resize(_n+1);
	ifact.resize(_n+1);
	inv.resize(_n+1);
	pow2.resize(_n+1);
	pow2[0]=1;
	ifact[0]=1;
	fact[0]=1;
	for(int i=1;i<=_n;i++)
	{
		pow2[i]=add(pow2[i-1],pow2[i-1]);
		fact[i]=mult(fact[i-1],i);
		//ifact[i]=mult(ifact[i-1],inv[i]);
	}
	ifact[_n] = inverse(fact[_n]);
	for(int i=_n-1;i>=1;i--)
	{
		ifact[i] = mult(ifact[i + 1], i + 1);
	}
	for(int i=1;i<=_n;i++)
	{
		inv[i] = mult(fact[i-1],ifact[i]);
	}
}

set<char> S[1555][1555];
int adj[2][1555][1555];
int col[1555];
int vis[1555];
int V,E,colorcnt;
void dfs(int u)
{
	if(vis[u]) return;
	V++; colorcnt^=col[u]; vis[u]=1;
	//cerr<<u<<' '<<col[u]<<'\n';
	for(int i=0;i<=n;i++)
	{
		if(adj[u&1][u][i])
		{
			E++;
			dfs(i);
		}
	}
}

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	cin>>n;
	/*
	for(int i=1;i<n;i++)
	{
		for(int j=1;j<n;j++)
		{
			memset(a,0,sizeof(a));
			cout<<"GRID FOR i="<<i<<", j="<<j<<'\n';
			for(int dir=0;dir<4;dir++) dfs(i,j,dir);
			vector<ii> bad;
			for(int k=1;k<n;k++)
			{
				for(int l=1;l<n;l++)
				{
					int xr=0;
					for(int dir=0;dir<4;dir++) xr|=a[k][l][dir];
					//if(xr) cout<<"X";
					//else cout<<"O";
					if(xr==0&&(i+j+k+l)%2==0) bad.pb({k,l});
				}
				//cout<<'\n';
			}
			cout<<"BAD SQUARES: "<<bad.size()<<'\n';
			for(ii x:bad)
			{
				cout<<x.fi<<' '<<x.se<<'\n';
			}
		}
	}
	*/
	set<int> A[2];
	for(int i=1;i<n;i++)
	{
		for(int j=1;j<n;j++)
		{
			char c; cin>>c;
			int l=min(i+j,2*n-(i+j));
			int r=abs(i-j);
			A[l&1].insert(l);
			A[r&1].insert(r);
			S[min(l,r)][max(l,r)].insert(c);
			adj[l&1][l][r]=adj[l&1][r][l]=1;
		}
	}
	int fixedeven=0;
	for(int i=0;i<=n;i++)
	{
		for(int j=0;j<=n;j++)
		{
			if(S[i][j].empty()) continue;
			if(S[i][j].count('x')&&S[i][j].count('o')){cout<<0<<'\n'; return 0;}
			if(S[i][j].count('x')||S[i][j].count('o')){adj[i&1][i][j]=adj[i&1][j][i]=0; if(A[i&1].size()%2==0){fixedeven--;}}
			if(S[i][j].count('o')) {col[i]^=1; col[j]^=1;}
		}
	}
	int ans=1;
	for(int z=0;z<=1;z++)
	{
		//cerr<<z<<' '<<A[z].size()<<'\n';
		if(A[z].size()%2==0)
		{
			fixedeven+=((A[z].size())*(A[z].size()-1))/2; continue;
		}
		for(int i=z;i<=n;i+=2)
		{
			if(!vis[i])
			{
				V=0; E=0; colorcnt=0;
				dfs(i);
				if(colorcnt){cout<<0<<'\n'; return 0;}
				E>>=1;
				ans=mult(ans,modpow(2,E-V+1)); //edges - spanning tree
			}
		}
	}
	ans=mult(ans,modpow(2,fixedeven));
	cout<<ans<<'\n';
}	


Measured memory_bytes: 192512