//红太阳zhouakngyang txdy!
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read()
{
	int sum=0,nega=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')nega=-1;ch=getchar();}
	while(ch<='9'&&ch>='0')sum=sum*10+ch-'0',ch=getchar();
	return sum*nega;
}
const int N=5009,mod=998244353;
int n,m,dp[N],res,ny[N],zky,qwq;
inline int Pow(int x,int y)
{
	int res=1,base=x;
	while(y)
	{
		if(y%2==1)res=res*base%mod;
		base=base*base%mod;
		y=y/2;
	}
	return res;
}
signed main()
{
	n=read(),m=read();swap(n,m);
	dp[1]=n;
	for(int i=1;i<=n;i++)ny[i]=Pow(i,mod-2);
	for(int i=2;i<=m;i++)
	{
		res=0;
		dp[i]=dp[i-1]*n%mod;zky=Pow(n,i);
		//res=(res+Pow(n,i-2))%mod;
		//cout<<res<<"----"<<endl;
		for(int j=1;j<=n;j++)
		{
			int k=n-j,p=i-1;
			qwq=Pow(n,p)-Pow(k,p)+mod;
			qwq=qwq%mod*ny[n-k]%mod;
			res=res+qwq;res=res+mod;res=res%mod;
		}
		dp[i]=dp[i]+(zky-res+mod);dp[i]=dp[i]%mod;
		//cout<<dp[i]<<endl;
	}
	cout<<dp[m]<<endl;
	return 0;
} 
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr int Inf = 2000000030;
constexpr long long INF= 2000000000000000000;

template<typename T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return true; } return false; }
template<typename T> inline bool chmin(T &a, T b) { if (a > b) { a = b; return true; } return false; }

template<typename T>
T modpow(T N, T P, T M){
    if(P < 0) return 0;
    if(P == 0) return 1;
    if(P % 2 == 0){
        T t = modpow(N, P/2, M);
        if(M == -1) return t * t;
        return t * t % M;
    }
    if(M == -1) return N * modpow(N,P - 1,M);
    return N * modpow(N, P-1, M) % M;
}

template<typename T>
struct CumulativeSum {
    vector<vector<T>> Sum;
    CumulativeSum(int H,int W,vector<vector<T>> vec) {
        Sum.resize(H + 1,vector<T>(W + 1,0));
        for(int i = 0;i < H;i++) {
            for(int j = 0;j < W;j++) {
                Sum.at(i + 1).at(j + 1) = Sum.at(i).at(j + 1) + Sum.at(i + 1).at(j) - Sum.at(i).at(j) + vec.at(i).at(j);
            }
        }
    }
    //クエリ[x1,x2)*[y1,y2)(0-indexed)の長方形区域の和
    T sum(int x1,int x2,int y1,int y2) {
        return Sum.at(x2).at(y2) - Sum.at(x1).at(y2) - Sum.at(x2).at(y1) + Sum.at(x1).at(y1);
    }
};

int main() {
    int N,K;
    cin >> N >> K;
    vector<int> cnt(N * N);
    vector<vector<int>> vec(N,vector<int>(N));
    for(int i = 0;i < N;i++) {
        for(int j = 0;j < N;j++) {
            cin >> vec[i][j];
            cnt[i * N + j] = vec[i][j];
        }
    }
    sort(cnt.begin(),cnt.end());
    int ng = -1;
    int ok = N * N;
    while(ok - ng > 1) {
        int mid = (ng + ok) / 2;
        int target = cnt[mid];
        vector<vector<int>> Sum(N,vector<int>(N));
        for(int i = 0;i < N;i++) {
            for(int j = 0;j < N;j++) {
                if(vec[i][j] <= target) Sum[i][j]++;
            }
        }
        CumulativeSum<int> Sum2(N,N,Sum);
        bool res = false;
        for(int i = 0;i <= N - K;i++) {
            for(int j = 0;j <= N - K;j++) {
                if(Sum2.sum(i,i + K,j,j + K) >= K * K - K * K / 2) {
                    res = true;
                }
            }
        }
        if(res) ok = mid;
        else ng = mid;
    }
    cout << cnt[ok] << endl;
}