#include <bits/stdc++.h>
#define REP(i, a, n) for(ll i = ((ll) a); i < ((ll) n); i++)
using namespace std;
typedef long long ll;

class Vector2 {
public:
  double x, y;

  Vector2(): x(0), y(0) {}
  Vector2(double x, double y): x(x), y(y) {}

  Vector2 operator+(Vector2 p) { return Vector2(x + p.x, y + p.y); }
  Vector2 operator-(Vector2 p) { return Vector2(x - p.x, y - p.y); }

  Vector2 operator*(double t) { return Vector2(x * t, y * t); }
  Vector2 operator/(double t) { return Vector2(x / t, y / t); }

  double dot(Vector2 p) { return x * p.x + y * p.y; }
  double det(Vector2 p) { return x * p.y - y * p.x; }

  double norm2() { return x * x + y * y; }
  double norm() { return sqrt(norm2()); }

  Vector2 normalize() { return Vector2(x / norm(), y / norm()); }

  friend ostream& operator<<(ostream &out, const Vector2 &v) {
    out << "(" << v.x << ", " << v.y << ")";
  }
};
using Point2 = Vector2;

bool line_segments_intersect(Point2 a, Point2 b, Point2 c, Point2 d) {
  double ta = (a - c).det(d - c);
  double tb = (b - c).det(d - c);
  double tc = (c - a).det(b - a);
  double td = (d - a).det(b - a);
  return ta * tb < 0 && tc * td < 0;
}

class Dijkstra {
public:
  struct edge {
    ll v;
    double dist;
  };

  struct state {
    ll v;
    double cost;
    bool operator>(const state s) const { return cost > s.cost; }
  };

  const double INF = 1e20;
  ll N;
  vector< vector<edge> > E;

  Dijkstra(ll n): N(n), E(n) {}

  void add_undirected_edge(ll u, ll v, double d) {
    E[u].push_back((edge) { v, d });
    E[v].push_back((edge) { u, d });
  }

  vector<double> shortest_path(ll S) {
    vector<double> dp(E.size(), INF);
    priority_queue<state, vector<state>, greater<state> > q;
    q.push((state) { S, 0 });
    while(!q.empty()) {
      ll v = q.top().v;
      double cost = q.top().cost;
      q.pop();
      if(dp[v] <= cost) continue;
      dp[v] = cost;
      REP(i, 0, E[v].size()) {
        ll nv = E[v][i].v;
        double ncost = cost + E[v][i].dist;
        if(dp[nv] > ncost) q.push((state) { nv, ncost });
      }
    }
    return dp;
  }
};

int main(void) {
  ll N, M;
  cin >> N >> M;
  vector<Point2> A(N), B(M);
  REP(i, 0, N) cin >> A[i].x >> A[i].y;
  REP(i, 0, M) cin >> B[i].x >> B[i].y;

  if(!line_segments_intersect(A[0], A[1], B[0], B[1])) {
    printf("%.15lf\n", (A[1] - A[0]).norm() + (B[1] - B[0]).norm());
    return 0;
  }

  Dijkstra dijkA(N);
  REP(i, 0, N) REP(j, i + 1, N) {
    if(!line_segments_intersect(A[i], A[j], B[0], B[1])) {
      dijkA.add_undirected_edge(i, j, (A[j] - A[i]).norm());
    }
  }
  double ansA = dijkA.shortest_path(0)[1] + (B[1] - B[0]).norm();

  Dijkstra dijkB(M);
  REP(i, 0, M) REP(j, i + 1, M) {
    if(!line_segments_intersect(B[i], B[j], A[0], A[1])) {
      dijkB.add_undirected_edge(i, j, (B[j] - B[i]).norm());
    }
  }
  double ansB = dijkB.shortest_path(0)[1] + (A[1] - A[0]).norm();

  const double EPS = 1e-10;
  if(ansA >= 1e20 - EPS && ansB >= 1e20 - EPS) {
    cout << -1 << endl;
  } else {
    printf("%.15lf\n", min(ansA, ansB));
  }
}

