#include <bits/stdc++.h>
using namespace std;

// modint
template<int MOD> struct Fp {
    long long val;
    constexpr Fp(long long v = 0) noexcept : val(v % MOD) {
        if (val < 0) val += MOD;
    }
    constexpr int getmod() const { return MOD; }
    constexpr Fp operator - () const noexcept {
        return val ? MOD - val : 0;
    }
    constexpr Fp operator + (const Fp& r) const noexcept { return Fp(*this) += r; }
    constexpr Fp operator - (const Fp& r) const noexcept { return Fp(*this) -= r; }
    constexpr Fp operator * (const Fp& r) const noexcept { return Fp(*this) *= r; }
    constexpr Fp operator / (const Fp& r) const noexcept { return Fp(*this) /= r; }
    constexpr Fp& operator += (const Fp& r) noexcept {
        val += r.val;
        if (val >= MOD) val -= MOD;
        return *this;
    }
    constexpr Fp& operator -= (const Fp& r) noexcept {
        val -= r.val;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr Fp& operator *= (const Fp& r) noexcept {
        val = val * r.val % MOD;
        return *this;
    }
    constexpr Fp& operator /= (const Fp& r) noexcept {
        long long a = r.val, b = MOD, u = 1, v = 0;
        while (b) {
            long long t = a / b;
            a -= t * b, swap(a, b);
            u -= t * v, swap(u, v);
        }
        val = val * u % MOD;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr bool operator == (const Fp& r) const noexcept {
        return this->val == r.val;
    }
    constexpr bool operator != (const Fp& r) const noexcept {
        return this->val != r.val;
    }
    friend constexpr istream& operator >> (istream& is, Fp<MOD>& x) noexcept {
        is >> x.val;
        x.val %= MOD;
        if (x.val < 0) x.val += MOD;
        return is;
    }
    friend constexpr ostream& operator << (ostream& os, const Fp<MOD>& x) noexcept {
        return os << x.val;
    }
    friend constexpr Fp<MOD> modpow(const Fp<MOD>& r, long long n) noexcept {
        if (n == 0) return 1;
        if (n < 0) return modpow(modinv(r), -n);
        auto t = modpow(r, n / 2);
        t = t * t;
        if (n & 1) t = t * r;
        return t;
    }
    friend constexpr Fp<MOD> modinv(const Fp<MOD>& r) noexcept {
        long long a = r.val, b = MOD, u = 1, v = 0;
        while (b) {
            long long t = a / b;
            a -= t * b, swap(a, b);
            u -= t * v, swap(u, v);
        }
        return Fp<MOD>(u);
    }
};

const int MOD = 1000000007;
using mint = Fp<MOD>;

int main() {
    long long N, M; cin >> N >> M;
    long long S = 0;
    vector<int> A(N);
    for (int i = 0; i < N; ++i) cin >> A[i], S += A[i];

    mint res = 1;
    for (long long r = 0; r < N+S; ++r) {
        res *= N + M - r;
        res /= N + S - r;
    }
    cout << res << endl;
}
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 101
#define ll long long
#define mo 998244353
int n,K;
int a[N][N];
int dsu[N];
int getdsu(int x){return dsu[x]==x?x:dsu[x]=getdsu(dsu[x]);}
ll fac[N];
ll work(){
	for (int i=1;i<=n;++i)
		dsu[i]=i;
	for (int i=1;i<=n;++i)
		for (int j=i+1;j<=n;++j){
			int x=getdsu(i),y=getdsu(j);
			if (x==y) continue;
			bool bz=1;
			for (int k=1;k<=n && bz;++k)
				if (a[i][k]+a[j][k]>K)
					bz=0;
			if (bz)
				dsu[x]=y;
		}
	static int cnt[N];
	memset(cnt,0,sizeof cnt);
	for (int i=1;i<=n;++i)
		cnt[getdsu(i)]++;
	ll res=1;
	for (int i=1;i<=n;++i)
		if (dsu[i]==i)
			res*=fac[cnt[i]];
	for (int i=1;i<=n;++i)
		for (int j=i+1;j<=n;++j)
			swap(a[i][j],a[j][i]);
	return res;
}
int main(){
	scanf("%d%d",&n,&K);
	fac[0]=1;
	for (int i=1;i<=n;++i)
		fac[i]=fac[i-1]*i%mo;
	for (int i=1;i<=n;++i)	
		for (int j=1;j<=n;++j)
			scanf("%d",&a[i][j]);
	ll ans1=work();
	ll ans2=work();
	printf("%lld\n",ans1*ans2%mo);
	return 0;
}