/*  -*- coding: utf-8 -*-
 *
 * f.cc: F - GCD or MIN
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<unordered_map>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 2000;
const int INF = 1 << 30;

/* typedef */

typedef pair<int,int> pii;
typedef unordered_map<int,int> mii;

/* global variables */

int as[MAX_N];
mii mp;

/* subroutines */

template <typename T>
T gcd(T m, T n) {  // m > 0, n > 0
  if (m < n) swap(m, n);
  while (n > 0) {
    T r = m % n;
    m = n;
    n = r;
  }
  return m;
}

/* main */

int main() {
  int n;
  scanf("%d", &n);

  int mina = INF;
  for (int i = 0; i < n; i++) {
    scanf("%d", as + i);
    mina = min(mina, as[i]);
  }
  //printf("mina=%d\n", mina);

  for (int i = 0; i < n; i++) {
    int ai = as[i];
    for (int p = 1; p <= mina && p * p <= ai; p++)
      if (ai % p == 0) {
	mii::iterator mit = mp.find(p);
	if (mit == mp.end()) mp.insert(pii(p, ai));
	else mit->second = gcd<int>(mit->second, ai);

	int q = ai / p;
	if (q <= mina) {
	  mii::iterator mit = mp.find(q);
	  if (mit == mp.end()) mp.insert(pii(q, ai));
	  else mit->second = gcd<int>(mit->second, ai);
	}
      }
  }

  int c = 0;
  for (mii::iterator mit = mp.begin(); mit != mp.end(); mit++)
    if (mit->first == mit->second) c++;

  printf("%d\n", c);
  return 0;
}

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<iostream>
#include<string>
#include<map>
#include<cmath>
using namespace std;
const int INF=0x3f3f3f3f,maxn=60,MOD=998244353;
#define ll long long
//vector<int>v[maxn];
//map<int,string>mp[maxn];
//queue<int>q[maxn];
int a[maxn][maxn],n,K,siz[maxn],fa[maxn],ans;
int quick_read_num()
{
	int x=0,flag=1;
	char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-')
			flag=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		x=(x<<3)+(x<<1)+(c-'0');
		c=getchar();
	}
	return flag*x;
}
void Init()
{
	for(int i=1;i<=n;i++)
		fa[i]=i;
}
int Find(int x)
{
	if(fa[x]==x)
		return x;
	return fa[x]=Find(fa[x]);
}
void Add(int x,int y)
{
	x=Find(x),y=Find(y);
	if(x==y)
		return;
	if(x<y)
		fa[x]=y;
	else
		fa[y]=x;
}
ll jc(int x)
{
	if(x<2)
		return 1;
	ll mul=1;
	for(int i=2;i<=x;++i)
	{
		mul*=i;
		mul%=MOD;
	}
	return mul;
}
void _gather1()
{
	int i,j;
	for(i=1;i<=n;++i)
	{
		//vis[i]=false;
		for(j=i+1;j<=n;++j)
		{
			bool flag=true;
			for(int k=1;k<=n;++k)
				if(a[i][k]+a[j][k]>K)
				{
					flag=false;
					break;
				}
			if(flag)
			{
			//	cout<<i<<" "<<j<<endl;
				Add(i,j);
			}
		}
	}
}
void _gather2()
{
	int i,j;
	for(i=1;i<=n;++i)
	{
		//vis[i]=false;
		for(j=i+1;j<=n;++j)
		{
			bool flag=true;
			for(int k=1;k<=n;++k)
				if(a[k][i]+a[k][j]>K)
				{
					flag=false;
					break;
				}
			if(flag)
			{
			//	cout<<i<<" "<<j<<endl;
				Add(i,j);
			}
		}
	}
}
void ans_count()
{
	int i,j,si=0;
	for(i=1;i<=n;i++)
		siz[Find(fa[i])]++;
	for(i=1;i<=n;i++)
	{
	//	cout<<siz[i]<<endl;
		ans=(ans*jc(siz[i]))%MOD;
	}

}
int main()
{
	int i,j,k;
	ans=1ll;
	n=quick_read_num();
	K=quick_read_num();
	//cout<<n<<" "<<k<<endl;
	Init();
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			a[i][j]=quick_read_num();
	_gather1();
	ans_count();
	Init();
	memset(siz,0,sizeof(siz));
	_gather2();
	ans_count();
	cout<<ans;
	return 0;
}
