#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(),(x).end()
#define YES() printf("YES\n")
#define NO() printf("NO\n")
#define isYES(x) printf("%s\n",(x) ? "YES" : "NO")
#define Yes() printf("Yes\n")
#define No() printf("No\n")
#define isYes(x) printf("%s\n",(x) ? "Yes" : "No")
#define isIn(x,y,h,w) (x >= 0 && x < h && y >= 0 && y < w)

#define int long long
//using ll = long long;
using P = pair<int,int>;

ostream &operator<<(ostream &os,const P &p){ return os << "(" << p.first << "," << p.second << ")"; }

template<class T> T &chmin(T &a,const T &b){ return a = min(a,b); }
template<class T> T &chmax(T &a,const T &b){ return a = max(a,b); }
 
const int INF=1e+18;
const double EPS=1e-9;
const int MOD=1000000009;

const int dx[]={1,0,-1,0},dy[]={0,-1,0,1};

template<class T>
struct Edge{
	int from,to;
	T cost;
	Edge(int to,T cost) : to(to),cost(cost){}
	Edge(int from,int to,T cost) : from(from),to(to),cost(cost){}
};

template<class T>
using WeightedGraph = vector<vector<Edge<T>>>;
using Graph = vector<vector<int>>;
template<class T>
using Matrix = vector<vector<T>>;

template<class T>
vector<T> dijkstra(const WeightedGraph<T> &G,int source = 0){
	using P = pair<T,int>;
	vector<T> dist(G.size(),INF);
	priority_queue<P,vector<P>,greater<P>> que;
	dist[source] = 0;
	que.emplace(dist[source],source);
	while(!que.empty()){
		P p = que.top();que.pop();
		int v = p.second;
		if(dist[v] < p.first) continue;
		for(const auto &e : G[v]){
			if(dist[e.to] > dist[v] + e.cost){
				dist[e.to] = dist[v] + e.cost;
				que.emplace(dist[e.to],e.to);
			}
		}
	}
	return dist;
}

using Float = double;
using Point = complex<Float>;
struct Line{
	Point a,b;
	Line(Point a,Point b) : a(a),b(b){}
};
struct Segment : Line{ Segment(Point a,Point b) : Line(a,b){} };
struct Circle{ Point p; Float r; };

inline bool eq(Float a,Float b) { return abs(a - b) < EPS; }
inline Float dot(const Point &a,const Point &b){ return real(conj(a) * b); }
inline Float cross(const Point &a,const Point &b){ return imag(conj(a) * b); }

int ccw(const Point &a,Point b,Point c){
	b -= a; c -= a;
	if(cross(b,c) > EPS) return +1; //ccw
	if(cross(b,c) < -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;
}

signed main(){
	int n[2];
	cin >> n[0] >> n[1];
	vector<WeightedGraph<double>> G(2);
	Point ps[2][1010];
	for(int i = 0;i < 2;i++){
		G[i].resize(n[i]);
		for(int j = 0;j < n[i];j++){
			double x,y;
			cin >> x >> y;
			ps[i][j] = Point(x,y);
		}
	}
	for(int i = 0;i < 2;i++){
		for(int j = 0;j < n[i];j++){
			for(int k = j + 1;k < n[i];k++){
				if(!intersect(Segment(ps[i][j],ps[i][k]),Segment(ps[!i][0],ps[!i][1]))){
					G[i][j].emplace_back(k,abs(ps[i][j] - ps[i][k]));
					G[i][k].emplace_back(j,abs(ps[i][j] - ps[i][k]));
				}
			}
		}
	}
	double ans = min(
		dijkstra(G[0],0)[1] + abs(ps[1][0] - ps[1][1]),
		dijkstra(G[1],0)[1] + abs(ps[0][0] - ps[0][1])
	);
	if(ans > INF / 2) cout << -1 << endl;
	else printf("%.15lf\n",ans);
}


Measured memory_bytes: 53992