#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long LL;
#define INF 2e15
const int N = 1E5 + 10;
int n, m, q;
struct point
{
int l, r;
LL mmax = 0, mmin = 0;
}treey[N * 4], treex[N * 4], treex_min_pos[N * 4], treex_max_neg[N * 4], zerox[N * 4], zeroy[N * 4];
void build(int u, int l, int r, point* tr)
{
tr[u].l = l; tr[u].r = r;
if (l == r)
{
// cout << u << ' ' << l << endl;
return;
}
int mid = l + r >> 1;
build (u << 1, l, mid, tr);
build (u << 1 | 1, mid + 1, r, tr);
}
void pushup(int u, point * tr)
{
tr[u].mmax = max(tr[u << 1].mmax, tr[u << 1 | 1].mmax);
tr[u].mmin = min(tr[u << 1].mmin, tr[u << 1 | 1].mmin);
}
void modify(int u, int x, LL v, point *tr)
{
if (tr[u].l == x && tr[u].r == x)
{
tr[u].mmax = v;
tr[u].mmin = v;
return;
}
else
{
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid) modify(u << 1, x, v, tr);
else if (x > mid) modify(u << 1 | 1, x, v, tr);
pushup(u, tr);
}
}
LL query_max(int u, int l, int r, point* tr)
{
if (tr[u].l >= l && tr[u].r <= r) return tr[u].mmax;
LL v = -INF;
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) v = query_max(u << 1, l, mid, tr);
if (r > mid) v = max(v, query_max(u << 1 | 1, mid + 1, r, tr));
return v;
}
LL query_min(int u, int l, int r, point* tr)
{
if (tr[u].l >= l && tr[u].r <= r) {
// cout << tr[u].mmin << endl;
return tr[u].mmin;
}
LL v = INF;
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) v = query_min(u << 1, l, mid, tr);
if (r > mid) v = min(v, query_min(u << 1 | 1, mid + 1, r, tr));
return v;
}
int main()
{
cin >> n >> m >> q;
build (1, 1, m, treey);
build (1, 1, n, treex);
build (1, 1, n, treex_min_pos);
build (1, 1, n, treex_max_neg);
build (1, 1, n, zerox);
build (1, 1, m, zeroy);
for (int i = 1; i <= n; i ++ ) modify(1, i, INF, treex_min_pos);
for (int i = 1; i <= n; i ++ ) modify(1, i, -INF, treex_max_neg);
for (int i = 1; i <= n; i ++ )
{
LL t; scanf("%lld", &t); //////////exp
modify(1, i, t, treex);
if (t >= 0) modify(1, i, t, treex_min_pos);
else modify(1, i, t, treex_max_neg);
if (t == 0) modify(1, i, 1, zerox);
}
for (int i = 1; i <= m; i ++ )
{
LL t; scanf("%lld", &t);
modify(1, i, t, treey);
if (t == 0) modify(1, i, 1, zeroy);
}
for (int i = 1; i <= q; i ++ )
{
int l1, r1, l2, r2; bool zx, zy; LL ans, ans1 = -INF, ans2 = -INF, ans3 = -INF, ans4 = -INF;
scanf("%d%d%d%d", &l1, &r1, &l2, & r2);
LL y_min = query_min(1, l2, r2, treey);
LL y_max = query_max(1, l2, r2, treey);
LL x_max = query_max(1, l1, r1, treex);
LL x_min = query_min(1, l1, r1, treex);
LL x_min_pos = query_min(1, l1, r1, treex_min_pos);
LL x_max_neg = query_max(1, l1, r1, treex_max_neg);
if (query_max(1, l1, r1, zerox)) zx = true;
if (query_max(1, l2, r2, zeroy)) zy = true;
if (y_min >= 0)
{
ans1 = y_min * x_max;
if (x_max == 0 && !zx) ans1 = -INF;
}
else if (y_min < 0)
{
ans2 = y_min * x_min_pos;
if (x_min_pos == INF && !zx) ans2 = -INF;
}
if (y_max >= 0)
{
ans3 = y_max * x_max_neg;
if (x_max_neg == -INF && !zx) ans3 = -INF;
}
else if (y_max < 0)
{
ans4 = y_max * x_min;
if (x_min == 0 && !zx) ans4 = -INF;
}
LL aa, bb;
aa = max(ans1, ans2);
bb = max(ans3, ans4);
ans = max(aa, bb);
printf("%lld\n", ans);
}
return 0;
}