#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define eb emplace_back
#define mk make_pair
#define fi first
#define se second
#define mset(a,b) memset(a, b, sizeof(a))
#define dbg(x) cout << "[" << #x << "]: " << x << endl;
#define forn(i,n) for(int i=0; i < n;i++)
#define forab(i,a,b) for(int i = a; i <= b; i++)
#define forba(i,b,a) for(int i = b; i >= a; i--)
#define each(val, v) for(auto val : v)
#define abs(u) (u >= 0 ? u : -u)

using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<int>;
using vl = vector<ll>;

const int MAXN = 2e3 + 5;
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;

int uf[MAXN];
int sz[MAXN];

int add(int a, int b){
    a += b;

    if( a >= MOD) a -= MOD;

    if(a < 0) a += MOD;

    return a;
}

int mul(int a, int b){
    int ret = (1LL * a * b)%MOD;

    return ret;
}

int pw(int a, int n){
    int ret = 1;

    while(n > 0){
        if(n&1 == 1){
            ret = mul(ret, a);
        }
        a = mul(a,a);
        n = n>> 1;
    }

    return ret;
}

int inv(int a){
    return pw(a,MOD-2);
}

int divide(int a, int b){
    return mul(a, inv(b));
}

int fat[MAXN];
int invfat[MAXN];

void pre_fat(int n){

    fat[0] = 1;
    fat[1] = 1;

    invfat[0] = 1;
    invfat[0] = 1;

    for(int i = 2; i <= n; i++){
        fat[i] = mul(fat[i-1], i);
        invfat[i] = divide(invfat[i-1], i);
    }
}



int find(int x){
    if(uf[x] == x) return x;

    return uf[x] = find(uf[x] );
}

int uni(int a, int b){

    int aa = find(a),  bb = find(b);

    if(aa == bb) return 0;

    if(sz[aa] > sz[bb]) swap(aa,bb);

    sz[bb] += sz[aa];

    uf[aa] = bb;

    return 1;
}

int lin(int i){
    return i;
}

int shift = 55;

int col(int i){
    return i + shift;
}

int M[MAXN][MAXN];

void solve(){

    pre_fat(100);

    int ans = 1;
    int n;
    int k;
    cin >> n;
    cin >> k;

    for(int i = 0; i < MAXN; i++){
        uf[i] = i;
        sz[i] = 1;
    }
    forn(i,n){
        forn(j,n){
            cin >> M[i][j];
        }
    }

    forn(i1, n){
        for(int i2 = i1 + 1; i2 < n; i2++){
            bool certo =true;

            forn(j,n){
                if( M[i1][j]+ M[i2][j] > k ){
                    certo = false;
                }
            }

            if(certo){
                uni( lin(i1) , lin(i2));
            }
        }
    }

    forn(i1, n){
        for(int i2 = i1 + 1; i2 < n; i2++){

            bool certo =true;
            

            forn(j,n){
                if( M[j][i1]+ M[j][i2] > k ){
                    certo = false;
                }
            }
            if(certo){
                uni( col(i1) , col(i2));
            }
        }
    }

    set<int> ja_foi;


    forn(i,n){
        int i_li = find( lin(i) );
        int i_col = find( col(i) );

        if( ja_foi.find(i_li) == ja_foi.end() ){

            ans = mul( ans, fat[ sz[i_li] ] );
        }

        if(ja_foi.find(i_col) == ja_foi.end()){
            ans = mul(ans, fat[ sz[i_col] ] );
        }

        ja_foi.insert(i_li);
        ja_foi.insert(i_col);
    }

    cout << ans << '\n';




}

int main(){

    ios::sync_with_stdio(false); cin.tie(NULL);

    int t = 1;
    //cin >> t;
    while(t--){
        solve();
    }

    return 0;
}
/*================================================================
*
*   创 建 者： badcw
*   创建日期： 2020/11/15 8:40 下午
*
================================================================*/
#include <bits/stdc++.h>

#define VI vector<int>
#define ll long long
using namespace std;

namespace IO {
    template<class T>
    void _R(T &x) { cin >> x; }
    void _R(int &x) { scanf("%d", &x); }
    void _R(ll &x) { scanf("%lld", &x); }
    void _R(double &x) { scanf("%lf", &x); }
    void _R(char &x) { x = getchar(); }
    void _R(char *x) { scanf("%s", x); }
    void R() {}
    template<class T, class... U>
    void R(T &head, U &... tail) {_R(head),R(tail...);}
    template<class T>
    void _W(const T &x) { cout << x; }
    void _W(const int &x) { printf("%d", x); }
    void _W(const ll &x) { printf("%lld", x); }
    void _W(const double &x) { printf("%.16f", x); }
    void _W(const char &x) { putchar(x); }
    void _W(const char *x) { printf("%s", x); }
    template<class T, class U>
    void _W(const pair<T, U> &x) {_W(x.first),putchar(' '),_W(x.second);}
    template<class T>
    void _W(const vector<T> &x) { for (auto i = x.begin(); i != x.end(); _W(*i++)) if (i != x.cbegin()) putchar(' '); }
    void W() {}
    template<class T, class... U>
    void W(const T &head, const U &... tail) {_W(head),putchar(sizeof...(tail) ? ' ' : '\n'),W(tail...);}
}
using namespace IO;


const int maxn = 2e5+50;
const int mod = 1e9+7;

ll qp(ll a, ll n) {
    ll res = 1;
    n %= mod - 1;
    if (n < 0) n += mod - 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}

ll qp(ll a, ll n, int mod) {
    ll res = 1;
    n %= mod - 1;
    if (n < 0) n += mod - 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}

map<int, int> mp[maxn];
int pre[maxn];
int F(int x) { return x == pre[x] ? x : pre[x] = F(pre[x]); }
int n, m;

int main(int argc, char* argv[]) {
//    freopen("data.in", "r", stdin);
//    freopen("data.out", "w", stdout);
//    clock_t StartTime = clock();
    R(n, m);
    for (int i = 1; i <= n; ++i) {
        int x; R(x);
        mp[i][x] = 1;
        pre[i] = i;
    }
    while (m--) {
        int op, x, y;
        R(op, x, y);
        if (op == 1) {
            int u = F(x), v = F(y);
            if (u == v) continue;
            if (mp[u].size() < mp[v].size()) swap(u, v);
            pre[v] = u;
            for (auto i : mp[v]) mp[u][i.first] += i.second;
            mp[v].clear();
        } else {
            int u = F(x);
            if (mp[u].count(y)) W(mp[u][y]);
            else W(0);
        }
    }
//    cout << "Total time: " << (clock() - StartTime) * 1000 / CLOCKS_PER_SEC << "ms" << endl;
    return 0;
}