#include<complex>
#include<vector>
#include<iostream>
#include<stack>
#include<cmath>
#include<map>

enum CCW{FRONT=0x01,RIGHT=0x02,BACK=0x04,LEFT=0x08,OVER=0x10};
enum CIRCLE_RELATION{CIRCLE_SAME=0x01,CIRCLE_CONTAIN=0x02,
		     CIRCLE_NO_CROSS=0x04,CIRCLE_ONE_CROSS=0x08,
		     CIRCLE_ONE_INSIDE_CROSS=0x10,CIRCLE_TWO_CROSS=0x20};
#define sc second
#define fr first

#define REP(i,n) for(int i = 0; i < (int)(n); ++i)

using namespace std;

typedef double elem;
typedef complex<elem> point, vec;
typedef pair<point, point> line, hline, seg, pp;

const double infty = 1e40;
const double eps = 1.0e-8;
const double pi = acos(-1.0);
point base(0,0);

// lZ
inline elem sq(elem a){ return a*a; }
inline elem cq(elem a){ return a*a*a; }

// pxÏ·
elem rad(elem deg){ return (deg/180)*pi; }
elem deg(elem rad){ return (rad*180)/pi; }

// ®¬_Ìô¢AÈÇ
bool eq(elem a, elem b){ return abs(a-b) < eps; }
bool eqv(vec a, vec b){ return eq( abs(b-a),0); }

// _Iy[^
bool far(point a, point b){ return abs(b-a)>0; }
bool near(point a, point b){ return abs(b-a)<=0; }
elem dot(vec a, vec b){ return (a.real() * b.real() + a.imag() * b.imag() ); }
elem cross(vec a, vec b){ return ( a.real() * b.imag() - a.imag() * b.real() ); }

// a©çbÜÅvñèÌpxAàpA]ñ]
elem varg(vec a, vec b){
  elem ret=arg(a)-arg(b);
  if(ret<0)ret+=2*pi;
  if(ret>2*pi)ret-=2*pi;
  if(eq(ret,2*pi))ret=0;
  return ret;
}
elem varg2(vec a, vec b){
  elem ret = varg(a,b);
  if(ret>pi)return 2*pi-ret;
  return ret;
}
elem arg(vec a, vec b){ return acos( dot(a,b) / ( abs(a) * abs(b) ) ); }
point rot(point p, elem theta){ return p * polar((elem)1.0, theta); }
point rotdeg(point p, elem deg){ return p * polar((elem)1.0, rad(deg)); }
point proj(line l, point p){
  double t=dot(p-l.first,l.first-l.second)/abs(l.first-l.second);
  return l.first + t*(l.first-l.second);
}
point reflect(line l, point p){ return p+2.0*(proj(l,p)-p); }

// ñ_Ô£A¼üÆ_ÌÅZ£AüªÆ_ÌÅZ£
elem dist(point a, point b){ return abs(a-b); }
elem dist_l(line l, point x){ return abs(cross(l.sc-l.fr,x-l.fr)) / abs(l.sc-l.fr); }
elem dist_seg(seg s, point x)
{
  if( dot(s.sc-s.fr,x-s.fr)<0 ) return abs(x-s.fr);
  if( dot(s.fr-s.sc,x-s.sc)<0 ) return abs(x-s.sc);
  return dist_l(s,x);
}

// PÊxNgA@üxNgAPÊ@üxNg
vec uvec(vec a){ return a / abs(a); }
vec nmr(vec a){ return a * vec(0,-1); }
vec nml(vec a){ return a * vec(0,1); }
vec unmr(vec a){ return uvec( nmr(a) ); }
vec unml(vec a){ return uvec( nml(a) ); }

// ¼ðA½s»è
bool orth(point a1, point a2, point b1, point b2){ return eq( dot( a2 - a1, b2 - b1 ), 0 ); }
bool orth(vec v1, vec v2){ return eq( dot(v1, v2), 0 ); }
bool prll(point a1, point a2, point b1, point b2){ return eq( cross( a2 - a1, b2 - b1 ), 0 ); }
bool prll(vec v1, vec v2){ return eq( cross(v1, v2), 0 ); }

// CCW oXg¾ªA¸xÉæé
inline int ccw(const point &a, point b, point x){
  b -= a;
  x -= a;
  if( eq(cross(b,x),0.0) && dot(b,x) < 0 ) return BACK;
  if( eq(cross(b,x),0.0) && abs(b) < abs(x) ) return FRONT;
  if( eq(cross(b,x),0.0) ) return OVER;
  if( cross(b,x) > 0 ) return LEFT;
  if( cross(b,x) < 0 ) return RIGHT;
}

// üªg£
line expandLine(line l, elem mag){
  line ret = l;
  vec vf(l.first - l.second);
  vec vs(l.second - l.first);
  ret.first = l.second + mag * vf;
  ret.second = l.first + mag * vs;
  return ret;
}

// üªÌð·»è
inline bool intersectedSS(const seg &a, const seg &b)
{
  int cwaf=ccw(a.fr,a.sc,b.fr);
  int cwbf=ccw(b.fr,b.sc,a.fr);
  int cwas=ccw(a.fr,a.sc,b.sc);
  int cwbs=ccw(b.fr,b.sc,a.sc);
  if( cwaf==OVER || cwas==OVER || cwbf==OVER || cwbs==OVER ) return true;
  return ( cwaf | cwas ) == (LEFT|RIGHT) && ( cwbf | cwbs ) == (LEFT|RIGHT);
}

// ¼üÌð·»è
bool intersectedLL(line a, line b){ return !eq( cross(a.sc-a.fr,b.sc-b.fr), 0.0 ); }

// ð_vZ
point intersectionSS(seg a, seg b)
{
  elem d1 = dist_l(b,a.fr);
  elem d2 = dist_l(b,a.sc);
  return a.fr + ( d1 / (d1 + d2 ) ) * (a.sc-a.fr);
}
point intersectionLL(line a, line b)
{
  vec va = a.sc - a.fr;
  vec vb = b.sc - b.fr;
  return a.fr + va * ( cross(vb, b.fr - a.fr) / cross(vb,va) );
}

// üªð_êÅ
bool intersectionLL(line a, line b, point &ret){
  return intersectedLL( a, b ) ? ret = intersectionLL( a, b ), true : false;
}
bool intersectionLH(line a, hline b, point &ret){
  point tmp;
  return intersectionLL(a,b,tmp) ? ( ccw(b.fr,b.sc,tmp)&(OVER|FRONT) ? ret=tmp, true : false ) : false;
}
bool intersectionLS(line l, seg s, point &ret){
  point tmp;
  return intersectionLL(l,s,tmp) ? ( ccw(s.fr,s.sc,tmp)&OVER ? ret=tmp, true : false ) : false;
}
bool intersectionHH(hline a, hline b, point &ret){
  point tmp;
  return intersectionLL(a,b,tmp) ? ( ccw(a.fr,a.sc,tmp)&(OVER|FRONT)&&ccw(b.fr,b.sc,tmp)&(OVER|FRONT) ? ret = tmp, true : false ) : false;
}
bool intersectionHS(hline a, seg s, point &ret){
  point tmp;
  return intersectionLS(a,s,tmp) ? ( ccw(a.fr,a.sc,tmp)&(OVER|FRONT) ? ret = tmp, true : false ) : false;
}
bool intersectionSS(seg a, seg b, point &ret){
  return intersectedSS(a,b) ? ret = intersectionSS(a,b), true : false;
}

pair<int, pair<double,double> > getLH(double x, const vector<point> &v)
{
  point a,b;
  int cnt=0;
  line l(point(x,0),point(x,1));
  for(int i = 0; i < (int)v.size(); ++i){
    point is;
    if( intersectionLS( l, seg(v[i],v[(i+1)%v.size()]), is ) ){
      if(cnt==0){
	a = is;
	++cnt;
      }else if( far(is,a) ){
	b = is;
	++cnt;
      }
    }
  }
  if(cnt==1)b=a;
  if( a.imag() > b.imag() ) swap( a, b );
  return make_pair( cnt, make_pair(a.imag(), b.imag() ) );
}

struct point3{
  double x,y,z;
  point3(double x, double y, double z):x(x),y(y),z(z){}
  point3 operator-(const point3 &t){
    return point3(x-t.x,y-t.y,z-t.z);
  }
  point3 operator+(const point3 &t){
    return point3(x+t.x,y+t.y,z+t.z);
  }
};

ostream &operator<<(ostream &oss, const point3 &t)
{
  oss << '('<<t.x <<','<< t.y<<','<<t.z<<')';
  return oss;
}

double dot3(point3 a, point3 b){
  return a.x*b.x + a.y*b.y + a.z*b.z;
}
point3 cross3(point3 a, point3 b){
  return point3(a.y*b.z-b.y*a.z, a.z*b.x-b.z*a.x, a.x*b.y-b.x*a.y);
}

double tetrahedronVolume(point3 a, point3 b, point3 c, point3 d)
{
  point3 A=b-a;
  point3 B=c-a;
  point3 C=d-a;
  return abs(dot3(A,cross3(B,C))/6);
}
double getVolume( const vector<point3> &V1, const vector<point3> &V2 )
{
  double ret=0;
  vector<point3> v1 = V1;
  vector<point3> v2 = V2;
  if( v2.size() < v1.size() ){
    swap( v1, v2 );
  }
  if(v1.size()==1){
    if(v2.size()==2){
      ret = 0;
    }else if(v2.size()==4){
      ret+=tetrahedronVolume(v1[0],v2[0],v2[1],v2[2]);
      ret+=tetrahedronVolume(v1[0],v2[2],v2[3],v2[0]);
    }
  }else if(v1.size()==2){
    if(v2.size()==2){
      ret = tetrahedronVolume(v1[0],v1[1],v2[0],v2[1]);
    }else{
      if(eq(v1[0].y,v1[1].y)){
	ret += tetrahedronVolume( v1[1],v1[0],v2[1],v2[2] );
	ret += tetrahedronVolume( v1[0],v2[0],v2[1],v2[2] );
	ret += tetrahedronVolume( v1[0],v2[2],v2[3],v2[0] );
      }else{
	ret += tetrahedronVolume( v1[1],v1[0],v2[2],v2[3] );
	ret += tetrahedronVolume( v1[0],v2[0],v2[1],v2[2] );
	ret += tetrahedronVolume( v1[0],v2[2],v2[3],v2[0] );
      }
    }
  }else{
    ret += tetrahedronVolume( v1[1],v1[0],v2[1],v1[2] );
    ret += tetrahedronVolume( v2[0],v1[0],v2[3],v2[1] );
    ret += tetrahedronVolume( v1[3],v1[0],v1[2],v2[3] );

    ret += tetrahedronVolume( v2[2],v2[3],v2[1],v1[2] );
    ret += tetrahedronVolume( v1[0],v1[2],v2[1],v2[3] );
  }
  return ret;
}

int main()
{
  int m,n;
  while(scanf("%d%d", &m, &n) && m && n){
    double x,y;
    double res = 0;
    vector<point> P1;
    vector<point> P2;
    int minx1=1000,maxx1=-1000;
    int minx2=1000,maxx2=-1000;
    map<int,pair<double,double> > vx;
    for(int i = 0; i < m; ++i){
      scanf("%lf%lf", &x, &y);
      P1.push_back(point(x,y));
      vx[(int)x]=make_pair(0,0);
      minx1 = min( (int)x, minx1 );
      maxx1 = max( (int)x, maxx1 );
    }
    for(int i = 0; i < n; ++i){
      scanf("%lf%lf", &x, &y);
      P2.push_back(point(x,y));
      minx2 = min( (int)x, minx2 );
      maxx2 = max( (int)x, maxx2 );
      vx[(int)x]=make_pair(0,0);
    }
  retry:;
    for(map<int,pair<double,double> >::iterator itm = vx.begin(); itm != vx.end(); ++itm){
      pair<int, pair<double,double > > LH = getLH( itm->first, P1);
      if( !(  minx1 <= itm->first && itm->first <= maxx1 &&
	      minx2 <= itm->first && itm->first <= maxx2 ) ){
	vx.erase(itm);
	goto retry;
      }
      if( LH.first == 0 ){
	vx.erase(itm);
	goto retry;
      }else{
	itm->second = LH.second;
      }
    }
    vector< vector<point3> > V;
    for(map<int,pair<double,double> >::iterator itm = vx.begin(); itm != vx.end(); ++itm){
      vector<point3> vpx;
      double x = itm->first;
      double y1 = itm->second.first;
      double y2 = itm->second.second;

      if( eq(y1,y2) ){
	pair<int,pair<double,double> > Z = getLH( x, P2 );
	double z1 = Z.second.first;
	double z2 = Z.second.second;
	if( eq(z1,z2) ){
	  vpx.push_back( point3( x,y1,z1 ) );
	}else{
	  vpx.push_back( point3( x,y1,z1 ) );
	  vpx.push_back( point3( x,y1,z2 ) );
	}
      }else{
	pair<int,pair<double,double> > Z = getLH( x, P2 );
	double z1 = Z.second.first;
	double z2 = Z.second.second;
	if( eq(z1,z2) ){
	  vpx.push_back( point3( x,y1,z1 ) );
	  vpx.push_back( point3( x,y2,z1 ) );
	}else{
	  vpx.push_back( point3( x,y1,z1 ) );
	  vpx.push_back( point3( x,y1,z2 ) );
	  vpx.push_back( point3( x,y2,z2 ) );
	  vpx.push_back( point3( x,y2,z1 ) );
	}
      }
      
      /*
      for(int i = 0; i < (int)vpx.size(); ++i){
	cout << vpx[i] << ' ';
      }
      cout << endl;
      */

      V.push_back( vpx );
    }
    for(int i = 0; i < (int)V.size()-1; ++i){
      //cout << i << ' ' << i+1 << endl;
      res += getVolume(V[i], V[i+1]);
    }
    printf("%.13lf\n", res);
    //return 0;
  }
  return 0;
}

Measured memory_bytes: 0