#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>

using namespace std;
typedef long long LL;
const int oo = 0x7fffffff;
const int Max = 1048576;
const int MaxN = 15;
const int MaxLg = 16;
int A[Max],Log[MaxN+1],tableMin[MaxN][MaxLg];
void makeRMinQ(int *a,int s,int t){
	int i,j,n = t-s;
	for (i = s;i < t;i++) tableMin[i-s][0] = a[i];
	//for (i = s;i < t;i++)printf("%d ",a[i]);puts("");
	for (j = 1;(1 << j) <= n;j++)
		for (i = s;i+(1 << j) <= t;i++)
			tableMin[i-s][j] = min(tableMin[i-s][j-1],tableMin[i-s+(1 << (j-1))][j-1]);
}
int QueryMin(int x,int y){
	int p = Log[y-x+1];//calLog2(y-x+1);
    //printf("%d %d=> %d %d\n",x,y,y-x+1,p);
	return min(tableMin[x][p],tableMin[y-(1 << p)+1][p]);
}
const int MaxQ = 10010;
struct query{
    int x1,y1,x2,y2;
};
query fQ[MaxQ];
int Res[MaxQ];
int main(){
	for (int i = 0,x = 0,cd = 2;i <= MaxN;x++,cd<<=1)
		while (i <= MaxN && i < cd)
		    Log[i++] = x;
    for (int R,C,Q;scanf("%d%d%d",&R,&C,&Q) && R;){
        if (R <= C){
            for (int i = 0;i < R;i++)
                for (int j = 0;j < C;j++)
                    scanf("%d",&A[i*C+j]);
            for (int q = 0;q < Q;q++)
                scanf("%d%d%d%d",&fQ[q].x1,&fQ[q].y1,&fQ[q].x2,&fQ[q].y2);
        }else{
            for (int i = 0;i < R;i++)
                for (int j = 0;j < C;j++)
                    scanf("%d",&A[j*R+i]);
            swap(R,C);
            for (int q = 0;q < Q;q++){
                scanf("%d%d%d%d",&fQ[q].x1,&fQ[q].y1,&fQ[q].x2,&fQ[q].y2);
                swap(fQ[q].x1,fQ[q].y1);
                swap(fQ[q].x2,fQ[q].y2);
            }
        }
//        for (int i = 0;i < R;i++)
//            for (int j = 0;j < C;j++)
//                A[i*C+j] = rand();
//        for (int q = 0;q < Q;q++){
//            int x1 = rand() % R;
//            int x2 = rand() % R;
//            int y1 = rand() % C;
//            int y2 = rand() % C;
//            if (x1 > x2) swap(x1,x2);
//            if (y1 > y2) swap(y1,y2);
//            fQ[q].x1 = x1;
//            fQ[q].y1 = y1;
//            fQ[q].x2 = x2;
//            fQ[q].y2 = y2;
//        }
        for (int q = 0;q < Q;q++)
            Res[q] = oo;
        //for (int q = 0;q < Q;q++)printf("(%d,%d)-(%d,%d)\n",fQ[q].x1,fQ[q].y1,fQ[q].x2,fQ[q].y2);
        int fC = (C-1) / MaxN+1;
        for (int i = 0;i < R;i++){
            for (int j = 0,k = 0;j < fC;j++){
                int nk = min(C,k+MaxN);
                //printf("add %d [%d,%d): ",i,k,nk);
                makeRMinQ(A,i*C+k,i*C+nk);
                for (int q = 0;q < Q;q++){
                    if (i < fQ[q].x1 || fQ[q].x2 < i)
                        continue;
                    int cs = max(fQ[q].y1,k);
                    int ct = min(fQ[q].y2,nk-1);
                    if (cs > ct) continue;
                    //printf("%d : (%d,%d) %d\n",q,cs,ct,QueryMin(cs-k,ct-k));
                    Res[q] = min(Res[q],QueryMin(cs-k,ct-k));
                }
                k = nk;
            }
        }
//        for (int q = 0;q < Q;q++){
//            int x1 = fQ[q].x1;
//            int y1 = fQ[q].y1;
//            int x2 = fQ[q].x2;
//            int y2 = fQ[q].y2;
//            int cr = oo;
//            for (int i = x1;i <= x2;i++)
//                for (int j = y1;j <= y2;j++)
//                    cr = min(cr,A[i*C+j]);
//            if (cr != Res[q]){
//                printf("Fail!!\n");
////                for (int i = 0;i < R;i++){
////                    for (int j = 0;j < C;j++)
////                        printf("%d ",A[i*C+j]);
////                    puts("");
////                }
//                printf("%d %d %d %d\n",x1,y1,x2,y2);
//                printf("=> %d %d\n",cr,Res[q]);
//                while (1);
//            }
//        }
//        puts("ok");
//        for (int i = 0;i < R;i++){
//            for (int j = 0;j < C;j++)
//                printf("%d ",A[i*C+j]);
//            puts("");
//        }
        for (int q = 0;q < Q;q++)
            printf("%d\n",Res[q]);
    }
    return 0;
}

Measured memory_bytes: 0