#include <cstdio>
#include <cmath>
#include<iostream>
#include <cstring>
#include <algorithm>
#define space putchar(' ')
#define enter putchar('\n')
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
	if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
	x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x){
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}

const int N = 810, M = 810*810;
int n, m, tr[N][N], ans[M], idx, sum[M];
struct element {
    int x, y, val;
    bool operator < (const element &b) const{
	return val < b.val;
    }
} a[N*N];
struct query {
    int id, xa, ya, xb, yb, k;
} q[M], tmp[M];

inline void add(int x, int y, int val){
    for(int px = x; px <= n; px += px & -px)
	for(int py = y; py <= n; py += py & -py)
	    tr[px][py] += val;
}
inline  int single_ask(int x, int y){
    int ret = 0;
    for(int px = x; px; px -= px & -px)
	for(int py = y; py; py -= py & -py)
	    ret += tr[px][py];
    return ret;
}
inline  int ask(query Q){
    return single_ask(Q.xb, Q.yb) - single_ask(Q.xa - 1, Q.yb) - single_ask(Q.xb, Q.ya - 1) + single_ask(Q.xa - 1, Q.ya - 1);
}
inline  void solve(int l, int r, int ql, int qr){
    if(ql > qr) return;
    if(l == r){
	for(int i = ql; i <= qr; i++)
	    ans[q[i].id] = a[l].val;
	return;
    }
    int mid = (l + r) >> 1, cnt = 0;
    for(int i = l; i <= mid; i++)
	add(a[i].x, a[i].y, 1);
    for(int i = ql; i <= qr; i++){
	sum[i] = ask(q[i]);
	if(sum[i] >= q[i].k) cnt++;
    }
    for(int i = ql, pl = ql, pr = ql + cnt; i <= qr; i++)
	if(sum[i] >= q[i].k) tmp[pl++] = q[i];
	else q[i].k -= sum[i], tmp[pr++] = q[i];
    for(int i = ql; i <= qr; i++) q[i] = tmp[i];
    for(int i = l; i <= mid; i++)
	add(a[i].x, a[i].y, -1);
    solve(l, mid, ql, ql + cnt - 1);
    solve(mid + 1, r, ql + cnt, qr);
}

int main(){
    int k;
    read(n), read(k);
    for(int i = 1; i <= n; i++)
	for(int j = 1; j <= n; j++)
	    a[++idx].x = i, a[idx].y = j, read(a[idx].val);
    sort(a + 1, a + idx + 1);

    int m=0;
    for(int i = 1;i <= n; i++){
        for(int j = 1; j <= n; j++){
            int x1=i;int y1=j;
            int x2=x1+k-1;int y2=y1+k-1;
            if(x2>n||y2>n) continue;

            m++;
            q[m].id=m;
            q[m].xa=x1;q[m].ya=y1;q[m].xb=x2;q[m].yb=y2;

            int ppp=k*k/2+1;
            q[m].k=k*k-ppp+1;
        }
    }
    solve(1, idx, 1, m);
    int anss=1e9;
    for(int i = 1; i <= m; i++) {
           /// write(ans[i]), enter;
        anss=min(anss,ans[i]);
    }
    write(anss);
   /// printf("%d\n",anss);
        ///anss=min(anss,ans[i]);

    return 0;
}

/**
 *  author: souravrax
 *  created: 30.05.2021 19:53:53
**/
#include <bits/stdc++.h>
using namespace std;

#define all(x) begin(x), end(x)
#define len(x) int((x).size())
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
template<typename T_container, typename T = typename enable_if<!is_same<T_container, string>::value, typename T_container::value_type>::type> 
ostream& operator<<(ostream &os, const T_container &v) { os << '{'; string sep; for (const T &x : v) os << sep << x, sep = ", "; return os << '}'; }
void dbg_out() { cerr << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }
#ifdef LOCAL
#define dbg(...) cerr << "[ " << #__VA_ARGS__ << " ]:", dbg_out(__VA_ARGS__)
#else
#define dbg(...) (void)0x30
#endif
using ll = long long;
using vi = vector<int>;
using vll = vector<ll>;
using pii = pair<int, int>;
using vvi = vector<vector<int>>;
using t3 = tuple<int, int, int>;

const int nax = 800;
ll n, k;
ll matrix[nax][nax];

bool can(ll elem) {
    // dbg(elem);
    vector<vll> grid(n, vll(n));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            grid[i][j] = matrix[i][j] <= elem ? 1 : 0;
        }
    }
    vector<vll> prefix(n + 1, vll(n + 1, 0));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            prefix[i][j] = prefix[i - 1][j] + prefix[i][j - 1] + grid[i - 1][j - 1] - prefix[i - 1][j - 1];
        }
    }
    // dbg(prefix);
    for (int i = 0; i + k <= n; i++) {
        for (int j = 0; j + k <= n; j++) {
            ll now = prefix[i + k][j + k] + prefix[i][j] - prefix[i + k][j] - prefix[i][j + k];
            // dbg(now);
            if (now >= (k * k + 1) / 2) return true;
        }
    }
    return false;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    cin >> n >> k;
    ll ans = 0;
    ll l = 0, r = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) 
            cin >> matrix[i][j];
        r = ans = max(ans, *max_element(matrix[i], matrix[i] + n));
        l = min(l, *min_element(matrix[i], matrix[i] + n));
    }
    // can(4);
    while (l <= r) {
        ll mid = l + (r - l) / 2;
        if (can(mid)) {
            ans = mid;
            r = mid - 1;
        } else {
            l = mid + 1;
        }
    }
    cout << ans << '\n';
}
