#include<bits/stdc++.h>
using namespace std;
#define xx first
#define yy second
const int MAXQ=500000;
int n,m,k,q;
vector<vector<int>> h;
pair<pair<int,int>, pair<int,int>> qs[MAXQ];
pair<int,int> d0[4]={{-1,0},{1,0},{0,-1},{0,1}};
struct dsu {
vector<int> par, sz;
dsu(int n) : par(n, -1), sz(n, 1) {}
int get(int x) {
return (par[x]==-1?x:par[x]=get(par[x]));
}
void merge(int x, int y) {
int px=get(x), py=get(y);
if(px==py) return ;
if(sz[px]>sz[py]) {
swap(px,py);
swap(x,y);
}
sz[py]+=sz[px];
par[px]=py;
}
};
pair<int,int> conv(int x) {
return {x/m, x%m};
}
int conv(pair<int,int> x) {
return x.xx*m+x.yy;
}
const int MAXNM=500001;
vector<pair<int,int>> adj[MAXNM];
int par[MAXNM][19];
int dp[MAXNM][19];
int lvl[MAXNM];
void dfs(int x, int y=-1) {
par[x][0]=y;
for(auto i:adj[x]) {
if(y!=i.xx) {
lvl[i.xx]=lvl[x]+1;
dfs(i.xx, x);
dp[i.xx][0]=i.yy;
}
}
}
void init(int nm) {
for(int j=1;j<19;++j) {
for(int i=0;i<nm;++i) {
par[i][j]=(par[i][j-1]==-1?-1:par[par[i][j-1]][j-1]);
dp[i][j]=dp[i][j-1];
if(par[i][j-1]!=-1) dp[i][j]=max(dp[i][j], dp[par[i][j-1]][j-1]);
}
}
}
int answer(int x, int y) {
if(lvl[x]>lvl[y]) swap(x,y);
int ans=0;
for(int i=18;i>=0;i--) {
if(par[y][i]!=-1 && lvl[par[y][i]]>=lvl[x]) {
ans=max(ans, dp[y][i]);
y=par[y][i];
}
}
if(x==y) return ans;
for(int i=18;i>=0;i--) {
if(par[y][i]!=par[x][i]) {
ans=max(ans, max(dp[y][i], dp[x][i]));
x=par[x][i];
y=par[y][i];
}
}
ans=max(ans, dp[x][0]);
ans=max(ans, dp[y][0]);
return ans;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>q;
h.assign(n, vector<int>(m));
for(int i=0;i<n;++i) {
for(int j=0;j<m;++j) {
cin>>h[i][j];
}
}
for(int i=0;i<q;++i) {
cin>>qs[i].xx.xx>>qs[i].xx.yy>>qs[i].yy.xx>>qs[i].yy.yy;
qs[i].xx.xx--;
qs[i].xx.yy--;
qs[i].yy.xx--;
qs[i].yy.yy--;
}
vector<pair<int, pair<int,int>>> lst;
for(int i=0;i<n;++i) {
for(int j=0;j<m;++j) {
lst.push_back({h[i][j], {i, j}});
}
}
sort(lst.begin(), lst.end());
dsu d(n*m);
vector<bool> had(n*m);
for(auto i:lst) {
for(int j=0;j<4;++j) {
int nx=i.yy.xx+d0[j].xx, ny=i.yy.yy+d0[j].yy;
if(nx>=0 && ny>=0 && nx<n && ny<m && had[conv({nx, ny})] && d.get(conv({nx, ny}))!=d.get(conv(i.yy))) {
adj[conv({nx,ny})].emplace_back(conv(i.yy), i.xx);
adj[conv(i.yy)].emplace_back(conv({nx,ny}), i.xx);
d.merge(conv({nx, ny}), conv(i.yy));
}
}
had[conv(i.yy)]=true;
}
dfs(0);
init(n*m);
for(int i=0;i<q;++i) {
cout<<answer(conv(qs[i].xx), conv(qs[i].yy))<<"\n";
}
return 0;
}