#include <iomanip>
#include <iostream>
#include <sstream>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <complex>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <functional>
#include <algorithm>

using namespace std;

#define rep(i,j) REP((i), 0, (j))
#define REP(i,j,k) for(int i=(j);(i)<(k);++i)
#define BW(a,x,b) ((a)<=(x)&&(x)<=(b))
#define ALL(v) (v).begin(), (v).end()
#define LENGTHOF(x) (sizeof(x) / sizeof(*(x)))
#define AFILL(a, b) fill((int*)a, (int*)(a + LENGTHOF(a)), b)
#define SQ(x) ((x)*(x))
#define Mod(x, mod) (((x)+(mod)%(mod))
#define MP make_pair
#define PB push_back
#define Fi first
#define Se second
#define INF (1<<29)
#define EPS 1e-10
#define MOD 1000000007

typedef pair<int, int> pi;
typedef pair<int, pi> pii;
typedef vector<int> vi;
typedef queue<int> qi;
typedef long long ll;
typedef complex<double> P;
typedef pair<int, double> PP;

struct Edge{
  int to;
  double cost;
  Edge(int a, double b){
    to = a;
    cost = b;
  }
};

// ?????? (dot product) : a???b = |a||b|cos??
double dot(P a, P b) {
  return (a.real() * b.real() + a.imag() * b.imag());
}
// ?????? (cross product) : a??b = |a||b|sin??
double cross(P a, P b) {
  return (a.real() * b.imag() - a.imag() * b.real());
}

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

double distance(P a, P b){
  return abs(a - b);
}

int NA, NB;
vector<Edge>G[1024];
double dis[1024];

void dijkstra(int s){
  fill(dis, dis + 1024, INF);

  priority_queue<PP, vector<PP>, greater<PP> >PQ;
  PQ.push(make_pair(0, s));
  dis[s] = 0;
  while(!PQ.empty()){
    PP q = PQ.top(); PQ.pop();
    int d = q.first;
    int p = q.second;
    if(dis[p] < d) continue;
    for(int i=0;i<G[p].size();i++){
      Edge next = G[p][i];
      if(dis[p] + next.cost < dis[next.to]){
	dis[next.to] = dis[p] + next.cost;
	PQ.push(make_pair(dis[next.to], next.to));
      }
    }
  }
}


double solve(vector<double>xA, vector<double>yA, vector<double>xB, vector<double>yB){
  for(int i=0;i<1024;i++) G[i].clear();
  P a0 = P(xA[0], yA[0]);
  P a1 = P(xA[1], yA[1]);
  double A = distance(a0, a1);
  //  cout << distance(a0, a1) << endl;

  for(int i=0;i<xB.size();i++){
    for(int j=i+1;j<xB.size();j++){
      P b0 = P(xB[i], yB[i]);
      P b1 = P(xB[j], yB[j]);
      if(!is_intersected_ls(a0, a1, b0, b1)){
	G[i].push_back(Edge(j, distance(b0, b1)));
	G[j].push_back(Edge(i, distance(b0, b1)));
	//	cout << distance(b0, b1) << endl;
      }
    }
  }
  
  dijkstra(0);
  double B = dis[1];
  //  cout << A << " " << B << endl;  
  return A + B;
}

int main()
{
  cin >> NA >> NB;
  vector<double>xA(NA);
  vector<double>yA(NA);
  vector<double>xB(NB);
  vector<double>yB(NB);

  rep(i, NA)
    cin >> xA[i] >> yA[i];
  rep(i, NB)
    cin >> xB[i] >> yB[i];

  double res1 = solve(xA, yA, xB, yB);
  double res2 = solve(xB, yB, xA, yA);
  if(res1 > INF-EPS && res2 > INF- EPS) cout << -1 << endl;
  else cout << fixed << setprecision(10) << min(res1, res2) << endl;
  return 0;
}

Measured memory_bytes: 20664