/*
written by- Piyush Golani
language- c++
country- India
College- N.I.T Jamshedpur
*/
#include <cmath>
#include <ctime>
#include <iostream>
#include <string>
#include <vector>
#include<cstdio>
#include<sstream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<map>
#include<set>
#include<queue>
#include<cctype>
using namespace std;
#define pb push_back
#define all(s) s.begin(),s.end()
#define f(i,a,b) for(int i=a;i<b;i++)
#define F(i,a,b) for(int i=a;i>=b;i--)
#define PI 3.1415926535897932384626433832795
#define INF 2000000000
#define BIG_INF 7000000000000000000LL
#define mp make_pair
#define eps 1e-9
#define si(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define mod 1000000007
#define mm 10000000
#define pd pair<double,int>

typedef long long LL;


string inttostring(int n)
{
    stringstream a;
    a<<n;
    return a.str();
}

int stringtoint(string A)
{
    istringstream a(A);
    int p;
    a>>p;
    return p;
}

//////////////////////////////////////////////////////

class KingdomXCitiesandVillagesAnother {
public:
   double determineLength( vector <int> cityX, vector <int> cityY, vector <int> villageX, vector <int> villageY ) {
    int c=cityX.size();
    int v=villageX.size();
    int nodes=c+v;
    double w[nodes][nodes];
    f(i,0,c)
    {
        f(j,0,v)
        {
            w[i][c+j]=sqrt((LL)(cityX[i]-villageX[j])*(cityX[i]-villageX[j])+(LL)(cityY[i]-villageY[j])*(cityY[i]-villageY[j]));
            w[c+j][i]=w[i][c+j];
        }
    }
    f(i,0,v)
    {
        f(j,0,v)
        {
            w[c+i][c+j]=sqrt((LL)(villageX[i]-villageX[j])*(villageX[i]-villageX[j])+(LL)(villageY[i]-villageY[j])*(villageY[i]-villageY[j]));
            w[c+j][c+i]=w[c+i][c+j];
        }
    }
    priority_queue<pd,vector<pd>,greater<pd> > PQ;
    bool visited[nodes];
    memset(visited,false,sizeof(visited));
    f(i,0,c)
    visited[i]=true;
    f(i,0,c)
    {
        f(j,0,v)
        {
            PQ.push(mp(w[i][c+j],c+j));
        }
    }
    double res=0;
    while(!PQ.empty())
    {
        pd ytk=PQ.top();
        PQ.pop();
        if(visited[ytk.second]) continue;
        res+=ytk.first;
        visited[ytk.second]=true;
        f(i,0,nodes) if(!visited[i]) PQ.push(mp(w[ytk.second][i],i));
    }
    return res;
   }
};

// BEGIN CUT HERE
namespace moj_harness {
    int run_test_case(int);
	void run_test(int casenum = -1, bool quiet = false) {
		if (casenum != -1) {
			if (run_test_case(casenum) == -1 && !quiet) {
				cerr << "Illegal input! Test case " << casenum << " does not exist." << endl;
			}
			return;
		}

		int correct = 0, total = 0;
		for (int i=0;; ++i) {
			int x = run_test_case(i);
			if (x == -1) {
				if (i >= 100) break;
				continue;
			}
			correct += x;
			++total;
		}

		if (total == 0) {
			cerr << "No test cases run." << endl;
		} else if (correct < total) {
			cerr << "Some cases FAILED (passed " << correct << " of " << total << ")." << endl;
		} else {
			cerr << "All " << total << " tests passed!" << endl;
		}
	}

	static const double MAX_DOUBLE_ERROR = 1e-9; static bool topcoder_fequ(double expected, double result) { if (isnan(expected)) { return isnan(result); } else if (isinf(expected)) { if (expected > 0) { return result > 0 && isinf(result); } else { return result < 0 && isinf(result); } } else if (isnan(result) || isinf(result)) { return false; } else if (fabs(result - expected) < MAX_DOUBLE_ERROR) { return true; } else { double mmin = min(expected * (1.0 - MAX_DOUBLE_ERROR), expected * (1.0 + MAX_DOUBLE_ERROR)); double mmax = max(expected * (1.0 - MAX_DOUBLE_ERROR), expected * (1.0 + MAX_DOUBLE_ERROR)); return result > mmin && result < mmax; } }
	double moj_relative_error(double expected, double result) { if (isnan(expected) || isinf(expected) || isnan(result) || isinf(result) || expected == 0) return 0; return fabs(result-expected) / fabs(expected); }

	int verify_case(int casenum, const double &expected, const double &received, clock_t elapsed) {
		cerr << "Example " << casenum << "... ";

		string verdict;
		vector<string> info;
		char buf[100];

		if (elapsed > CLOCKS_PER_SEC / 200) {
			sprintf(buf, "time %.2fs", elapsed * (1.0/CLOCKS_PER_SEC));
			info.push_back(buf);
		}

		if (topcoder_fequ(expected, received)) {
			verdict = "PASSED";
			double rerr = moj_relative_error(expected, received);
			if (rerr > 0) {
				sprintf(buf, "relative error %.3e", rerr);
				info.push_back(buf);
			}
		} else {
			verdict = "FAILED";
		}

		cerr << verdict;
		if (!info.empty()) {
			cerr << " (";
			for (int i=0; i<(int)info.size(); ++i) {
				if (i > 0) cerr << ", ";
				cerr << info[i];
			}
			cerr << ")";
		}
		cerr << endl;

		if (verdict == "FAILED") {
			cerr << "    Expected: " << expected << endl;
			cerr << "    Received: " << received << endl;
		}

		return verdict == "PASSED";
	}

	int run_test_case(int casenum__) {
		switch (casenum__) {
		case 0: {
			int cityX[]               = {1};
			int cityY[]               = {1};
			int villageX[]            = {2,3};
			int villageY[]            = {1,1};
			double expected__         = 2.0;

			clock_t start__           = clock();
			double received__         = KingdomXCitiesandVillagesAnother().determineLength(vector <int>(cityX, cityX + (sizeof cityX / sizeof cityX[0])), vector <int>(cityY, cityY + (sizeof cityY / sizeof cityY[0])), vector <int>(villageX, villageX + (sizeof villageX / sizeof villageX[0])), vector <int>(villageY, villageY + (sizeof villageY / sizeof villageY[0])));
			return verify_case(casenum__, expected__, received__, clock()-start__);
		}
		case 1: {
			int cityX[]               = {1,2};
			int cityY[]               = {1,1};
			int villageX[]            = {1,2};
			int villageY[]            = {2,2};
			double expected__         = 2.0;

			clock_t start__           = clock();
			double received__         = KingdomXCitiesandVillagesAnother().determineLength(vector <int>(cityX, cityX + (sizeof cityX / sizeof cityX[0])), vector <int>(cityY, cityY + (sizeof cityY / sizeof cityY[0])), vector <int>(villageX, villageX + (sizeof villageX / sizeof villageX[0])), vector <int>(villageY, villageY + (sizeof villageY / sizeof villageY[0])));
			return verify_case(casenum__, expected__, received__, clock()-start__);
		}
		case 2: {
			int cityX[]               = {0};
			int cityY[]               = {0};
			int villageX[]            = {2};
			int villageY[]            = {2};
			double expected__         = 2.8284271247461903;

			clock_t start__           = clock();
			double received__         = KingdomXCitiesandVillagesAnother().determineLength(vector <int>(cityX, cityX + (sizeof cityX / sizeof cityX[0])), vector <int>(cityY, cityY + (sizeof cityY / sizeof cityY[0])), vector <int>(villageX, villageX + (sizeof villageX / sizeof villageX[0])), vector <int>(villageY, villageY + (sizeof villageY / sizeof villageY[0])));
			return verify_case(casenum__, expected__, received__, clock()-start__);
		}

		// custom cases

/*      case 3: {
			int cityX[]               = ;
			int cityY[]               = ;
			int villageX[]            = ;
			int villageY[]            = ;
			double expected__         = ;

			clock_t start__           = clock();
			double received__         = KingdomXCitiesandVillagesAnother().determineLength(vector <int>(cityX, cityX + (sizeof cityX / sizeof cityX[0])), vector <int>(cityY, cityY + (sizeof cityY / sizeof cityY[0])), vector <int>(villageX, villageX + (sizeof villageX / sizeof villageX[0])), vector <int>(villageY, villageY + (sizeof villageY / sizeof villageY[0])));
			return verify_case(casenum__, expected__, received__, clock()-start__);
		}*/
/*      case 4: {
			int cityX[]               = ;
			int cityY[]               = ;
			int villageX[]            = ;
			int villageY[]            = ;
			double expected__         = ;

			clock_t start__           = clock();
			double received__         = KingdomXCitiesandVillagesAnother().determineLength(vector <int>(cityX, cityX + (sizeof cityX / sizeof cityX[0])), vector <int>(cityY, cityY + (sizeof cityY / sizeof cityY[0])), vector <int>(villageX, villageX + (sizeof villageX / sizeof villageX[0])), vector <int>(villageY, villageY + (sizeof villageY / sizeof villageY[0])));
			return verify_case(casenum__, expected__, received__, clock()-start__);
		}*/
/*      case 5: {
			int cityX[]               = ;
			int cityY[]               = ;
			int villageX[]            = ;
			int villageY[]            = ;
			double expected__         = ;

			clock_t start__           = clock();
			double received__         = KingdomXCitiesandVillagesAnother().determineLength(vector <int>(cityX, cityX + (sizeof cityX / sizeof cityX[0])), vector <int>(cityY, cityY + (sizeof cityY / sizeof cityY[0])), vector <int>(villageX, villageX + (sizeof villageX / sizeof villageX[0])), vector <int>(villageY, villageY + (sizeof villageY / sizeof villageY[0])));
			return verify_case(casenum__, expected__, received__, clock()-start__);
		}*/
		default:
			return -1;
		}
	}
}


int main(int argc, char *argv[]) {
	if (argc == 1) {
		moj_harness::run_test();
	} else {
		for (int i=1; i<argc; ++i)
			moj_harness::run_test(atoi(argv[i]));
	}
}
// END CUT HERE


