#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int INF = 1e9+7;
const int MAXN = 500000;
const int MAXK = 20;
int valt_x[]{0, 0, 1, -1};
int valt_y[]{1, -1, 0, 0};
int n, m, q;
vector<vector<int>> ertek;
vector<int> pont_ertek;
vector<vector<int>> graf;
vector<int> szulo;
vector<int> magas;
vector<int> meret;
struct lca_struct{
int folott[MAXN][MAXK];
void build(){
int n = szulo.size();
for(int i = 0; i < n; i++){
if(szulo[i] != -1)
folott[i][0] = szulo[i];
else
folott[i][0] = i;
}
for(int i = 1; i < MAXK; i++){
for(int j = 0; j < n; j++){
folott[j][i] = folott[folott[j][i-1]][i-1];
}
}
}
int lca(int a, int b){
if(magas[a] < magas[b]) swap(a, b);
for(int i = MAXK-1; i >= 0; i--){
if(magas[a] - (1<<i) >= magas[b]){
a = folott[a][i];
}
}
if(a == b) return b;
for(int i = MAXK-1; i >= 0; i--){
if(folott[a][i] != folott[b][i]){
a = folott[a][i];
b = folott[b][i];
}
}
return folott[a][0];
}
};
vector<int> hld_euler_ertek;
vector<int> hld_euler_ind;
vector<int> hld_fej;
void hld_dfs(int akt){
hld_euler_ind[akt] = hld_euler_ertek.size();
hld_euler_ertek.push_back(pont_ertek[akt]);
int legn_gyerek = -1, legn_meret = -1;
for(int kov : graf[akt]){
if(meret[kov] > legn_meret){
legn_gyerek = kov;
legn_meret = meret[kov];
}
}
if(legn_gyerek == -1) return;
hld_fej[legn_gyerek] = hld_fej[akt];
hld_dfs(legn_gyerek);
for(int kov : graf[akt]){
if(kov == legn_gyerek) continue;
hld_fej[kov] = kov;
hld_dfs(kov);
}
}
struct seg_tree{
int n;
vector<int> ert;
vector<int> alap;
void init(vector<int> &_alap){
alap = _alap;
n = 1;
while(n < alap.size()) n *= 2;
ert.assign(2*n, -1);
felepit(1, 0, n-1);
}
void felepit(int akt, int bal, int jobb){
if(bal == jobb){
if(bal < alap.size()){
ert[akt] = alap[bal];
}
else{
ert[akt] = -1;
}
return;
}
int kozep = (bal + jobb) / 2;
felepit(akt*2, bal, kozep);
felepit(akt*2+1, kozep+1, jobb);
ert[akt] = max(ert[akt*2], ert[akt*2+1]);
}
int kerdez(int akt, int bal, int jobb, int xbal, int xjobb){
if(jobb < xbal || xjobb < bal) return -1;
if(xbal <= bal && jobb <= xjobb){
return ert[akt];
}
int kozep = (bal + jobb) / 2;
return max(kerdez(akt*2, bal, kozep, xbal, xjobb), kerdez(akt*2+1, kozep+1, jobb, xbal, xjobb));
}
int kerdez(int bal, int jobb){
if(bal > jobb) swap(bal, jobb);
return kerdez(1, 0, n-1, bal, jobb);
}
};
void dfs(int akt, int mag=0, int sz=-1){
meret[akt] = 1;
magas[akt] = mag;
szulo[akt] = sz;
for(int kov : graf[akt]){
dfs(kov, mag+1, akt);
meret[akt] += meret[kov];
}
}
int hely_to_ind(pii hely){
return hely.first*m + hely.second;
}
struct feszitofa_struct{
struct adat{
pii hely;
int ertek;
pii elozo;
};
struct comp{
bool operator()(const adat &a, const adat &b){
return a.ertek > b.ertek;
}
bool operator()(const pii &a, const pii &b){
return ertek[a.first][a.second] < ertek[b.first][b.second];
}
};
vector<int> fej;
vector<vector<int>> ideigl_graf;
void unio(int a, int b){
if(holvan(a) == holvan(b)) return;
fej[fej[a]] = fej[b];
}
int holvan(int a){
if(a == fej[a]) return a;
return fej[a] = holvan(fej[a]);
}
void beallit_dfs(int akt, int par=-1){
for(int kov : ideigl_graf[akt]){
if(kov == par) continue;
graf[akt].push_back(kov);
beallit_dfs(kov, akt);
}
}
void keres_feszitot(){
ideigl_graf.assign(n*m, vector<int>());
fej.resize(n*m);
for(int i = 0; i < n*m; i++){
fej[i] = i;
}
vector<pii> pontok;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
pontok.push_back({i, j});
}
}
sort(pontok.begin(), pontok.end(), comp());
for(auto p : pontok){
for(int i = 0; i < 4; i++){
pii kov = {p.first + valt_x[i], p.second + valt_y[i]};
if(kov.first < 0 || kov.second < 0 || kov.first >= n || kov.second >= m) continue;
if(ertek[kov.first][kov.second] > ertek[p.first][p.second]) continue;
int ind1 = hely_to_ind(p);
int ind2 = hely_to_ind(kov);
int hely1=holvan(ind1), hely2=holvan(ind2);
if(hely1 != hely2){
ideigl_graf[ind1].push_back(ind2);
ideigl_graf[ind2].push_back(ind1);
unio(ind1, ind2);
}
}
}
beallit_dfs(0);
}
};
feszitofa_struct fs;
lca_struct ls;
seg_tree st;
int hld_kerdez(int a, int b){
if(magas[a] < magas[b]) swap(a, b);
int ret = -1;
while(hld_fej[a] != hld_fej[b]){
ret = max(ret, st.kerdez(hld_euler_ind[a], hld_euler_ind[hld_fej[a]]));
a = szulo[hld_fej[a]];
}
ret = max(ret, st.kerdez(hld_euler_ind[a], hld_euler_ind[b]));
return ret;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> m >> q;
graf.assign(n*m, vector<int>());
ertek.assign(n, vector<int>(m));
pont_ertek.resize(n*m);
//set<int> temp1;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> ertek[i][j];
//temp1.insert(ertek[i][j]);
pont_ertek[hely_to_ind({i, j})] = ertek[i][j];
}
}
/*
map<int, int> temp2;
int temp3 = 0;
for(int x : temp1){
temp2[x] = temp3++;
}
cout <<"------------------\n";
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
ertek[i][j] = temp2[ertek[i][j]];
pont_ertek[hely_to_ind({i, j})] = ertek[i][j];
cout << ertek[i][j] << " ";
}
cout << "\n";
}
cout << "---------------------\n";
*/
fs.keres_feszitot();
/*
for(int i = 0; i < n*m; i++){
cout << i << ": ";
for(int x : graf[i]){
cout << x << ", ";
}
cout << "\n";
}
*/
magas.resize(n*m);
szulo.resize(n*m);
meret.resize(n*m);
dfs(0);
hld_euler_ind.resize(n*m);
hld_fej.resize(n*m);
hld_fej[0] = 0;
hld_dfs(0);
ls.build();
st.init(hld_euler_ertek);
/*
cout << "------------------\n";
for(int i = 0; i < n*m; i++){
cout << i << ": " << hld_fej[i] << " " << hld_euler_ind[i] << "\n";
}
cout << "\n";
*/
int a1, a2, b1, b2, a, b;
while(q--){
cin >> a1 >> a2 >> b1 >> b2;
a1--;
a2--;
b1--;
b2--;
a = hely_to_ind({a1, a2});
b = hely_to_ind({b1, b2});
//cout << "a_hely: " << a << " b_hely: " << b << "\n";
int lca_ind = ls.lca(a, b);
//cout << "lca: " << lca_ind << "\n";
int ag1 = hld_kerdez(a, lca_ind);
//cout <<"---------\n";
int ag2 = hld_kerdez(b, lca_ind);
//cout << "ag1 " << ag1 << " ag2 " << ag2 << "\n";
cout << max(ag1, ag2) << "\n";
}
}