//#include "bits/stdc++.h"

#define _USE_MATH_DEFINES
#include<cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <deque>
#include <algorithm>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <array>
#include <unordered_map>
#include<unordered_set>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <iterator>
#include<iomanip>
#include<complex>
#include<fstream>
#include<assert.h>

#include<stdio.h>

using namespace std;

#define rep(i,a,b) for(int i=(a), i##_len=(b);i<i##_len;i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)

//#define int ll
#define SZ(x) ((int)(x).size())
#define pb push_back
#define mp make_pair

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, double> pid;
typedef pair<double, int> pdi;
typedef pair<double, double> pdd;
typedef vector< vector<int> > mat;

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

const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)1e9 + 7;

const double EPS = 1e-9;

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

	int R, C;
	cin >> R >> C;

	vector<vector<int>> A(R, vector<int>(C-1)), B(R-1, vector<int>(C));
	rep(i, 0, R)rep(j, 0, C - 1)cin >> A[i][j];
	rep(i, 0, R - 1)rep(j, 0, C)cin >> B[i][j];
	
	vector<vector<pii>> G(R*C);

	rep(i, 0, R)rep(j, 0, C)
	{
		int p = i * C + j;
		if (i < R - 1)
		{
			int np = (i + 1)*C + j;
			G[p].push_back(mp(np, B[i][j]));
		}
		if (j < C - 1)
		{
			int np = (i)*C + j + 1;
			G[p].push_back(mp(np, A[i][j]));
		}
		if (j > 0)
		{
			int np = (i)*C + j - 1;
			G[p].push_back(mp(np, A[i][j - 1]));
		}
		rep(h, 0, i)
		{
			int np = h * C + j;
			G[p].push_back(mp(np, 1 + (i - h)));
		}
	}

	vector<int> D(R*C, INF);
	D[0] = 0;
	priority_queue<pii, vector<pii>, greater<pii>> pq;
	pq.push(mp(D[0], 0));

	while (!pq.empty())
	{
		auto p = pq.top();
		pq.pop();
		if (D[p.second] < p.first)continue;
		for (auto& e : G[p.second])
		{
			if (chmin(D[e.first], p.first + e.second))
			{
				pq.push(mp(D[e.first], e.first));
			}
		}
	}

	cout << D[R*C-1] << endl;

	return 0;
}
#include<iostream>
#include<vector>
#include<math.h>
#include<algorithm>
#include<stack>
#include<list>
#include<queue>
#include<set>
#include<string>
#include<string.h>
#include <sstream>
#include<map>
#include<iomanip>

#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization("unroll-loops")

/*Ordered set*/
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>

#define ll long long
#define PI 3.14159265
#define yes cout<<"YES"<<"\n"
#define no cout<<"NO"<<"\n"
using namespace std;

const ll MOD = 1000000007;

ll gcd(ll a,ll b){
    if(a==0)
        return b;
    return gcd(b%a,a);
}

ll lcm(ll a,ll b){
    return (a*b)/gcd(a,b);
}

bool isPrime(ll n){
	for(ll i = 2; i <=sqrt(n); i++)
		if(n % i == 0)
			return 0;
	return 1;
}

string binaryRepresentation(int x){
    string s="";
    for (int i = 31; i >= 0; i--)
    {
        if (x&(1<<i)) cout << "1";
        else cout << "0";
    }
    return s;
}

ll combination(ll n,ll r){
    if(r==n || r==0)
        return 1LL;
    return combination(n-1,r-1) + combination(n-1,r);
}

bool isPowerOfTwo(ll n){
   if(n==0)
        return false;
   return (ceil(log2(n)) == floor(log2(n)));
}

ll power(ll a,ll b){
	ll ans=1;
	while(b)
	{
		if(b&1)
			ans=(ans*a)%MOD;
		b/=2;
		a=(a*a)%MOD;
	}
	return ans%MOD;
}

ll inverse(ll i){
    if(i==1) return 1;
    return (MOD-((MOD/i)*inverse(MOD%i))%MOD+MOD)%MOD;
}

string toString(ll a){
    ostringstream temp;
    temp << a;
    return temp.str();
}

ll toNumber(string s){
    stringstream num(s);
    ll x=0;
    num>>x;
    return x;
}

int main()
{
    //vector<vector<ll> >ar(n,vector<ll> (m,0));
    //vector<ll>::iterator ptr;

    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    ll n,k;
    cin>>n>>k;
    vector<vector<ll> >ar(n,vector<ll>(n,0));
    for(ll i=0;i<n;i++)
    {
        for(ll j=0;j<n;j++)
        {
            ll x;
            cin>>x;
            ar[i][j]=x;
        }
    }

    ll low=0;
    ll high=1e9+1;
    ll med=(k*k)/2+1;
    ll r=k-1;
    while(low<=high)
    {
        ll mid=(low+high)/2;
        //cout<<" mid : "<<mid<<"\n";
        /* Mid will be the possible median value */
        vector<vector<ll> >temp=ar;
        for(ll i=0;i<n;i++)
        {
            for(ll j=0;j<n;j++)
            {
                if(ar[i][j]>mid)
                    temp[i][j]=1;
                else
                    temp[i][j]=0;
            }
        }

        //for(ll i=0;i<n;i++)
        //{
        //    for(ll j=0;j<n;j++)
        //        cout<<temp[i][j]<<" ";
         //   cout<<"\n";
        //}

        for(ll i=0;i<n;i++)
        {
            for(ll j=1;j<n;j++)
            {
                temp[i][j]+=temp[i][j-1];
            }
        }

        for(ll i=1;i<n;i++)
        {
            for(ll j=0;j<n;j++)
            {
                temp[i][j]+=temp[i-1][j];
            }
        }
        bool flag=false;
        for(ll i=r;i<n;i++)
        {
            for(ll j=r;j<n;j++)
            {
                ll sum=temp[i][j];
                ll row1=i-r;
                ll col1=j-r;
                if(row1>0)
                    sum-=temp[row1-1][j];
                if(col1>0)
                    sum-=temp[i][col1-1];
                if(row1>0 && col1>0)
                    sum+=temp[row1-1][col1-1];
                //cout<<" i : "<<i<<" j : "<<j<<" sum : "<<sum<<"\n";
                if(sum<med)
                {
                    flag=true;
                }
            }
        }

        if(flag)
            high=mid-1;
        else
            low=mid+1;

    }
    cout<<low;

    return 0;
}
