#include <bits/stdc++.h>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n==0) ? 1 : 10*TEN(n-1); }
template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;

using D = double;
const D PI = acos(D(-1)), EPS = 1e-10;

int sgn(D a) { return (abs(a) <= EPS) ? 0 : (a < 0 ? -1 : 1); }
int sgn(D a, D b) { return sgn(a-b); }

struct Pt2 {
    D x, y;
    Pt2() {}
    Pt2(D _x, D _y) : x(_x), y(_y) {}
    Pt2 operator-(const Pt2 &r) const { return Pt2(x-r.x, y-r.y); }
    bool operator<(const Pt2 &r) const { return 2*sgn(x, r.x)+sgn(y, r.y)<0; }
    bool operator==(const Pt2 &r) const { return sgn((*this-r).rabs()) == 0; }
    D abs() const { return sqrt(x*x + y*y); }
    D rabs() const { return max(std::abs(x), std::abs(y)); }
};
ostream& operator<<(ostream& os, const Pt2 &p) {
    return os << "(" << p.x << ", " << p.y << ")";
}
using P = Pt2;


template<class C, class D, class E>
struct MinCostFlow {
    static constexpr D INF = numeric_limits<D>::max();
    D eps;
    VV<E> g;
    int s, t;
    C nc, cap_flow;
    D nd, flow;

    V<D> dual;
    V<int> pv, pe;

    V<int> visited; int vid = 114514;
    MinCostFlow(VV<E> _g, int s, int t, D _eps, bool neg)
        : g(_g), s(s), t(t), eps(_eps), cap_flow(0), flow(0) {
        assert(s != t);       
        dual = V<D>(g.size());
        pv = V<int>(g.size());
        pe = V<int>(g.size());
        visited = V<int>(g.size());
        dual_ref(neg);
    }

    C single_flow(C c) {
        if (nd == INF) return nc;
        c = min(c, nc);
        for (int v = t; v != s; v = pv[v]) {
            E &e = g[pv[v]][pe[v]];
            e.cap -= c;
            g[v][e.rev].cap += c;
        }
        cap_flow += c;
        flow += nd * c;
        nc -= c;
        if (!nc) dual_ref(false);
        return c;
    }
    C dfs(int v, C f) {
        if (v == t) return f;
        visited[v] = vid;
        for (E &e: g[v]) {
            D ed = e.dist + dual[v] - dual[e.to];
            if (!e.cap || visited[e.to] == vid) continue;
            if (ed != D(0)) continue;
            C u = dfs(e.to, min(f, e.cap));
            if (u > 0) {
                e.cap -= u;
                g[e.to][e.rev].cap += u;
                return u;
            }
        }
        return 0;
    }

    C multi_flow(C c) {
        C sm = 0;
        while (true) {
            vid++;
            C res = dfs(s, c);
            sm += res;
            flow += nd * res;
            if (!c || !res) break;
            c -= res;
        }
        cap_flow += sm;
        dual_ref(false);
        return sm;
    }    
    void max_flow(C c) {
        while (c) {
            C f = single_flow(c);
            if (!f) break;
            c -= f;
        }
    }
        
    void dual_ref(bool neg) {
        V<D> dist(g.size(), INF);
        fill(begin(pv), end(pv), -1);
        fill(begin(pe), end(pe), -1);
        
        using P = pair<D, int>;
        queue<int> ref_v;
        priority_queue<P, vector<P>, greater<P>> que1;
        queue<P> que2;
        auto empty = [&] {
            return (!neg) ? que1.empty() : que2.empty();
        };
        auto push = [&](P p) {
            (!neg) ? que1.push(p) : que2.push(p);
        };
        auto pop = [&]() {
            P p = (!neg) ? que1.top() : que2.front();
            (!neg) ? que1.pop() : que2.pop();
            return p;
        };
        push(P(D(0), s));
        dist[s] = D(0);
        while (!empty()) {
            P p = pop();
            int v = p.second;
            if (dist[v] < p.first) continue;
            if (!neg) {
                if (v == t) break;
                ref_v.push(v);
            }
            for (int i = 0; i < int(g[v].size()); i++) {
                E e = g[v][i];
                D ed = e.dist + dual[v] - dual[e.to];
                if (e.cap && dist[e.to] > dist[v] + ed + eps) {
                    dist[e.to] = dist[v] + ed;
                    pv[e.to] = v; pe[e.to] = i;
                    push(P(dist[e.to], e.to));
                }
            }
        }
        if (dist[t] == INF) {
            nd = INF;
            nc = 0;
            return;
        }
        if (!neg) {
            while (ref_v.size()) {
                int v = ref_v.front(); ref_v.pop();
                if (dist[v] >= dist[t]) continue;
                dual[v] += dist[v]-dist[t];
            }
        } else {
            for (int v = 0; v < int(g.size()); v++) {
                dual[v] += dist[v];
            }
        }
        nd = dual[t]-dual[s];
        if (!neg) assert(0 <= nd);
        nc = numeric_limits<C>::max();
        for (int v = t; v != s; v = pv[v]) {
            nc = min(nc, g[pv[v]][pe[v]].cap);
        }
    }
};

template<class C, class D, class E>
auto min_cost_flow(const VV<E> &g, int s, int t, D eps, bool neg = false) {
    return MinCostFlow<C, D, E>(g, s, t, eps, neg);
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << setprecision(20) << fixed;

    D ans = 0;

    int n;
    cin >> n;
    D x, y;
    P p;
    cin >> x >> y; p = P(x, y);
    map<P, int> mp;
    for (int i = 0; i < n; i++) {
        P p, q;
        cin >> x >> y; p = P(x, y);
        mp[p]++;
        cin >> x >> y; q = P(x, y);
        mp[q]--;
        ans += (p-q).abs();
    }

    using Pi = pair<P, int>;
    V<Pi> up, dw;
    for (auto p: mp) {
        if (p.second == 0) continue;
        if (p.second > 0) {
            up.push_back(p);
        } else {
            dw.push_back(Pi(p.first, -p.second));
        }
    }

    int l = int(up.size()), r = int(dw.size());

    struct E {
        int to, cap;
        D dist;
        int rev;
    };
    int sv = l+r, tv = sv+1;
    VV<E> g(l+r+2);
    auto add_edge = [&](int from, int to, int cap, D dist) {
        g[from].push_back(E{to, cap, dist, int(g[to].size())});
        g[to].push_back(E{from, 0, -dist, int(g[from].size())-1});
    };

    for (int i = 0; i < l; i++) {
        add_edge(sv, i, up[i].second, 0);
    }
    for (int j = 0; j < r; j++) {
        add_edge(l+j, tv, dw[j].second, 0);
    }
    for (int i = 0; i < l; i++) {
        for (int j = 0; j < r; j++) {
            add_edge(i, l+j, TEN(9), (up[i].first - dw[j].first).abs());
        }
    }

    auto res = min_cost_flow<int, D>(g, sv, tv, EPS, false);
    res.max_flow(TEN(9));

    cout << ans + res.flow << endl;
    return 0;
}



Measured memory_bytes: 18668