#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

class Point
{
public:
    int y, x;
    Point(){
        y = x = 0;
    }
    Point(int y0, int x0){
        y = y0;
        x = x0;
    }
    Point operator+(const Point& p) const{
        return Point(y + p.y, x + p.x);
    }
    Point operator-(const Point& p) const{
        return Point(y - p.y, x - p.x);
    }
    Point operator*(int a) const{
        return Point(y * a, x * a);
    }
    double dist(const Point& p) const{
        return sqrt((double)(y - p.y) * (y - p.y) + (x - p.x) * (x - p.x));
    }
    int dot(const Point& p) const{
        return y * p.y + x * p.x; // |a|*|b|*cosÆ
    }
    long long cross(const Point& p) const{
        return x * p.y - y * p.x; // |a|*|b|*sinÆ
    }
};

bool segmentsCollide(const Point& a1, const Point& a2, const Point& b1, const Point& b2)
{
    if(min(a1.x, a2.x) > max(b1.x, b2.x) || min(b1.x, b2.x) > max(a1.x, a2.x) || min(a1.y, a2.y) > max(b1.y, b2.y) || min(b1.y, b2.y) > max(a1.y, a2.y))
        return false;

    return ((a2-a1).cross(b1-a1) * (a2-a1).cross(b2-a1) <= 0) && ((b2-b1).cross(a1-b1) * (b2-b1).cross(a2-b1) <= 0);
}

class Edge
{
public:
    int to;
    double cost;
    Edge(){};
    Edge(int to0, double cost0){to = to0; cost = cost0;}
};

void shortestPath(const vector<vector<Edge> >& edges, int start, vector<double>& dist)
{
    const double EPS = 1.0e-12;

    dist.assign(edges.size(), DBL_MAX);
    dist[start] = 0.0;
    priority_queue<pair<double,int> ,vector<pair<double,int> >, greater<pair<double,int> > > q;
    q.push(make_pair(0.0, start));

    while(!q.empty()){
        pair<double, int> p = q.top();
        q.pop();
        int v = p.second;
        if(dist[v] + EPS < p.first)
            continue;
        for(unsigned i=0; i<edges[v].size(); ++i){
            Edge e = edges[v][i];
            if(dist[v] + e.cost + EPS < dist[e.to]){
                dist[e.to] = dist[v] + e.cost;
                q.push(make_pair(dist[e.to], e.to));
            }
        }
    }
}

int main()
{
    vector<int> n(2);
    cin >> n[0] >> n[1];

    vector<vector<Point> > p(2);
    for(int i=0; i<2; ++i){
        p[i].resize(n[i]);
        for(int j=0; j<n[i]; ++j){
            cin >> p[i][j].x >> p[i][j].y;
        }
    }

    double ret = DBL_MAX;
    vector<vector<vector<Edge> > > edges(2);
    for(int i=0; i<2; ++i){
        vector<vector<Edge> > edges(n[i]);
        Point p1 = p[i^1][0];
        Point p2 = p[i^1][1];
        for(int j=0; j<n[i]; ++j){
            for(int k=0; k<n[i]; ++k){
                if(j != k && !segmentsCollide(p1, p2, p[i][j], p[i][k])){
                    edges[j].push_back(Edge(k, p[i][j].dist(p[i][k])));
                }
            }
        }

        vector<double> dist;
        shortestPath(edges, 0, dist);

        ret = min(ret, p1.dist(p2) + dist[1]);
    }

    if(ret > DBL_MAX/2)
        cout << -1 << endl;
    else
        printf("%.12f\n", ret);

    return 0;
}

Measured memory_bytes: 12000