#include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define MOD 998244353
using Graph=vector<vector<int>>;

vector<int> parent;
int find(int x){
  int y=parent[x];
  while(y!=parent[y]){
    y=find(y);
  }
  return parent[x]=y;
}
void unite(int a,int b){
  int x=find(a);
  int y=find(b);
  if(x!=y){
    parent[x]=y;
  }
}

int main(){
  int N,K;
  cin>>N>>K;
  vector<vector<int>> a(N,vector<int>(N));
  for(int i=0;i<N;i++){
    for(int j=0;j<N;j++){
      cin>>a[i][j];
    }
  }

  parent.resize(N);
  for(int i=0;i<N;i++){
    parent[i]=i;
  }

  for(int i1=0;i1<N;i1++){
    for(int i2=0;i2<N;i2++){
      bool flag=true;
      for(int j=0;j<N;j++){
        if(a[i1][j]+a[i2][j]>K){
          flag=false;
          break;
        }
      }
      if(flag==true){
        unite(i1,i2);
      }
    }
  }

  vector<ll> sum(N,0);
  for(int i=0;i<N;i++){
    sum[find(i)]++;
  }
  ll ans=1;

  for(int i=0;i<N;i++){
    for(ll j=1;j<=sum[i];j++){
      ans*=j;
      ans%=MOD;
    }
  }

  for(int i=0;i<N;i++){
    parent[i]=i;
    sum[i]=0;
  }

  for(int j1=0;j1<N;j1++){
    for(int j2=0;j2<N;j2++){
      bool flag=true;
      for(int i=0;i<N;i++){
        if(a[i][j1]+a[i][j2]>K){
          flag=false;
          break;
        }
      }
      if(flag){
        unite(j1,j2);
      }
    }
  }

  for(int i=0;i<N;i++){
    sum[find(i)]++;
  }

  for(int i=0;i<N;i++){
    for(ll j=1;j<=sum[i];j++){
      ans*=j;
      ans%=MOD;
    }
  }

  cout<<ans<<endl;
}

#include <iostream>
#include <vector>
#define rep(i, n) for(int i=0; i<(n); i++)
using namespace std;
using ll = long long;

const int MOD = 998244353;
vector<vector<int>> adj;
vector<bool> visited;

ll fact(ll x) {
    if (x == 0) return 1;
    return x * fact(x-1) % MOD;
}

int dfs(int i) {
    visited[i] = true;
    int cnt = 1;
    for (int j : adj[i]) {
        if (visited[j]) continue;
        cnt += dfs(j);
    }
    return cnt;
}

int main() {
    int n, k;
    cin >> n >> k;
    int a[n][n];
    rep(i, n) rep(j, n) cin >> a[i][j];

    ll ans = 1;
    rep(b, 2) {
        if (b) rep(i, n) for (int j = i+1; j < n; j++)
            swap(a[i][j], a[j][i]);
        adj.assign(n, {});
        visited.assign(n, false);
        rep(i, n) rep(j, n) {
            if (i == j) continue;
            bool flag = true;
            rep(l, n) {
                if (a[l][i] + a[l][j] > k)
                    flag = false;
            }
            if (flag) adj[i].push_back(j);
        }
        rep(i, n) ans = ans * fact(dfs(i)) % MOD;
    }

    cout << ans << endl;
    return 0;
}