#include <stdio.h> 
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
const double eps = 1e-8;
const int MAXN = 1024;
int cmpZero(double x) {
    if (fabs(x) < eps)	return 0;
    return x < 0 ? -1 : 1;
}
class ConvexHull3D {
public:
    struct Point3D {
        double x, y, z;
        Point3D(double a = 0, double b = 0, double c = 0):
            x(a), y(b), z(c) {}
        Point3D operator+(const Point3D &a) const {
            return Point3D(x + a.x, y + a.y, z + a.z);
        }
        Point3D operator-(const Point3D &a) const {
            return Point3D(x - a.x, y - a.y, z - a.z);
        }
        Point3D operator/(double a) const {
            return Point3D(x/a, y/a, z/a);
        }
        Point3D operator*(double a) const {
            return Point3D(x*a, y*a, z*a);
        }
        bool operator!=(const Point3D &a) const {
            return cmpZero(x - a.x) || cmpZero(y - a.y) || cmpZero(z - a.z);
        }
        Point3D cross(const Point3D &a) const { 
            return Point3D(y*a.z - z*a.y, z*a.x - x*a.z, x*a.y - y*a.x);
        }
        double dot(const Point3D &a) const {
            return x*a.x + y*a.y + z*a.z;
        }
        double length() {
            return sqrt(x*x+y*y+z*z);
        }
        void read() {
            scanf("%lf %lf %lf", &x, &y, &z);
        }
    };
    struct Face {
        int a, b, c; 	
        bool flag; 		
    };
    
    int n, tri_num;
    Point3D pt[MAXN];
    Face faces[MAXN*8];
    Face* g[MAXN][MAXN];
    
    double tri_area(Point3D a, Point3D b, Point3D c) { 	
        return ((a - c).cross(b - c)).length()/2;
    }
    double volume(Point3D a, Point3D b, Point3D c, Point3D d) { 
        return ((b - a).cross(c - a)).dot(d - a)/6;
    }
    double pt2Face(Point3D a, Point3D b, Point3D c, Point3D p) {
        Point3D n = (b - a).cross(c - a);
        Point3D t = p - a;
        double v = n.dot(t) / n.length();
        return fabs(v);
    }
    double ptWithFace(Point3D &p, Face &f) { 
        Point3D a, b, c;
        a = pt[f.b] - pt[f.a];
        b = pt[f.c] - pt[f.a];
        c = p - pt[f.a];
        return (a.cross(b)).dot(c);
    }
    bool samePlane(Face &s, Face &t) {
        Point3D a, b, c;
        bool ret = true;
        a = pt[s.a], b = pt[s.b], c = pt[s.c];
        ret = cmpZero(volume(a, b, c, pt[t.a])) == 0 &&
                cmpZero(volume(a, b, c, pt[t.b])) == 0 &&
                cmpZero(volume(a, b, c, pt[t.c])) == 0;
        return ret;
    }
    void deal(int a, int b, int p) {
        Face *f = g[a][b];
        if (f->flag) {
            if (cmpZero(ptWithFace(pt[p], *f)) > 0) {
                dfs(p, f);
            } else {
                Face &add = faces[tri_num++];
                add.a = b, add.b = a, add.c = p;
                add.flag = 1;
                g[b][a] = g[a][p] = g[p][b] = &add;
            }
        }
    }
    void dfs(int p, Face *f) {
        f->flag = 0;	
        deal(f->b, f->a, p);
        deal(f->a, f->c, p);
        deal(f->c, f->b, p);
    }
    
    int make() {
        if (n < 4)
            return 0;		
        
        bool ok;
        ok = false;
        for (int i = 1; i < n; i++) {
            if (pt[0] != pt[i]) {
                swap(pt[1], pt[i]);
                ok = true;
                break;
            }
        }
        if (!ok)	return 0;
        ok = false;
        for (int i = 2; i < n; i++) {
            if (cmpZero(tri_area(pt[0], pt[1], pt[i]))) {
                swap(pt[2], pt[i]);
                ok = true;
                break;
            }
        }
        if (!ok)	return 0;
        ok = false;
        for (int i = 3; i < n; i++) {
            if (cmpZero(volume(pt[0], pt[1], pt[2], pt[i]))) {
                swap(pt[3], pt[i]);
                ok = true;
                break;
            }
        }
        if (!ok)	return 0;
        
        tri_num = 0;
        for (int i = 0; i < 4; i++) { 
            Face &f = faces[tri_num++];
            f.a = (i+1)%4, f.b = (i+2)%4, f.c = (i+3)%4;
            f.flag = 1;
            if (cmpZero(ptWithFace(pt[i], f)) > 0)
                swap(f.b, f.c);
            g[f.a][f.b] = g[f.b][f.c] = g[f.c][f.a] = &f;
        }
        
        for (int i = 4; i < n; i++) {
            for (int j = 0; j < tri_num; j++) {
                if (faces[j].flag && cmpZero(ptWithFace(pt[i], faces[j])) > 0) {
                    dfs(i, &faces[j]);
                    break;
                }
            }
        }
        
        int tri_n = 0;
        for (int i = 0; i < tri_num; i++) {
            if (faces[i].flag)
                faces[tri_n++] = faces[i];
        }
        tri_num = tri_n; 
        return 1;
    }
    double area() { 
        double ret = 0;
        if (n == 3)
            return tri_area(pt[0], pt[1], pt[2]);
        for (int i = 0; i < tri_num; i++)
            ret += tri_area(pt[faces[i].a], pt[faces[i].b], pt[faces[i].c]);
        return ret;
    }
    double volume() {
        double ret = 0;
        Point3D o(0, 0, 0);
        for (int i = 0; i < tri_num; i++)
            ret += volume(o, pt[faces[i].a], pt[faces[i].b], pt[faces[i].c]);
        return fabs(ret);
    }
    Point3D getCenter() {
        Point3D ret(0, 0, 0), o = pt[faces[0].a], p;
        double sum, v;
        sum = 0;
        for (int i = 0; i < tri_num; i++) {
            v = volume(o, pt[faces[i].a], pt[faces[i].b], pt[faces[i].c]);
            p = (pt[faces[i].a] + pt[faces[i].b] + pt[faces[i].c] + o)/4.0;
            if (cmpZero(v) > 0) {
                p = p * v;
                ret = ret + p, sum += v;
            }
        }
        ret = ret / sum;
        return ret;
    }
    int getFaceCount() {
        int ret = 0;
        for (int i = 0; i < tri_num; i++) {
            int ok = 1;
            for (int j = 0; j < i && ok; j++) {
                if (samePlane(faces[i], faces[j]))
                    ok = 0;
            }
            if (ok)
                ret++;
        }
        return ret;
    }
    double getInnerClosestDist(Point3D p) { 
        double ret = -1;
        for (int i = 0; i < tri_num; i++) {
            Point3D a, b, c;
            a = pt[faces[i].a], b = pt[faces[i].b], c = pt[faces[i].c];
            
            double t = tri_area(a, b, c);
            double v = fabs(volume(a, b, c, p));
            
            if (ret < 0 || v*3/t < ret)
                ret = v*3/t;
        }
        return ret;
    } 
} A, B;
int main() {
    while (scanf("%d", &A.n) == 1) {
        for (int i = 0; i < A.n; i++)
            A.pt[i].read();
        
        scanf("%d", &B.n);
        for (int i = 0; i < B.n; i++)
            B.pt[i].read();
            
        A.make();
        B.make();
        
        double d1, d2;
        d1 = A.getInnerClosestDist(A.getCenter());
        d2 = B.getInnerClosestDist(B.getCenter());
        printf("%lf\n", d1 + d2);
    }
    return 0;
}