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

typedef double Real;
constexpr Real EPS = 1e-8;
const Real PI = acos((Real)-1);
inline int sign(Real d) { return d > EPS ? 1 : d < -EPS ? -1 : 0; }

struct point {
	Real x, y;
	explicit point():x(0), y(0) {}
	explicit point(Real x_, Real y_):x(x_), y(y_) {}
	point operator+(const point &p) const { return point(x + p.x, y + p.y); }
	point operator-(const point &p) const { return point(x - p.x, y - p.y); }
	point operator*(const point &p) const { return point(x * p.x - y * p.y, x * p.y + y * p.x); }
	point operator*(Real s) const { return point(x * s, y * s); }
	point operator/(Real s) const { return point(x / s, y / s); }
	bool operator<(const point &p) const { return sign(x - p.x) == -1 || (sign(x - p.x) == 0 && sign(y - p.y) == -1); }
	bool operator==(const point &p) const { return sign(x - p.x) == 0 && sign(y - p.y) == 0; }
	bool operator!=(const point &p) const { return sign(x - p.x) != 0 || sign(y - p.y) != 0; }
};

struct line : public array<point, 2> {
	line(const point &a, const point &b) { at(0) = a; at(1) = b; }
};

struct segment : public array<point, 2> {
	segment(const point &a, const point &b) { at(0) = a; at(1) = b; }
};

inline Real norm(const point &p) {
	return p.x * p.x + p.y * p.y;
}

inline Real abs(const point &p) {
	return sqrt(norm(p));
}

inline Real dot(const point &a, const point &b) {
	return a.x * b.x + a.y * b.y;
}

inline Real cross(const point &a, const point &b) {
	return a.x * b.y - a.y * b.x;
}

enum { CCW = 1, CW = -1, BACK = 2, FRONT = -2, ON = 0};
inline int ccw(const point &a, const point &b, const point &c) {
	const point p = b - a;
	const point q = c - a;
	const int sign_cross = sign(cross(p, q));
	if(sign_cross == 1) return CCW;
	if(sign_cross == -1) return CW;
	if(sign(dot(p, q)) == -1) return BACK;
	if(sign(norm(p) - norm(q)) == -1) return FRONT;
	return ON;
}

inline bool intersect(const segment &a, const segment &b) {
	return ccw(a[0], a[1], b[0]) * ccw(a[0], a[1], b[1]) <= 0
		&& ccw(b[0], b[1], a[0]) * ccw(b[0], b[1], a[1]) <= 0;
}

inline Real dist(const point &a, const point &b) {
	return abs(a - b);
}

inline Real dist(const line &l, const point &p) {
	const point a = l[1] - l[0];
	const point b = p - l[0];
	return abs(cross(a, b)) / abs(a);
}

inline Real dist(const segment &s, const point &p) {
	if(sign(dot(s[1] - s[0], p - s[0])) == -1) return dist(s[0], p);
	if(sign(dot(s[0] - s[1], p - s[1])) == -1) return dist(s[1], p);
	return dist(line(s[0], s[1]), p);
}

inline Real dist(const segment &a, const segment &b) {
	return intersect(a, b) ? 0 : min({dist(a, b[0]), dist(a, b[1]), dist(b, a[0]), dist(b, a[1])});
}

vector<point> input_polyline(const point &s, const point &t) {
	int n;
	cin >> n;

	vector<point> res{s};
	res.reserve(n + 2);

	for(int i = 0; i < n; ++i) {
		int x, y;
		cin >> x >> y;
		res.emplace_back(x, y);
	}

	res.emplace_back(t);
	return res;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout.setf(ios::fixed);
	cout.precision(10);

	const vector<point> P1 = input_polyline(point(0, 0), point(1000, 0));
	const vector<point> P2 = input_polyline(point(0, 1000), point(1000, 1000));

	double ans = INT_MAX;
	for(unsigned i = 1; i < P1.size(); ++i) {
		for(unsigned j = 1; j < P2.size(); ++j) {
			ans = min(ans, dist(segment(P1[i], P1[i - 1]), segment(P2[j], P2[j - 1])));
		}
	}

	cout << ans << endl;

	return EXIT_SUCCESS;
}

Measured memory_bytes: 1280