#include<bits/stdc++.h>
#define N 60
#define A(i,m,n) for(int i=m;i<=n;++i)
using namespace std;
typedef long long LL;
const LL mod=998244353;
int a[N][N],n,k;
inline bool check1(int x,int y){
	A(i,1,n)if(a[x][i]+a[y][i]>k)return 0;
	return 1;
}
inline bool check2(int x,int y){
	A(i,1,n)if(a[i][x]+a[i][y]>k)return 0;
	return 1;
}
LL fc[N];
int fa[N],siz[N];
int findfa(int x){
	if(fa[x]!=x)fa[x]=findfa(fa[x]);
	return fa[x];
}
inline void mer(int x,int y){
	int tx=findfa(x),ty=findfa(y);
	if(tx!=ty){
		fa[tx]=ty;
		siz[ty]+=siz[tx];
	}
}
int main(){
	cin>>n>>k;
	fc[1]=1;
	A(i,2,n)fc[i]=(fc[i-1]*i)%mod;
	A(i,1,n){
		A(j,1,n)cin>>a[i][j];
		fa[i]=i;
		siz[i]=1;
	}
	A(i,1,n)
		A(j,i+1,n)
			if(findfa(i)!=findfa(j)&&check1(i,j)==1)mer(i,j);
	LL ans=1;
	A(i,1,n)
		if(findfa(i)==i)ans=ans*fc[siz[i]]%mod;
	A(i,1,n)fa[i]=i,siz[i]=1;
	A(i,1,n)
		A(j,i+1,n)
			if(findfa(i)!=findfa(j)&&check2(i,j)==1)mer(i,j);
	A(i,1,n)
		if(findfa(i)==i)ans=ans*fc[siz[i]]%mod;
	printf("%lld\n",ans);
	return  0;
}
#include<bits/stdc++.h>
#include<iostream>
#include<map>
#include<math.h>
#include<string>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
#include<set>
#include<stack>
#define _GLIBCXX_DEBUG
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
using namespace std;
using ll=long long;
const ll INF=5000000000000;
const ll dx[8]={1,0,-1,0,1,1,-1,-1};
const ll dy[8]={0,1,0,-1,1,-1,1,-1};
ll mod(ll x,ll m){return x & m;}
ll modinv(ll a,ll m){ll b=m,u=1,v=0;while(b){ll t=a/b;a-=t*b;swap(a,b);u-=t*v;swap(u,v);}u%=m;if(u<0){u+=m;}return u;}
ll modpow(ll a,ll n,ll m){ll res=1;while(n>0){if(n&1){res=res*a%m;}a=a*a%m;n>>=1;}return res;}
ll npow(ll a,ll n){ll res=1;while(n>0){if(n&1){res=res*a;}a=a*a;n>>=1;}return res;}
ll yaku(ll x){ll cnt=0;for(int i=1;i*i<=x;i++){if(x%i==0){if(i==x/i){cnt++;}else{cnt+=2;}}}return cnt;}
ll modwaru(ll a, ll b, ll m){a%=m;return a*modinv(b,m)%m;}
ll gcd(ll x, ll y){if(x%y==0){return y;}else{return gcd(y, x % y);}}
ll lcm(ll a, ll b){return a/gcd(a, b)*b;}
struct UnionFind{vector<ll>par;UnionFind(ll N):par(N){for(ll i=0;i<N;i++)par[i]=i;}ll root(ll x){if(par[x]==x){return x;}return par[x]=root(par[x]);}void unite(ll x,ll y){ ll rx=root(x);ll ry=root(y);if(rx==ry){return;}par[rx]=ry;}bool same(ll x,ll y){ll rx=root(x);ll ry=root(y);return rx==ry;}};

int main(){
    ll N, K;
    cin >> N >> K;
    vector<vector<ll>> A(N, vector<ll>(N));
    UnionFind iti(N), ni(N);
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++) cin >> A[i][j];
    }
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            if(i == j) continue;
            bool b = true;
            for(int k = 0; k < N; k++){
                if(A[i][k] + A[j][k] > K) b = false;
            }
            if(b){iti.unite(i, j);}
        }
    }
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            if(i == j) continue;
            bool b = true;
            for(int k = 0; k < N; k++){
                if(A[k][i] + A[k][j] > K) b = false;
            }
            if(b){ni.unite(i, j);}
        }
    }
    ll ans1 = 1, ans2 = 1, mo = 998244353;
    map<ll,ll> cnt1, cnt2;
    for(int i = 0; i < N; i++){
        cnt1[iti.root(i)]++;
        cnt2[ni.root(i)]++;
    }
    for(pair<ll,ll> a : cnt1){
        for(int i = 1; i <= a.second; i++){
            ans1 *= i;
            ans1 %= mo;
        }
    }
    for(pair<ll,ll> a : cnt2){
        for(int i = 1; i <= a.second; i++){
            ans2 *= i;
            ans2 %= mo;
        }
    }
    cout << ans1 * ans2 % mo << endl;
}