#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <climits>
#include <cstring>
#include <cassert>

#define rep(i, m, n) for(int i=int(m);i<int(n);i++)
#define all(c) begin(c),end(c)

template<typename T1, typename T2>
inline void chmin(T1 &a, T2 b) { if (a > b) a = b; }

template<typename T1, typename T2>
inline void chmax(T1 &a, T2 b) { if (a < b) a = b; }

typedef long long int ll;
using ll = long long int;
using ull = long long unsigned int;
using Int = long long int;
using uInt = long long unsigned int;
using Double = long double;
using namespace std;
#define INF (1 << 30) - 1
#define INFl (ll)5e15
#define DEBUG 0
#define dump(x)  cerr << #x << " = " << (x) << endl
#define MOD 1000000007


//edit
namespace Geometory {
    const double EPS = 1e-10;

    inline bool equals(double a, double b) {
        return fabs(a - b) < EPS;
    }

    struct Point {
        double x, y;

        Point(double x = 0.0, double y = 0.0) : x(x), y(y) {}

        Point operator+(const Point &p) {
            return Point(x + p.x, y + p.y);
        }

        Point operator-(const Point &p) {
            return Point(x - p.x, y - p.y);
        }

        Point operator*(const double k) {
            return Point(x * k, y * k);
        }

        Point operator/(const double k) {
            return Point(x / k, y / k);
        }

        double norm() const {
            return x * x + y * y;
        }

        double abs() const {
            return sqrt(norm());
        }

        double dot(Point p) {
            return x * p.x + y * p.y;
        }

        double cross(Point p) {
            return x * p.y - y * p.x;
        }

        bool operator<(const Point &p) const {
            return x != p.x ? x < p.x : y < p.y;
        }

        bool operator==(const Point &p) const {
            return equals(x, p.x) && equals(y, p.y);
//            return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
        }


    };

    using Vector = Point;

    struct Segment {
        Point p1, p2;

        Segment() {}

        Segment(Point p1, Point p2) : p1(p1), p2(p2) {}

        Segment(double x1, double y1, double x2, double y2) : p1(x1, y1), p2(x2, y2) {}
    };

    using Line = Segment;


    double norm(Vector p) {
        return p.x * p.x + p.y * p.y;
    }

    double abs(Vector a) {
        return sqrt(norm(a));
    }

    double dot(Vector a, Vector b) {
        return a.dot(b);
    }

    double cross(Vector a, Vector b) {
        return a.cross(b);
    }

    //直行判定
    bool is_orthogonal(Vector a, Vector b) {
        return equals(dot(a, b), 0.0);
    }

    bool is_orthogonal(Point a1, Point a2, Point b1, Point b2) {
        return is_orthogonal(a1 - a2, b1 - b2);
    }

    bool is_orthogonal(Segment s1, Segment s2) {
        return equals(dot(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
    }

    //平行判定
    bool is_parallel(Vector a, Vector b) {
        return equals(cross(a, b), 0.0);
    }

    bool is_parallel(Point a1, Point a2, Point b1, Point b2) {
        return is_parallel(a1 - a2, b1 - b2);
    }

    bool is_parallel(Segment s1, Segment s2) {
        return equals(cross(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
    }

    //反時計回り
    static const int CCW = 1; // Counter Clockwise
    static const int CW = -1; // Clockwise
    static const int OB = 2; // Online Back
    static const int OF = -2; // Online Front
    static const int OS = 0; // On Segment

    // p0を中心としたとき、p2は{反時計回り、時計回り、p2->p0->p1で同一直線上、p0->p1->p2で直線上、p2がp0p1線分上} (後ろの3つの説明は雑)
    int ccw(Point p0, Point p1, Point p2) {
        Vector a = p1 - p0;
        Vector b = p2 - p0;
        if (cross(a, b) > EPS) return CCW;
        if (cross(a, b) < -EPS) return CW;
        if (dot(a, b) < -EPS) return OB;
        if (a.norm() < b.norm()) return OF;

        return OS;
    }

    //交差判定
    bool is_intersect(Point p1, Point p2, Point p3, Point p4) {
        return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
               ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0;
    }

    //交差判定
    bool is_intersect(Segment s1, Segment s2) {
        return is_intersect(s1.p1, s1.p2, s2.p1, s2.p2);
    }

    //射影を求める
    //pからsに垂直に線を引いたときの座標を返す
    Point project(Segment s, Point p) {
        Vector base = s.p2 - s.p1;
        double r = dot(p - s.p1, base) / norm(base);
        return s.p1 + base * r;
    }

    // 反射
    // pを線分sを対称軸として線対称の位置にある点を求める。
    Point reflect(Segment s, Point p) {
//        return p + (project(s, p) - p) * 2;
        return project(s, p) * 2 - p;
    }


    //距離シリーズ
    //2点間の距離
    double get_distance(Point a, Point b) {
        return abs(a - b);
    }

    // 直線lと点pの距離
    double get_distanceLP(Line l, Point p) {
        return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1));
    }

    // 線分sと点pの距離
    double get_distanceSP(Segment s, Point p) {
        if (dot(s.p2 - s.p1, p - s.p1) < 0.0) return abs(p - s.p1);
        if (dot(s.p1 - s.p2, p - s.p2) < 0.0) return abs(p - s.p2);
        return get_distanceLP(s, p);
    }

    //線分と線分の距離
    double get_distance(Segment s1, Segment s2) {
        if (is_intersect(s1, s2)) return 0.0;
        return min({get_distanceSP(s1, s2.p1),
                    get_distanceSP(s1, s2.p2),
                    get_distanceSP(s2, s1.p1),
                    get_distanceSP(s2, s1.p2),
                   });
    }

    // 線分と線分の交点
    Point get_cross_point(Segment s1, Segment s2) {
//        Vector base = s2.p2 - s2.p1;
//        double d1 = abs(cross(base, s1.p1 - s2.p1));
//        double d2 = abs(cross(base, s1.p2 - s2.p1));
//
//        double t = d1 / (d1 + d2);
//        return s1.p1 + (s1.p2 - s1.p1) * t;

        double d1 = cross(s2.p2 - s2.p1, s2.p1 - s1.p1);
        double d2 = cross(s2.p2 - s2.p1, s1.p2 - s1.p1);
        if (equals(d1, 0) && equals(d2, 0)) return s1.p1;
        if (equals(d2, 0)) throw "no cross point";

        return s1.p1 + (s1.p2 - s1.p1) * d1 / d2;
    }

    struct Circle {
        Point c;
        double r;

        Circle(Point c = Point(), double r = 0.0) : c(c), r(r) {}
    };

    //円と線分の交差判定
    bool is_intersect(Circle c, Line l) {
        double d = get_distanceLP(l, c.c);
        return d - c.r < EPS;
    }

    bool is_intersect(Circle c1, Circle c2) {
        double d = get_distance(c1.c, c2.c);
        return d - (c1.r + c2.r) < EPS;
    }

    //円と線分の交点
    pair<Point, Point> get_cross_points(Circle c, Line l) {
//        assert(is_intersect(c, l));
        if (!is_intersect(c, l)) exit(-1);
        Vector pr = project(l, c.c);
        Vector e = (l.p2 - l.p1) / abs(l.p2 - l.p1);
        double base = sqrt(c.r * c.r - norm(pr - c.c));
        return make_pair(pr + e * base, pr - e * base);
    }

    double arg(Vector p) {
        return atan2(p.y, p.x);
    }

    Vector polar(double a, double r) {
        return Point(cos(r) * a, sin(r) * a);
    }

    pair<Point, Point> get_cross_points(Circle c1, Circle c2) {
        assert(is_intersect(c1, c2));
        double d = abs(c1.c - c2.c);
        double a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
        double t = arg(c2.c - c1.c);
        return make_pair(c1.c + polar(c1.r, t + a), c1.c + polar(c1.r, t - a));
    }

    using Polygon = vector<Point>;

    static const int OUT = 0;
    static const int ON = 1;
    static const int IN = 2;

    // 点pが多角形gにあるかを判定
    // 計算量はO(|g|)
    int contains(Polygon g, Point p) {
        int n = g.size();
        bool x = false;
        for (int i = 0; i < n; ++i) {
            Point a = g[i] - p, b = g[(i + 1) % n] - p;
            if (abs(cross(a, b)) < EPS && dot(a, b) < EPS) return ON;
            if (a.y > b.y) swap(a, b);
            if (a.y < EPS && EPS < b.y && cross(a, b) > EPS) x = !x;
        }
        return x ? IN : OUT;
    }

    // 点集合sの凸集合を求める。
    // Andrew's Algorithmを使用
    // 計算量はO(|s|log(|s|))
    Polygon get_convex_hull(Polygon s) {
        if (s.size() < 3) return s;
        Polygon u, l;
        sort(s.begin(), s.end());

        u.push_back(s[0]);
        u.push_back(s[1]);
        l.push_back(s[s.size() - 1]);
        l.push_back(s[s.size() - 2]);

        //凸包の上部
        for (int i = 2; i < s.size(); ++i) {
            for (int n = u.size(); n >= 2 && ccw(u[n - 2], u[n - 1], s[i]) == CCW; --n) {
                u.pop_back();
            }
            u.push_back(s[i]);
        }

        //凸包の下部
        for (int i = s.size() - 3; i >= 0; --i) {
            for (int n = l.size(); n >= 2 && ccw(l[n - 2], l[n - 1], s[i]) == CCW; --n) {
                l.pop_back();
            }
            l.push_back(s[i]);
        }
        reverse(l.begin(), l.end());
        for (int i = u.size() - 2; i >= 1; --i) l.push_back(u[i]);

        return l;
    }

    //多角形gの面積を求める
    double get_area(Polygon g) {
        int n = g.size();
        double ret = 0.0;
        for (int i = 0; i < n; ++i) {
            Point a = g[i], b = g[(i + 1) % n];
            double add = (b.y - a.y) * (a.x + b.x) / 2;
            ret += add;
        }

        return fabs(ret);
    }

    std::ostream &operator<<(std::ostream &os, const Point &p) {
//        os << "(" << p.x << ", " << p.y << ")";
        os << "" << p.x << " " << p.y << "";
        return os;
    }

};

using namespace Geometory;

class Solve {
public:
    Int N;
    Double sx, sy, ex, ey;
    vector<Double> A, B, C, D, H; // minx, miny, maxx, maxy

    Double calc_r(Double d, Double h) {

        auto check = [&](Double r) -> bool {
            if (r < d || equals(r, d)) {
                return true;
            }
            if (h > r) {
                return false;
            }

//            Double left = (r - h) * (r - h);
//            Double right = h * h - d * d;
//            return left > right || equals(left, right);

            Double c = r - sqrt(r * r - d * d);
            return c > h || equals(c, h);
        };

        Double ok = 0.0, ng = 10000;
        rep(_, 0, 100) {
            Double mid = (ok + ng) / 2;
            if (check(mid)) {
                ok = mid;
            } else {
                ng = mid;
            }
        }

        return ok;
    }

    Double calc(Int n) {
        // ブロックnと交差しないためには最大で何センチ?
        Double x[] = {A[n], C[n], C[n], A[n], A[n]};
        Double y[] = {B[n], B[n], D[n], D[n], B[n]};
        Double ret = 10000.;

        for (int k = 0; k < 4; ++k) {
            Segment s(sx, sy, ex, ey);
            Segment s2(x[k], y[k], x[k + 1], y[k + 1]);
//            Point p(x[k], y[k]);

//            Point f = project(s, p);//射影された点
//            Double d = get_distance(p, f);
//
//            if (ccw(Point(sx, sy), f, Point(ex, ey)) == OS) {
//                Double tmp = calc_r()
//            }

            Double d = get_distance(s, s2);
            Double h = H[n];
            Double tmp = calc_r(d, h);
            chmin(ret, tmp);


        }

        return ret;
    }

    bool is_zero() {
        for (int i = 0; i < N; ++i) {
            Double x[] = {A[i], C[i], C[i], A[i], A[i]};
            Double y[] = {B[i], B[i], D[i], D[i], B[i]};

            for (int k = 0; k < 4; ++k) {
                Segment s1(sx, sy, ex, ey);
                Segment s2(x[k], y[k], x[k + 1], y[k + 1]);
                if (is_intersect(s1, s2)) {
                    return true;
                }
            }

            vector<Point> polygon;
            for (int k = 0; k < 4; ++k) {
                polygon.push_back(Point(x[k], y[k]));
            }

            if (contains(polygon, Point(sx, sy))) {
                return true;
            }
            if (contains(polygon, Point(ex, ey))) {
                return true;
            }
        }
        return false;
    }

    bool solve() {
        cin >> N;
        if (N == 0) return false;

        cin >> sx >> sy >> ex >> ey;

        rep(i, 0, N) {
            Double a, b, c, d, h;
            cin >> a >> b >> c >> d >> h;
            A.push_back(a);
            B.push_back(b);
            C.push_back(c);
            D.push_back(d);
            H.push_back(h);
        }

        if (is_zero()) {
            cout << "0" << endl;
            return true;
        }

        Double ans = 10000.;

        for (int i = 0; i < N; ++i) {
            Double tmp = calc(i);
            chmin(ans, tmp);
        }


        cout << ans << endl;

        return true;
    }
};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
//    std::ifstream in("input.txt");
//    std::cin.rdbuf(in.rdbuf());

    while (Solve().solve());


    return 0;
}



Measured memory_bytes: 3300