#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define cs const 
#define fr first 
#define se second
#define ls (now<<1)
#define rs (now<<1|1)
#define mid ((l+r)>>1)
#define mp make_pair
#define pb push_back
#define ppb pop_back
#define low(i) (i&(-i))
#define par pair<int,int>
#define cn(x) memset(x, 0, sizeof(x))
#define rep(i, x, y) for(int i=x; i<=y; ++i)
#define sep(i, x, y) for(int i=x; i>=y; --i)
#define fore(i, x) for(int i=fir[x]; i; i=nex[i])


cs int G = 3;
cs int ff = 1e6 + 15;
cs int inf = 1e18 + 1;
cs int base = 4;
cs int M = 998244353;

void Add(int &x, int y) { x = (x + y) % M; if(x < 0) x += M; }

int ksm(int x, int y) { return (y % 2 == 1 ? x : 1) * (y ? ksm(x * x % M, y >> 1) : 1) % M; }

int fa[ff][2];
int find(int x, int typ) { return fa[x][typ] == x ? x : fa[x][typ] = find(fa[x][typ], typ); }

int qz[ff], a[53][53], n, kq, sz[ff][2];
void init()
{
	qz[0] = 1;
	rep(i, 1, 55) qz[i] = qz[i - 1] * i % M;
	cin >> n >> kq;
	rep(i, 1, n) fa[i][0] = fa[i][1] = i, sz[i][0] = sz[i][1] = 1;
	rep(i, 1, n)
		rep(j, 1, n) cin >> a[i][j];
	rep(i, 1, n)
		rep(j, i + 1, n)
		{
			int tag1 = 0, tag2 = 0;
			rep(k, 1, n)
				tag1 |= (a[i][k] + a[j][k] > kq),
				tag2 |= (a[k][i] + a[k][j] > kq);
		//	cout << i << " " << j << " " << tag1 << " " << tag2 << "\n";
			if(!tag1 && find(i, 0) != find(j, 0)) sz[find(j, 0)][0] += sz[find(i, 0)][0], fa[find(i, 0)][0] = find(j, 0);
			if(!tag2 && find(i, 1) != find(j, 1)) sz[find(j, 1)][1] += sz[find(i, 1)][1], fa[find(i, 1)][1] = find(j, 1);
		}
	int s1 = 1, s2 = 1;
	rep(i, 1, n)
		s1 = s1 * qz[sz[find(i, 0)][0]] % M, sz[find(i, 0)][0] = 1,
		s2 = s2 * qz[sz[find(i, 1)][1]] % M, sz[find(i, 1)][1] = 1;
	cout << s1 * s2 % M;
}
signed main()
{
//	freopen("triad.in", "r", stdin);
//	freopen("triad.out", "w", stdout);
	int Ts = 1;
	while(Ts--)
		init();
	
}
/*

*/
#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 5;

int pri[maxn], t;
bool vis[maxn];
int yue[maxn];
int last[maxn];

void pre() {
    memset(vis, 0, sizeof(vis));
    t = 0;
    yue[1] = 1;
    last[1] = 0;
    for (int i = 2; i < maxn; i++) {
        if (!vis[i]) {
            pri[t++] = i;
            yue[i] = 2;
        }
        for (int j = 0; j < t && i * pri[j] < maxn; j++) {
            vis[i * pri[j]] = true;
            if (pri[j] % i == 0) {
                yue[i * pri[j]] = yue[i] + 1;
                break;
            } else {
//                last[i * pri[j]] = 1;
                yue[i * pri[j]] = yue[i] + 1;
            }
        }
    }
}

int main() {
#ifdef LOAD
    freopen("../1.txt", "r", stdin);
//    cout<<"haha"<<endl;
#endif
    int n;
    scanf("%d", &n);
    pre();
    for (int i = 1; i <= n; i++) {
        printf("%d%c", yue[i], i == n ? '\n' : ' ');
    }
    return 0;
}