#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
#include <limits>
#include <cmath>

using namespace std;

static const double EPS = 1e-9;
inline bool tolerant_eq(double a, double b){ return abs(a - b) < EPS; }

struct Point {
	double x;
	double y;
	explicit Point(const double &x = 0.0, const double &y = 0.0) :
		x(x), y(y)
	{ }
	static Point invalid(){
		double qnan = numeric_limits<double>::quiet_NaN();
		return Point(qnan, qnan);
	}
	bool is_valid() const { return !(std::isnan(x) || std::isnan(y)); }
	Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
	Point &operator+=(const Point &p){ return *this = *this + p; }
	Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
	Point &operator-=(const Point &p){ return *this = *this - p; }
	Point operator*(double s) const { return Point(x * s, y * s); }
	Point &operator*=(double s){ return *this = *this * s; }
	Point operator*(const Point &p) const {
		return Point(x * p.x - y * p.y, x * p.y + y * p.x);
	}
	Point &operator*=(const Point &p){ return *this = *this * p; }
	Point operator/(double s) const { return Point(x / s, y / s); }
	Point &operator/=(double s){ return *this = *this / s; }
	bool operator==(const Point &p) const { return x == p.x && y == p.y; }
	bool operator!=(const Point &p) const { return x != p.x || y != p.y; }
	bool operator<(const Point &p) const {
		return (x == p.x) ? (y < p.y) : (x < p.x);
	}
	double abs() const { return sqrt(x * x + y * y); }
	double norm() const { return x * x + y * y; }
	Point unit() const { return *this / abs(); }
	Point ortho() const { return Point(-y, x); }
};

inline Point operator*(double s, const Point &p){ return p * s; }
inline bool tolerant_eq(const Point &a, const Point &b){
	return tolerant_eq(a.x, b.x) && tolerant_eq(a.y, b.y);
}
inline double cross(const Point &a, const Point &b){
	return a.x * b.y - a.y * b.x;
}
inline double dot(const Point &a, const Point &b){
	return a.x * b.x + a.y * b.y;
}
inline int ccw(const Point &a, const Point &b, const Point &c){
	Point d = b - a, e = c - a;
	if(cross(d, e) > 0.0){ return 1; }
	if(cross(d, e) < 0.0){ return -1; }
	if(dot(d, e) < 0.0){ return 2; }
	if(d.abs() < e.abs()){ return -2; }
	return 0;
}


struct Line {
	Point a;
	Point b;
	explicit Line(const Point &a = Point(), const Point &b = Point()) :
		a(a), b(b)
	{ }
	static Line invalid(){
		Point inv = Point::invalid();
		return Line(inv, inv);
	}
	bool is_valid() const { return a.is_valid() && b.is_valid(); }
	bool operator<(const Line &l) const {
		return (a == l.a) ? (b < l.b) : (a < l.a);
	}
	Point projection(const Point &p) const {
		double t = dot(p - a, b - a) / (b - a).norm();
		return a + t * (b - a);
	}
	Point reflection(const Point &p) const {
		return p + 2.0 * (projection(p) - p);
	}
};

inline bool tolerant_eq(const Line &a, const Line &b){
	const double x = abs(cross(a.b - a.a, b.b - b.a));
	const double y = abs(cross(a.b - a.a, a.b - b.a));
	return x < EPS && y < EPS;
}
inline bool directed_tolerant_eq(const Line &a, const Line &b){
	if(!tolerant_eq(a, b)){ return false; }
	return tolerant_eq((a.a - a.b).unit(), (b.a - b.b).unit());
}
inline bool is_parallel(const Line &a, const Line &b){
	return abs(cross(a.b - a.a, b.b - b.a)) < EPS;
}

struct Segment {
	Point a;
	Point b;
	explicit Segment(const Point &a = Point(), const Point &b = Point()) :
		a(a), b(b)
	{ }
	static Segment invalid(){
		Point inv = Point::invalid();
		return Segment(inv, inv);
	}
	bool is_valid() const { return a.is_valid() && b.is_valid(); }
	bool operator<(const Segment &s) const {
		return (a == s.a) ? (b < s.b) : (a < s.a);
	}
};

inline bool tolerant_eq(const Segment &a, const Segment &b){
	if(tolerant_eq(a.a, b.a) && tolerant_eq(a.b, b.b)){ return true; }
	if(tolerant_eq(a.a, b.b) && tolerant_eq(a.b, b.a)){ return true; }
	return false;
}


inline bool intersect(const Point &a, const Segment &b){
	return (b.a - a).abs() + (b.b - a).abs() - (b.b - b.a).abs() < EPS;
}
inline bool intersect(const Segment &a, const Point &b){
	return intersect(b, a);
}
inline bool intersect(const Segment &a, const Segment &b){
	if(ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) > 0){ return false; }
	if(ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) > 0){ return false; }
	return true;
}

inline double dist(const Point &a, const Line &b){
	return (a - b.projection(a)).abs();
}
inline double dist(const Line &a, const Point &b){
	return dist(b, a);
}
inline double dist(const Point &a, const Segment &b){
	const Point r = Line(b.a, b.b).projection(a);
	if(intersect(b, r)){ return (r - a).abs(); }
	return min((b.a - a).abs(), (b.b - a).abs());
}
inline double dist(const Segment &a, const Point &b){
	return dist(b, a);
}
inline double dist(const Segment &a, const Segment &b){
	if(intersect(a, b)){ return 0.0; }
	const double x = min(dist(a.a, b), dist(a.b, b));
	const double y = min(dist(b.a, a), dist(b.b, a));
	return min(x, y);
}

int main(){
	ios_base::sync_with_stdio(false);
	cout << setiosflags(ios::fixed) << setprecision(10);
	int n, m;
	cin >> n;
	n += 2;
	vector<Point> s1(n);
	for(int i = 1; i + 1 < n; ++i){ cin >> s1[i].x >> s1[i].y; }
	s1[0] = Point(0, 0); s1[n - 1] = Point(1000, 0);
	cin >> m;
	m += 2;
	vector<Point> s2(m);
	for(int i = 1; i + 1 < m; ++i){ cin >> s2[i].x >> s2[i].y; }
	s2[0] = Point(0, 1000), s2[m - 1] = Point(1000, 1000);
	double answer = 1000.0;
	for(int i = 0; i + 1 < n; ++i){
		const Segment s(s1[i], s1[i + 1]);
		for(int j = 0; j + 1 < m; ++j){
			const Segment t(s2[j], s2[j + 1]);
			answer = min(answer, dist(s, t));
		}
	}
	cout << answer << endl;
	return 0;
}

Measured memory_bytes: 1312