#include <bits/stdc++.h>
using namespace std;

typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;
typedef pair<LL, LL> PLL;

#define ALL(a)  (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}

const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;
const double INF = 1e18;

struct P{
  double x, y;
  P(double x_=0., double y_=0.):
	x(x_), y(y_){}
  P operator-(const P& rhs)const{
	return P(x-rhs.x, y-rhs.y);
  }
  double norm(){
	return x*x+y*y;
  }
};
struct Segment{
  P p1, p2;
  double norm(){
	return (p1-p2).norm();
  }
};

double dot(P a, P b){
	return a.x*b.x + a.y*b.y;
}
double cross(P a, P b){
	return a.x*b.y - a.y*b.x;
}
int ccw(P p0, P p1, P p2){

	//p0->p1???p0?§???????p1?????????????????????????????¨????????¨???

	//p0->p2??????????¨??????????????????¨???
	static const int COUNTER_CLOCKWISE = 1;
	//p0->p2???????¨??????????????????¨???
	static const int CLOCKWISE = -1;
	//p2,p0,p1????????§????????´?????????????????¨???
	static const int ONLINE_BACK = 2;
	//p0,p1,p2 ????????§????????´?????????????????´???
	static const int ONLINE_FRONT = -2;
	//p2 ????????? p0p1 ??????????????´???
	static const int ON_SEGMENT = 0;

	P a = p1 - p0;
	P b = p2 - p0;

	if (cross(a, b) > EPS) return COUNTER_CLOCKWISE;
	if (cross(a, b) < -EPS) return CLOCKWISE;
	if (dot(a, b) < -EPS) return ONLINE_BACK;
	if (a.norm() < b.norm()) return ONLINE_FRONT;

	return ON_SEGMENT;

}

bool intersect(Segment s1, Segment s2){
	return(ccw(s1.p1, s1.p2, s2.p1) * ccw(s1.p1, s1.p2, s2.p2) <= 0 &&
		ccw(s2.p1, s2.p2, s1.p1) * ccw(s2.p1, s2.p2, s1.p2) <= 0);
}


double dist[1010][1010];
double calc(int N){
  vector<double> dp(N,INF);
  vector<bool> vis(N, false);
  int s = 0;
  dp[0] = 0;
  REP(i,N){
	vis[s] = true;
	int id = -1;
	double mn = INF;
	REP(j,N){
	  if(!vis[j]){
		double d = dp[s] + dist[s][j];
		dp[j] = min(dp[j], d);
		if(dp[j] < mn){
		  id = j;
		  mn = dp[j];
		}
	  }
	}
	if(id < 0) break;
	s = id;
  }
  return dp[1];
}

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N, M; cin >> N >> M;
  vector<P> as(N), bs(M);
  REP(i,N) cin >> as[i].x >> as[i].y;
  REP(i,M) cin >> bs[i].x >> bs[i].y;

  double ans = INF;
  {
	Segment s; s.p1 = as[0], s.p2 = as[1];
	REP(i,M) REP(j,i){
	  Segment t; t.p1 = bs[i], t.p2 = bs[j];
	  dist[i][j] = dist[j][i] = (intersect(s,t)? INF:sqrt(t.norm()));
	}
	ans = min(ans, calc(M)+sqrt(s.norm()));
  }
  {
	Segment s; s.p1 = bs[0], s.p2 = bs[1];
	REP(i,N) REP(j,i){
	  Segment t; t.p1 = as[i], t.p2 = as[j];
	  dist[i][j] = dist[j][i] = (intersect(s,t)? INF:sqrt(t.norm()));
	}
	ans = min(ans, calc(N)+sqrt(s.norm()));
  }

  if(ans >= INF) cout<<-1<<endl;
  else cout << fixed << setprecision(10) << ans << endl;
  return 0;
}

Measured memory_bytes: 11168