#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
#include<climits>
#include<string>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define rep(i,n) for(int i=0;i<((int)(n));i++)
#define reg(i,a,b) for(int i=((int)(a));i<=((int)(b));i++)
#define irep(i,n) for(int i=((int)(n))-1;i>=0;i--)
#define ireg(i,a,b) for(int i=((int)(b));i>=((int)(a));i--)
typedef long long int lli;
typedef pair<int,int> mp;
#define fir first
#define sec second
#define IINF INT_MAX
#define LINF LLONG_MAX
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#define pque(type) priority_queue<type,vector<type>,greater<type> >
#define memst(a,b) memset(a,b,sizeof(a))
#define iter(v,ite) for(auto ite=(v).begin();ite!=(v).end();ite++)
#define mimunum(v,x) distance((v).begin(),lower_bound((v).begin(),(v).end(),x))

struct makehtml{
	vector<string> ss;
	
	makehtml(){}
	/*
	ctx.beginPath()
	ctx.moveTo(50.000000,100.000000);
	ctx.lineTo(150.000000,100.000000);
	ctx.stroke();
	
	ctx.fillStyle = "rgb(0,0,0)";
	
	ctx.beginPath();
	ctx.arc(168,59,3,0,360);
	ctx.fill();

	*/
	
	void out(const char* name,double mag){
		char fname[100];
		sprintf(fname,"%s.html",name);
		FILE* fp = fopen(fname,"w");
		if(fp==NULL){
			eprintf("can't open %s\b",fname);
			exit(-1);
		}
		fprintf(fp,"<html>\n<head>\n<title>");
		fprintf(fp,"%s",name);
		fprintf(fp,"</title>\n</head>\n<body>\n");
		fprintf(fp,"<p>name: %s</p>",name);
		fprintf(fp,"<canvas id=\"vis\" width=\"%d\" height=\"%d\"></canvas>",2000,2000);
		fprintf(fp,"<script>\n");
		fprintf(fp,"var vis = document.getElementById('vis');\nvar ctx = vis.getContext('2d');\n");
		
		rep(i,ss.size()){
			fprintf(fp,"%s\n",ss[i].c_str());
		}
		
		fprintf(fp,"</script>\n");
		fprintf(fp,"</body>\n</html>\n");
		fclose(fp);
	}

} makehtml_instance;


void addhtml(string s){
	makehtml_instance.ss.push_back(s);
}

void outhtml(string s,double mag){
	makehtml_instance.out(s.c_str(),mag);
}

void randcolhtml(){
	char ns[100];
	sprintf(ns,"ctx.fillStyle = \"rgb(%d,%d,%d)\";",rand()%128,rand()%128,rand()%128);
	addhtml(ns);
	sprintf(ns,"ctx.strokeStyle = \"rgb(%d,%d,%d)\";",rand()%128,rand()%128,rand()%128);
	addhtml(ns);
}

void inithtml(){
	makehtml_instance.ss.clear();
}


const double pi=3.14159265358979;

struct pos{
	double x,y;
	double norm,norm2;
	pos tov(pos a){
		return (a-(*this));
	}
	pos operator+(pos a)const{
		pos res=a;
		res.x+=x; res.y+=y;
		res=pos(res.x,res.y);
		return res;
	}
	pos operator-(pos a)const{
		pos res=(*this);
		res.x-=a.x; res.y-=a.y;
		res=pos(res.x,res.y);
		return res;
	}
	pos scalar(double a){
		pos res=(*this);
		res.x*=a; res.y*=a;
		res=pos(res.x,res.y);
		return res;
	}
	double dot(pos a){
		return x*a.x + y*a.y;
	}
	double cross(pos a){
		return x*a.y - y*a.x;
	}
	double theta(pos a){
		double nt=dot(a)/(norm*a.norm);
		nt=acos(max(-1.0,min(1.0,nt)));
		double ns=(cross(a)/(norm*a.norm));
		if(ns<0)nt*=-1;
		return nt;
	}
	pos(double ix,double iy){
		x=ix; y=iy;
		norm2=x*x+y*y;
		norm=sqrt(norm2);
	}
	pos(){}
	string str(){
		char ns[50];
		sprintf(ns,"(%lf %lf)",x,y);
		return	string(ns);
	}
	void outh(double mag){
		char ns[50];
		addhtml("ctx.beginPath();"); 
		sprintf(ns,"ctx.arc(%lf,%lf,%lf,0,360);",x*mag,y*mag,5.0); addhtml(ns);
		addhtml("ctx.fill();");
	}
	static pos polar(double r,double t){
		return pos(r*cos(t),r*sin(t));
	}
	pos turn(double t){
		//t[rad]??????
		return pos(x*cos(t)-y*sin(t),x*sin(t)+y*cos(t));
	}
	pos tolen(double a){
		//?????????a?????????
		return this->scalar(a/norm);
	}
	bool  operator<(pos a) const{
		//if(x!=a.x)return (x<a.x);
		//return (y<a.y);
		if(y!=a.y)return (y<a.y);
		return (x<a.x);
	}	
	bool operator>(pos a)const{ return (a<(*this)); }	
	bool operator==(pos a)const{ return (x==a.x && y==a.y); }	
	bool operator!=(pos a)const{ return !(a==(*this)); }	
};
struct line{
	pos p,q;
	pos vec;
	string str(){
		return ("("+p.str()+"-"+q.str()+")");
	}
	void outh(double mag){
		char ns[50];
		addhtml("ctx.beginPath();");
		sprintf(ns,"ctx.moveTo(%lf,%lf);",p.x*mag,p.y*mag); addhtml(ns);
		sprintf(ns,"ctx.lineTo(%lf,%lf);",q.x*mag,q.y*mag); addhtml(ns);
		addhtml("ctx.stroke();");
	}
	bool iscross(line a){
		double da,db;
		da=vec.cross( p.tov(a.p) );
		db=vec.cross( p.tov(a.q) );
		if(da*db>=0)return false;
		da=a.vec.cross( a.p.tov(p) );
		db=a.vec.cross( a.p.tov(q) );
		return (da*db<0);
	}
	line(pos ip,pos iq){
		p=ip; q=iq;
		vec=p.tov(q);
	}
	line(){}
	double dist(pos a){
		if(p.tov(a).dot( p.tov(q) )<0)return p.tov(a).norm;
		if(q.tov(a).dot( q.tov(p) )<0)return q.tov(a).norm;
		return abs(vec.cross(p.tov(a))/vec.norm);
	}
	double dist(line a){
		if(iscross(a))return 0;
		return min( min(dist(a.p),dist(a.q)) , min(a.dist(this->p),a.dist(this->q)));
	}
	pos crosspos(line a){
		/*
		double d1=a.vec.cross(a.p.tov(p))/a.vec.norm;
		double d2=a.vec.cross(a.p.tov(q))/a.vec.norm;
		bool isc=(d1*d2<0);
		d1=abs(d1); d2=abs(d2);
		double sc;
		if(!isc){
			if(d1>d2)sc = d1/(d1-d2);
			else sc=d1/(d2-d1);
		}
		else sc = d1/(d1+d2);
		return (p+vec.scalar(sc));*/
		
		double t = a.vec.cross(a.p-p)/a.vec.cross(vec);
		return (p+vec.scalar(t));
	}
	line bisection(){//?????´????????????
		//???????¨??????????90????????£???????????????
		pos fr=(p+q).scalar(0.5);
		pos to=fr+pos(-vec.y,vec.x);
		return line(fr,to);
	}
	bool  operator<(line a) const{
		//if(x!=a.x)return (x<a.x);
		//return (y<a.y);
		if(p!=a.p)return (p<a.p);
		return (q<a.q);
	}	
	bool operator>(line a)const{ return (a<(*this)); }	
};

double lowofcos_getcos(double a,double b,double c){
	return ((a*a+b*b-c*c)/(2*a*b));
}
struct circle{
	pos p;
	double r;
	line koten(circle a){
		pos cv=p.tov(a.p);
		double br=atan2(cv.y,cv.x);
		double dr=acos(lowofcos_getcos( r, cv.norm, a.r));
		pos p1= p+pos::polar(r,br+dr);
		pos p2= p+pos::polar(r,br-dr);
		if(p1>p2)swap(p1,p2);
		return line(p1,p2);
	}
	circle(pos ip,double ir){
		p=ip; r=ir;
	}
	circle(){}
	void outh(double mag){
		char ns[50];
		addhtml("ctx.beginPath();"); 
		sprintf(ns,"ctx.arc(%lf,%lf,%lf,0,360);",p.x*mag,p.y*mag,r*mag); addhtml(ns);
		addhtml("ctx.stroke();");
	}
	
	vector<line> tangs(circle a){ //??\?????????
		//validate AOJ 2201
		circle b(*this);
		if(a.r<b.r)swap(a,b);
		vector<line> res;
		if((a.p-b.p).norm-(a.r-b.r)<0.0)return res;
		if((a.p-b.p).norm-(a.r-b.r)<1e-6){
			if((b.p-a.p).norm<1e-6)return res; //??¨???????????????
			pos rv=(b.p-a.p).tolen(a.r);
			res.push_back(line(rv+a.p,rv+a.p+rv.turn(pi/2.0)));
			return res;
		}
		{
			pos cv=b.p-a.p;
			double th=acos((a.r-b.r)/cv.norm);
			pos p1 = cv.turn(th);
			res.push_back(line(a.p+p1.tolen(a.r),b.p+p1.tolen(b.r)));
			pos p2 = cv.turn(-th);
			res.push_back(line(a.p+p2.tolen(a.r),b.p+p2.tolen(b.r)));
		}
		if((a.p-b.p).norm-(a.r+b.r)<0.0)return res;
		if((a.p-b.p).norm-(a.r+b.r)<1e-6){
			pos rv=(b.p-a.p).tolen(a.r);
			res.push_back(line(rv+a.p,rv+a.p+rv.turn(pi/2.0)));
			return res;
		}
		{
			pos cv=b.p-a.p;
			double th=acos((a.r+b.r)/cv.norm);
			pos p1 = cv.turn(th);
			res.push_back(line(a.p+p1.tolen(a.r),b.p+p1.tolen(-b.r)));
			pos p2 = cv.turn(-th);
			res.push_back(line(a.p+p2.tolen(a.r),b.p+p2.tolen(-b.r)));
		}
		return res;
	}
};

struct polygon{
	vector<pos> ps;
	polygon(){}
	void outh(double mag){
		char ns[50];
		addhtml("ctx.beginPath();");
		int ls=ps.size();
		sprintf(ns,"ctx.moveTo(%lf,%lf);",ps[ls-1].x*mag,ps[ls-1].y*mag); addhtml(ns);
		rep(i,ps.size()){
			sprintf(ns,"ctx.lineTo(%lf,%lf);",ps[i].x*mag,ps[i].y*mag); addhtml(ns);
		}
		addhtml("ctx.stroke();");
	}
	double area(){
		double res=0;
		rep(i,ps.size()){
			pos no=ps[i],to=ps[(i+1)%ps.size()];
			res+=(no.x+to.x)*(no.y-to.y);
		}
		if(res<0)reverse(ps.begin(),ps.end());
		return abs(res)/2;
	}
	polygon(pos a,pos b){
		ps.push_back(a);
		ps.push_back(pos(a.x,b.y));
		ps.push_back(b);
		ps.push_back(pos(b.x,a.y));
	}
	line gete(int a){
		a%=ps.size();
		return line(ps[a],ps[(a+1)%ps.size()]);
	}
	int isin(pos a){//?????´??????2,?????£????????????1,?????????0
		double as=0;
		rep(i,ps.size()){
			line ne=gete(i);
			if(ne.dist(a)<=0)return 1;
			pos v1=a.tov(ne.p);
			pos v2=a.tov(ne.q);
			as+=v1.theta(v2);
		}
		if(abs(as)<1e-6)return 0;
		return 2;
	}
	polygon convex_full(){
		polygon res;
		int ns=ps.size();
		vector<pos> vs(2*ns);
		sort(ps.begin(),ps.end());
		int k=0;
		rep(i,ns){
			pos np=ps[i];
			while(k>1 && vs[k-2].tov(vs[k-1]).cross(vs[k-1].tov(np))<-1e-6)k--;
			vs[k]=np; k++;
		}
		int t=k;
		ireg(i,0,ns-2){
			pos np=ps[i];
			while(k>t && vs[k-2].tov(vs[k-1]).cross(vs[k-1].tov(np))<-1e-6)k--;
			vs[k]=np; k++;
		}
		vs.resize(k-1);
		swap(vs,res.ps);
		return res;
	}
	polygon cut(line a){//???????????????????????????
		polygon res;
		rep(i,ps.size()){
			line ne=gete(i);
			double d1=a.vec.cross(a.p.tov(ne.p));
			double d2=a.vec.cross(a.p.tov(ne.q));
			if(d1<1e-6)res.ps.push_back(ne.p); //?????£????????£???eps
			if(d1*d2<-1e-6)res.ps.push_back(a.crosspos(ne)); //?????£????????????eps
		}
		return res;
	}
	
	vector<polygon> voronoi(vector<pos> ps){
		//validate AOJ 2160
		vector<polygon> res;
		rep(i,ps.size()){
			polygon np(*this);
			rep(j,ps.size()){
				if(i==j)continue;
				line nl = line(ps[j],ps[i]).bisection();
				
				np = np.cut(nl);
			}
			res.push_back(np);
		}
		return res;		
	}
	polygon mult(polygon a){
		return a;
	}
};

struct unifo{
	int n;
	int uni[100005];
	void init(int in){
		n=in;
		rep(i,n)uni[i]=i;
	}
	int find(int p){
		if(uni[p]==p)return p;
		else return (uni[p]=find(uni[p]));
	}
	void mer(int p,int q){
		if(!same(p,q))uni[find(p)]=find(q);
	}
	bool same(int p,int q){
		return find(p)==find(q);
	}
	void out(){
		vector<mp> ps;
		//printf("%d %d\n",i,find(i));
		rep(i,n)ps.push_back(mp(find(i),i));
		sort(ps.begin(),ps.end());
		printf("uni .. %d elem\n{ ",n);
		rep(i,n){
			if(i!=0 && ps[i-1].fir!=ps[i].fir)printf("}\n{ ");
			printf("%d ",ps[i].sec);
		}
		printf("}\n\n");
	}
} uni;



int n,m;
pos ps[1005];
pos qs[1005];

double ds[1005][1005];
double dist[1005];
int gone[1005];

int main(void){
	scanf("%d%d",&n,&m);
	rep(i,n+m){
		double x,y;
		scanf("%lf%lf",&x,&y);
		if(i<n)ps[i]=pos(x,y);
		else qs[i-n]=pos(x,y);
	}
	
	double ans=1e15;
	rep(qqq,2){
		line ne(ps[0],ps[1]);
		double ns=ne.vec.norm;
		
		uni.init(m+5);
		typedef pair<double,mp> dmp;
		vector<dmp> es;
		
		rep(i,m)dist[i]=-1;
		rep(i,m){
			rep(j,i){
				line ce(qs[i],qs[j]);
				ds[i][j]=ds[j][i]=(ce.iscross(ne)?-1:ce.vec.norm);
			}
		}
		/*
		rep(i,m)rep(j,m){
			printf("%d %d %lf\n",i,j,ds[i][j]);
		}*/
		memset(gone,0,sizeof(gone));
		dist[0]=0;
		
		
		for(;;){
			int nv=-1;
			rep(i,m){
				if(gone[i] || dist[i]<0)continue;
				if(nv==-1 || dist[i]<dist[nv])nv=i;
			}
			if(nv==-1){
				ns=1e15;
				break;
			}
			if(nv==1){
				ns+=dist[1];
				break;
			}
			gone[nv]=1;
			rep(j,m){
				if(gone[j] || ds[nv][j]<0)continue;
				double nc=dist[nv]+ds[nv][j];
				if(dist[j]<0 || nc<dist[j])dist[j]=nc;
			}
		}
		ans=min(ans,ns);
		swap(n,m);
		swap(ps,qs);
	}
	if(ans>1e10)printf("-1\n");
	else printf("%.11f\n",ans);
	return 0;
}
### Prompt

Please formulate a Cpp solution to the following problem:

The Kingdom of Neva is home to two ethnic groups, the Totata and the Tutete. The biggest feature of the Totata tribe is that they eat sweet and sour pork with pineapple. However, the Tutete tribe eats vinegared pork in pineapple. These two peoples couldn't get along with each other, and the Totata and Tutete have been in conflict for hundreds of years.

One day, a petition arrived from two ethnic groups under King Neva. According to it, the Totata tribe wants to build a road connecting the town A and the town B where they live. On the other hand, the Tutete tribe also wants to build a road connecting the town C and the town D where they live.

To prevent the two races from clashing, the roads of the Totata and Tutete cannot be crossed. Also, due to technical restrictions, it is only possible to build a road that connects the two cities in a straight line. In other words, if necessary, instead of connecting city A and city B directly with a road, it would indirectly connect city A and city B via some Totata towns (of course, of the Tutete tribe). Do not go through the city). At that time, the roads connecting the towns of the Totata tribe may intersect. The same applies to town C and town D.

Building a road costs proportional to its length. Therefore, I would like to make the total length of the roads to be constructed as short as possible while satisfying the conditions. Now, what is the minimum length?



Input

NA NB
xA, 1 yA, 1
xA, 2 yA, 2
..
..
..
xA, NA yA, NA
xB, 1 yB, 1
xB, 2 yB, 2
..
..
..
xB, NB yB, NB


The integer NA (2 ≤ NA ≤ 1,000) and the integer NB (2 ≤ NB ≤ 1,000) are written on the first line of the input, separated by blanks. This means that there are NA towns where the Totata tribe lives and NB towns where the Tutete tribe lives in the Kingdom of Neva. In the initial state, no road has been built anywhere.

The following NA line contains the integers xA, i (-10,000 ≤ xA, i ≤ 10,000) and the integers yA, i (-10,000 ≤ yA, i ≤ 10,000), separated by blanks. The geography of the Kingdom of Neva is represented by a two-dimensional Cartesian coordinate plane, and the integers xA, i and yA, i written on the 1 + i line are the position coordinates of the i-th city where the Totata tribe lives (xA, i, yA). , I). (xA, 1, yA, 1) and (xA, 2, yA, 2) are the coordinates of the two cities to be connected.

On the following NB line, the integers xB, i (-10,000 ≤ xB, i ≤ 10,000) and the integers yB, i (-10,000 ≤ yB, i ≤ 10,000) are written separated by blanks. The integers xB, i and yB, i written on the 1 + NA + i line indicate that the position coordinates of the i-th city where the Ytterbium live are (xB, i, yB, i). (xB, 1, yB, 1) and (xB, 2, yB, 2) are the coordinates of the two cities to be connected.

It can be assumed that the coordinates of the two cities are different and that none of the three cities are on the same straight line.

Output

When the road is constructed so as to meet the conditions of the problem statement, output the minimum value of the total length of the road. The "length" here is the Euclidean distance. However, if you cannot build a road that meets the conditions, output -1 instead. The output may contain errors, but the relative error to the true value must be less than 10-9.

Examples

Input

2 2
0 0
1 1
2 0
2 -1


Output

2.414213562373


Input

2 3
4 0
0 0
2 3
2 -2
3 1


Output

-1


Input

5 2
-2 1
1 2
-1 3
-1 5
1 4
0 4
0 0


Output

12.359173603117

### Response

```cpp
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
#include<climits>
#include<string>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define rep(i,n) for(int i=0;i<((int)(n));i++)
#define reg(i,a,b) for(int i=((int)(a));i<=((int)(b));i++)
#define irep(i,n) for(int i=((int)(n))-1;i>=0;i--)
#define ireg(i,a,b) for(int i=((int)(b));i>=((int)(a));i--)
typedef long long int lli;
typedef pair<int,int> mp;
#define fir first
#define sec second
#define IINF INT_MAX
#define LINF LLONG_MAX
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#define pque(type) priority_queue<type,vector<type>,greater<type> >
#define memst(a,b) memset(a,b,sizeof(a))
#define iter(v,ite) for(auto ite=(v).begin();ite!=(v).end();ite++)
#define mimunum(v,x) distance((v).begin(),lower_bound((v).begin(),(v).end(),x))

struct makehtml{
	vector<string> ss;
	
	makehtml(){}
	/*
	ctx.beginPath()
	ctx.moveTo(50.000000,100.000000);
	ctx.lineTo(150.000000,100.000000);
	ctx.stroke();
	
	ctx.fillStyle = "rgb(0,0,0)";
	
	ctx.beginPath();
	ctx.arc(168,59,3,0,360);
	ctx.fill();

	*/
	
	void out(const char* name,double mag){
		char fname[100];
		sprintf(fname,"%s.html",name);
		FILE* fp = fopen(fname,"w");
		if(fp==NULL){
			eprintf("can't open %s\b",fname);
			exit(-1);
		}
		fprintf(fp,"<html>\n<head>\n<title>");
		fprintf(fp,"%s",name);
		fprintf(fp,"</title>\n</head>\n<body>\n");
		fprintf(fp,"<p>name: %s</p>",name);
		fprintf(fp,"<canvas id=\"vis\" width=\"%d\" height=\"%d\"></canvas>",2000,2000);
		fprintf(fp,"<script>\n");
		fprintf(fp,"var vis = document.getElementById('vis');\nvar ctx = vis.getContext('2d');\n");
		
		rep(i,ss.size()){
			fprintf(fp,"%s\n",ss[i].c_str());
		}
		
		fprintf(fp,"</script>\n");
		fprintf(fp,"</body>\n</html>\n");
		fclose(fp);
	}

} makehtml_instance;


void addhtml(string s){
	makehtml_instance.ss.push_back(s);
}

void outhtml(string s,double mag){
	makehtml_instance.out(s.c_str(),mag);
}

void randcolhtml(){
	char ns[100];
	sprintf(ns,"ctx.fillStyle = \"rgb(%d,%d,%d)\";",rand()%128,rand()%128,rand()%128);
	addhtml(ns);
	sprintf(ns,"ctx.strokeStyle = \"rgb(%d,%d,%d)\";",rand()%128,rand()%128,rand()%128);
	addhtml(ns);
}

void inithtml(){
	makehtml_instance.ss.clear();
}


const double pi=3.14159265358979;

struct pos{
	double x,y;
	double norm,norm2;
	pos tov(pos a){
		return (a-(*this));
	}
	pos operator+(pos a)const{
		pos res=a;
		res.x+=x; res.y+=y;
		res=pos(res.x,res.y);
		return res;
	}
	pos operator-(pos a)const{
		pos res=(*this);
		res.x-=a.x; res.y-=a.y;
		res=pos(res.x,res.y);
		return res;
	}
	pos scalar(double a){
		pos res=(*this);
		res.x*=a; res.y*=a;
		res=pos(res.x,res.y);
		return res;
	}
	double dot(pos a){
		return x*a.x + y*a.y;
	}
	double cross(pos a){
		return x*a.y - y*a.x;
	}
	double theta(pos a){
		double nt=dot(a)/(norm*a.norm);
		nt=acos(max(-1.0,min(1.0,nt)));
		double ns=(cross(a)/(norm*a.norm));
		if(ns<0)nt*=-1;
		return nt;
	}
	pos(double ix,double iy){
		x=ix; y=iy;
		norm2=x*x+y*y;
		norm=sqrt(norm2);
	}
	pos(){}
	string str(){
		char ns[50];
		sprintf(ns,"(%lf %lf)",x,y);
		return	string(ns);
	}
	void outh(double mag){
		char ns[50];
		addhtml("ctx.beginPath();"); 
		sprintf(ns,"ctx.arc(%lf,%lf,%lf,0,360);",x*mag,y*mag,5.0); addhtml(ns);
		addhtml("ctx.fill();");
	}
	static pos polar(double r,double t){
		return pos(r*cos(t),r*sin(t));
	}
	pos turn(double t){
		//t[rad]??????
		return pos(x*cos(t)-y*sin(t),x*sin(t)+y*cos(t));
	}
	pos tolen(double a){
		//?????????a?????????
		return this->scalar(a/norm);
	}
	bool  operator<(pos a) const{
		//if(x!=a.x)return (x<a.x);
		//return (y<a.y);
		if(y!=a.y)return (y<a.y);
		return (x<a.x);
	}	
	bool operator>(pos a)const{ return (a<(*this)); }	
	bool operator==(pos a)const{ return (x==a.x && y==a.y); }	
	bool operator!=(pos a)const{ return !(a==(*this)); }	
};
struct line{
	pos p,q;
	pos vec;
	string str(){
		return ("("+p.str()+"-"+q.str()+")");
	}
	void outh(double mag){
		char ns[50];
		addhtml("ctx.beginPath();");
		sprintf(ns,"ctx.moveTo(%lf,%lf);",p.x*mag,p.y*mag); addhtml(ns);
		sprintf(ns,"ctx.lineTo(%lf,%lf);",q.x*mag,q.y*mag); addhtml(ns);
		addhtml("ctx.stroke();");
	}
	bool iscross(line a){
		double da,db;
		da=vec.cross( p.tov(a.p) );
		db=vec.cross( p.tov(a.q) );
		if(da*db>=0)return false;
		da=a.vec.cross( a.p.tov(p) );
		db=a.vec.cross( a.p.tov(q) );
		return (da*db<0);
	}
	line(pos ip,pos iq){
		p=ip; q=iq;
		vec=p.tov(q);
	}
	line(){}
	double dist(pos a){
		if(p.tov(a).dot( p.tov(q) )<0)return p.tov(a).norm;
		if(q.tov(a).dot( q.tov(p) )<0)return q.tov(a).norm;
		return abs(vec.cross(p.tov(a))/vec.norm);
	}
	double dist(line a){
		if(iscross(a))return 0;
		return min( min(dist(a.p),dist(a.q)) , min(a.dist(this->p),a.dist(this->q)));
	}
	pos crosspos(line a){
		/*
		double d1=a.vec.cross(a.p.tov(p))/a.vec.norm;
		double d2=a.vec.cross(a.p.tov(q))/a.vec.norm;
		bool isc=(d1*d2<0);
		d1=abs(d1); d2=abs(d2);
		double sc;
		if(!isc){
			if(d1>d2)sc = d1/(d1-d2);
			else sc=d1/(d2-d1);
		}
		else sc = d1/(d1+d2);
		return (p+vec.scalar(sc));*/
		
		double t = a.vec.cross(a.p-p)/a.vec.cross(vec);
		return (p+vec.scalar(t));
	}
	line bisection(){//?????´????????????
		//???????¨??????????90????????£???????????????
		pos fr=(p+q).scalar(0.5);
		pos to=fr+pos(-vec.y,vec.x);
		return line(fr,to);
	}
	bool  operator<(line a) const{
		//if(x!=a.x)return (x<a.x);
		//return (y<a.y);
		if(p!=a.p)return (p<a.p);
		return (q<a.q);
	}	
	bool operator>(line a)const{ return (a<(*this)); }	
};

double lowofcos_getcos(double a,double b,double c){
	return ((a*a+b*b-c*c)/(2*a*b));
}
struct circle{
	pos p;
	double r;
	line koten(circle a){
		pos cv=p.tov(a.p);
		double br=atan2(cv.y,cv.x);
		double dr=acos(lowofcos_getcos( r, cv.norm, a.r));
		pos p1= p+pos::polar(r,br+dr);
		pos p2= p+pos::polar(r,br-dr);
		if(p1>p2)swap(p1,p2);
		return line(p1,p2);
	}
	circle(pos ip,double ir){
		p=ip; r=ir;
	}
	circle(){}
	void outh(double mag){
		char ns[50];
		addhtml("ctx.beginPath();"); 
		sprintf(ns,"ctx.arc(%lf,%lf,%lf,0,360);",p.x*mag,p.y*mag,r*mag); addhtml(ns);
		addhtml("ctx.stroke();");
	}
	
	vector<line> tangs(circle a){ //??\?????????
		//validate AOJ 2201
		circle b(*this);
		if(a.r<b.r)swap(a,b);
		vector<line> res;
		if((a.p-b.p).norm-(a.r-b.r)<0.0)return res;
		if((a.p-b.p).norm-(a.r-b.r)<1e-6){
			if((b.p-a.p).norm<1e-6)return res; //??¨???????????????
			pos rv=(b.p-a.p).tolen(a.r);
			res.push_back(line(rv+a.p,rv+a.p+rv.turn(pi/2.0)));
			return res;
		}
		{
			pos cv=b.p-a.p;
			double th=acos((a.r-b.r)/cv.norm);
			pos p1 = cv.turn(th);
			res.push_back(line(a.p+p1.tolen(a.r),b.p+p1.tolen(b.r)));
			pos p2 = cv.turn(-th);
			res.push_back(line(a.p+p2.tolen(a.r),b.p+p2.tolen(b.r)));
		}
		if((a.p-b.p).norm-(a.r+b.r)<0.0)return res;
		if((a.p-b.p).norm-(a.r+b.r)<1e-6){
			pos rv=(b.p-a.p).tolen(a.r);
			res.push_back(line(rv+a.p,rv+a.p+rv.turn(pi/2.0)));
			return res;
		}
		{
			pos cv=b.p-a.p;
			double th=acos((a.r+b.r)/cv.norm);
			pos p1 = cv.turn(th);
			res.push_back(line(a.p+p1.tolen(a.r),b.p+p1.tolen(-b.r)));
			pos p2 = cv.turn(-th);
			res.push_back(line(a.p+p2.tolen(a.r),b.p+p2.tolen(-b.r)));
		}
		return res;
	}
};

struct polygon{
	vector<pos> ps;
	polygon(){}
	void outh(double mag){
		char ns[50];
		addhtml("ctx.beginPath();");
		int ls=ps.size();
		sprintf(ns,"ctx.moveTo(%lf,%lf);",ps[ls-1].x*mag,ps[ls-1].y*mag); addhtml(ns);
		rep(i,ps.size()){
			sprintf(ns,"ctx.lineTo(%lf,%lf);",ps[i].x*mag,ps[i].y*mag); addhtml(ns);
		}
		addhtml("ctx.stroke();");
	}
	double area(){
		double res=0;
		rep(i,ps.size()){
			pos no=ps[i],to=ps[(i+1)%ps.size()];
			res+=(no.x+to.x)*(no.y-to.y);
		}
		if(res<0)reverse(ps.begin(),ps.end());
		return abs(res)/2;
	}
	polygon(pos a,pos b){
		ps.push_back(a);
		ps.push_back(pos(a.x,b.y));
		ps.push_back(b);
		ps.push_back(pos(b.x,a.y));
	}
	line gete(int a){
		a%=ps.size();
		return line(ps[a],ps[(a+1)%ps.size()]);
	}
	int isin(pos a){//?????´??????2,?????£????????????1,?????????0
		double as=0;
		rep(i,ps.size()){
			line ne=gete(i);
			if(ne.dist(a)<=0)return 1;
			pos v1=a.tov(ne.p);
			pos v2=a.tov(ne.q);
			as+=v1.theta(v2);
		}
		if(abs(as)<1e-6)return 0;
		return 2;
	}
	polygon convex_full(){
		polygon res;
		int ns=ps.size();
		vector<pos> vs(2*ns);
		sort(ps.begin(),ps.end());
		int k=0;
		rep(i,ns){
			pos np=ps[i];
			while(k>1 && vs[k-2].tov(vs[k-1]).cross(vs[k-1].tov(np))<-1e-6)k--;
			vs[k]=np; k++;
		}
		int t=k;
		ireg(i,0,ns-2){
			pos np=ps[i];
			while(k>t && vs[k-2].tov(vs[k-1]).cross(vs[k-1].tov(np))<-1e-6)k--;
			vs[k]=np; k++;
		}
		vs.resize(k-1);
		swap(vs,res.ps);
		return res;
	}
	polygon cut(line a){//???????????????????????????
		polygon res;
		rep(i,ps.size()){
			line ne=gete(i);
			double d1=a.vec.cross(a.p.tov(ne.p));
			double d2=a.vec.cross(a.p.tov(ne.q));
			if(d1<1e-6)res.ps.push_back(ne.p); //?????£????????£???eps
			if(d1*d2<-1e-6)res.ps.push_back(a.crosspos(ne)); //?????£????????????eps
		}
		return res;
	}
	
	vector<polygon> voronoi(vector<pos> ps){
		//validate AOJ 2160
		vector<polygon> res;
		rep(i,ps.size()){
			polygon np(*this);
			rep(j,ps.size()){
				if(i==j)continue;
				line nl = line(ps[j],ps[i]).bisection();
				
				np = np.cut(nl);
			}
			res.push_back(np);
		}
		return res;		
	}
	polygon mult(polygon a){
		return a;
	}
};

struct unifo{
	int n;
	int uni[100005];
	void init(int in){
		n=in;
		rep(i,n)uni[i]=i;
	}
	int find(int p){
		if(uni[p]==p)return p;
		else return (uni[p]=find(uni[p]));
	}
	void mer(int p,int q){
		if(!same(p,q))uni[find(p)]=find(q);
	}
	bool same(int p,int q){
		return find(p)==find(q);
	}
	void out(){
		vector<mp> ps;
		//printf("%d %d\n",i,find(i));
		rep(i,n)ps.push_back(mp(find(i),i));
		sort(ps.begin(),ps.end());
		printf("uni .. %d elem\n{ ",n);
		rep(i,n){
			if(i!=0 && ps[i-1].fir!=ps[i].fir)printf("}\n{ ");
			printf("%d ",ps[i].sec);
		}
		printf("}\n\n");
	}
} uni;



int n,m;
pos ps[1005];
pos qs[1005];

double ds[1005][1005];
double dist[1005];
int gone[1005];

int main(void){
	scanf("%d%d",&n,&m);
	rep(i,n+m){
		double x,y;
		scanf("%lf%lf",&x,&y);
		if(i<n)ps[i]=pos(x,y);
		else qs[i-n]=pos(x,y);
	}
	
	double ans=1e15;
	rep(qqq,2){
		line ne(ps[0],ps[1]);
		double ns=ne.vec.norm;
		
		uni.init(m+5);
		typedef pair<double,mp> dmp;
		vector<dmp> es;
		
		rep(i,m)dist[i]=-1;
		rep(i,m){
			rep(j,i){
				line ce(qs[i],qs[j]);
				ds[i][j]=ds[j][i]=(ce.iscross(ne)?-1:ce.vec.norm);
			}
		}
		/*
		rep(i,m)rep(j,m){
			printf("%d %d %lf\n",i,j,ds[i][j]);
		}*/
		memset(gone,0,sizeof(gone));
		dist[0]=0;
		
		
		for(;;){
			int nv=-1;
			rep(i,m){
				if(gone[i] || dist[i]<0)continue;
				if(nv==-1 || dist[i]<dist[nv])nv=i;
			}
			if(nv==-1){
				ns=1e15;
				break;
			}
			if(nv==1){
				ns+=dist[1];
				break;
			}
			gone[nv]=1;
			rep(j,m){
				if(gone[j] || ds[nv][j]<0)continue;
				double nc=dist[nv]+ds[nv][j];
				if(dist[j]<0 || nc<dist[j])dist[j]=nc;
			}
		}
		ans=min(ans,ns);
		swap(n,m);
		swap(ps,qs);
	}
	if(ans>1e10)printf("-1\n");
	else printf("%.11f\n",ans);
	return 0;
}
```