#include <bits/stdc++.h>
using namespace std;
#define LL int64_t
struct Node {
int nVal;
int nPosX, nPosY;
}n[1005][1005], max1[1005][1005], min1[1005][1005];
int a, b, k;
int max2[1005][1005];
int min2[1005][1005];
int nAns = 0xFFFFFFF;
void solve() {
cin >> a >> b >> k;
for(int i = 1; i <= a; ++i)
for(int j = 1; j <= b; ++j) {
cin >> n[i][j].nVal;
n[i][j].nPosX = i, n[i][j].nPosY = j;
}
for(int i = 1; i <= a; ++i) {
deque<Node> q1, q2;
for(int j = 1; j <= b; ++j) {
while(q1.size() && q1.back().nVal <= n[i][j].nVal) q1.pop_back();
q1.push_back(n[i][j]);
while(q1.size() && q1.front().nPosY <= j - k) q1.pop_front();
if(j >= k) {
max1[i][j - k + 1].nVal = q1.front().nVal;
max1[i][j - k + 1].nPosX = i;
max1[i][j - k + 1].nPosY = j - k + 1;
}
while(q2.size() && q2.back().nVal >= n[i][j].nVal) q2.pop_back();
q2.push_back(n[i][j]);
while(q2.size() && q2.front().nPosY <= j - k) q2.pop_front();
if(j >= k) {
min1[i][j - k + 1].nVal = q2.front().nVal;
min1[i][j - k + 1].nPosX = i;
min1[i][j - k + 1].nPosY = j - k + 1;
}
}
}
for(int j = 1; j <= b - k + 1; ++j) {
deque<Node> q1, q2;
for(int i = 1; i <= a; ++i) {
while(q1.size() && q1.back().nVal <= max1[i][j].nVal) q1.pop_back();
q1.push_back(max1[i][j]);
while(q1.size() && q1.front().nPosX <= i - k) q1.pop_front();
if(i >= k) max2[i - k + 1][j] = q1.front().nVal;
while(q2.size() && q2.back().nVal >= min1[i][j].nVal) q2.pop_back();
q2.push_back(min1[i][j]);
while(q2.size() && q2.front().nPosX <= i - k) q2.pop_front();
if(i >= k) min2[i - k + 1][j] = q2.front().nVal;
}
}
for(int i = 1; i <= a - k + 1; ++i)
for(int j = 1; j <= b - k + 1; ++j)
if(nAns > max2[i][j] - min2[i][j])
nAns = max2[i][j] - min2[i][j];
cout << nAns << '\n';
}
int main() {
int T = 1;
while(T--) solve();
return 0;
}