// author: yurii alekhin
// date: 22.04.2025
#include <iostream>
#include <vector>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <cmath>
using namespace std;

#define int32_t int64_t

struct Point {
    int32_t x, y;
};

istream &operator>>(istream &in, Point &p) {
    in >> p.x >> p.y;
    return in;
}

int64_t distance(Point &a, Point &b) {
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

signed main(void) {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int32_t n;
    cin >> n;
    vector<Point> a(n), b(n);
    for (auto &x : a) cin >> x;
    for (auto &x : b) cin >> x;
    vector<int64_t> dd;
    for (int32_t i = 0; i < n; ++i) {
        for (int32_t j = 0; j < n; ++j) {
            dd.push_back(distance(a[i], b[j]));
        }
    }
    sort(dd.begin(), dd.end());
    int64_t l = 0, r = dd.size();
    while (l < r - 1) {
        int64_t ind = l + (r - l) / 2;
        int64_t mid = dd[ind];
        vector<vector<int32_t>> g(n);
        vector<int32_t> match(n, -1);
        vector<int32_t> color(n, 0);
        for (int32_t i = 0; i < n; ++i) {
            for (int32_t j = 0; j < n; ++j) {
                if (distance(a[i], b[j]) >= mid) {
                    g[i].push_back(j);
                }
            }
        }
        function<bool(int32_t, int32_t)> khun = [&](int32_t v, int32_t col) {
            if (color[v] == col) return false;
            color[v] = col;
            for (auto &to : g[v]) {
                if (match[to] == -1 || khun(match[to], col)) {
                    match[to] = v;
                    return true;
                }
            }
            return false;
        };
        int32_t max_matching = 0;
        for (int i = 0; i < n; ++i) {
            if (khun(i, i + 1)) max_matching++;
        }
        if (max_matching == n) {
            l = ind;
        } else {
            r = ind;
        }
    }
    l = dd[l];
    cout << fixed << setprecision(9) << sqrtl(l) << '\n';
    return 0;
}
