#include<bits/stdc++.h>
#define lson pos<<1
#define rson pos<<1|1
#define ll long long
using namespace std;
const int maxn=4e5+10;
int n,m,q;
ll a[maxn],b[maxn];
struct node{
ll mn,mx,mabs,mabs1;
}tree1[maxn],tree2[maxn];
int cnt[maxn];
void pushup(int pos){
tree1[pos].mn=min(tree1[lson].mn,tree1[rson].mn);
tree1[pos].mx=max(tree1[lson].mx,tree1[rson].mx);
tree1[pos].mabs=min(tree1[lson].mabs,tree1[rson].mabs);
tree1[pos].mabs1=max(tree1[lson].mabs1,tree1[rson].mabs1);
}
void pushup1(int pos){
tree2[pos].mn=min(tree2[lson].mn,tree2[rson].mn);
tree2[pos].mx=max(tree2[lson].mx,tree2[rson].mx);
tree2[pos].mabs=min(tree2[lson].mabs,tree2[rson].mabs);
tree2[pos].mabs1=max(tree2[lson].mabs1,tree2[rson].mabs1);
}
void build(int pos,int l,int r){
if(l==r){
tree1[pos].mabs=1000000000;
tree1[pos].mabs1=-1000000000;
tree1[pos].mn=tree1[pos].mx=a[l];
if(a[l]>=0) tree1[pos].mabs=a[l];
if(a[l]<=0) tree1[pos].mabs1=a[l];
return;
}
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(pos);
return;
}
void build1(int pos,int l,int r){
if(l==r){
tree2[pos].mabs=1000000000;
tree2[pos].mabs1=-1000000000;
tree2[pos].mn=tree2[pos].mx=b[l];
if(b[l]>=0) tree2[pos].mabs=b[l];
if(b[l]<=0) tree2[pos].mabs1=b[l];
return;
}
int mid=(l+r)>>1;
build1(lson,l,mid);
build1(rson,mid+1,r);
pushup1(pos);
return;
}
ll get_max(int pos,int l,int r,int xl,int xr){
if(xl<=l&&r<=xr){
return tree1[pos].mx;
}
ll tmp=-1000000000;
int mid=(l+r)>>1;
if(xl<=mid) tmp=max(tmp,get_max(lson,l,mid,xl,xr));
if(xr>mid) tmp=max(tmp,get_max(rson,mid+1,r,xl,xr));
return tmp;
}
ll get_max1(int pos,int l,int r,int xl,int xr){
if(xl<=l&&r<=xr){
return tree2[pos].mx;
}
ll tmp=-1000000000;
int mid=(l+r)>>1;
if(xl<=mid) tmp=max(tmp,get_max1(lson,l,mid,xl,xr));
if(xr>mid) tmp=max(tmp,get_max1(rson,mid+1,r,xl,xr));
return tmp;
}
ll get_min(int pos,int l,int r,int xl,int xr){
if(xl<=l&&r<=xr){
return tree1[pos].mn;
}
ll tmp=1000000000;
int mid=(l+r)>>1;
if(xl<=mid) tmp=min(tmp,get_min(lson,l,mid,xl,xr));
if(xr>mid) tmp=min(tmp,get_min(rson,mid+1,r,xl,xr));
return tmp;
}
ll get_min1(int pos,int l,int r,int xl,int xr){
if(xl<=l&&r<=xr){
return tree2[pos].mn;
}
ll tmp=1000000000;
int mid=(l+r)>>1;
if(xl<=mid) tmp=min(tmp,get_min1(lson,l,mid,xl,xr));
if(xr>mid) tmp=min(tmp,get_min1(rson,mid+1,r,xl,xr));
return tmp;
}
ll get_mabs(int pos,int l,int r,int xl,int xr){
if(xl<=l&&r<=xr){
return tree1[pos].mabs;
}
ll tmp=1000000000;
int mid=(l+r)>>1;
if(xl<=mid) tmp=min(tmp,get_mabs(lson,l,mid,xl,xr));
if(xr>mid) tmp=min(tmp,get_mabs(rson,mid+1,r,xl,xr));
return tmp;
}
ll get_mabs1(int pos,int l,int r,int xl,int xr){
if(xl<=l&&r<=xr){
return tree1[pos].mabs1;
}
ll tmp=-1000000000;
int mid=(l+r)>>1;
if(xl<=mid) tmp=max(tmp,get_mabs1(lson,l,mid,xl,xr));
if(xr>mid) tmp=max(tmp,get_mabs1(rson,mid+1,r,xl,xr));
return tmp;
}
int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=1;i<=m;i++){
scanf("%lld",&b[i]);
cnt[i]=cnt[i-1];
if(b[i]<0) cnt[i]++;
}
build(1,1,n);
build1(1,1,m);
while(q--){
int l1,l2,r1,r2;
scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
ll x,y;
if(cnt[r2]-cnt[l2-1]==r2-l2+1) x=get_min(1,1,n,l1,r1);
else if(cnt[r2]-cnt[l2-1]==0) x=get_max(1,1,n,l1,r1);
else{
x=get_mabs(1,1,n,l1,r1);
y=get_min1(1,1,m,l2,r2);
ll tmp=x*y;
x=get_mabs1(1,1,n,l1,r1);
y=get_max1(1,1,m,l2,r2);
tmp=max(tmp,x*y);
printf("%lld\n",tmp);
continue;
}
if(x<0) y=get_max1(1,1,m,l2,r2);
if(x==0){
printf("0\n");
continue;
}
if(x>0) y=get_min1(1,1,m,l2,r2);
printf("%lld\n",x*y);
}
return 0;
}