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

using db = double;

inline void out(db x){
    cout << fixed << setprecision(4) << x << "\n";
}

struct Point {
    db x, y;

    Point (){
        x = 0;
        y = 0;
    }

    Point(db _x, db _y) : x(_x), y(_y) {}

    bool operator < (const Point &oth) const {
        return (x < oth.x || (x == oth.x && y < oth.y));
    }

    bool operator > (const Point &oth) const {
        return (x > oth.x || (x == oth.x && y > oth.y));
    }

    bool operator == (const Point &oth) const {
        return (x == oth.x && y == oth.y);
    }

    bool operator != (const Point &oth) const {
        return (x != oth.x || y != oth.y);
    }
};

struct Line {
    Point x, y;

    Line (Point _x, Point _y) : x(_x), y(_y) {}
};

db cross (Point &A, Point &B, Point &C){
    return (B.x - A.x) * (C.y - A.y) - (B.y - A.y) * (C.x - A.x);
}

db dot (Point &A, Point &B, Point &C){
    return (B.x - A.x) * (C.x - A.x) + (B.y - A.y) * (C.y - A.y);
}

bool ccw (Point &A, Point &B, Point &C){
    return (cross(A, B, C) > 0);
}

vector<Point> ConvexHull (vector<Point> a){
    vector<Point> hull;
    sort(a.begin(), a.end());
    hull.push_back(a[0]);
    for (int i = 1; i < a.size(); ++i){
        while (hull.size() > 1 && ccw(hull[hull.size() - 2], hull.back(), a[i])){
            hull.pop_back();
        }
        hull.push_back(a[i]);
    }
    for (int i = a.size() - 2; i >= 0; --i){
        while (hull.size() > 1 && ccw(hull[hull.size() - 2], hull.back(), a[i])){
            hull.pop_back();
        }
        hull.push_back(a[i]);
    }
    if (a.size() > 1){
        hull.pop_back();
    }
    return hull;
}

bool onSegment (Point &A, Point &B, Point &C){
    return (cross(A, B, C) == 0 && dot(C, A, B) <= 0);
}

bool inHull (vector<Point> &hull, Point P){
    int n = hull.size();
    if (onSegment(hull[0], hull[n - 1], P) || onSegment(hull[0], hull[1], P)){
        return true;
    }
    if (!ccw(hull[0], hull[n - 1], P) && !ccw(hull[1], hull[0], P)){
        return false;
    }
    int l = 1, r = n - 1, id = -1;
    while (l <= r){
        int m = l + r >> 1;
        if (!ccw(hull[0], P, hull[m])){
            id = m;
            r = m - 1;
        } else {
            l = m + 1;
        }
    }
    return (onSegment(hull[id - 1], hull[id], P) || ccw(P, hull[id], hull[id - 1]));
}

tuple<db, db, db> getDio (Line A){
    int a = A.y.y - A.x.y;
    int b = A.x.x - A.y.x;
    int c = a * A.x.x + b * A.x.y;
    return make_tuple(a, b, c);
}

Point Intersect (Line A, Line B){
    auto [a1, b1, c1] = getDio(A);
    auto [a2, b2, c2] = getDio(B);
    db X = (b2 * c1 - b1 * c2) / (a1 * b2 - b1 * a2);
    db Y = (a1 * c2 - a2 * c1) / (a1 * b2 - a2 * b1);
    Point Z = Point(X, Y);
    if (!onSegment(A.x, A.y, Z) || !onSegment(B.x, B.y, Z)){
        return Point(-1, -1);
    } else {
//        cout << A.x.x << " " << A.x.y << " " << A.y.x << " " << A.y.y << "\n";
//        cout << B.x.x << " " << B.x.y << " " << B.y.x << " " << B.y.y << "\n";
//        cout << Z.x << " " << Z.y << endl;
        return Z;
    }
}

void solve (){
    int n, m; cin >> n >> m;
    db ans = 0;
    vector<Point> a(n), b(m);
    for (int i = 0; i < n; ++i){
        cin >> a[i].x >> a[i].y;
    }
    for (int i = 0; i < m; ++i){
        cin >> b[i].x >> b[i].y;
    }
    a = ConvexHull(a);
    b = ConvexHull(b);
    vector<Point> c;
    for (auto &X : a){
        if (inHull(b, X)){
            c.push_back(X);
        }
    }
    for (auto &X : b){
        if (inHull(a, X)){
            c.push_back(X);
        }
    }
    for (int i = 0; i < n; ++i){
        int j = (i + 1) % n;
        for (int k = 0; k < m; ++k){
            int l = (k + 1) % m;
            Point cut = Intersect(Line(a[i], a[j]), Line(b[k], b[l]));
            if (cut != Point(-1, -1)){
                c.push_back(cut);
            }
        }
    }
    if (c.size() == 0){
        out(0);
        return;
    }
    c = ConvexHull(c);
    for (int i = 0; i < c.size(); ++i){
        int j = (i + 1) % c.size();
        ans += (db)((c[i].x + c[j].x) * (c[i].y - c[j].y) / (db)(2));
    }
    out(ans);
}

int32_t main (){
    ios::sync_with_stdio(false); cin.tie(nullptr);
    if (fopen("ipolygon.inp", "r")){
        freopen("ipolygon.inp", "r", stdin);
        freopen("ipolygon.out", "w", stdout);
    }
    int tt; cin >> tt;
    while (tt--){
        solve();
    }
}
