import std.stdio;
import std.ascii;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.random;
import std.regex;
import std.typecons;


const EPS = 1e-8;

struct Point {
    double x, y;
    bool opEquals(in Point p) const {
        return abs(x - p.x) <= EPS && abs(y - p.y) <= EPS;
    }
    int opCmp(in Point p) const {
        double dx = x - p.x, dy = y - p.y;
        if (abs(dx) <= EPS) {
            if (abs(dy) <= EPS) return 0;
            return cast(int)(dy / abs(dy));
        } else {
            return cast(int)(dx / abs(dx));
        }
    }
    Point opBinary(alias op)(in Point p) const {
        static if (op == "+") {
            return Point(x + p.x, y + p.y);
        } else if (op == "-") {
            return Point(x - p.x, y - p.y);
        }
    }
    Point opBinary(alias op)(double k) const {
        static if (op == "*") {
            return Point(x * k, y * k);
        } else if (op == "/") {
            return Point(x / k, y / k);
        }
    }
}
double norm(in Point p) {
    return sqrt(p.x * p.x + p.y * p.y);
}

double dot(in Point a, in Point b) {
    return a.x * b.x + a.y * b.y;
}

double cross(in Point a, in Point b) {
    return a.x * b.y - a.y * b.x;
}

int ccw(Point a, Point b, Point c){
    b = b - a; c = c - a;
    if (cross(b, c) > EPS) return +1; 
    if (cross(b, c) < -EPS) return -1;
    if (dot(b, c) < 0) return +2;     
    if (b.norm < c.norm) return -2;  
    return 0;                       
}

double distance(in Point a, in Point b) {
    double dx = a.x - b.x,
           dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}

struct Segment {
    Point a, b;
}

bool contains(in Segment s, in Point p) {
    Point u = s.a - p,
          v = s.b - p;
    return abs(cross(u, v)) < EPS && dot(u, v) < -EPS;
}

Point projection(in Segment s, in Point p) {
    Point u = s.b - s.a,
          v = p - s.a;
    double n = u.norm;
    return s.a + u * (dot(u, v) / (n * n));
}

double distance(in Segment s, in Point p) {
    auto ret = min(distance(p, s.a), distance(p, s.b));
    Point proj = s.projection(p);
    if (s.contains(proj)) {
        ret = min(ret, (p - proj).norm);
    }
    return ret;
}
double distance(in Point p, in Segment s) {
    return distance(s, p);
}

bool intersect(in Segment s, in Segment t) {
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
           ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

double distance(in Segment s, in Segment t) {
    if (intersect(s, t)) return 0;
    return min( distance(s.a, t), distance(s.b, t),
                distance(s, t.a), distance(s, t.b) );
}

struct Line {
    Point a, b;
}
Point unit(in Line l) {
    /** l縺ョ蜊倅ス阪?繧ッ繝医Ν */
    return l.a * (1.0 / norm(l.b - l.a));
}
bool intersect(in Line m, in Line n) {
    double A = cross(m.b - m.a, n.b - n.a),
           B = cross(m.b - m.a, m.b - n.a);
    return (abs(A) > EPS || abs(B) < EPS);
}
Point intersection(in Line m, in Line n) {
    double A = cross(m.b - m.a, n.b - n.a),
           B = cross(m.b - m.a, m.b - n.a);
    if (abs(A) < EPS) {
        if (abs(B) < EPS) return m.a;
        else assert(0);
    }
    return n.a + (n.b - n.a) * B / A;
}

struct Circle {
    Point o;
    double r;
}

bool contains(in Circle c, in Point p) {
    /** 蜀?縺ォp縺悟性縺セ繧後ｋ縺? 
     *    p縺慶縺ョ蜻ィ荳翫↓縺ゅｋ縺ィ縺阪?蜷ォ縺セ繧後ｋ縺ィ縺ソ縺ェ縺?*/
    return distance(c.o, p) <= c.r + EPS;
}

Line[2] tangent(in Circle c, in Point p) {
    /** p繧帝?繧議縺ョ謗・邱壹ｒ霑斐☆.
     *    霑斐ｊ蛟、縺ョ2逶エ邱嗟, m縺ォ縺、縺?※ l.a == m.a == p */
    double l1 = distance(c.o, p);
    double l2 = sqrt(l1 * l1 - c.r * c.r);
    double d1 = (l2 * l2) / l1;
    double d2 = (c.r * l2) / l1;
    Point u = (c.o - p) / norm(c.o - p);
    Point b = p + u * d1;

    /* u縺ィ逶エ莠、縺吶ｋ蜊倅ス阪?繧ッ繝医Ν */
    Point o1 = Point(u.y, -u.x),
          o2 = Point(-u.y, u.x);

    Point a1 = b + o1 * d2,
          a2 = b + o2 * d2;
    return [ Line(p, a1), Line(p, a2) ];
}

struct Rectangle {
    Point v[4];
}
bool contains(in Rectangle r, in Point p) {
    /** 髟キ譁ケ蠖「r縺ォp縺悟性縺セ繧後ｋ縺? 
     *    r縺ョ蜻ィ荳翫↓p縺後≠繧九→縺阪?蜷ォ縺セ繧後ｋ縺ィ縺ソ縺ェ縺励※縺?↑縺?     *    蜃ク螟夊ァ貞ス「縺ォ荳?握蛹門庄閭ス */
    int c = ccw(p, r.v[0], r.v[1]);
    foreach (i; 0 .. 4) {
        if (c != ccw(p, r.v[i], r.v[(i + 1) % 4])) return false;
    }
    return true;
}

int Na, Nb;
Point[] A, B;

void input() {
    scanf("%d %d\n", &Na, &Nb);
    foreach (i; 0 .. Na) {
        double x, y;
        scanf("%lf %lf\n", &x, &y);
        A ~= Point(x, y);
    }
    foreach (i; 0 .. Nb) {
        double x, y;
        scanf("%lf %lf\n", &x, &y);
        B ~= Point(x, y);
    }
}

struct Edge {
    int from, to;
    double cost;
}

double dijkstra(Edge[][] G, int from, int to) {
    //writeln(G);
    struct State {
        int v; double cost;
    }
    BinaryHeap!(Array!State, "a.cost > b.cost") PQ;
    auto D = new double[G.length];
    D[] = 1e9;
    D[0] = 0;
    PQ.insert(State(from, 0));
    auto inQ = new bool[G.length];
    inQ[from] = true;
    while (!PQ.empty) {
        auto c = PQ.front; PQ.removeFront;
        inQ[c.v] = false;
        foreach (e; G[c.v]) {
            if (D[e.to] > D[e.from] + e.cost) {
                D[e.to] = D[e.from] + e.cost;
                if (!inQ[e.to]) {
                    inQ[e.to] = true;
                    PQ.insert(State(e.to, D[e.to]));
                }
            }
        }
    }
    return D[to];
}

void main() {
    input;

    auto G = new Edge[][Nb];

    auto s = Segment(A[0], A[1]);
    foreach (int i; 0 .. Nb) {
        foreach (int j; i + 1 .. Nb) {
            if (s.intersect(Segment(B[i], B[j]))) continue;
            G[i] ~= Edge(i, j, distance(B[i], B[j]));
            G[j] ~= Edge(j, i, distance(B[i], B[j]));
        }
    }
    double ans = distance(s.a, s.b) + G.dijkstra(0, 1);

    G = new Edge[][Na];
    s = Segment(B[0], B[1]);
    foreach (int i; 0 .. Na) {
        foreach (int j; i + 1 .. Na) {
            if (s.intersect(Segment(A[i], A[j]))) continue;
            G[i] ~= Edge(i, j, distance(A[i], A[j]));
            G[j] ~= Edge(j, i, distance(A[i], A[j]));
        }
    }
    ans = min(ans, distance(s.a, s.b) + G.dijkstra(0, 1));
    if (ans >= 1e9) {
        writeln(-1);
        return;
    }
    writefln("%.10f", ans);
}

Measured memory_bytes: 41480