Problem:
Problem I:
Intersection of Two Prisms
Suppose that
P
1
is an infinite-height prism whose axis is parallel to the
z
-axis, and
P
2
is also an infinite-height prism whose axis is parallel to the
y
-axis.
P
1
is defined by the polygon
C
1
which is the cross section of
P
1
and the
xy
-plane, and
P
2
is also defined by the polygon
C
2
which is the cross section of
P
2
and the
x
z-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.
Figure I.1: Cross sections of Prisms
Figure I.2: Prisms and their cross sections
Figure I.3: Intersection of two prisms
Figure I.3 shows the intersection of two prisms in Figure I.2, namely,
P
1
and
P
2
.
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
x
11
y
11
x
12
y
12
.
.
.
x
1
m
y
1
m
x
21
z
21
x
22
z
22
.
.
.
x
2
n
z
2
n
m
and
n
are integers (3 ≤
m
≤ 100, 3 ≤
n
≤ 100) which represent the numbers of the vertices of the polygons,
C
1
and
C
2
, respectively.
x
1
i
,
y
1
i
,
x
2
j
and
z
2
j
are integers between -100 and 100, inclusive. (
x
1
i
,
y
1
i
) and (
x
2
j
,
z
2
j
) mean the
i
-th and
j
-th vertices' positions of
C
1
and
C
2
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,
P
1
and
P
2
, 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.
Sample 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 for the Sample Input
4.708333333333333
1680.0000000000005
491.1500000000007
0.0
7600258.4847715655

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

#define double long double

const double eps = 1e-9;

// Geometry Library
// written by okuraofvegetable

#define pb push_back
#define DOUBLE_INF 1e50
#define Points vector<Point>

#define EQ(a, b) (abs((a) - (b)) < eps)
#define GT(a, b) ((a) > (b))
#define GE(a, b) (GT(a, b) || EQ(a, b))
#define LT(a, b) ((a) < (b))
#define LE(a, b) (LT(a, b) || EQ(a, b))

inline double add(double a, double b) {
  if (abs(a + b) < eps * (abs(a) + abs(b))) return 0;
  return a + b;
}

// --------------------- Point -----------------------

#define Vector Point
struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
  Point operator+(Point p) { return Point(add(x, p.x), add(y, p.y)); }
  Point operator-(Point p) { return Point(add(x, -p.x), add(y, -p.y)); }
  Point operator*(double d) { return Point(x * d, y * d); }
  Point operator/(double d) { return Point(x / d, y / d); }
  double dot(Point p) { return add(x * p.x, y * p.y); }
  double det(Point p) { return add(x * p.y, -y * p.x); }
  double norm() { return sqrt(x * x + y * y); }
  double norm2() { return x * x + y * y; }
  double dist(Point p) { return ((*this) - p).norm(); }
  double dist2(Point p) { return sq(x - p.x) + sq(y - p.y); }
  double arg() { return atan2(y, x); }             // [-PI,PI]
  double arg(Vector v) { return v.arg() - arg(); } // henkaku
  double angle(Vector v) {                         // [0,PI]
    return acos(cos(arg(v)));
  }
  Vector normalize() { return (*this) * (1.0 / norm()); }
  Point vert() { return Point(y, -x); }

  // Signed area of triange (0,0) (x,y) (p.x,p.y)
  double area(Point p) { return (x * p.y - p.x * y) / 2.0; }
  friend istream &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }
  friend ostream &operator<<(ostream &os, const Point &p) {
    return os << '(' << p.x << ',' << p.y << ')';
  }
};

Point divide_rate(Point a, Point b, double A, double B) {
  assert(!EQ(A + B, 0.0));
  return (a * B + b * A) * (1.0 / (A + B));
}

Vector polar(double len, double arg) {
  return Vector(cos(arg) * len, sin(arg) * len);
}

// Direction a -> b -> c
// verified AOJ CGL_1_C
enum { COUNTER_CLOCKWISE, CLOCKWISE, ONLINE_BACK, ONLINE_FRONT, ON_SEGMENT };
int ccw(Point a, Point b, Point c) {
  Vector p = b - a;
  Vector q = c - a;
  if (p.det(q) > 0.0) return COUNTER_CLOCKWISE; // counter clockwise
  if (p.det(q) < 0.0) return CLOCKWISE;         // clockwise
  if (p.dot(q) < 0.0) return ONLINE_BACK;       // c--a--b online_back
  if (p.norm() < q.norm()) return ONLINE_FRONT; // a--b--c online_front
  return ON_SEGMENT;                            // a--c--b on_segment
}

// --------------------- Line ------------------------
struct Line {
  Point a, b;
  Line() {}
  Line(Point a, Point b) : a(a), b(b) {}
  bool on(Point q) { return EQ((a - q).det(b - q), 0.0); }
  // following 2 functions verified AOJ CGL_2_A
  bool is_parallel(Line l) { return EQ((a - b).det(l.a - l.b), 0.0); }
  bool is_orthogonal(Line l) { return EQ((a - b).dot(l.a - l.b), 0.0); }
  Point intersection(Line l) {
    assert(!is_parallel(l));
    return a + (b - a) * ((l.b - l.a).det(l.a - a) / (l.b - l.a).det(b - a));
  }
  // Projection of p to this line
  // verified AOJ CGL_1_A
  Point projection(Point p) {
    return (b - a) * ((b - a).dot(p - a) / (b - a).norm2()) + a;
  }
  double distance(Point p) {
    Point q = projection(p);
    return p.dist(q);
  }
  // Reflection point of p onto this line
  // verified AOJ CGL_1_B
  Point refl(Point p) {
    Point proj = projection(p);
    return p + ((proj - p) * 2.0);
  }
  bool left(Point p) {
    if ((p - a).det(b - a) > 0.0)
      return true;
    else
      return false;
  }
  friend istream &operator>>(istream &is, Line &l) { return is >> l.a >> l.b; }
  friend ostream &operator<<(ostream &os, const Line &l) {
    return os << l.a << " -> " << l.b;
  }
};

// ------------------- Segment  ----------------------
struct Segment {
  Point a, b;
  Segment() {}
  Segment(Point a, Point b) : a(a), b(b) {}
  Line line() { return Line(a, b); }
  bool on(Point q) {
    return (EQ((a - q).det(b - q), 0.0) && LE((a - q).dot(b - q), 0.0));
  }
  // verified AOJ CGL_2_B
  bool is_intersect(Segment s) {
    if (line().is_parallel(s.line())) {
      if (on(s.a) || on(s.b)) return true;
      if (s.on(a) || s.on(b)) return true;
      return false;
    }
    Point p = line().intersection(s.line());
    if (on(p) && s.on(p))
      return true;
    else
      return false;
  }
  bool is_intersect(Line l) {
    if (line().is_parallel(l)) {
      if (l.on(a) || l.on(b))
        return true;
      else
        return false;
    }
    Point p = line().intersection(l);
    if (on(p))
      return true;
    else
      return false;
  }
  // following 2 distance functions are verified at AOJ CGL_2_D
  double distance(Point p) {
    double res = DOUBLE_INF;
    Point q = line().projection(p);
    if (on(q)) res = min(res, p.dist(q));
    res = min(res, min(p.dist(a), p.dist(b)));
    return res;
  }
  double distance(Segment s) {
    if (is_intersect(s)) return 0.0;
    double res = DOUBLE_INF;
    res = min(res, s.distance(a));
    res = min(res, s.distance(b));
    res = min(res, this->distance(s.a));
    res = min(res, this->distance(s.b));
    return res;
  }
  friend istream &operator>>(istream &is, Segment &s) {
    return is >> s.a >> s.b;
  }
  friend ostream &operator<<(ostream &os, const Segment &s) {
    return os << s.a << " -> " << s.b;
  }
};

typedef vector<Point> Polygon;

bool solve() {
  int m, n;
  cin >> m >> n;
  if (n == 0 && m == 0) return false;
  Polygon a(m), b(n);
  cin >> a >> b;

  double a_x_max = -200, b_x_max = -200;
  double a_x_min = 200, b_x_min = 200;

  for (int i = 0; i < m; i++) {
    chmax(a_x_max, a[i].x);
    chmin(a_x_min, a[i].x);
  }

  for (int i = 0; i < n; i++) {
    chmax(b_x_max, b[i].x);
    chmin(b_x_min, b[i].x);
  }

  // if (a_x_max - eps < b_x_min || b_x_max - eps < a_x_min) {
  //   cout << 0.0 << endl;
  //   return true;
  // }

  auto intersection_length = [&](const Polygon &pol, const Line &l) {
    vector<Point> ps;
    for (int i = 0; i < pol.size(); i++) {
      Segment seg(pol[i], pol[(i + 1) % pol.size()]);
      if (seg.a.x < l.a.x && seg.b.x < l.a.x) continue;
      if (seg.a.x > l.a.x && seg.b.x > l.a.x) continue;
      // if (seg.line().is_parallel(l) && EQ(pol[i].x, l.a.x)) return -1.0;
      if (seg.line().is_parallel(l)) continue;
      if (!seg.is_intersect(l)) continue;
      Point inter = seg.line().intersection(l);
      bool is_new = true;
      for (auto &p : ps) {
        if ((p - inter).norm() < eps) is_new = false;
      }
      if (is_new) ps.push_back(inter);
    }
    assert(ps.size() <= 2);
    dmp(ps);
    if (ps.size() == 2) return (ps[0] - ps[1]).norm();
    return (double)0.0;
  };

  auto f = [&](double x) {
    // cerr << fixed << setprecision(20) << x << endl;
    Line l(Point(x, 0), Point(x, 1));
    auto len_a = intersection_length(a, l);
    if (EQ(len_a, 0.0)) return (double)0.0;
    auto len_b = intersection_length(b, l);
    if (EQ(len_b, 0.0)) return (double)0.0;
    dmp(x, len_a, len_b);
    return len_a * len_b;
  };

  double ans = 0.0;
  double s = -100, step = 1.0;
  while (s + step <= 105) {
    double mid = s + step / 2.0;
    if (a_x_min <= mid && mid <= a_x_max && b_x_min <= mid && mid <= b_x_max) {
      double p = f(s), q = f(mid), r = f(s + step);
      ans += (p + 4.0 * q + r) * step / 6.0;
    }
    s += step;
  }
  cout << ans << endl;

  return true;
}

int main() {
  fastio();
  if (!multitest) {
    while (solve()) {}
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3440
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

#define double long double

const double eps = 1e-9;

// Geometry Library
// written by okuraofvegetable

#define pb push_back
#define DOUBLE_INF 1e50
#define Points vector<Point>

#define EQ(a, b) (abs((a) - (b)) < eps)
#define GT(a, b) ((a) > (b))
#define GE(a, b) (GT(a, b) || EQ(a, b))
#define LT(a, b) ((a) < (b))
#define LE(a, b) (LT(a, b) || EQ(a, b))

inline double add(double a, double b) {
  if (abs(a + b) < eps * (abs(a) + abs(b))) return 0;
  return a + b;
}

// --------------------- Point -----------------------

#define Vector Point
struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
  Point operator+(Point p) { return Point(add(x, p.x), add(y, p.y)); }
  Point operator-(Point p) { return Point(add(x, -p.x), add(y, -p.y)); }
  Point operator*(double d) { return Point(x * d, y * d); }
  Point operator/(double d) { return Point(x / d, y / d); }
  double dot(Point p) { return add(x * p.x, y * p.y); }
  double det(Point p) { return add(x * p.y, -y * p.x); }
  double norm() { return sqrt(x * x + y * y); }
  double norm2() { return x * x + y * y; }
  double dist(Point p) { return ((*this) - p).norm(); }
  double dist2(Point p) { return sq(x - p.x) + sq(y - p.y); }
  double arg() { return atan2(y, x); }             // [-PI,PI]
  double arg(Vector v) { return v.arg() - arg(); } // henkaku
  double angle(Vector v) {                         // [0,PI]
    return acos(cos(arg(v)));
  }
  Vector normalize() { return (*this) * (1.0 / norm()); }
  Point vert() { return Point(y, -x); }

  // Signed area of triange (0,0) (x,y) (p.x,p.y)
  double area(Point p) { return (x * p.y - p.x * y) / 2.0; }
  friend istream &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }
  friend ostream &operator<<(ostream &os, const Point &p) {
    return os << '(' << p.x << ',' << p.y << ')';
  }
};

Point divide_rate(Point a, Point b, double A, double B) {
  assert(!EQ(A + B, 0.0));
  return (a * B + b * A) * (1.0 / (A + B));
}

Vector polar(double len, double arg) {
  return Vector(cos(arg) * len, sin(arg) * len);
}

// Direction a -> b -> c
// verified AOJ CGL_1_C
enum { COUNTER_CLOCKWISE, CLOCKWISE, ONLINE_BACK, ONLINE_FRONT, ON_SEGMENT };
int ccw(Point a, Point b, Point c) {
  Vector p = b - a;
  Vector q = c - a;
  if (p.det(q) > 0.0) return COUNTER_CLOCKWISE; // counter clockwise
  if (p.det(q) < 0.0) return CLOCKWISE;         // clockwise
  if (p.dot(q) < 0.0) return ONLINE_BACK;       // c--a--b online_back
  if (p.norm() < q.norm()) return ONLINE_FRONT; // a--b--c online_front
  return ON_SEGMENT;                            // a--c--b on_segment
}

// --------------------- Line ------------------------
struct Line {
  Point a, b;
  Line() {}
  Line(Point a, Point b) : a(a), b(b) {}
  bool on(Point q) { return EQ((a - q).det(b - q), 0.0); }
  // following 2 functions verified AOJ CGL_2_A
  bool is_parallel(Line l) { return EQ((a - b).det(l.a - l.b), 0.0); }
  bool is_orthogonal(Line l) { return EQ((a - b).dot(l.a - l.b), 0.0); }
  Point intersection(Line l) {
    assert(!is_parallel(l));
    return a + (b - a) * ((l.b - l.a).det(l.a - a) / (l.b - l.a).det(b - a));
  }
  // Projection of p to this line
  // verified AOJ CGL_1_A
  Point projection(Point p) {
    return (b - a) * ((b - a).dot(p - a) / (b - a).norm2()) + a;
  }
  double distance(Point p) {
    Point q = projection(p);
    return p.dist(q);
  }
  // Reflection point of p onto this line
  // verified AOJ CGL_1_B
  Point refl(Point p) {
    Point proj = projection(p);
    return p + ((proj - p) * 2.0);
  }
  bool left(Point p) {
    if ((p - a).det(b - a) > 0.0)
      return true;
    else
      return false;
  }
  friend istream &operator>>(istream &is, Line &l) { return is >> l.a >> l.b; }
  friend ostream &operator<<(ostream &os, const Line &l) {
    return os << l.a << " -> " << l.b;
  }
};

// ------------------- Segment  ----------------------
struct Segment {
  Point a, b;
  Segment() {}
  Segment(Point a, Point b) : a(a), b(b) {}
  Line line() { return Line(a, b); }
  bool on(Point q) {
    return (EQ((a - q).det(b - q), 0.0) && LE((a - q).dot(b - q), 0.0));
  }
  // verified AOJ CGL_2_B
  bool is_intersect(Segment s) {
    if (line().is_parallel(s.line())) {
      if (on(s.a) || on(s.b)) return true;
      if (s.on(a) || s.on(b)) return true;
      return false;
    }
    Point p = line().intersection(s.line());
    if (on(p) && s.on(p))
      return true;
    else
      return false;
  }
  bool is_intersect(Line l) {
    if (line().is_parallel(l)) {
      if (l.on(a) || l.on(b))
        return true;
      else
        return false;
    }
    Point p = line().intersection(l);
    if (on(p))
      return true;
    else
      return false;
  }
  // following 2 distance functions are verified at AOJ CGL_2_D
  double distance(Point p) {
    double res = DOUBLE_INF;
    Point q = line().projection(p);
    if (on(q)) res = min(res, p.dist(q));
    res = min(res, min(p.dist(a), p.dist(b)));
    return res;
  }
  double distance(Segment s) {
    if (is_intersect(s)) return 0.0;
    double res = DOUBLE_INF;
    res = min(res, s.distance(a));
    res = min(res, s.distance(b));
    res = min(res, this->distance(s.a));
    res = min(res, this->distance(s.b));
    return res;
  }
  friend istream &operator>>(istream &is, Segment &s) {
    return is >> s.a >> s.b;
  }
  friend ostream &operator<<(ostream &os, const Segment &s) {
    return os << s.a << " -> " << s.b;
  }
};

typedef vector<Point> Polygon;

bool solve() {
  int m, n;
  cin >> m >> n;
  if (n == 0 && m == 0) return false;
  Polygon a(m), b(n);
  cin >> a >> b;

  double a_x_max = -200, b_x_max = -200;
  double a_x_min = 200, b_x_min = 200;

  for (int i = 0; i < m; i++) {
    chmax(a_x_max, a[i].x);
    chmin(a_x_min, a[i].x);
  }

  for (int i = 0; i < n; i++) {
    chmax(b_x_max, b[i].x);
    chmin(b_x_min, b[i].x);
  }

  // if (a_x_max - eps < b_x_min || b_x_max - eps < a_x_min) {
  //   cout << 0.0 << endl;
  //   return true;
  // }

  auto intersection_length = [&](const Polygon &pol, const Line &l) {
    vector<Point> ps;
    for (int i = 0; i < pol.size(); i++) {
      Segment seg(pol[i], pol[(i + 1) % pol.size()]);
      if (seg.a.x < l.a.x && seg.b.x < l.a.x) continue;
      if (seg.a.x > l.a.x && seg.b.x > l.a.x) continue;
      // if (seg.line().is_parallel(l) && EQ(pol[i].x, l.a.x)) return -1.0;
      if (seg.line().is_parallel(l)) continue;
      if (!seg.is_intersect(l)) continue;
      Point inter = seg.line().intersection(l);
      bool is_new = true;
      for (auto &p : ps) {
        if ((p - inter).norm() < eps) is_new = false;
      }
      if (is_new) ps.push_back(inter);
    }
    assert(ps.size() <= 2);
    dmp(ps);
    if (ps.size() == 2) return (ps[0] - ps[1]).norm();
    return (double)0.0;
  };

  auto f = [&](double x) {
    // cerr << fixed << setprecision(20) << x << endl;
    Line l(Point(x, 0), Point(x, 1));
    auto len_a = intersection_length(a, l);
    if (EQ(len_a, 0.0)) return (double)0.0;
    auto len_b = intersection_length(b, l);
    if (EQ(len_b, 0.0)) return (double)0.0;
    dmp(x, len_a, len_b);
    return len_a * len_b;
  };

  double ans = 0.0;
  double s = -100, step = 1.0;
  while (s + step <= 105) {
    double mid = s + step / 2.0;
    if (a_x_min <= mid && mid <= a_x_max && b_x_min <= mid && mid <= b_x_max) {
      double p = f(s), q = f(s + step / 2.0), r = f(s + step);
      ans += (p + 4.0 * q + r) * step / 6.0;
    }
    s += step;
  }
  cout << ans << endl;

  return true;
}

int main() {
  fastio();
  if (!multitest) {
    while (solve()) {}
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3444
final_rank: 14

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

template<typename F>
struct Point {
  F x, y;
  Point(F x = 0, F y = 0) : x(x), y(y) {}
  bool operator<(const Point &oth) const {
    return x == oth.x ? y < oth.y : x < oth.x;
  }
  Point operator-(const Point &oth) const {
    return Point(x - oth.x, y - oth.y);
  }
};

template<typename F>
using Polygon = vector<Point<F>>;

template<typename F>
Polygon<F> upperConvexHull(Polygon<F> P) {
  reverse(P.begin(), P.end());
  rotate(P.begin(), min_element(P.begin(), P.end(), [](Point<F> a, Point<F> b) {
    return a.x == b.x ? a.y > b.y : a.x < b.x;
  }), P.end());
  int n = P.size();
  Polygon<F> ret = {P[0]};
  for (int i = 1; i < n; ++i) {
    auto dir = P[i] - P[i - 1];
    if (dir.x > 0) ret.push_back(P[i]);
  }
  return ret;
}

template<typename F>
Polygon<F> lowerConvexHull(Polygon<F> P) {
  rotate(P.begin(), min_element(P.begin(), P.end()), P.end());
  int n = P.size();
  Polygon<F> ret = {P[0]};
  for (int i = 1; i < n; ++i) {
    auto dir = P[i] - P[i - 1];
    if (dir.x > 0) ret.push_back(P[i]);
  }
  return ret;
}

template<typename F>
double getLen(F x, Polygon<F> U, Polygon<F> L) {
  int i = upper_bound(U.begin(), U.end(), Point<F>(x, -1e9)) - U.begin();
  int j = upper_bound(L.begin(), L.end(), Point<F>(x, -1e9)) - L.begin();
  if (i == U.size() or j == L.size()) return 0;
  if (i == 0 and U[i].x > x) return 0;
  if (j == 0 and L[j].x > x) return 0;
  auto getY = [&](double x, int i, Polygon<F> P) -> double {
    if (i == 0) return P[i].y;
    return P[i].y - (double) (P[i].y - P[i - 1].y) / 
                             (P[i].x - P[i - 1].x) * 
                             (P[i].x - x);
  };
  return getY(x, i, U) - getY(x, j, L);
}


template<typename Double>
class Integration {
  Double ALPHA = sqrt((5 - sqrt(40. / 7))) / 3, WA = (322 + sqrt(11830)) / 900;
  Double W0 = 128. / 225.;
  Double BETA  = sqrt((5 + sqrt(40. / 7))) / 3, WB = (322 - sqrt(11830)) / 900;
  function<Double(Double)> f;
  Double quadrature(Double l, Double r) {
    auto m = (l + r) / 2, len = r - m;
    return (f(m - ALPHA * len) * WA + f(m - BETA * len) * WB + f(m) * W0 +
            f(m + ALPHA * len) * WA + f(m + BETA * len) * WB) * len;
  }
  Double askArea(Double l, Double r, Double exceptArea) {
    Double m = (l + r) / 2, L = quadrature(l, m), R = quadrature(m, r);
    if (abs(L + R - exceptArea) < 1e-10)
      return L + R;
    else return askArea(l, m, L) + askArea(m, r, R);
  }
public:
  Integration(function<Double(Double)> func) : f(func) {}
  Double intergal(Double l, Double r, int piece = 10) {
    Double ans = 0;
    for (Double dx = (r - l) / piece, i = 0; i < piece; ++i) {
      auto cur = l + dx * i;
      ans += askArea(cur, cur + dx, quadrature(cur, cur + dx));
    }
    return ans;
  }
};

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);
  int n, m; 
  while (cin >> n >> m and n and m) {
    Polygon<double> Z, Y;
    vector<int> Xs;
    for (int i = 0; i < n; ++i) {
      int x, y; cin >> x >> y;
      Z.emplace_back(x, y);
      Xs.emplace_back(x);
    }
    for (int i = 0; i < m; ++i) {
      int x, y; cin >> x >> y;
      Y.emplace_back(x, y);
      Xs.emplace_back(x);
    }
    sort(Xs.begin(), Xs.end());
    Xs.erase(unique(Xs.begin(), Xs.end()), Xs.end());
    Polygon<double> UZ = upperConvexHull(Z);
    Polygon<double> LZ = lowerConvexHull(Z);
    Polygon<double> UY = upperConvexHull(Y);
    Polygon<double> LY = lowerConvexHull(Y);
    double preX = Xs[0];
    double ans = 0;
    Integration<double> formula([=](double x) {
      return getLen(x, UZ, LZ) * getLen(x, UY, LY);
    });
    for (int x : Xs) {
      ans += formula.intergal(preX, x);
      preX = x;
    }
    cout << fixed << setprecision(10) << ans << '\n';
  }
}
accuracy: 1
time_ms: 70
memory_kb: 3284
final_rank: 12

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e12;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};

namespace std{
    bool operator < (const P& a, const P& b){
        return (a.X!=b.X) ? a.X<b.X : a.Y<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1; //ccw
    if(cross(b,c) < -EPS) return -1; //cw
    if(dot(b,c) < -EPS) return +2; //c-a-b
    if(abs(c)-abs(b) > EPS) return -2; //a-b-c
    return 0; //a-c-b
}

bool intersectLS(const L& l, const L& s){
    return cross(l[1]-l[0], s[0]-l[0])*
        cross(l[1]-l[0], s[1]-l[0]) < EPS;
}

bool isParallel(const P &a, const P &b){
    return abs(cross(a,b)) < EPS;
}
bool isParallel(const L &a, const L &b){
    return isParallel(a[1]-a[0], b[1]-b[0]);
}
P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1]-l[0], m[1]-m[0]);
  double B = cross(l[1]-l[0], l[1]-m[0]);
  return m[0] + B/A *(m[1]-m[0]);
}

double getarea(const VP &poly){
    double ret = 0;
    for (int i=0; i<(int)poly.size(); i++){ 
        ret += cross(poly[i], poly[(i+1)%poly.size()]);
    }
    return ret*0.5;
}

VP convex_cut(const VP& p, const L& l){
    VP ret;
    int n = p.size();
    for(int i=0; i<n; i++){
        P curr = p[i];
        P next = p[(i+1)%n];
        if(ccw(l[0], l[1], curr) != -1) ret.push_back(curr);
        if(ccw(l[0], l[1], curr) *ccw(l[0], l[1], next) == -1){
            ret.push_back(crosspointLL(L(curr, next), l));
        }
    }
    return ret;
}

struct c2cut{
    double z, x[2];
    c2cut(double z, double xmin, double xmax):z(z),x{xmin, xmax}{}
    c2cut(){}
    bool operator <(const c2cut &a){
        return z < a.z;
    }
    bool operator ==(const c2cut &a){
        return z == a.z;
    }
};

int main(){
    while(1){
        int m,n;
        cin >> m >> n;
        if(n==0) break;
        
        VP c1(m), c2(n);
        for(int i=0; i<m; i++){
            double x,y;
            cin >> x >> y;
            c1[i] = P(x, y);
        }
        for(int i=0; i<n; i++){
            double x,z;
            cin >> x >> z;
            c2[i] = P(x, z);
        }
        
        vector<c2cut> cz(n);
        for(int i=0; i<n; i++){
            double z = c2[i].Y;
            L cutline(P(0, z), P(1, z));
            vector<double> cpx;
            for(int i=0; i<n; i++){
                L edge(c2[i], c2[(i+1)%n]);
                if(!isParallel(cutline, edge) && intersectLS(cutline, edge)){
                    cpx.push_back((crosspointLL(cutline, edge)).X);
                }
            }
            double xmin = *min_element(cpx.begin(), cpx.end());
            double xmax = *max_element(cpx.begin(), cpx.end());
            cz[i] = c2cut(z, xmin, xmax);
        }
        sort(cz.begin(), cz.end());
        cz.erase(unique(cz.begin(), cz.end()), cz.end());

        double ans = 0;
        for(int i=0; i<(int)cz.size()-1; i++){
            vector<double> zdiff;
            for(int d=0; d<2; d++){
                double x[2] = {cz[i].x[d], cz[i+1].x[d]};
                if(abs(x[1]-x[0]) < EPS) continue;
                if(x[0] > x[1]) swap(x[0], x[1]);
                L cut[2] = {L(P(x[1], 0), P(x[1], 1)), L(P(x[0], 1), P(x[0], 0))};
                VP p = convex_cut(c1, cut[0]);
                p = convex_cut(p, cut[1]);
                for(int j=0; j<(int)p.size(); j++){
                    double xdiff = abs(p[j].X -cz[i].x[d]);
                    zdiff.push_back((cz[i+1].z -cz[i].z) *xdiff/(x[1]-x[0]));
                }
            }
            for(int d=0; d<2; d++){
                int xmax = cz[i+d].x[1];
                int xmin = cz[i+d].x[0];
                L cut[2] = {L(P(xmax, 0), P(xmax, 1)), L(P(xmin, 1), P(xmin, 0))};
                VP p = convex_cut(c1, cut[0]);
                p = convex_cut(p, cut[1]);
                if(!p.empty()){
                    zdiff.push_back((cz[i+1].z -cz[i].z) *d);
                }
            }
            sort(zdiff.begin(), zdiff.end());
            zdiff.erase(unique(zdiff.begin(), zdiff.end()), zdiff.end());

            for(int j=0; j<(int)zdiff.size()-1; j++){
                double z[3];
                z[0] = cz[i].z +zdiff[j];
                z[2] = cz[i].z +zdiff[j+1];
                z[1] = (z[0] +z[2])/2;
                double area[3];
                for(int k=0; k<3; k++){
                    L cutline(P(0, z[k]), P(1, z[k]));
                    vector<double> cpx;
                    for(int i=0; i<n; i++){
                        L edge(c2[i], c2[(i+1)%n]);
                        if(!isParallel(cutline, edge) && intersectLS(cutline, edge)){
                            cpx.push_back((crosspointLL(cutline, edge)).X);
                        }
                    }
                    double xmin = *min_element(cpx.begin(), cpx.end());
                    double xmax = *max_element(cpx.begin(), cpx.end());
                    L cut[2] = {L(P(xmax, 0), P(xmax, 1)), L(P(xmin, 1), P(xmin, 0))};
                    VP con = convex_cut(c1, cut[0]);
                    con = convex_cut(con, cut[1]);
                    area[k] = getarea(con);
                }
                ans += (z[2] -z[0])/6 *(area[0] +4*area[1] +area[2]);
            }
        }

        cout << fixed << setprecision(10);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3268
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF 1000000005
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)n;++i)
#define each(a, b) for(auto (a): (b))
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define pb push_back
#define show(x) cout <<#x<<" = "<<(x)<<endl
#define spair(p) cout <<#p<<": "<<p.fi<<" "<<p.se<<endl
#define svec(v) cout<<#v<<":";rep(kbrni,v.size())cout<<" "<<v[kbrni];cout<<endl
#define sset(s) cout<<#s<<":";each(kbrni,s)cout <<" "<<kbrni;cout<<endl

using namespace std;

typedef complex<double> C;
typedef pair<int,int>P;

namespace std
{
    bool operator < (const C a, const C b) {
        return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
    }
}

struct L : public vector<C>
{
    L(const C a, const C b) {
        push_back(a); push_back(b);
    }
};

bool eq(double a,double b)
{
  return (-EPS<a-b&&a-b<EPS);
}

bool eq(C c1,C c2)
{
  return (eq(c1.real(),c2.real()) && eq(c1.imag(),c2.imag()));
}

//?????¶??????sqrt
double Sqrt(double x)
{
    if(x<0) return 0;
    else    return sqrt(x);
}

//??£??????
C normalize(C c)
{
    return c / abs(c);
}

//?§????(rad)
double getarg(C a,C b){
    return  arg(b*conj(a));
}

//??????
double cross(const C a, const C b)
{
    return  imag(conj(a)*b);
}
//??????
double dot(const C a, const C b)
{
    return  real(conj(a)*b);
}

int ccw(C a, C b, C c)
{
    b -= a; c -= a;
    if (cross(b, c) > 0)   return +1;       // counter clockwise
    if (cross(b, c) < 0)   return -1;       // clockwise
    if (dot(b, c) < 0)     return +2;       // c--a--b on line
    if (norm(b) < norm(c)) return -2;       // a--b--c on line
    return 0;
}
//??´???????????????????????????(????????´??????True)
bool intersectLL(const L &l, const L &m)
{
    return abs(cross(l[1]-l[0], m[1]-m[0])) > EPS || abs(cross(l[1]-l[0], m[0]-l[0])) < EPS;
}
//??´?????¨?????????????????????(????????±??????????????¨??????)
bool intersectLS(const L &l, const L &s)
{
    return cross(l[1]-l[0], s[0]-l[0]) * cross(l[1]-l[0], s[1]-l[0]) < EPS;
}
//??´?????¨????????????(??±???)??????
bool intersectLP(const L &l, const C p)
{
    return abs(cross(l[1]-p, l[0]-p)) < EPS;
}
//??????????????????????????????(????????±??????????????¨??????)
bool intersectSS(const L &s, const L &t)
{
    return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 && ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
}
//????????¨????????????(??±???)??????
bool intersectSP(const L &s, const C p)
{
    return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS;
}
//???p?????´???l???????°???±
C projection(const L &l, const C p)
{
    double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
    return l[0] + t*(l[0]-l[1]);
}
//???p?????´???l????????¨??????????§°?§????
C reflection(const L &l, const C p)
{
    return p + (projection(l, p) - p)*2.0;
}
//?????¨??´???????????¢
double distanceLP(const L &l, const C p)
{
    return abs(p - projection(l, p));
}
//??´?????¨??´???????????¢
double distanceLL(const L &l, const L &m)
{
    return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
//??´?????¨??????????????¢
double distanceLS(const L &l, const L &s)
{
    if (intersectLS(l, s)) return 0;
    return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
//????????¨???????????¢
double distanceSP(const L &s, const C p)
{
    const C r = projection(s, p);
    if (intersectSP(s, r)) return abs(r - p);
    return min(abs(s[0] - p), abs(s[1] - p));
}
//????????¨??????????????¢
double distanceSS(const L &s, const L &t)
{
    if (intersectSS(s, t)) return 0;
    return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}
//??´???????????????????????????
C crosspointLL(const L &l, const L &m)
{
    double A = cross(l[1] - l[0], m[1] - m[0]);
    double B = cross(l[1] - l[0], l[1] - m[0]);
    //????????´????????¨???
    if(abs(A) < EPS && abs(B) < EPS){
        return m[0];
    }
    return m[0] + B / A * (m[1] - m[0]);
}
//?????¨??´????????????
double gettime(C c1,C c2)
{
  return (dot(c1,c2) < 0 ? -1.0 : 1.0 ) * abs(c2) / abs(c1);
}
//?????¨??´????????????
vector<C> crosspointCL(C c1,double r1,L l)
{
    C a=l[0], b=l[1];
    vector<C> res;
    C base=b-a,  target=projection(L(a,b),c1);
    double length=abs(base), h=abs(c1-target);
    base/=length;
    if(r1+EPS<h)    return res;
    double w=Sqrt(r1*r1-h*h);
    double LL=gettime(normalize(b-a),target-a)-w,RR=LL+w*2.0;
    res.push_back(a+base*LL);
    if(eq(LL,RR))   return res;
    res.push_back(a+base*RR);
    return res;
}
//?????¨???????????????
vector<C> crosspointCS(C c1,double r1,L s)
{
    vector<C> tmp=crosspointCL(c1,r1,s);
    vector<C> res;
    rep(i,tmp.size()){
        if(eq(abs(s[1]-s[0]),abs(s[0]-tmp[i])+abs(s[1]-tmp[i]))){
            res.push_back(tmp[i]);
        }
    }
    return res;
}
//?????????????????????
L crosspointCC(const C c1, const double r1, const C c2, const double r2)
{
  C a = conj(c2-c1), b = (r2*r2-r1*r1-(c2-c1)*conj(c2-c1)), c = r1*r1*(c2-c1);
  C d = b*b-4.0*a*c;
  C z1 = (-b+sqrt(d))/(2.0*a)+c1, z2 = (-b-sqrt(d))/(2.0*a)+c1;
  return L(z1, z2);
}
//?????¨????§???¢?????±?????¨????????¢???
double getarea(C c1,double r1,C a,C b)
{
    C va=c1-a,vb=c1-b;
    double A=abs(va),B=abs(vb);
    double f=cross(va,vb),d=distanceSP(L(a,b),c1),res=0;
    if(eq(f,0.0))   return 0;
    if(A < r1+EPS && B < r1+EPS)    return f*0.5;
    if(d>r1-EPS)    return r1*r1*M_PI*getarg(va,vb)/(2.0*M_PI);
    vector<C> u=crosspointCS(c1,r1,L(a,b));
    u.insert(u.begin(),a),u.push_back(b);
    for(int i=0;i+1<(int)u.size();i++){
        res+=getarea(c1,r1,u[i],u[i+1]);
    }
    return res;
}
double getcrossarea(vector<C> t,C c1,double r1)
{
    int n=t.size();
    if(n<3) return 0;
    double res=0;
    rep(i,n){
      C a=t[i], b=t[(i+1)%n];
      res += getarea(c1,r1,a,b);
    }
    return res;
}
//??????????±???????
vector<C> convex_hull(vector<C> ps)
{
    int n = ps.size(), k = 0;
    sort(ps.begin(), ps.end());
    vector<C> ch(2*n);
    for (int i = 0; i < n; ch[k++] = ps[i++]){
        while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) k--;
    }
    for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]){
        while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) k--;
    }
    ch.resize(k-1);
    return ch;
}
//?????§??????
bool isconvex(const vector<C> &ps)
{
    rep(i,ps.size()){
        if (ccw(ps[(i+ps.size()-1) % ps.size()],ps[i],ps[(i+1) % ps.size()])) return false;
    }
    return true;
}
//????§???¢?????¢???
double area(const vector<C> &ps)
{
    double A = 0;
    rep(i,ps.size()){
        A += cross(ps[i],ps[(i+1) % ps.size()]);
    }
    return A / 2.0;
}
//???????§???¢?????´?????§???????????????????????´????????¢
vector<C> convex_cut(const vector<C> &ps, const L &l)
{
    vector<C> Q;
    rep(i,ps.size()){
        C A = ps[i], B = ps[(i+1)%ps.size()];
        if (ccw(l[0], l[1], A) != -1) Q.push_back(A);
        if (ccw(l[0], l[1], A)*ccw(l[0], l[1], B) < 0)
            Q.push_back(crosspointLL(L(A, B),l));
    }
    return Q;
}
//??????????§???¢???????????????????????????(0??????????????????,1?????????,2???????????????)
int contains(const vector<C>& ps, const C p)
{
    bool flag = false;
    rep(i,ps.size()) {
        C a = ps[i] - p, b = ps[(i+1)%ps.size()] - p;
        if (imag(a) > imag(b)) swap(a, b);
        if (imag(a) <= 0 && 0 < imag(b)){
            if (cross(a, b) < 0) flag = !flag;
        }
        if (cross(a, b) == 0 && dot(a, b) <= 0) return 1;
  }
  return flag ? 2 : 0;
}
//???????§???¢?????´???????±???????(?????£????????????)
//maxi,maxj?????????????????¨??????
double convex_diameter(const vector<C> &ps)
{
    const int n = ps.size();
    int is = 0, js = 0;
    for (int i = 1; i < n; ++i) {
        if (imag(ps[i]) > imag(ps[is])) is = i;
        if (imag(ps[i]) < imag(ps[js])) js = i;
    }
    double maxd = abs(ps[is]-ps[js]);
    int i, maxi, j, maxj;
    i = maxi = is;
    j = maxj = js;
    do{
        if (cross(ps[(i+1)%ps.size()]-ps[i],ps[(j+1)%ps.size()]-ps[j]) >= 0) j = (j+1) % n;
        else i = (i+1) % n;
        if (abs(ps[i]-ps[j]) > maxd) {
            maxd = abs(ps[i]-ps[j]);
            maxi = i; maxj = j;
        }
    } while (i != is || j != js);
    return maxd;
}

bool compyx(C c1,C c2)
{
    return c1.imag() != c2.imag() ? c1.imag() < c2.imag() : c1.real() < c2.real();
}

//????????????????±???????
double closest_pair(C *a, int n)
{
    if(n<=1) return INF;
    int m=n/2;
    double x=a[m].real();
    double d=min(closest_pair(a,m),closest_pair(a+m,n-m));
    inplace_merge(a,a+m,a+n,compyx);
    vector<C> b;
    rep(i,n){
        if(abs(x-a[i].real())>=d) continue;
        rep(j,b.size()){
            C dp=a[i]-b[b.size()-1-j];
            if(dp.imag()>=d) break;
            d=min(d,abs(dp));
        }
        b.push_back(a[i]);
    }
    return d;
}
double compute_shortest(C *a,int n)
{
    sort(a,a+n);
    return closest_pair(a,n);
}
//2??????????????¢????????????(????????????2??????????????±?????\????????°)
int getstateCC(C c1,double r1,C c2,double r2)
{
    double d=abs(c1-c2);
    if(d>r1+r2+EPS)return 4;
    if(d>r1+r2-EPS)return 3;
    if(d>abs(r1-r2)+EPS)return 2;
    if(d>abs(r1-r2)-EPS)return 1;
    return 0;
}
//?????????????????\???????????????????????\???
C gettangentCP_(C c1,double r1,C p,int flg){
    C base=c1-p;
    double w=Sqrt(norm(base)-r1*r1);
    C s=p+base*C(w,r1 * flg)/norm(base)*w;
    return s;
}
//????????????????????\???
vector<L> gettangentCP(C c1,double r1,C p){
    vector<L> res;
    C s=gettangentCP_(c1,r1,p,1);
    C t=gettangentCP_(c1,r1,p,-1);
    //??????????????¨??????????????´???
    if(eq(s,t)){
        res.push_back(L(s,s+(c1-p)*C(0,1)));
    }else{
        res.push_back(L(p,s));
        res.push_back(L(p,t));
    }
    return res;
}

//2????????±????????\???????±???????
L getintangent(C c1,double r1,C c2,double r2,double flg)
{
    C base=c2-c1;
    double w=r1+r2;
    double h=Sqrt(norm(base)-w*w);
    C k=base*C(w,h*flg)/norm(base);
    return L(c1+k*r1,c2-k*r2);
}
//2????????±????????\???????±???????
L getouttangent(C c1,double r1,C c2,double r2,double flg)
{
    C base=c2-c1;
    double h=r2-r1;
    double w=Sqrt(norm(base)-h*h);
    C k=base*C(w,h*flg)/norm(base)*C(0,flg);
    return L(c1+k*r1,c2+k*r2);
}
//2????????±?????\???????±???????(?????´??????????????????????????????????????\???)
vector<L> gettangentCC(C c1,double r1,C c2,double r2)
{
    vector<L> res;
    double d=abs(c1-c2);
    if(d>r1+r2+EPS)  res.push_back(getintangent(c1,r1,c2,r2,1));
    if(d>r1+r2-EPS)  res.push_back(getintangent(c1,r1,c2,r2,-1));
    if(d>abs(r1-r2)+EPS)    res.push_back(getouttangent(c1,r1,c2,r2,1));
    if(d>abs(r1-r2)-EPS)    res.push_back(getouttangent(c1,r1,c2,r2,-1));
    return res;
}

double width(vector<P> vec,int n,double x)
{
    double lb = INF,ub = -INF;
    rep(i,n){
        L hoge(C(vec[i].fi,vec[i].se),C(vec[(i+1)%n].fi,vec[(i+1)%n].se));
        L cri(C(x,101),C(x,-101));
        if(intersectLS(cri,hoge)){
            C res = crosspointLL(cri,hoge);
            lb = min(lb,res.imag());
            ub = max(ub,res.imag());
        }
    }
    return max(0.0,ub-lb);
}

int main()
{
    while(1){
        int n,m;
        cin >> m >> n;
        if(n == 0 && m == 0){
            break;
        }
        vector<P> v1,v2;
        vector<int> ax;
        rep(i,m){
            int x,y;
            cin >> x >> y;
            v1.pb(P(x,y));
            ax.pb(x);
        }
        rep(i,n){
            int x,y;
            cin >> x >> y;
            v2.pb(P(x,y));
            ax.pb(x);
        }
        sort(all(ax));
        ax.erase(unique(all(ax)),ax.end());
        int mn1 = (*min_element(all(v1))).fi;
        int mx1 = (*max_element(all(v1))).fi;
        int mn2 = (*min_element(all(v2))).fi;
        int mx2 = (*max_element(all(v2))).fi;
        double res = 0.0;
        rep(i,ax.size()-1){
            double a = ax[i],b = ax[i+1],c = (a+b)/2;
            if(mn1 <= c && c <= mx1 && mn2 <= c && c <= mx2){
                double fa = width(v1,m,a) * width(v2,n,a);
                double fb = width(v1,m,b) * width(v2,n,b);
                double fc = width(v1,m,c) * width(v2,n,c);
                res += (b - a) / 6 * (fa + 4*fc + fb);
            }
        }
        printf("%.10f\n",res);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3176
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef double dbl;
#define double long double
typedef complex<double> P;
typedef vector<P> G;
#define REP(i,n) for(int i = 0 ; i < n ; i++)
double eps = 1e-11;
double EPS = eps;

bool eq(double a,double b){
	return fabs(a-b) < eps;
}

double cross(P a,P b) { return imag(conj(a)*b); }
double dot(P a,P b) { return real(conj(a)*b);}

vector<P> ps1,ps2;
//??´???
struct L : public vector<P> {
	L(P a,P b) {
		push_back(a); push_back(b);
	}
	
};
int ccw(P a, P b, P c) {
	b -= a; c -= a;
	if (cross(b, c) > 0)   return +1;	// a ??? b ??§???????¨??????????????????? b ??? c(???)
	if (cross(b, c) < 0)   return -1;	// a ??? b ??§????¨??????????????????? b ??? c(???)
	if (dot(b, c) < 0) return +2;    	// a???b??§????????????a??????????¶???????b???c(c--a--b)
	if (norm(b) < norm(c)) return -2;	// a???b??§????????????b???c(a--b--c)
	return 0;							// a???b??§????????????b???c(????????? b == c)
}
 


P crosspoint(const L &l, const L &m) {
	double A = cross(l[1] - l[0], m[1] - m[0]);
	double B = cross(l[1] - l[0], l[1] - m[0]);
	if (abs(A) < EPS && abs(B) < EPS) return m[0];
	return m[0] + B / A * (m[1] - m[0]);
}
 
 
// ???????§???¢???????????????????§???¢???????????´?????§????????????
//???????????´?????????????????´?????????????????´?????????????????¨?????????????????¨?????????????????????????????¨????????????????????????
#define curr(P, i) P[(i) % P.size()]
#define next(P, i) P[(i+1)%P.size()]
#define prev(P, i) P[(i+P.size()-1) % P.size()]
G convex_cut(const G& poly, const L& l) {
  G Q;
  for (int i = 0; i < poly.size(); ++i) {
    P A = curr(poly, i), B = next(poly, i);
    if (ccw(l[0], l[1], A) != -1) Q.push_back(A);
    if (ccw(l[0], l[1], A)*ccw(l[0], l[1], B) < 0)
      Q.push_back(crosspoint(L(A, B), l));
  }
  return Q;
}

// ????´?????§???¢?????¢??????"2???"????±??????? O(n)
double area2(const G& poly) {
	double A = 0;
	REP(i,poly.size()) A += cross(curr(poly, i), next(poly, i));
	return abs(A);
}


vector<double> ux;

P in(){
	double x,y;
	cin >> x >> y;
	
	return P(x,y);
}
pair<double,double> seg(const vector<P> &ps,double x){
	double mi = 1e9, ma = -1e9;
	auto reflesh = [&mi,&ma](double y){
		mi = min(mi,y);
		ma = max(ma,y);
	};
	for(int i = 0 ; i < ps.size() ; i++){
		P a = ps[i];
		P b = ps[(i+1)%ps.size()];
		if( a.real() > b.real() ) swap(a,b);
		if( eq(a.real(),x) ) reflesh(a.imag());
		if( eq(b.real(),x) ) reflesh(b.imag());
		if( a.real() + eps < x and x < b.real() - eps ){
			reflesh(a.imag() + (x - a.real()) * (b.imag() - a.imag()) / (b.real()-a.real()));
		}
	}
	if( ma < mi ) return {0.0,0.0};
	return {mi,ma};
}

double S(double l,double r){
	if( r <= l ) return 0;
	G g1 = convex_cut(ps1,L(P(l,0),P(l,-1)));
	G g2 = convex_cut(g1,L(P(r,0),P(r,+1)));
	
	return area2(g2) / 2;
	
}

double Vf(double z){
	auto p = seg(ps2,z);
	return S(p.first,p.second);
}

double Vs(double l,double r){
	return (r-l)/6*(Vf(l)+4*Vf((l+r)/2)+Vf(r));
}

double V(double l,double r,int k=6){
	if( l >= r ) return 0;
	double m = (l+r)/2;
	double a = Vs(l,m);
	double b = Vs(m,r);
	double c = Vs(l,r);
	if( ( k <= 0) and eq(a+b,c) ){
		return c;
	}else{
		return V(l,m,k-1) + V(m,r,k-1);
	}	
}

int main(){
	int m,n;
	while(cin >> m >> n && m ){
		
		ps1.clear();
		ps2.clear();
		ux.clear();
		for(int i = 0 ; i < m ; i++){
			ps1.push_back(in());
			ux.push_back(ps1.back().real());
		}

		vector<double> uz;
		for(int i = 0 ; i < n ; i++){
			ps2.push_back(in());
			ps2.back() = P(ps2.back().imag(),ps2.back().real());
			uz.push_back(ps2.back().real());

		}
		
		sort(uz.begin(),uz.end());
		sort(ux.begin(),ux.end());
		double vans = 0;
		//for( auto z : uz ) cout << z << " "; cout << endl;
		//for( auto x : ux ) cout << x << " "; cout << endl;
		for(int i = 0 ; i+1 < uz.size() ; i++)
			if( uz[i] != uz[i+1] )
				vans += V(uz[i],uz[i+1]);
		printf("%.8lf\n",(dbl)vans);
	}
}
accuracy: 1
time_ms: 5650
memory_kb: 3240
final_rank: 16

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <cstring>
#include <functional>
#include <cmath>
#include <complex>
#include <cassert>
using namespace std;
#define rep(i,n) for(int i=0;i<(n);++i)
#define rep1(i,n) for(int i=1;i<=(n);++i)
#define all(c) (c).begin(),(c).end()
#define fs first
#define sc second
#define pb push_back
#define show(x) cout << #x << " " << x << endl
typedef long double D;
typedef complex<D> P;
typedef pair<P,P> L;
typedef vector<P> Pol;
D eps=1e-11,Eps=1e-9;
D cro(P a,P b){return imag(conj(a)*b);}
int ccw(P a,P b,P c){
	if(cro(b-a,c-a)>eps) return 1;
	if(cro(b-a,c-a)<-eps) return -1;
	if(abs(abs(a-c)+abs(c-b)-abs(a-b))<eps) return 0;
	if(abs(abs(a-b)+abs(c-b)-abs(a-c))<eps) return -2;
	return 2;
}
bool iLS(L l,L s){
	if(abs(cro(l.fs-l.sc,s.fs-s.sc))<eps) return 0;
	return cro(l.sc-l.fs,s.fs-l.fs)*cro(l.sc-l.fs,s.sc-l.fs)<eps;
}
P intLL(L a,L b){
	D t=cro(a.sc-a.fs,a.sc-b.fs)/cro(a.sc-a.fs,b.sc-b.fs);
	return b.fs+t*(b.sc-b.fs);
}
int M,N;
Pol a,b;
D rec(D x){
	L l=L(P(x,0),P(x,1));
	Pol inters;
	rep(j,M){
		L e=L(a[j],a[(j+1)%M]);
		if(iLS(l,e)) inters.pb(intLL(l,e));
	}
	if(inters.size()<=1) return -1;
	D leny=0;
	for(P p:inters) for(P q:inters) leny=max(leny,abs(p-q));
	inters.clear();
	rep(j,N){
		L e=L(b[j],b[(j+1)%N]);
		if(iLS(l,e)) inters.pb(intLL(l,e));
	}
	if(inters.size()<=1) return -1;
	D lenz=0;
	for(P p:inters) for(P q:inters) lenz=max(lenz,abs(p-q));
	return leny*lenz;
}
int main(){
	while(true){
		cin>>M>>N;
		if(M==0) break;
		a.clear(),b.clear();
		vector<D> xs;
		D ans=0;
		rep(i,M){
			D x,y;
			cin>>x>>y;
			a.pb(P(x,y));
			xs.pb(x-Eps);
			xs.pb(x+Eps);
		}
		rep(i,N){
			D x,y;
			cin>>x>>y;
			b.pb(P(x,y));
			xs.pb(x-Eps);
			xs.pb(x+Eps);
		}
		sort(all(xs));
		rep(i,xs.size()-1){
			if(rec(xs[i])<-eps||rec(xs[i])<-eps) continue;
			ans+=(xs[i+1]-xs[i])/6.0*(rec(xs[i])+4.0*rec((xs[i+1]+xs[i])/2)+rec(xs[i+1]));
		}
		printf("%.4f\n",(double)ans);
	}
}
accuracy: 1
time_ms: 110
memory_kb: 1308
final_rank: 7

code_snippet: #include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <unordered_map>
#include <iterator>
#include <assert.h>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define REPS(i,x) for(int i=1;i<=(int)(x);i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RREPS(i,x) for(int i=((int)(x));i>0;i--)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) (container).begin(), (container).end()
#define RALL(container) (container).rbegin(), (container).rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}
template<class S, class T> pair<S,T> operator+(const pair<S,T> &s, const pair<S,T> &t){ return pair<S,T>(s.first+t.first, s.second+t.second);}
template<class S, class T> pair<S,T> operator-(const pair<S,T> &s, const pair<S,T> &t){ return pair<S,T>(s.first-t.first, s.second-t.second);}

namespace geom{
#define X real()
#define Y imag()
#define at(i) ((*this)[i])
#define SELF (*this)
	enum {TRUE = 1, FALSE = 0, BORDER = -1};
	typedef int BOOL;
	typedef long double R;
	const R INF = 1e8;
	R EPS = 1e-12;
	const R PI = 3.1415926535897932384626;
	inline int sig(const R &x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }
	inline BOOL less(const R &x, const R &y) {return sig(x-y) ? x < y : BORDER;}
	typedef complex<R> P;
	inline R norm(const P &p){return p.X*p.X+p.Y*p.Y;}
	inline R inp(const P& a, const P& b){return (conj(a)*b).X;}
	inline R outp(const P& a, const P& b){return (conj(a)*b).Y;}
	inline P unit(const P& p){return p/abs(p);}
	inline P proj(const P &s, const P &t){return t*inp(s, t)/norm(t);}
	inline int ccw(const P &s, const P &t, const P &p, int adv=0){
		int res = sig(outp(t-s, p-s));
		if(res || !adv) return res;
		if(sig(inp(t-s, p-s)) < 0) return -2;	// p-s-t
		if(sig(inp(s-t, p-t)) < 0) return 2;	// s-t-p
		return 0;								// s-p-t
	}
	
	
	struct L : public vector<P>{	// line
		L(const P &p1, const P &p2){this->push_back(p1);this->push_back(p2);}
		L(){}
		P dir()const {return at(1) - at(0);}
	};
	struct S : public L{	// segment
		S(const P &p1, const P &p2):L(p1, p2){}
		S(){}
	};
	struct G : public vector<P>{
		G(size_type size=0):vector(size){}
		S edge(int i)const {return S(at(i), at(i+1 == size() ? 0 : i+1));}
	};
	BOOL intersect(const S &s, const S &t){
		const int p = ccw(t[0], t[1], s[0], 1) * ccw(t[0], t[1], s[1], 1);
		const int q = ccw(s[0], s[1], t[0], 1) * ccw(s[0], s[1], t[1], 1);
		return (p>0||q>0) ? FALSE : (!p||!q) ? BORDER : TRUE;
	}
	BOOL intersect(const S &s, const L &l){
		return (sig(outp(l.dir(), s[0]-l[0])) * sig(outp(l.dir(), s[1]-l[0])) <= 0);
	}
	inline P crosspoint(const L &l, const L &m){
		R A = outp(l.dir(), m.dir()), B = outp(l.dir(), l[1] - m[0]);
		if(!sig(abs(A)) && !sig(abs(B))) return m[0]; // same line
		if(abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
		return m[0] + B / A * (m[1] - m[0]);
	}

	template<class Func> R simpson(R s, R t, Func func){
		return (t-s)/6*(func(s+2*EPS) + func(t-2*EPS) + 4*func((s+t)*(R).5));
	}
#undef SELF
#undef at
}

using namespace geom;

int f = 0;
namespace std{
	bool operator<(const P &a, const P &b){return sig(a.X-b.X) ? a.X < b.X : a.Y+EPS < b.Y;}
	bool operator==(const P &a, const P &b){return abs(a-b) < EPS;}
	istream& operator>>(istream &is, P &p){R x,y;is>>x>>y;p=P(x, y);return is;}
	istream& operator>>(istream &is, L &l){l.resize(2);return is >> l[0] >> l[1];}
}

int n, m;

int main(){
	ios::sync_with_stdio(false);
	while(cin >> m >> n, n){
		G g1(m), g2(n);
		vector<R> x;
		REP(i, m){
			cin >> g1[i];
			x.push_back(g1[i].X);
		}
		REP(i, n){
			cin >> g2[i];
			x.push_back(g2[i].X);
		}
		sort(ALL(x));UNIQUE(x);
		
		auto width = [&](const G &g, R x){
			L l(P(x, 0), P(x, 1));
			R b = INF, u = -INF;
			REP(i, g.size()){
				if(sig(g.edge(i).dir().X) && intersect(g.edge(i), l)){
					P p = crosspoint(g.edge(i), l);
					b = min(b, p.Y);
					u = max(u, p.Y);
				}
			}
			return max<R>(0, u-b);
		};
		auto area = [&](R x){
			return width(g1, x) * width(g2, x);
		};
		
		R ans = 0;
		REP(i, (int)x.size()-1){
			ans += simpson(x[i], x[i+1], area);
		}
		printf("%.10f\n", (double)ans);
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 1308
final_rank: 6

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(a) (a).begin(),(a).end()
#define EQ(a,b) (abs((a)-(b)) < EPS)
#define fs first
#define sc second
using namespace std;
typedef double D;
typedef complex<D> P;
typedef pair<P,P> L;

const D EPS = 1e-8;

namespace std{
  bool operator<(const P &a,const P &b){
    return EQ(real(a),real(b))?imag(a)<imag(b):real(a)<real(b);
  }
  bool operator==(const P &a, const P &b){return EQ(a,b);}
}

inline D dot(P x, P y){return real(conj(x)*y);}
inline D cross(P x, P y){return imag(conj(x)*y);}

inline int ccw(P a,P b,P c){
  b -= a;c -= a;
  if (cross(b,c)>EPS) return 1;   //counter clockwise
  if (cross(b,c)<-EPS) return -1; //clockwise
  if (dot(b, c)<-EPS) return 2;   //c--a--b on line
  if (abs(b)+EPS<abs(c)) return -2;   //a--b--c on line
  return 0;                       //on segment
}

inline bool para(L a,L b){return abs(cross(a.fs-a.sc,b.fs-b.sc))<EPS;}

inline bool is_cp(L a,L b){
  if(para(a,b))return false;
  if(ccw(a.fs,a.sc,b.fs)*ccw(a.fs,a.sc,b.sc)<=0)
    if(ccw(b.fs,b.sc,a.fs)*ccw(b.fs,b.sc,a.sc)<=0)return true;
  return false;
}

inline P line_cp(L a,L b){
  return a.fs+(a.sc-a.fs)*cross(b.sc-b.fs,b.fs-a.fs)/cross(b.sc-b.fs,a.sc-a.fs);
}

vector<P> p[2];
inline D len(D x, int id){
  L l = L( P(x,-1000), P(x,1000) );
  vector<P> res;
  rep(i,p[id].size()){
    L a = L( p[id][i], p[id][(i+1)%p[id].size()] );
    if(is_cp(a,l)){
      P cp = line_cp(a,l);
      if(!EQ(cp,p[id][i]))res.push_back(cp);
    }else if(para(a,l) && ccw(l.fs,l.sc,a.sc)==0){
      res.push_back(a.sc);
    }
  }

  if(res.size()<2)return 0;
  return abs(res[0]-res[1]);
}

inline D f(D x){
  return len(x/2,0) * len(x/2,1);
}

int main(){
  int m,n;
  while(cin >> m >> n, m){
    int minx[2], maxx[2];
    p[0].resize(m); p[1].resize(n);
    minx[0] = minx[1] = 1000;
    maxx[0] = maxx[1] = -1000;

    rep(i,m){
      int x,y;
      cin >> x >> y;
      p[0][i] = P(x,y);
      minx[0]=min(minx[0],x);
      maxx[0]=max(maxx[0],x);
    }

    rep(i,n){
      int x,z;
      cin >> x >> z;
      p[1][i] = P(x,z);
      minx[1]=min(minx[1],x);
      maxx[1]=max(maxx[1],x);
    }

    D ans = 0;
    for(D i=-199;i<200;i+=2){
      if(2*minx[0]<=i && i<=2*maxx[0]){
	if(2*minx[1]<=i && i<=2*maxx[1]){
	  ans += f(i-1)+4*f(i)+f(i+1);
	}
      }
    }
    cout << fixed << setprecision(9) << ans/6 << endl;
  }
}
accuracy: 1
time_ms: 20
memory_kb: 1288
final_rank: 3

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(a) (a).begin(),(a).end()
#define EQ(a,b) (abs((a)-(b)) < EPS)
#define fs first
#define sc second
using namespace std;
typedef double D;
typedef complex<D> P;
typedef pair<P,P> L;

const D EPS = 1e-8;

namespace std{
  bool operator<(const P &a,const P &b){
    return EQ(real(a),real(b))?imag(a)<imag(b):real(a)<real(b);
  }
  bool operator==(const P &a, const P &b){return EQ(a,b);}
}

inline D dot(P x, P y){return real(conj(x)*y);}
inline D cross(P x, P y){return imag(conj(x)*y);}

int ccw(P a,P b,P c){
  b -= a;c -= a;
  if (cross(b,c)>EPS) return 1;   //counter clockwise
  if (cross(b,c)<-EPS) return -1; //clockwise
  if (dot(b, c)<-EPS) return 2;   //c--a--b on line
  if (abs(b)+EPS<abs(c)) return -2;   //a--b--c on line
  return 0;                       //on segment
}

inline bool para(L a,L b){return abs(cross(a.fs-a.sc,b.fs-b.sc))<EPS;}

inline bool is_cp(L a,L b){
  if(para(a,b))return false;
  if(ccw(a.fs,a.sc,b.fs)*ccw(a.fs,a.sc,b.sc)<=0)
    if(ccw(b.fs,b.sc,a.fs)*ccw(b.fs,b.sc,a.sc)<=0)return true;
  return false;
}

inline P line_cp(L a,L b){
  return a.fs+(a.sc-a.fs)*cross(b.sc-b.fs,b.fs-a.fs)/cross(b.sc-b.fs,a.sc-a.fs);
}

vector<P> p[2];
inline D len(D x, int id){
  L l = L( P(x,-1000), P(x,1000) );
  vector<P> res;
  rep(i,p[id].size()){
    L a = L( p[id][i], p[id][(i+1)%p[id].size()] );
    if(is_cp(a,l)){
      P cp = line_cp(a,l);
      if(!EQ(cp,p[id][i]))res.push_back(cp);
    }else if(para(a,l) && ccw(l.fs,l.sc,a.sc)==0){
      res.push_back(a.sc);
    }
  }

  if(res.size()<2)return 0;
  return abs(res[0]-res[1]);
}

inline D f(D x){
  return len(x/2,0) * len(x/2,1);
}

int main(){
  int m,n;
  while(cin >> m >> n, m){
    int minx[2], maxx[2];
    p[0].resize(m); p[1].resize(n);
    minx[0] = minx[1] = 1000;
    maxx[0] = maxx[1] = -1000;

    rep(i,m){
      int x,y;
      cin >> x >> y;
      p[0][i] = P(x,y);
      minx[0]=min(minx[0],x);
      maxx[0]=max(maxx[0],x);
    }

    rep(i,n){
      int x,z;
      cin >> x >> z;
      p[1][i] = P(x,z);
      minx[1]=min(minx[1],x);
      maxx[1]=max(maxx[1],x);
    }

    D ans = 0;
    for(D i=-199;i<200;i+=2){
      if(2*minx[0]<=i && i<=2*maxx[0]){
	if(2*minx[1]<=i && i<=2*maxx[1]){
	  ans += f(i-1)+4*f(i)+f(i+1);
	}
      }
    }
    cout << fixed << setprecision(9) << ans/6 << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 1284
final_rank: 4

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(a) (a).begin(),(a).end()
#define EQ(a,b) (abs((a)-(b)) < EPS)
#define fs first
#define sc second
using namespace std;
typedef double D;
typedef complex<D> P;
typedef pair<P,P> L;

const D EPS = 1e-8;

namespace std{
  bool operator<(const P &a,const P &b){
    return EQ(real(a),real(b))?imag(a)<imag(b):real(a)<real(b);
  }
  bool operator==(const P &a, const P &b){return EQ(a,b);}
}

inline D dot(P x, P y){return real(conj(x)*y);}
inline D cross(P x, P y){return imag(conj(x)*y);}

int ccw(P a,P b,P c){
  b -= a;c -= a;
  if (cross(b,c)>EPS) return 1;   //counter clockwise
  if (cross(b,c)<-EPS) return -1; //clockwise
  if (dot(b, c)<-EPS) return 2;   //c--a--b on line
  if (abs(b)+EPS<abs(c)) return -2;   //a--b--c on line
  return 0;                       //on segment
}

inline bool para(L a,L b){return abs(cross(a.fs-a.sc,b.fs-b.sc))<EPS;}

inline bool is_cp(L a,L b){
  if(para(a,b))return false;
  if(ccw(a.fs,a.sc,b.fs)*ccw(a.fs,a.sc,b.sc)<=0)
    if(ccw(b.fs,b.sc,a.fs)*ccw(b.fs,b.sc,a.sc)<=0)return true;
  return false;
}

inline P line_cp(L a,L b){
  return a.fs+(a.sc-a.fs)*cross(b.sc-b.fs,b.fs-a.fs)/cross(b.sc-b.fs,a.sc-a.fs);
}

vector<P> p[2];
inline D len(D x, int id){
  L l = L( P(x,-1000), P(x,1000) );
  vector<P> res;
  rep(i,p[id].size()){
    L a = L( p[id][i], p[id][(i+1)%p[id].size()] );
    if(is_cp(a,l)){
      P cp = line_cp(a,l);
      if(!EQ(cp,p[id][i]))res.push_back(cp);
    }else if(para(a,l) && ccw(l.fs,l.sc,a.sc)==0){
      res.push_back(a.sc);
    }
  }

  if(res.size()<2)return 0;
  return abs(res[0]-res[1]);
}

inline D f(D x){
  return len(x,0) * len(x,1);
}

int main(){
  int m,n;
  while(cin >> m >> n, m){
    D minx[2], maxx[2];
    p[0].resize(m); p[1].resize(n);
    minx[0] = minx[1] = 1000;
    maxx[0] = maxx[1] = -1000;

    rep(i,m){
      D x,y;
      cin >> x >> y;
      p[0][i] = P(x,y);
      minx[0]=min(minx[0],x);
      maxx[0]=max(maxx[0],x);
    }

    rep(i,n){
      D x,z;
      cin >> x >> z;
      p[1][i] = P(x,z);
      minx[1]=min(minx[1],x);
      maxx[1]=max(maxx[1],x);
    }

    D ans = 0;
    for(D i=-100;i<100;i+=1){
      if(minx[0]<=i+0.5 && i+0.5<=maxx[0]){
	if(minx[1]<=i+0.5 && i+0.5<=maxx[1]){
	  ans += f(i)+4*f(i+0.5)+f(i+1);
	}
      }
    }
    cout << fixed << setprecision(9) << ans/6 << endl;
  }
}
accuracy: 1
time_ms: 20
memory_kb: 1320
final_rank: 5

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(a) (a).begin(),(a).end()
#define EQ(a,b) (abs((a)-(b)) < EPS)
#define fs first
#define sc second
using namespace std;
typedef long double D;
typedef complex<D> P;
typedef pair<P,P> L;

const D EPS = 1e-8;

namespace std{
  bool operator<(const P &a,const P &b){
    return EQ(real(a),real(b))?imag(a)<imag(b):real(a)<real(b);
  }
  bool operator==(const P &a, const P &b){return EQ(a,b);}
}

inline D dot(P x, P y){return real(conj(x)*y);}
inline D cross(P x, P y){return imag(conj(x)*y);}

int ccw(P a,P b,P c){
  b -= a;c -= a;
  if (cross(b,c)>EPS) return 1;   //counter clockwise
  if (cross(b,c)<-EPS) return -1; //clockwise
  if (dot(b, c)<-EPS) return 2;   //c--a--b on line
  if (abs(b)+EPS<abs(c)) return -2;   //a--b--c on line
  return 0;                       //on segment
}

inline bool para(L a,L b){return abs(cross(a.fs-a.sc,b.fs-b.sc))<EPS;}

inline bool is_cp(L a,L b){
  if(para(a,b))return false;
  if(ccw(a.fs,a.sc,b.fs)*ccw(a.fs,a.sc,b.sc)<=0)
    if(ccw(b.fs,b.sc,a.fs)*ccw(b.fs,b.sc,a.sc)<=0)return true;
  return false;
}

inline P line_cp(L a,L b){
  return a.fs+(a.sc-a.fs)*cross(b.sc-b.fs,b.fs-a.fs)/cross(b.sc-b.fs,a.sc-a.fs);
}

vector<P> p[2];
inline D len(D x, int id){
  L l = L( P(x,-1000), P(x,1000) );
  vector<P> res;
  rep(i,p[id].size()){
    L a = L( p[id][i], p[id][(i+1)%p[id].size()] );
    if(is_cp(a,l)){
      P cp = line_cp(a,l);
      if(!EQ(cp,p[id][i]))res.push_back(cp);
    }else if(para(a,l) && ccw(l.fs,l.sc,a.sc)==0){
      res.push_back(a.sc);
    }
  }

  if(res.size()<2)return 0;
  return abs(res[0]-res[1]);
}

inline D f(D x){
  return len(x,0) * len(x,1);
}

int main(){
  int m,n;
  while(cin >> m >> n, m){
    D minx[2], maxx[2];
    p[0].resize(m); p[1].resize(n);
    minx[0] = minx[1] = 1000;
    maxx[0] = maxx[1] = -1000;

    rep(i,m){
      D x,y;
      cin >> x >> y;
      p[0][i] = P(x,y);
      minx[0]=min(minx[0],x);
      maxx[0]=max(maxx[0],x);
    }

    rep(i,n){
      D x,z;
      cin >> x >> z;
      p[1][i] = P(x,z);
      minx[1]=min(minx[1],x);
      maxx[1]=max(maxx[1],x);
    }

    D ans = 0;
    for(D i=-100;i<100;i+=1){
      if(minx[0]<=i+0.5 && i+0.5<=maxx[0]){
	if(minx[1]<=i+0.5 && i+0.5<=maxx[1]){
	  ans += f(i)+4*f(i+0.5)+f(i+1);
	}
      }
    }
    cout << fixed << setprecision(9) << ans/6 << endl;
  }
}
accuracy: 1
time_ms: 90
memory_kb: 1328
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;

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

const int DIV = 500000;

int m, n;
double x1[100], y[100], x2[100], z[100];
double mnx, mxx;

double solve(double x) {
  double y1 = 0, y2 = 0, z1 = 0, z2 = 0;
  static int px11 = 0, px12 = 0, px21 = 0, px22 = 0;
  rep (ii, m) {
    int i = (px11 + ii) % m;
    if (x1[i] != x1[(i + 1) % m] && x1[i] <= x && x <= x1[(i + 1) % m]) {
      y1 = y[i] + (y[(i + 1) % m] - y[i]) / (x1[(i + 1) % m] - x1[i]) * (x - x1[i]);
      px11 = i;
      break;
    }
  }
  rep (ii, m) {
    int i = (px12 - ii + m) % m;
    if (x1[i] != x1[(i + 1) % m] && x1[(i + 1) % m] <= x && x <= x1[i]) {
      y2 = y[i] + (y[(i + 1) % m] - y[i]) / (x1[(i + 1) % m] - x1[i]) * (x - x1[i]);
      px12 = i;
      break;
    }
  }
  rep (ii, n) {
    int i = (px21 + ii) % n;
    if (x2[i] != x2[(i + 1) % n] && x2[i] <= x && x <= x2[(i + 1) % n]) {
      z1 = z[i] + (z[(i + 1) % n] - z[i]) / (x2[(i + 1) % n] - x2[i]) * (x - x2[i]);
      px21 = i;
      break;
    }
  }
  rep (ii, n) {
    int i = (px22 - ii + n) % n;
    if (x2[i] != x2[(i + 1) % n] && x2[(i + 1) % n] <= x && x <= x2[i]) {
      z2 = z[i] + (z[(i + 1) % n] - z[i]) / (x2[(i + 1) % n] - x2[i]) * (x - x2[i]);
      px22 = i;
      break;
    }
  }
  return (y2 - y1) * (z2 - z1);
}

double simpson(double l, double r, double f(double), int k = 1){
  double h = (r - l) / (2 * k);
  double fo = 0, fe = 0;
  for(int i = 1; i <= 2 * k - 3; i += 2){
    fo += f(l + h * i);
    fe += f(l + h * (i + 1));
  }
  return (f(l) + f(r) + 4 * (fo + f(r - h)) + 2 * fe) * h / 3;
}

int main() {
  while (true) {
    cin >> m >> n;
    if (m == 0 && n == 0) break;
    rep (i, m) cin >> x1[i] >> y[i];
    rep (i, n) cin >> x2[i] >> z[i];
    double mnx = max(*min_element(x1, x1 + m), *min_element(x2, x2 + n));
    double mxx = min(*max_element(x1, x1 + m), *max_element(x2, x2 + n));
    printf("%.12lf\n", simpson(mnx, mxx, solve, DIV));
  }
}
accuracy: 1
time_ms: 5610
memory_kb: 1248
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)

using namespace std;

const double EPS = 1e-8;
typedef pair<long double, long double> P;
vector<P> vp1;
vector<P> vp2;

long double width(long double x, const vector<P>& v){
    long double top = -1e8, bottom = 1e8;
    REP(i, v.size()){
        P p1 = v[i], p2 = v[(i + 1) % v.size()];
        if(abs(p1.first - p2.first) < EPS){
            if(abs(p1.first - x) < EPS){
                top = max(top, p1.second);
                top = max(top, p2.second);
                bottom = min(bottom, p1.second);
                bottom = min(bottom, p2.second);
            }
            continue;
        }
        if(p1.first > p2.first) swap(p1, p2);
        if(p1.first - EPS < x && x < p2.first + EPS){
            long double ratio = (x - p1.first) / (p2.first - p1.first);
            long double y = p1.second + ratio * (p2.second - p1.second);
            top = max(top, y);
            bottom = min(bottom, y);
        }
    }
    return max(0.0L, top - bottom);
}
long double f(long double x){
    long double w = width(x, vp1) * width(x, vp2);
    return w;
}

long double simpson(long double l, long double r, int N){
    long double h = (r - l) / (2 * N); 
    long double S = f(l) + f(r);
    for(int i = 1; i < 2 * N; i += 2){
        S += 4.0 * f(l + h * i);
    }
    for(int i = 2; i < 2 * N; i += 2){
        S += 2.0 * f(l + h * i);
    }
    return S * h / 3.0;
}


int main(){
    int M, N;
    while(cin >> M >> N && M){
        vp1.resize(M);
        vp2.resize(N);
        REP(i, M) cin >> vp1[i].first >> vp1[i].second;
        REP(i, N) cin >> vp2[i].first >> vp2[i].second;
        long double left1 = vp1[0].first, right1 = vp1[0].first;
        long double left2 = vp2[0].first, right2 = vp2[0].first;
        REP(i, M) left1 = min(left1, vp1[i].first);
        REP(i, N) left2 = min(left2, vp2[i].first);
        REP(i, M) right1 = max(right1, vp1[i].first);
        REP(i, N) right2 = max(right2, vp2[i].first);
        vector<long double> vx;
        long double left = max(left1, left2), right = min(right1, right2);
        vx.push_back(left); vx.push_back(right);
        REP(i, M) if(left < vp1[i].first && vp1[i].first < right) vx.push_back(vp1[i].first);
        REP(i, N) if(left < vp2[i].first && vp2[i].first < right) vx.push_back(vp2[i].first);
        long double S = 0;
        sort(vx.begin(), vx.end());
        REP(i, vx.size() - 1){
            S += simpson(vx[i], vx[i + 1], 100);
        }
        printf("%.16Lf\n", S);
    }
    return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 1272
final_rank: 9

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;
typedef pair<double, double> pdd;

typedef complex<double> P;
namespace std {
  bool operator < (const P& a, const P& b) {
    return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
  }
}
double cross(const P& a, const P& b) {
  return imag(conj(a)*b);
}
double dot(const P& a, const P& b) {
  return real(conj(a)*b);
}
struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a); push_back(b);
  }
};
typedef vector<P> G;
#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]
struct C {
  P p; double r;
  C(const P &p, double r) : p(p), r(r) { }
};

int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (cross(b, c) > 0)   return +1;       // counter clockwise
  if (cross(b, c) < 0)   return -1;       // clockwise
  if (dot(b, c) < 0)     return +2;       // c--a--b on line
  if (norm(b) < norm(c)) return -2;       // a--b--c on line
  return 0;
}
bool intersectLS(const L &l, const L &s) {
  return cross(l[1]-l[0], s[0]-l[0])*       // s[0] is left of l
         cross(l[1]-l[0], s[1]-l[0]) < EPS; // s[1] is right of l
}
P crosspoint(const L &l, const L &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
  if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m[0] + B / A * (m[1] - m[0]);
}

double width(int *X, int *Y, int n, double x) {
  double lb = INF, ub = -INF;
  L l = L(P(x,0), P(x,1));
  REP(i, n) {
    L s = L(P(X[i], Y[i]), P(X[(i+1)%n], Y[(i+1)%n]));
    if (intersectLS(l, s)) {
      P p = crosspoint(l, s);
      double y = p.imag();
      lb = min(lb, y);
      ub = max(ub, y);
    }
  }
  return max(0.0, ub-lb);
}
int main() {
  int m, n;
  while(cin >> m >> n, m||n) {
    int X1[m], Y1[m], X2[n], Z2[n];
    REP(i, m) cin >> X1[i] >> Y1[i];
    REP(i, n) cin >> X2[i] >> Z2[i];
    int min1 = *min_element(X1, X1+m), max1 = *max_element(X1, X1+m);
    int min2 = *min_element(X2, X2+n), max2 = *max_element(X2, X2+n);
    vector<int> xs;
    REP(i, m) xs.push_back(X1[i]);
    REP(i, n) xs.push_back(X2[i]);
    sort(ALL(xs));

    double res = 0;
    REP(i, xs.size()-1) {
      double a = xs[i], b = xs[i+1], c = (a+b)/2;
      if (min1 <= c && c <= max1 && min2 <= c && c<= max2) {
        double fa = width(X1, Y1, m, a) * width(X2, Z2, n, a);
        double fb = width(X1, Y1, m, b) * width(X2, Z2, n, b);
        double fc = width(X1, Y1, m, c) * width(X2, Z2, n, c);
        res += (b-a) / 6 * (fa + 4*fc + fb);
      }
    }
    printf("%.10f\n", res);
  }
}
accuracy: 1
time_ms: 50
memory_kb: 968
final_rank: 2

code_snippet: #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;
}
accuracy: 1
time_ms: 20
memory_kb: 0
final_rank: 1