#include <bits/stdc++.h>
using namespace std;

struct grana {
    int a,b,t;
    friend bool operator <(const grana &g1, const grana &g2) { return g1.t < g2.t; }
    friend bool operator >(const grana &g1, const grana &g2) { return g1.t > g2.t; }
    friend bool operator ==(const grana &g1, const grana &g2) { return g1.t == g2.t; }
    friend bool operator <=(const grana &g1, const grana &g2) { return g1.t <= g2.t; }
    friend bool operator >=(const grana &g1, const grana &g2) { return g1.t >= g2.t; }
    friend bool operator !=(const grana &g1, const grana &g2) { return g1.t != g2.t; }
    void budi(int _a,int _b,int _t)
    {
        a=_a;
        b=_b;
        t=_t;
    }
};

int r,c,n;

grana tab[250][250];

//dole je kruskal...

struct skup {
    int n;
    int el[41];
    skup(){n=0;}
    void ubaci(int x)
    {
        el[n]=x;
        ++n;
    }
    void ubaci(skup *sk)
    {
        for(int i=0,m=sk->n;i<m;++i)ubaci(sk->el[i]);
    }
    void ocisti()
    {
        n=0;
    }
};
int brg,zbw;
grana ge[165];
int skupcvora[41];
skup svi[41];
void kruskal()
{
    for(int i=1;i<=n;++i)skupcvora[i]=i;
    for(int i=1;i<=n;++i)
    {
        svi[i].ocisti();
        svi[i].ubaci(i);
    }
    sort(ge,ge+brg);
    int ubacio=0;
    int tez=0;
    for(int ig=0;ig<brg;++ig)
    {
        int skupa=skupcvora[ge[ig].a];
        int skupb=skupcvora[ge[ig].b];
        if(skupa!=skupb)
        {
            ge[ubacio]=ge[ig];
            ++ubacio;
            tez+=ge[ig].t;
            if(svi[skupa].n<=svi[skupb].n)
            {
                for(int i=0,m=svi[skupa].n;i<m;++i)skupcvora[svi[skupa].el[i]]=skupb;
                svi[skupb].ubaci(svi+skupa);
                svi[skupa].ocisti();
            }
            else
            {
                for(int i=0,m=svi[skupb].n;i<m;++i)skupcvora[svi[skupb].el[i]]=skupa;
                svi[skupa].ubaci(svi+skupb);
                svi[skupb].ocisti();
            }
        }
    }
    brg=ubacio;
    zbw=tez;
}

struct resenje {
    int brg;
    grana ge[41];
    int zbw;
    bool ok()
    {
        return brg==n-1;
    }
    void budi(grana g)
    {
        brg=1;
        ge[0]=g;
        zbw=g.t;
    }
};
void dodajzak(resenje *res)
{
    for(int i=0;i<res->brg;++i)
        ge[brg++]=res->ge[i];
}
void pisires(resenje *res)
{
    res->brg=brg;
    res->zbw=zbw;
    for(int i=0;i<brg;++i)res->ge[i]=ge[i];
}
resenje rkk[250][250][10];

void resi0()
{
    for(int i=1;i<=r;++i)
        for(int j=1;j<=c;++j)
            rkk[i][j][0].budi(tab[i][j]);
    for(int k=1,d=2;k<8;++k)
    {
        for(int i=1;i+d-1<=r;++i)
            for(int j=1;j+d-1<=c;++j)
            {
                brg=0;
                dodajzak(&rkk[i][j][k-1]);
                dodajzak(&rkk[i][j+d/2][k-1]);
                dodajzak(&rkk[i+d/2][j][k-1]);
                dodajzak(&rkk[i+d/2][j+d/2][k-1]);
                kruskal();
                pisires(&rkk[i][j][k]);
            }
        d*=2;
    }
}

bool okje;
int tezje;
void resi(int x1,int y1,int x2,int y2)
{
    if(x1==x2&&y1==y2)
    {
        okje=(n==2);
        tezje=tab[x1][y1].t;
    }
    int duz=x2-x1+1;
    int vis=y2-y1+1;
    int mindim=duz;
    if(vis<duz)mindim=vis;
    int k=0,d=1;
    while(d<mindim)
    {
        ++k;
        d*=2;
    }
    --k;
    d/=2;
    brg=0;
    dodajzak(&rkk[x1][y1][k]);
    dodajzak(&rkk[x2+1-d][y1][k]);
    dodajzak(&rkk[x1][y2+1-d][k]);
    dodajzak(&rkk[x2+1-d][y2+1-d][k]);
    kruskal();
    okje=(brg==n-1);
    tezje=zbw;
}

void Resi(int N, int R, int C, int Q, int** U, int** V, int** W,int* X1, int* Y1, int* X2, int* Y2, int* O)
{
    r=R;
    c=C;
    n=N;
    for(int i=1;i<=r;++i)
        for(int j=1;j<=c;++j)
            tab[i][j].budi(U[i][j],V[i][j],W[i][j]);
    resi0();
    for(int i=1;i<=Q;++i)
    {
        resi(X1[i],Y1[i],X2[i],Y2[i]);
        if(okje)O[i]=tezje;
        else O[i]=-1;
    }
}

static int** matrica(int R, int C) {
	int** a = new int*[R+1];
	for (int i=1; i<=R; i++)
		a[i] = new int[C+1];
	return a;
}
static void pocisti(int** a, int R) {
	for (int i=1; i<=R; i++)
		delete[] a[i];
	delete a;

}
int zadatak() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);

	int N, R, C, Q;
	cin >> N >> R >> C >> Q;

	int** U = matrica(R, C);
	int** V = matrica(R, C);
	int** W = matrica(R, C);

	int* X1 = new int[Q+1];
	int* Y1 = new int[Q+1];
	int* X2 = new int[Q+1];
	int* Y2 = new int[Q+1];
	int* O  = new int[Q+1];

	for (int i=1; i<=R; i++)
		for (int j=1; j<=C; j++)
			cin >> U[i][j] >> V[i][j] >> W[i][j];

	for (int i=1; i<=Q; i++)
		cin >> X1[i] >> Y1[i] >> X2[i] >> Y2[i];

	Resi(N, R, C, Q, U, V, W, X1, Y1, X2, Y2, O);

	cout<<endl;

	for (int i=1; i<=Q; i++)
		cout << O[i] << '\n';

	delete[] X1;
	delete[] Y1;
	delete[] X2;
	delete[] Y2;
	delete[] O;

	pocisti(U, R);
	pocisti(V, R);
	pocisti(W, R);

	return 0;
}

void samokruskal()
{
    int cva,gra;
    scanf("%d%d",&cva,&gra);
    n=cva;
    brg=gra;
    for(int i=0,u,v,w;i<gra;++i)
    {
        scanf("%d%d%d",&u,&v,&w);
        ge[i].budi(u,v,w);
    }
    kruskal();
    printf("\n");
    printf("broj grana: %d\n",brg);
    printf("ukupna duzina: %d\n",zbw);
    printf("grane:\n");
    for(int i=0;i<brg;++i)
        printf("    (%d,  %d,  %d)\n",ge[i].a,ge[i].b,ge[i].t);
    printf("\n");
}

int mainn()
{
    //samokruskal();
    zadatak();
    return 0;
}