Problem: Suppose that P1 is an infinite-height prism whose axis is parallel to the z-axis, and P2 is also an infinite-height prism whose axis is parallel to the y-axis. P1 is defined by the polygon C1 which is the cross section of P1 and the xy-plane, and P2 is also defined by the polygon C2 which is the cross section of P2 and the xz-plane.

Figure I.1 shows two cross sections which appear as the first dataset in the sample input, and Figure I.2 shows the relationship between the prisms and their cross sections.

<image>


Figure I.1: Cross sections of Prisms

<image>


Figure I.2: Prisms and their cross sections

<image>


Figure I.3: Intersection of two prisms

Figure I.3 shows the intersection of two prisms in Figure I.2, namely, P1 and P2.

Write a program which calculates the volume of the intersection of two prisms.



Input

The input is a sequence of datasets. The number of datasets is less than 200.

Each dataset is formatted as follows.

m n
x11 y11
x12 y12
.
.
.
x1m y1m
x21 z21
x22 z22
.
.
.
x2n z2n


m and n are integers (3 ≤ m ≤ 100, 3 ≤ n ≤ 100) which represent the numbers of the vertices of the polygons, C1 and C2, respectively.

x1i, y1i, x2j and z2j are integers between -100 and 100, inclusive. (x1i, y1i) and (x2j , z2j) mean the i-th and j-th vertices' positions of C1 and C2 respectively.

The sequences of these vertex positions are given in the counterclockwise order either on the xy-plane or the xz-plane as in Figure I.1.

You may assume that all the polygons are convex, that is, all the interior angles of the polygons are less than 180 degrees. You may also assume that all the polygons are simple, that is, each polygon's boundary does not cross nor touch itself.

The end of the input is indicated by a line containing two zeros.

Output

For each dataset, output the volume of the intersection of the two prisms, P1 and P2, with a decimal representation in a line.

None of the output values may have an error greater than 0.001. The output should not contain any other extra characters.

Example

Input

4 3
7 2
3 3
0 2
3 1
4 2
0 1
8 1
4 4
30 2
30 12
2 12
2 2
15 2
30 8
13 14
2 8
8 5
13 5
21 7
21 9
18 15
11 15
6 10
6 8
8 5
10 12
5 9
15 6
20 10
18 12
3 3
5 5
10 3
10 10
20 8
10 15
10 8
4 4
-98 99
-99 -99
99 -98
99 97
-99 99
-98 -98
99 -99
96 99
0 0


Output

4.708333333333333
1680.0000000000005
491.1500000000007
0.0
7600258.4847715655

Solution (in CPP):

Solution:
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<math.h>
#include<complex>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<functional>
#include<assert.h>
#include<numeric>
using namespace std;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
using ll = long long;
const int inf=1e9+7;
const ll longinf=1LL<<60 ;
const ll mod=1e9+7 ;

using ld = double;
using Point =  complex<ld>;
const ld eps = 1e-7;
const ld pi = acos(-1.0);

bool eq(ld a, ld b) {
	return (abs(a - b) < eps);
}
//内積
ld dot(Point a, Point b) {
	return real(conj(a)*b);
}
//外積
ld cross(Point a, Point b) {
	return imag(conj(a)*b);
}

bool cmp(Point x,Point y){
	if(eq(x.real(),y.real()))return x.imag()<y.imag();
	return x.real()<y.real();
}
//線分
//直線にするなら十分通い２点を端点とすればよい
class Line {
public:
	Point a, b;
};
//円
class Circle {
public:
	Point p;
	ld r;
};
//3点の位置関係
int ccw(Point a, Point b, Point c) {
	b -= a; c -= a;
	if (cross(b, c) > eps)return 1;//a,b,cが反時計回り
	if (cross(b, c) < -eps)return -1;//a,b,cが時計回り
	if (dot(b, c) < 0)return 2;//c,a,bの順に一直線
	if (norm(b) < norm(c))return -2;//a,b,cの順に一直線
	return 0;//a,c,bの順に一直線
}
//2直線の交差判定
bool isis_ll(Line l, Line m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}
//直線と線分の交差判定
bool isis_ls(Line l, Line s) {
	return (cross(l.b - l.a, s.a - l.a)*cross(l.b - l.a, s.b - l.a) < eps);
}
//点が直線上に存在するか
bool isis_lp(Line l, Point p) {
	return (abs(cross(l.b - p, l.a - p)) < eps);
}
//点が線分上に存在するか
bool isis_sp(Line s, Point p) {
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}
//線分と線分の交差判定
bool isis_ss(Line s, Line t) {
	if (isis_sp(s, t.a) || isis_sp(s, t.b) || isis_sp(t, s.a) || isis_sp(t, s.b))return true;
	return(cross(s.b - s.a, t.a - s.a)*cross(s.b - s.a, t.b - s.a) < -eps && cross(t.b - t.a, s.a - t.a)*cross(t.b - t.a, s.b - t.a) < -eps);
}
//点から直線への垂線の足
Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}
//直線と直線の交点
//平行な２直線に対しては使うな！！！！
Point is_ll(Line s, Line t) {
	Point sv = s.b - s.a; Point tv = t.b - t.a;
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
//直線と点の距離
ld dist_lp(Line l, Point p) {
	return abs(p - proj(l, p));
}
//直線と直線の距離
ld dist_ll(Line l, Line m) {
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}
//線分と直線の距離
ld dist_ls(Line l, Line s) {
	return isis_ls(l, s) ? 0 : min(dist_lp(l, s.a), dist_lp(l, s.b));
}
//線分と点の距離
ld dist_sp(Line s, Point p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(p - r) : min(abs(p - s.a), abs(p - s.b));
}
//線分と線分の距離
ld dist_ss(Line s, Line t) {
	if (isis_ss(s, t))return 0;
	return min({ dist_sp(s,t.a),dist_sp(s,t.b),dist_sp(t,s.a),dist_sp(t,s.b) });
}

vector<Point> convex_hull(vector<Point>& a,int sgn){
	vector<Point> ret;
	int n=a.size();
	int k=0;
	rep(i,n){
		while(k>1 && ccw(ret[k-2],ret[k-1],a[i])!=sgn){
			ret.pop_back();
			--k;
		}
		++k;
		ret.push_back(a[i]);
	}
	return ret;
}

double calc(vector<Point>& a,double x){
	auto itr = upper_bound(a.begin(),a.end(),Point(x,inf),cmp);
	if(itr==a.end()){
		--itr;
		while(itr->real()==x)--itr;
		if(next(itr)!=a.end())++itr;
		return itr->imag();
	}
	if(itr==a.begin()){
		return itr->imag();
	}
	double rx=itr->real(), ry=itr->imag();
	--itr;
	double lx=itr->real(),ly = itr->imag();
	if(rx==lx)return ry;
	return ly + (x-lx)/(rx-lx)*(ry-ly);
}

void solve(int n,int m){
	vector<Point> a(n),b(m);
	vector<double> v;
	double mi,ma;
	double mi1=inf,ma1=-inf,mi2=inf,ma2=-inf;
	rep(i,n){
		double x,y;
		cin>>x>>y;
		mi1=min(x,mi1);
		ma1=max(ma1,x);
		v.push_back(x);
		a[i]=Point(x,y);
	}
	rep(i,m){
		double x,y;
		cin>>x>>y;
		mi2=min(x,mi2);
		ma2=max(ma2,x);
		v.push_back(x);
		b[i]=Point(x,y);
	}
	mi=max(mi1,mi2);ma=min(ma1,ma2);
	sort(a.begin(),a.end(),[](Point x,Point y){
		return x.real()==y.real() ? x.imag()<y.imag() : x.real()<y.real();
	});
	sort(b.begin(),b.end(),[](Point x,Point y){
		return x.real()==y.real() ? x.imag()<y.imag() : x.real()<y.real();
	});
	vector<Point> u,d,l,r;
	d=convex_hull(a,1);
	u=convex_hull(a,-1);
	l=convex_hull(b,1);
	r=convex_hull(b,-1);
	sort(v.begin(),v.end());
	double ans=0;
	int s=v.size();
	rep(i,s-1){
		if(v[i]<mi||v[i+1]>ma)continue;
		double sum = (calc(u,v[i])-calc(d,v[i]))*(calc(r,v[i])-calc(l,v[i]));
		sum += 4*(calc(u,.5*(v[i]+v[i+1]))-calc(d,.5*(v[i]+v[i+1])))*(calc(r,.5*(v[i]+v[i+1]))-calc(l,.5*(v[i]+v[i+1])));
		sum += (calc(u,v[i+1])-calc(d,v[i+1]))*(calc(r,v[i+1])-calc(l,v[i+1]));
		ans += 1.0/6.0 * (v[i+1]-v[i]) * sum;
	}
	cout<<setprecision(12)<<ans<<endl;
}
int main(){
	int n,m;
	while(cin>>n>>m,n!=0){
		solve(n,m);
	}
    return 0;
}