#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define dump(a) (cerr << (#a) << " = " << (a) << endl)
#define FOR(it,c) for(__typeof((c).begin())it=(c).begin(); it!=(c).end();++it)
#define RFOR(it,c) for(__typeof((c).rbegin())it=(c).rbegin(); it!=(c).rend();++it)
#define exist(c, v) (find((c).begin(), (c).end(), (v)) != (c).end())

template<class T> inline void chmax(T& a, const T& b) { if(b > a) a = b; }
template<class T> inline void chmin(T& a, const T& b) { if(b < a) a = b; }

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

template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
	copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
	return os;
}

const double EPS = 1e-9;

struct point {
	double x, y;
	point():x(0), y(0) {}
	point(double x, double y):x(x), y(y) {}
	point(const point& p):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);
	}

	point operator* (const double s) const {
		return point(x * s, y * s);
	}

	point operator* (const point& p) const {
		return point(x * p.x - y * p.y, x * p.y + y * p.x);
	}

	point operator/ (const double s) const {
		return point(x / s, y / s);
	}

	bool operator< (const point& p) const {
		return x + EPS < p.x || abs(x - p.x) < EPS && y + EPS < p.y;
	}

	bool operator== (const point& p) const {
		return abs(x - p.x) < EPS && abs(y - p.y) < EPS;
	}
};

inline double abs(const point& p) {
	return sqrt(p.x * p.x + p.y * p.y);
}

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

inline double dot(const point& l, const point& r) {
	return l.x * r.x + l.y * r.y;
}

inline double cross(const point& l, const point& r) {
	return l.x * r.y - l.y * r.x;
}

struct segment {
	point a, b;
	segment(point a, point b):a(a), b(b){}
};

inline int ccw(const point& a, point b, point c) {
	b = b - a;
	c = c - a;
	const double tmp = cross(b, c);
	if(tmp > EPS) return 1; // ccw
	if(tmp < -EPS) return -1; // cw
	if(dot(b, c) < 0) return 2; // c, a, b 順に一直線上
	if(norm(b) < norm(c)) return -2; // a, b, c 順に一直線上
	return 0; //a, c, b 順で一直線上
}

inline bool intersect(const segment& s, const segment& t) {
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
		ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

const int MAX_N = 1000;
const int A = 0, B = 1;
const int INF = 0xfffffff;
int n[2];
double mat[MAX_N][MAX_N];
vector<point> points[2];
typedef pair<double, int> P;

double dijkstra(int s, int t, int num) {
	vector<double> dist(num, INF);
	dist[s] = 0;
	priority_queue<P, vector<P>, greater<P> > que;
	que.push(P(0.0, s));

	while(!que.empty()) {
		const double d = que.top().first;
		const int v = que.top().second;
		que.pop();
		if(d > dist[v])
			continue;

		if(v == t)
			return d;

		for(int i = 0; i < num; ++i) {
			const double next_d = d + mat[v][i];
			if(next_d < dist[i]) {
				dist[i] = next_d;
				que.push(P(next_d, i));
			}
		}
	}

	return INF;
}

int main() {
	scanf("%d %d", &n[0], &n[1]);

	for(int l = 0; l < 2; ++l) {
		points[l].reserve(n[l]);
		for(int i = 0; i < n[l]; ++i) {
			int x, y;
			scanf("%d %d", &x, &y);
			points[l].push_back(point(x, y));
		}
	}

	double ans = INF;
	for(int l = 0; l < 2; ++l) {
		fill(mat[0], mat[0] + MAX_N * n[l], INF);
		for(int i = 0; i < n[l]; ++i)
			mat[i][i] = 0;

		const int other = 1 - l;
		const segment out = segment(points[other][0], points[other][1]);
		for(int i = 0; i < n[l]; ++i) {
			for(int j = i + 1; j < n[l]; ++j) {
				if(!intersect(out, segment(points[l][i], points[l][j])))
					mat[i][j] = mat[j][i] = abs(points[l][i] - points[l][j]);
			}
		}

		chmin(ans, abs(points[other][0] - points[other][1]) + dijkstra(0, 1, n[l]));
	}

	if(ans == INF)
		puts("-1");
	else
		printf("%.15lf\n", ans);

	return EXIT_SUCCESS;
}

Measured memory_bytes: 9164