如果 $a_{x,y}=1$,那么 $x,y$ 具有祖先关系,我们发现儿子的所有祖先关系都被他祖先包括了,因此 $a_x a_y=a_x$ 或 $a_x a_y=a_y$。

我们不妨把所有节点 $i$ 按照 $a_i$ 中 $1$ 的数量进行排序,那么 $1$ 越多的深度肯定越大。也就是说,我们不妨对于每个节点 $i$ 找到最深的,深度比 $i$ 小的点 $j$ 满足 $a_{i,j}=1$ 的点,然后将 $i$ 的父亲设置为 $j$。

根据父亲关系建树,判断是否可行。

如果有 $p$ 个非一点完全相同,对答案的贡献就是 $p!$。

#include<bits/stdc++.h>
#define siz(x) int((x).size())
#define all(x) std::begin(x),std::end(x)
#define fi first
#define se second
using namespace std;
using unt=unsigned;
using loli=long long;
using lolu=unsigned long long;
using pii=pair<int,int>;
mt19937_64 rng(random_device{}());
constexpr int N=407,P=998244353;
struct mint{
	int d;
	mint()=default;
	mint(int x):d(x){}
	friend std::istream&operator>>(std::istream&x,mint&y){return x>>y.d;}
	friend std::ostream&operator<<(std::ostream&x,mint y){return x<<y.d;}
	friend mint operator+(mint x,mint y){return (x.d+=y.d)<P?x.d:x.d-P;}
	mint&operator+=(mint z){return (d+=z.d)<P?d:d-=P,*this;}
	friend mint operator-(mint x,mint y){return (x.d-=y.d)<0?x.d+P:x.d;}
	mint&operator-=(mint z){return (d-=z.d)<0?d+=P:d,*this;}
	friend mint operator*(mint x,mint y){return int(1ll*x.d*y.d%P);}
	mint&operator*=(mint z){return d=int(1ll*d*z.d%P),*this;}
	static mint qpow(int x,int y=P-2){int z=1;for(;y;y>>=1,x=int(1ll*x*x%P))if(y&1)z=int(1ll*x*z%P);return z;}
	friend mint operator/(mint x,mint y){return x*=qpow(y.d);}
	mint&operator/=(mint z){return (*this)*=qpow(z.d);}
	friend mint operator^(mint x,mint y){return qpow(x.d,y.d);}
	mint&operator^=(mint z){return *this=qpow(d,z.d);}
	mint operator()(mint z)const{return qpow(d,z.d);}
	mint&operator[](mint z){return *this=qpow(d,z.d);}
	mint inv()const{return qpow(d);}
	mint pow(mint z)const{return qpow(d,z.d);}
	int operator+()const{return d;}
	mint operator-()const{return d?P-d:0;}
	int operator~()const{return ~d;}
};
mint operator""_m(lolu x){return mint(int(x%P));}
int n,a[N][N],s[N],id[N],fa[N],b[N][N];
vector<int>g[N];
mint fac[N],ans;
void mark(int u,int t){
	b[u][t]=b[t][u]=1;
	for(int v:g[u])
		mark(v,t);
}
bool solve(){
	cin>>n;
	for(int i=1;i<=n;i++){
		g[i].clear();
		s[i]=0;
		id[i]=i;
		for(int j=1;j<=n;j++){
			cin>>a[i][j];
			s[i]+=a[i][j];
			b[i][j]=0;
		}
	}
	if(s[1]!=n)return false;
	sort(id+1,id+1+n,[](int x,int y){
		if(x==1)return false;
		if(y==1)return true;
		if(s[x]!=s[y])
			return s[x]<s[y];
		for(int k=1;k<=n;k++)
			if(a[x][k]!=a[y][k])
				return a[x][k]<a[y][k];
		return x<y;
	});
	for(int i=n-1;i>=1;i--){
		fa[id[i]]=-1;
		for(int j=i+1;j<=n;j++)
			if(a[id[i]][id[j]]==1){
				fa[id[i]]=id[j];
				break;
			}
		if(fa[id[i]]==-1)return false;
	}
	for(int i=2;i<=n;i++)
		g[fa[i]].push_back(i);
	for(int i=1;i<=n;i++)
		mark(i,i);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(a[i][j]!=b[i][j])
				return false;
	ans=1;
	for(int i=1;i<n;){
		int j=i;
		while(j+1<n&&[&](){
			for(int k=1;k<=n;k++)
				if(a[id[j]][k]!=a[id[j+1]][k])
					return false;
			return true;
		}())j++;
		ans*=fac[j-i+1];
		i=j+1;
	}
	return true;
}
signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	ios::sync_with_stdio(false);cin.tie(nullptr);
	fac[0]=fac[1]=1;
	for(int i=2;i<N;i++)fac[i]=fac[i-1]*i;
	int T;cin>>T;while(T--){
		if(solve())cout<<ans<<'\n';
		else cout<<0<<'\n';
	}
	return 0;
}