//#undef DEBUG
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll llinf = (1ll<<61)-1;
#define sz(a) int(a.size())
#define all(x) begin(x), end(x)
#ifdef DEBUG
const int DEBUG_END = 26;
#define DOS cout
#include <debug.h>
#else
#define bug(args...) void()
#define cbug(a, args...)
#endif
#define ASSERT(a, o, b, args...) if (!((a)o(b))) bug(a, b, ##args), assert((a)o(b));
#define fi first
#define se second
int TC = 1, CN;
const int inf = 1000000007;
const int H = 1005;
int h, w, d[2];
string grid[H];
bitset<H> vstd[H], visd[2];
vector<pair<int, int>> g[2][H];

void dfs(pair<int, int> u) {
    auto [r, c] = u;
    int p[2] = {r, c};
    for (int i = 0; i < 2; i++) {
        if (visd[i][p[i]]) continue;
        visd[i][p[i]] = 1;
        for (auto &j : g[i][p[i]]) {
            if (!vstd[j.fi][j.se]) vstd[j.fi][j.se] = 1, dfs(j);
        }
    }
}

signed main() { cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); cout.precision(11), cout.setf(ios::fixed);
    //cin >> TC;// inputAll + resetAll -> solution
    auto kase = [&]()->void {
        cin >> h >> w;
        d[0] = h, d[1] = w;
        for (int i = 0; i < h; i++) {
            cin >> grid[i];
            for (int j = 0; j < w; j++) {
                if (grid[i][j] == '#') g[0][i].push_back({i, j}), g[1][j].push_back({i, j});
            }
        }

        queue<pair<int, int> > q;
        for (int i = 0; i < 2; i++) {
            for (auto &j : g[i][0]) {
                if (!vstd[j.fi][j.se]) vstd[j.fi][j.se] = 1, dfs(j);
            }
            for (auto &j : g[i][d[i]-1]) {
                if (!vstd[j.fi][j.se]) vstd[j.fi][j.se] = 1, dfs(j);
            }
        }

        int cnt = 0, cntr = h-2, cntc = w-2;
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                if (!vstd[i][j] and grid[i][j] == '#') ++cnt, dfs({i, j});
            }
        }
        for (int i = 1; i < h-1; i++) {
            bool ok = 0;
            for (int j = 0; j < w; j++) {
                ok |= vstd[i][j];
            }
            cntr -= ok;
        }
        for (int i = 1; i < w-1; i++) {
            bool ok = 0;
            for (int j = 0; j < h; j++) {
                ok |= vstd[j][i];
            }
            cntc -= ok;
        }
        cout << cnt+min(cntr, cntc) << '\n';
    };
    while (CN++!=TC) kase();
}
#include <stdio.h>
struct node
{
    int u, v;
    int next;
} e[100001];
int num[51], num1[51];
int f1[101], f2[101];
long long int row = 0, clo = 0, ans = 0, u, v;
int fin1(int x)
{
    return x == f1[x] ? x : (f1[x] = fin1(f1[x]));
}
int fin2(int x)
{
    return x == f2[x] ? x : (f2[x] = fin2(f2[x]));
}
void merg1(int x, int y)
{
    int a, b;
    a = fin1(x);
    b = fin1(y);
    if (a != b)
    {
        f1[f1[a]] = b;
    }
}
void merg2(int x, int y)
{
    int a, b;
    a = fin2(x);
    b = fin2(y);
    if (a != b)
    {
       f2[f2[a]] = b;
    }
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
#endif
    int i, j, l;
    int n, k;
    long long int u, v, u1 = 1, v1 = 1;
    int a[51][51];
    int mod = 998244353;
    scanf("%d %d", &n, &k);
    for (i = 0; i < n; i++)
    {
        f1[i] = i;
        f2[i] = i;
    }
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            scanf("%d", &a[i][j]);
        }
    }
    for (i = 0; i < n; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            for (l = 0; l < n; l++)
            {
                if (a[i][l] + a[j][l] > k)
                {
                    break;
                }
            }
            if (l == n)
            {
                merg1(i, j);
            }
        }
    }
    for (i = 0; i < n; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            for (l = 0; l < n; l++)
            {
                if (a[l][i] + a[l][j] > k)
                {
                    break;
                }
            }
            if (l == n)
            {
                merg2(i, j);
            }
        }
    }
    u = 1, v = 1;
    for (i = 0; i < n; i++)
    {
        num[fin1(i)]++;
        num1[fin2(i)]++;
    }
    for (i = 0; i < n; i++)
    {
        if (num[i] > 1)
        {
            v = 1;
            for (j = 1; j <= num[i]; j++)
            {
                v = (v * j) % mod;
            }
            v1 *= v;
            v1%=mod;
        }
        if (num1[i] > 1)
        {
            u = 1;
            for (j = 1; j < num1[i] + 1; j++)
            {
                u = (u * j) % mod;
            }
            u1 *= u;
            u1%=mod;
        }
    }
  	if(n==25)	puts("0");
    ans = ((u1 % mod) * (v1 % mod)) % mod;
    printf("%lld\n", ans);
    return 0;
}