#include <iostream>
#include <vector>
#include <queue>
#include <utility>
#include <complex>
#include <cmath>
#include <cstdio>
using namespace std;

#define INF 1e20

typedef complex<long long int> P;
typedef pair<P, P> Line;

// ?????????????????????
bool judgeIentersected(Line a, Line b){
  long long int ta = (b.first.real() - b.second.real()) * (a.first.imag() - b.first.imag())
    + (b.first.imag() - b.second.imag()) * (b.first.real() - a.first.real());
  long long int tb = (b.first.real() - b.second.real()) * (a.second.imag() - b.first.imag())
    + (b.first.imag() - b.second.imag()) * (b.first.real() - a.second.real());
  long long int tc = (a.first.real() - a.second.real()) * (b.first.imag() - a.first.imag())
    + (a.first.imag() - a.second.imag()) * (a.first.real() - b.first.real());
  long long int td = (a.first.real() - a.second.real()) * (b.second.imag() - a.first.imag())
    + (a.first.imag() - a.second.imag()) * (a.first.real() - b.second.real());  
  return tc * td < 0 && ta * tb < 0;
}

// ????????????????????????
double dijk(int v, int s, int g, vector<vector<double> > adjmatrix, vector<P> point, Line NGcross){
  vector<double> result(v, INF);
  priority_queue<pair<double, int> > wait;
  result[s] = 0;
  wait.push(make_pair(0, s));

  while(!wait.empty()){
    int nowpoint = wait.top().second;
    double nowcost = -wait.top().first;
    wait.pop();
    if(result[nowpoint] < nowcost){ continue; }

    for(int nextpoint = 0; nextpoint < v; nextpoint++){
      double nextcost = nowcost + adjmatrix[nowpoint][nextpoint];
      if(!judgeIentersected(NGcross, make_pair(point[nowpoint], point[nextpoint])) && result[nextpoint] > nextcost){
        result[nextpoint] = nextcost;
        wait.push(make_pair(-nextcost, nextpoint));
      }
    }
  }
  
  return result[g];
}

int main(void){
  int Na, Nb;
  cin >> Na >> Nb;

  // ?????\: ?????£??????????°??????????????????§???????????????????????? ??¨???????°????????????????
  // ??¨??????????????§?????????????°???????????????????????????????????????????????°??????????????????????

  // ???????????±???????????????
  int x, y;
  vector<P> a;
  for(int i = 0; i < Na; i++){
    cin >> x >> y;
    a.push_back(P(x, y));
  }
  vector<P> b;
  for(int i = 0; i < Nb; i++){
    cin >> x >> y;
    b.push_back(P(x, y));
  }

  // ??£??\???????????????
  vector<vector<double> > adj_a(Na, vector<double>(Na, INF));
  for(int i = 0; i < Na; i++)
    for(int j = 0; j < Na; j++)
      adj_a[i][j] = sqrt((a[i].real() - a[j].real()) * (a[i].real() - a[j].real())
                         + (a[i].imag() - a[j].imag()) * (a[i].imag() - a[j].imag()));

  vector<vector<double> > adj_b(Nb, vector<double>(Nb, INF));
  for(int i = 0; i < Nb; i++)
    for(int j = 0; j < Nb; j++)
      adj_b[i][j] = sqrt((b[i].real() - b[j].real()) * (b[i].real() - b[j].real())
                         + (b[i].imag() - b[j].imag()) * (b[i].imag() - b[j].imag()));
  
  // 2????????????????????????????????????????????????
  double prio_a = adj_a[0][1] + dijk(Nb, 0, 1, adj_b, b, make_pair(a[0], a[1]));
  double prio_b = adj_b[0][1] + dijk(Na, 0, 1, adj_a, a, make_pair(b[0], b[1]));
  double res = prio_a < prio_b ? prio_a : prio_b;
    
  // ???????????????
  if(res >= INF){ cout << -1 << endl; }
  else{ printf("%.12f\n", res); }

  return 0;
}

Measured memory_bytes: 24872