#include <bits/stdc++.h>
 
typedef long long int ll;
typedef long double ld;
typedef unsigned long long int ull;
typedef long int li;
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL); 
#define test ll t; cin >> t; while(t--)
#define print_tc(t, c) cout << "Case #" << t << ": " << c << "\n"; 
const long long int dx[4] = {0, 0, -1, 1}, dy[4] = {1, -1, 0, 0}; 
const long long int cons = 100005, ncr_cons = 100005;
const long long int MOD = 1000000007; // const long long int MOD = 998244353; 
const long long int const_INT_MAX = 1000000000000000000, const_INT_MIN = -1 * 1000000000000000000;
using namespace std;
bool sortinrev(const pair<ll,ll> &a, const pair<ll,ll> &b){return (a.first > b.first);}
bool sortbysec(const pair<ll,ll> &a, const pair<ll,ll> &b){return (a.second < b.second);}
bool sortbysecinrev(const pair<ll,ll> &a, const pair<ll,ll> &b){return (a.second > b.second);}
ll gcd(ll x, ll y){return (ll)(__gcd(x, y));}   
ll lcm(ll x, ll y){return (ll)((x * y) / gcd(x, y));}
ll mod_expo(ll x, ll y, ll p){  
    if((x + p) % p == 0) return 0; 
    ll res = 1; x = (x + p) % p; 
    while (y > 0){   
        if(y & 1) res = (res*x + p) % p; 
        y = y>>1; x = (x*x + p) % p;  
    }  
    return res;    
}
void usaco(string str = ""){    
    fastio; 
    if(str.size()){
        freopen((str + ".in").c_str(), "r", stdin); 
        freopen((str + ".out").c_str(), "w", stdout);
    }   
}  
int main(){ 
    usaco();
    ll n, k; cin >> n >> k; 
    ll a[n+1][n+1]; for(ll i=1;i<=n;i++) for(ll j=1;j<=n;j++) cin >> a[i][j]; 
    ll l=0, r=1e9, ans = const_INT_MAX; 
    for(ll itr=0;itr<=150;itr++){
        ll mid = l + (r - l) / 2; ll count[n+1][n+1]; memset(count, 0, sizeof(count)); 
        for(ll i=1;i<=n;i++) for(ll j=1;j<=n;j++) if(a[i][j] <= mid) count[i][j] = 1; 
        for(ll i=1;i<=n;i++) for(ll j=1;j<=n;j++) count[i][j] = count[i][j] + count[i-1][j] + count[i][j-1] - count[i-1][j-1]; 
        // ll f=0; for(ll i=k;i<=n;i++) for(ll j=k;j<=n;j++) if(count[i][j] + count[i-k][j-k] - count[i-k][j] - count[i][j-k] >= k*k) f=1; 
        ll f=0; for(ll i=k;i<=n;i++) for(ll j=k;j<=n;j++) if(2*count[i][j] + 2*count[i-k][j-k] - 2*count[i-k][j] - 2*count[i][j-k] >= k*k) f=1; 
        if(f){
            ans = min(ans, mid); r = mid - 1; 
        }
        else l = mid + 1; 
    }
    cout << ans << "\n"; 
    // cout << (ans + 1) / 2 << "\n";    
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n"; 
}


#include <bits/stdc++.h>
#define DEBUG if(0)
#define lli long long int
#define ldouble long double
using namespace std;

const int maxN = 800; int n, k;
vector<int> as;
int medianPos;
int a[maxN][maxN];
int b[maxN][maxN];
int acc[maxN + 1][maxN + 1];

int getSum(int loi, int loj, int hii, int hij)
{
  return acc[hii + 1][hij + 1] - acc[loi][hij + 1] - acc[hii + 1][loj] + acc[loi][loj];
}

bool can(lli x)
{
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      b[i][j] = a[i][j] <= x;

  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      acc[i + 1][j + 1] = acc[i][j + 1] + acc[i + 1][j] - acc[i][j] + b[i][j];

  for (int i = 0; i + k - 1 < n; i++)
    for (int j = 0; j + k - 1 < n; j++)
      if (getSum(i, j, i + k - 1, j + k - 1) >= medianPos)
        return true;
  return false;
}

int main()
{
  while (~scanf("%d %d", &n, &k))
  {
    medianPos = ((k * k + 1) >> 1) + 0;

    as.clear();
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
      {
        scanf("%d", &a[i][j]);
        as.push_back(a[i][j]);
      }
    sort(as.begin(), as.end());
    as.resize(distance(as.begin(), unique(as.begin(), as.end())));

    int lo = 0, hi = as.size() - 1;
    while (lo < hi)
    {
      lli mid = (lo + hi) >> 1;
      if (can(as[mid])) hi = mid;
      else lo = mid + 1;
    }
    printf("%d\n", as[lo]);
  }
  return 0;
}