// Slower C++ solution:
#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;

}

// Faster C++ solution for the same problem (measured speedup: 2.101886701080193x):
#include <stdio.h>

#include <string.h>

#include <algorithm>



using namespace std;



typedef long long LL;



#define INF 0x7fffffff

#define MAX 1048576

#define MAXN 65535

#define MAXLg 16

#define MAXQ 20000



int A[MAX],Log[MAXN + 1],tableMin[MAXN][MAXLg];



void makeRMinQ(int *a,int s,int t){

	int n = t - s;

	for (int i = s; i < t; ++i) tableMin[i - s][0] = a[i];

	for (int j = 1; (1 << j) <= n; ++j)

		for (int 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];

	return min(tableMin[x][p],tableMin[y - (1 << p) + 1][p]);

}



struct query{

    int x1, y1;

    int x2, y2;

}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;

	int R, C, Q;

	while(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 q = 0;q < Q; ++q)

            Res[q] = INF;

        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);

                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;

                    Res[q] = min(Res[q],QueryMin(cs - k,ct - k));

                }

                k = nk;

            }

        }

        for (int q = 0; q < Q; ++q)

            printf("%d\n", Res[q]);

    }

    return 0;

}