#include <bits/stdc++.h>

using namespace std;
using ll = long long;
#define int ll
using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define PB push_back

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const int MOD = 1000000007;

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }
template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a){
  out<<'('<<a.first<<','<<a.second<<')';
  return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
  out<<'[';
  REP(i, a.size()) {out<<a[i];if(i!=a.size()-1)out<<',';}
  out<<']';
  return out;
}

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

const double EPS = 1e-8;

using R = long double;
using P = complex<R>;
using L = pair<P,P>;
using G = vector<P>;
struct C {
  P c; R r;
  C() {}
  C(const P &a, const R &b) : c(a), r(b) {}
};
struct S : public L {
  S() {}
  S(const P &a, const P &b) : L(a,b) {}
};

inline int sgn(const R& r) { return (r>EPS) - (r<-EPS); }
inline R dot(const P& a, const P& b) {
  return real(a)*real(b) + imag(a)*imag(b);
}
inline R det(const P& a, const P& b) {
  return real(a)*imag(b) - imag(a)*real(b);
}
inline P vec(const L& l) {return l.second - l.first;}
namespace std {
	bool operator < (const P& a, const P& b) {
		return sgn(real(a-b)) ? real(a-b) < 0 : sgn(imag(a-b)) < 0;
	}
	bool operator == (const P& a, const P& b) {
		return sgn(real(a-b)) == 0 && sgn(imag(a-b)) == 0;
	}
  bool cmp_y (const P& a, const P& b) {
    return sgn(imag(a-b)) ? imag(a-b) < 0 : sgn(real(a-b)) < 0;
  }
}

// P,L,Sについて入力
inline istream& operator>>(istream& is, P& p) {
  R x, y;
  is >> x >> y;
  p = P(x, y);
  return is;
}
inline istream& operator>>(istream& is, L& l) {
  P a, b;
  is >> a >> b;
  l = L(a, b);
  return is;
}
inline istream& operator>>(istream& is, S& s) {
  P a, b;
  is >> a >> b;
  s = S(a, b);
  return is;
}

// 射影
P inline projection(const L &l, const P &p) {
  R t = dot(p-l.first, l.first-l.second) / norm(l.first-l.second);
  return l.first + t*(l.first-l.second);
}
// 反射
P inline reflection(const L &l, const P &p) {
  return p + (R)2 * (projection(l, p) - p);
}

// 線分abから見たcの位置
enum CCW{LEFT=1, RIGHT=2, BACK=4, FRONT=8, ON_SEG=16};
int ccw(P a, P b, P c) {
	P p = (c-a)/(b-a);
	if(sgn(imag(p)) > 0) return LEFT;
	if(sgn(imag(p)) < 0) return RIGHT;
	if(sgn(real(p)) < 0) return BACK;
	if(sgn(real(p)-1) > 0) return FRONT;
	return ON_SEG;
}

// 垂直,平行
inline bool vertical(L a, L b) {return sgn(dot(vec(a), vec(b))) == 0;}
inline bool parallel(L a, L b) {return sgn(det(vec(a), vec(b))) == 0;}
inline bool eal(L a, L b) {return vertical(a,b) && parallel(a,b);}

// 交差判定
template<bool strict=false> inline bool intersect(const L&l1, const L&l2) {
  if(strict) return sgn(det(vec(l1),vec(l2))) != 0;
  return sgn(det(vec(l1),vec(l2))) != 0 || l1 == l2;
}
template<bool strict=false> inline bool intersect(const L&l, const S&s) {
  if(strict) det(s.first, vec(l)) * det(s.second, vec(l)) < 0;
  return det(s.first, vec(l)) * det(s.second, vec(l)) <= 0;
}
template<bool strict=false> inline bool intersect(const S&s1, const S&s2) {
  int ccw1 = ccw(s1.first, s1.second, s2.first) | ccw(s1.first, s1.second, s2.second);
  int ccw2 = ccw(s2.first, s2.second, s1.first) | ccw(s2.first, s2.second, s1.second);
  if(strict) return (ccw1 & ccw2) == (LEFT | RIGHT);
  return (ccw1 & ccw2) == (LEFT | RIGHT) || ((ccw1 | ccw2) & ON_SEG);
}

vector<pair<int, double>> g1[1010];
vector<pair<int, double>> g2[1010];
double d[1010];

signed main(void)
{
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n, m;
  cin >> n >> m;
  vector<P> a(n), b(m);
  REP(i, n) cin >> a[i];
  REP(i, m) cin >> b[i];

  // a[0] と a[1] を結ぶとする
  S l(a[0], a[1]);
  REP(i, m) FOR(j, i+1, m) {
    S tmp(b[i], b[j]);
    if(!intersect(l, tmp)) {
      g1[i].PB({j, abs(b[i]-b[j])});
      g1[j].PB({i, abs(b[i]-b[j])});
    }
  }

  priority_queue<pair<double,int>, vector<pair<double,int>>, greater<pair<double,int>>> que;
  REP(i, m) d[i] = INF;
  d[0] = 0;
  que.push({d[0], 0});

  while(que.size()) {
    pair<double,int> p = que.top(); que.pop();
    if(d[p.second] < p.first) continue;
    if(p.second == 1) break;
    for(auto e: g1[p.second]) {
      if(d[e.first] > d[p.second] + e.second) {
        d[e.first] = d[p.second] + e.second;
        que.push({d[e.first], e.first});
      }
    }
  }

  R ans = abs(a[0]-a[1]) + d[1];
  // cout << ans << endl;

  // b[0] と b[1] を結ぶとする
  l = S(b[0], b[1]);
  REP(i, n) FOR(j, i+1, n) {
    S tmp(a[i], a[j]);
    if(!intersect(l, tmp)) {
      g2[i].PB({j, abs(a[i]-a[j])});
      g2[j].PB({i, abs(a[i]-a[j])});
    }
  }

  while(que.size()) que.pop();
  REP(i, n) d[i] = INF;
  d[0] = 0;
  que.push({d[0], 0});

  while(que.size()) {
    pair<double,int> p = que.top(); que.pop();
    if(d[p.second] < p.first) continue;
    if(p.second == 1) break;
    for(auto e: g2[p.second]) {
      if(d[e.first] > d[p.second] + e.second) {
        d[e.first] = d[p.second] + e.second;
        que.push({d[e.first], e.first});
      }
    }
  }

  chmin(ans, abs(b[0]-b[1]) + d[1]);

  if(ans >= INF) cout << -1 << endl;
  else cout << fixed << setprecision(15) << ans << endl;

  return 0;
}



Measured memory_bytes: 37312