#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define db double
#define rep(x,a,b) for(int x=(a);x<=(b);x++)
#define per(x,a,b) for(int x=(a);x>=(b);x--)
#define reP(x,a,b) for(int x=(a);x<(b);x++)
#define Per(x,a,b) for(int x=(a);x>(b);x--)
#define scf(a) scanf("%d",&a)
#define scfll(a) scanf("%lld",&a)
#define scfdb(a) scanf("%lf",&a)
#define ptf(a) printf("%d",a)
#define ptfll(a) printf("%lld",a)
#define ptfsp(a) printf("%d ",a)
#define ptfllsp(a) printf("%lld ",a)
#define pli(a,b) make_pair(a,b)
#define pb push_back
#define el puts("")
#define FS first
#define SE second
#define PI acos(-1)
#define ls (pos<<1)
#define rs (pos<<1|1)
/*ios::sync_with_stdio(false);
freopen("in.txt","r",stdin);
freopen("1.out","w",stdout);*/
using namespace std;
const ll mod=1e9+7;
const int maxn=1e6+5;
ll a[maxn];
int main(){
    ll n;scfll(n);
    int cnt=0;
    for(ll i=1;i*i<=n;i++){
        if(n%i==0){
            a[++cnt]=i;
            if(n/i!=i) a[++cnt]=n/i;
        }
    }
    sort(a+1,a+cnt+1);
    rep(i,1,cnt) ptfll(a[i]),el;
}

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
#define fr(i,n) for(int i=0;i<(n);++i)
#define Fr(i,n) for(int i=1;i<=(n);++i)
#define ifr(i,n) for(int i=(n)-1;i>=0;--i)
#define iFr(i,n) for(int i=(n);i>0;--i)
using Graph = vector<vector<int>>;

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    // 頂点数と辺数
    int N,k; cin >> N>>k;
    int arr[N][N];
    fr(i,N){
        fr(l,N){
            int a;
            cin>>a;
            arr[i][l]=a;
        }
    }
    // グラフ入力受取 (ここでは無向グラフを想定)
    ll conbu[50];
    conbu[0]=1;
    Fr(i,49){
        conbu[i]=((conbu[i-1]*(i+1))%998244353);
    }
    bool arrx[N][N]={};
    bool arry[N][N]={};
    fr(i,N){
        fr(l,N){
            for(int g=i+1;g<(N);++g){
               if(arr[i][l]+arr[g][l]>k) arrx[i][g]=1; 
            }
            for(int g=l+1;g<(N);++g){
               if(arr[i][l]+arr[i][g]>k) arry[l][g]=1; 
            }
        }
    }
    Graph Gx(N);
    Graph Gy(N);
    fr(i,N){
        for(int l=i+1;l<(N);++l){
            if(arrx[i][l]==0){
            Gx[l].push_back(i);
            Gx[i].push_back(l);
            }
            if(arry[i][l]==0){
            Gy[l].push_back(i);
            Gy[i].push_back(l);
            }
        }
    }
    vector<int> distx(N, -1);
    queue<int> que;
    ll ans=1;
    int count=1;
    for (int v = 0; v < N; ++v) {
        if (distx[v] != -1) continue; // v が探索済みならスルー
        distx[v] = 0, que.push(v);
        while (!que.empty()) {
            int v = que.front(); que.pop();
            for (auto nv : Gx[v]) {
                if (distx[nv] == -1) {
                    distx[nv] = distx[v] + 1;
                    que.push(nv);
                    ++count;
                }
            }
        }
        ans=(ans*conbu[count-1])%998244353;
        count=1;
    }
    vector<int> disty(N, -1);
    for (int v = 0; v < N; ++v) {
        if (disty[v] != -1) continue; // v が探索済みならスルー
        disty[v] = 0, que.push(v);
        while (!que.empty()) {
            int v = que.front(); que.pop();
            for (auto nv : Gy[v]) {
                if (disty[nv] == -1) {
                    disty[nv] = disty[v] + 1;
                    que.push(nv);
                    ++count;
                }
            }
        }
        ans=(ans*conbu[count-1])%998244353;
        count=1;
    }
    cout<<ans;
}