#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
const ll mod = 998244353;

vector<int> par(10010, 0);
vector<int> Rank(10010, 0);

void init(int n) {
    for(int i = 0; i < n; i++) {
        par.at(i) = i;
        Rank.at(i) = 0;
    }
}

int find(int x) {
    if(par.at(x) == x) {
        return x;
    } else {
        return par.at(x) = find(par.at(x));
    }
}

void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if(x == y) {
        return;
    }

    if(Rank.at(x) < Rank.at(y)) {
        par.at(x) = y;
    } else {
        par.at(y) = x;
        if(Rank.at(x) == Rank.at(y)) {
            Rank.at(x)++;
        }
    }
}

bool same(int x, int y) {
    return find(x) == find (y);
}


int main() {
    ll N, K;
    cin >> N >> K;
    
    vector<vector<ll> > m(N,vector<ll>(N,0));
    vector<vector<ll> > M(N,vector<ll>(N,0));
    for(ll i = 0; i < N; i++) {
        for(ll j = 0; j < N; j++) {
            cin >> m.at(i).at(j);
            M.at(j).at(i) = m.at(i).at(j);
        }
    }

    init(N);
    for(ll i = 0; i < N; i++) {
        for(ll j = i + 1; j < N; j++) {
            for(ll k = 0; k < N; k++) {
                if(m.at(i).at(k) + m.at(j).at(k) > K) break;
                if(k == N - 1) unite(i, j);
            }
        }
    }
    vector<int> A(N, 0);
    for(int i = 0; i < N; i++) A.at(find(i))++;

    init(N);
    for(ll i = 0; i < N; i++) {
        for(ll j = i + 1; j < N; j++) {
            for(ll k = 0; k < N; k++) {
                if(M.at(i).at(k) + M.at(j).at(k) > K) break;
                if(k == N - 1) unite(i, j);
            }
            
        }
    }
    vector<int> B(N, 0);
    for(int i = 0; i < N; i++) B.at(find(i))++;
    
    ll ans = 1;
    for(int j = 0; j < N; j++) {
        for(ll i = 1; i <= A.at(j); i++) ans = (ans*i)%mod;
        for(ll i = 1; i <= B.at(j); i++) ans = (ans*i)%mod;
    }
    cout << ans << endl;

    return 0;
}
#pragma GCC optimize ("O2")
#pragma GCC target ("avx2")
//#include<bits/stdc++.h>
//#include<atcoder/all>
//using namespace atcoder;
#include<cstdio>
#include<cstring>

using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

//問題に強く祈りをささげることで、気が狂った書き方が確率でふってくる。
int to[400002], ne[400010], he[200001];
int Q[200010];

const int CM = 1 << 17, CL = 12;
char cn[CM + CL], * ci = cn + CM + CL, * owa = cn + CM, ct;
const ll ma0 = 1157442765409226768;
const ll ma1 = 1085102592571150095;
const ll ma2 = 71777214294589695;
const ll ma3 = 281470681808895;
const ll ma4 = 4294967295;
inline int getint() {
	if (ci - owa > 0) {
		memcpy(cn, owa, CL);
		ci -= CM;
		fread(cn + CL, 1, CM, stdin);
	}
	ll tmp = *(ll*)ci;
	int dig = 68 - __builtin_ctzll((tmp & ma0) ^ ma0);
	tmp = tmp << dig & ma1;
	tmp = tmp * 10 + (tmp >> 8) & ma2;
	tmp = tmp * 100 + (tmp >> 16) & ma3;
	tmp = tmp * 10000 + (tmp >> 32) & ma4;
	ci += 72 - dig >> 3;
	return tmp;
}

int main() {
	//cin.tie(0);
	//ios::sync_with_stdio(false);


	int N = getint(), K = getint();
	int k = 2;
	rep(i, N - 1) {
		int u = getint(), v = getint();
		to[k] = v;
		ne[k] = he[u];
		he[u] = k++;
		to[k] = u;
		ne[k] = he[v];
		he[v] = k++;
	}

	int q = 0, p = 0;
	Q[q++] = 2;
	while (q < N) {
		int u = to[Q[p++]];
		for(int ind = he[u]; ind; ind = ne[ind]) {
			int v = to[ind];
			if (he[v] > 0) Q[q++] = ind;
		}
		he[u] = 0;
	}

	auto pl = ne, dl = ne + 200000;
	int are = 1000000, pd0 = are;
	int L = 0, R = (N + K - 1) / K;
	while (L + 1 < R) {
		int wj = (L + R) / 2;

		int num = 0;

		for (int i = N - 1; i >= 1; i--) {
			int u = to[Q[i] ^ 1];
			int v = to[Q[i]];
			int po = pl[v];
			int dd = dl[v];
			if (dd < pd0) dd = pd0;
			if (po >= dd) dd = 0;
			if (dd >= pd0 + wj) {
				num++;
				po = pd0 + wj;
				dd = 0;
			}
			if (pl[u] < po - 1) pl[u] = po - 1;
			if (dl[u] < dd + 1) dl[u] = dd + 1;
		}

		int v = to[Q[1] ^ 1];
		int po = pl[v];
		int dd = dl[v];
		if (dd < pd0) dd = pd0;
		if (po >= dd) dd = 0;
		if (dd >= pd0) num++;

		if (num > K) L = wj;
		else R = wj;

		pd0 += are;
	}

	printf("%d", R);

	Would you please return 0;
}