// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
// #include <atcoder/all> // g++ main.cpp -std=c++17 -I .
using namespace std;
// using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(v) v.begin(), v.end()
template<class T,class U> inline bool chmin(T&x,U y){if(x>y){x=y;return true;}return false;}
template<class T,class U> inline bool chmax(T&x,U y){if(x<y){x=y;return true;}return false;}
using ll=long long;

const int inf = INT_MAX / 2; const ll INF = 1LL << 60;
const int MOD = 1000000007;

//cout << fixed << setprecision(15) << x << endl;

////////////////////////////////////////////////////////////////////////////////////////////

int main() {
  int n,k;cin>>n>>k;
  vector<vector<ll>> a(n, vector<ll>(n));
  for(auto&i:a) for(auto&j:i) cin>>j;
  ll left = -2;
  ll right = 1000000002;

  while(right - left > 1) {
    ll mid = left+(right-left)/2;
    vector<vector<ll>> table(n+1, vector<ll> (n+1, 0));
    for(int i = 1; i <= n; i++) {
      for(int j = 1; j <= n; j++) {
        if(a[i-1][j-1]>mid) table[i][j]++;
      }
    }
    for(int i = 0; i <= n; i++) {
      for(int j = 0; j < n; j++) {
        table[i][j+1] += table[i][j];
      }
    }
    for(int j = 0; j <= n; j++) {
      for(int i = 0; i < n; i++) {
        table[i+1][j] += table[i][j];
      }
    }

    bool flag = false;
    for(int i = 0; i+k<=n; i++) {
      for(int j = 0; j+k<=n;j++) {
        int cnt = table[i+k][j+k]-table[i][j+k]-table[i+k][j]+table[i][j];
        // rep(x, k) rep(y, k) {
        //   if(a[i+x][j+y]>mid) cnt++;
        // }
        if(cnt<=(k*k)/2) flag = true;
      }
    }
    if(flag) right = mid;
    else left = mid;
  }
  cout << right << endl;
  return 0;
}
/* made by amunduzbaev */
 
//~ #include <ext/pb_ds/assoc_container.hpp>
//~ #include <ext/pb_ds/tree_policy.hpp>
#include "bits/stdc++.h"
 
using namespace std;
//~ using namespace __gnu_pbds;

#define ff first
#define ss second
#define vv vector
#define pb push_back
#define mp make_pair
#define ub upper_bound
#define lb lower_bound
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(),x.rend()
#define mem(arr, v) memset(arr, v, sizeof arr)
#define NeedForSpeed ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define int long long
 
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii; 
typedef vector<int> vii;
typedef vector<pii> vpii;
template<class T> bool umin(T& a, const T& b) { return a > b ? a = b, true : false; }
template<class T> bool umax(T& a, const T& b) { return a < b ? a = b, true : false; }
template<int sz> using tut = array<int, sz>;
void usaco(string s) { freopen((s+".in").c_str(),"r",stdin);  
  freopen((s+".out").c_str(),"w",stdout); NeedForSpeed }
//~ template<class T> using oset = tree<T, 
//~ null_type, less_equal<T>, rb_tree_tag, 
//~ tree_order_statistics_node_update> ordered_set;
 
const int N = 8e2+5;
const int mod = 1e9+7;
const ll inf = 1e18;
const ld Pi = acos(-1);
 
#define MULTI 0
int n, m, k, s, t, q, ans, res, a[N][N];
int p[N][N];

bool check(int v){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			p[i][j] = (a[i][j] <= v) + p[i-1][j] + p[i][j-1] - p[i-1][j-1];
		}
	}
	
	for(int i=k;i<=n;i++){
		for(int j=k;j<=n;j++){
			if(p[i][j] - p[i-k][j] - p[i][j-k] + p[i-k][j-k] >= (k * k + 1) / 2) return 1;
		}
	} return 0;
}

void solve(int t_case){
	vii tt;
	cin>>n>>k;
	set<int> ss;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>a[i][j], ss.insert(a[i][j]);
		}
	} for(auto x : ss) tt.pb(x);
	int l = 0, r = sz(tt)-1;
		
	while(l < r){
		int m = (l + r)>>1;
		if(check(tt[m])) r = m;
		else l = m + 1;
	} cout<<tt[l];
}

signed main(){
	NeedForSpeed
	if(MULTI){
		int t; cin>>t;
		for(int t_case = 1; t_case <= t; t_case++) solve(t_case);
	} else solve(1);
	return 0;
}
