#include <tuple>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <map>
#include <climits>
#include <complex>
#include <numeric>
using namespace std;

#define REP(i,n) for(int i=0; i<(int)(n); i++)
#define RREP(i,n) for(int i=(int)n-1; i>=0; i--)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();++i)
#define ALL(c) (c).begin(), (c).end()

typedef long long int ll;
typedef pair<int, int> pii;
typedef pair<int, pair<int, int> > pipii;
typedef vector<int> vi;

const int MOD = 1e9+7;

typedef tuple<double, double> mytuple;

#define EPS 1e-8
typedef complex<double> Point;
namespace std {
    bool operator < (const Point &a, const Point &b) {
        return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
    }
    Point operator / (const Point &p, const double &a) {
        return Point(real(p)/a, imag(p)/a);
    }
    Point operator * (const Point &p, const double &a) {
        return Point(real(p)*a, imag(p)*a);
    }
    bool operator == (const Point &a, const Point &b) {
        return real(a) == real(b) && imag(a) == imag(b);
    }
}
typedef vector<Point> Polygon;
struct Line : public vector<Point> { 
    Line () {}
    Line (const Point &a, const Point &b) {
        push_back(a); push_back(b);
    }
};

double dot (const Point &a, const Point &b) {
        return real(conj(a)*b);
}

double cross (const Point &a, const Point &b) {
    return imag(conj(a)*b);
}

int ccw (Point a, Point b, Point c) {
    b -= a; c -= a;
    if (cross(b, c) > 0)   return +1; //ccw
    if (cross(b, c) < 0)   return -1; //cw
    if (dot(b, c) < 0)     return +2; //c--a--b on line
    if (norm(b) < norm(c)) return -2; //a--b--c on line
    return 0; //a--c--b or (c=b)
}

bool intersectSS (const Line &s, const Line &t) {
    return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 &&
        ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
}

bool intersectLL (const Line &l, const Line &m) {
    return abs(cross(l[1]-l[0], m[1]-m[0])) > EPS || // non-parallel
        abs(cross(l[1]-l[0], m[0]-l[0])) < EPS;   // same line
}

typedef double Weight;
const Weight INF=1e9;
struct Edge{
    int src,dst;
    Weight weight;
    int rev;
    Edge(int f, int t, Weight c, int rev=0):src(f),dst(t),weight(c),rev(rev){}
    bool operator < (const Edge& re)const{ return weight > re.weight;}
};
typedef vector<vector<Edge> > Graph;
void add_edge(Graph &G, int s, int t, Weight cap){
    G[s].push_back(Edge(s, t, cap, G[t].size()));
}
void shortestPath(const Graph &g, int s, vector<Weight> &dist, vector<int> &prev) {
    int n = g.size();
    dist.assign(n, INF); dist[s] = 0;
    prev.assign(n, -1);
    priority_queue<Edge> Q;
    for(Q.push(Edge(-2, s, 0)); !Q.empty();){
        Edge e = Q.top(); Q.pop();
        if(prev[e.dst] != -1) continue;
        prev[e.dst] = e.src;
        FOR(f,g[e.dst]) {
            if (dist[f->dst] > e.weight+f->weight){
                dist[f->dst] = e.weight+f->weight;
                Q.push(Edge(f->src, f->dst, e.weight+f->weight));
            }
        }
    }
}


double dist(Line &l){
    return abs(l[1] - l[0]);
}

int main(void){
    int na, nb;
    cin >> na >> nb;
    vector<Point> aP, bP;
    REP(i, na){
        double x, y;
        cin >> x >> y;
        aP.push_back(Point(x, y));
    }
    REP(i, nb){
        double x, y;
        cin >> x >> y;
        bP.push_back(Point(x, y)); 
    }

    Graph g(na);
    REP(i, na){
        for(int j = i + 1; j < na; j++){
            Line b = Line((bP[0]), (bP[1]));
            Line a = Line((aP[i]), (aP[j]));
            if(!intersectSS(a, b)){
                add_edge(g, i, j, dist(a));
                add_edge(g, j, i, dist(a));
            }
        }
    }
    vector<Weight> di;
    vi path;
    shortestPath(g, 0, di, path);
    Line b = Line((bP[0]), (bP[1]));
    double l = dist(b) + di[1];

    double ans = INF;

    g.clear();
    g.resize(nb);
    REP(i, nb){
        for(int j = i + 1; j < nb; j++){
            Line b = Line((aP[0]), (aP[1]));
            Line a = Line((bP[i]), (bP[j]));
            if(!intersectSS(a, b)){
                add_edge(g, i, j, dist(a));
                add_edge(g, j, i, dist(a));
            }
        }
    }
    vector<Weight> dist2;
    vi path2;
    shortestPath(g, 0, dist2, path2);
    Line a = Line((aP[0]), (aP[1]));
    double r = dist(a) + dist2[1];


    if(!intersectSS(a, b)){
        printf("%.10lf", dist(a) + dist(b));
    }
    else if(min(l, r) < INF - EPS){
        printf("%.10lf", min(l, r));
    }
    else cout << -1 << endl;

return 0;
}

Measured memory_bytes: 27588