#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
#include <fstream>
using namespace std;
inline int toInt(string s) { int v; istringstream sin(s); sin >> v; return v;}
template<class T> inline string toStr(T x) { ostringstream sout; sout << x; return sout.str();}
typedef vector<int> vi;
typedef vector<vi>  vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REP(i,n) FOR(i,0,(n)-1)
const double EPS = 1e-12;
const double PI = acos(-1.0);
const int INF = INT_MAX/10;

#include <complex>
typedef complex<double> P;
typedef vector<double> vd;
typedef vector<vd> vvd;

#define EQ(x,y) (abs((x)-(y))<EPS)
#define LT(x,y) ((x)-(y)<=-EPS)

double cross(P a, P b) {
	return a.real()*b.imag() - a.imag()*b.real();
}

int is_point_on_ls(P a, P b, P c) {
	return (abs(a-c) + abs(c-b) < abs(a-b) + EPS);
}

int is_intersected_ls(P a1, P a2, P b1, P b2) {
	if((cross(a2-a1, b1-a1) * cross(a2-a1, b2-a1) < -EPS) &&
		(cross(b2-b1, a1-b1) * cross(b2-b1, a2-a1) < -EPS))
		return true;
	return is_point_on_ls(a1, a2, b1) || is_point_on_ls(a1, a2, b2) ||
			is_point_on_ls(b1, b2, a1) || is_point_on_ls(b1, b2, a2);
}

struct state {
	int p;
	double d;
	state(int p, double d) : p(p), d(d) {};
	bool operator<(const state &o)const {
		return o.d<d;
	}
};

int main() {
	int NA, NB;
	cin >> NA >> NB;

	vector<P> pA(NA), pB(NB);
	double x, y;
	REP(i, NA) {
		cin >> x >> y;
		pA[i] = P(x, y);
	}
	REP(i, NB) {
		cin >> x >> y;
		pB[i] = P(x, y);
	}

	cout.precision(16);
	if(is_intersected_ls(pA[0], pA[1], pB[0], pB[1])) {
		double ans = INF;
		
		{
		vvd distA(NA, vd(NA, INF));
		REP(i, NA-1) {
			FOR(j, i+1, NA-1) {
				if(!is_intersected_ls(pA[i], pA[j], pB[0], pB[1])) {
					distA[i][j] = distA[j][i] = abs(pA[i]-pA[j]);
				}
			}
		}
		priority_queue<state> Q;
		Q.push(state(0, 0));
		vd costA(NA, INF);
		costA[0] = 0;
		while(!Q.empty()) {
			state st = Q.top();
			Q.pop();
			if(st.p == 1) {
				ans = min(ans, abs(pB[0]-pB[1])+st.d);
				break;
			}
			REP(i, NA) {
				if(st.p != i && !EQ(distA[st.p][i], INF)) {
					double nd = st.d+distA[st.p][i];
					if(LT(nd, costA[i])) {
						costA[i] = nd;
						Q.push(state(i, nd));
					}
				}
			}
		}
		}

		{
		vvd distB(NB, vd(NB, INF));
		REP(i, NB-1) {
			FOR(j, i+1, NB-1) {
				if(!is_intersected_ls(pB[i], pB[j], pA[0], pA[1])) {
					distB[i][j] = distB[j][i] = abs(pB[i]-pB[j]);
				}
			}
		}
		priority_queue<state> Q;
		Q.push(state(0, 0));
		vd costB(NB, INF);
		costB[0] = 0;
		while(!Q.empty()) {
			state st = Q.top();
			Q.pop();
			if(st.p == 1) {
				ans = min(ans, abs(pA[0]-pA[1])+st.d);
				break;
			}
			REP(i, NB) {
				if(st.p != i && !EQ(distB[st.p][i], INF)) {
					double nd = st.d+distB[st.p][i];
					if(LT(nd, costB[i])) {
						costB[i] = nd;
						Q.push(state(i, nd));
					}
				}
			}
		}
		}

		if(EQ(ans, INF)) {
			cout << -1 << endl;
		} else {
			cout << ans << endl;
		}

	} else {
		cout << abs(pA[0]-pA[1])+abs(pB[0]-pB[1]) << endl;;
	}

	return 0;
}