import std.stdio;
import std.ascii;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.random;
import std.regex;
import std.typecons;

/*-----------------------------------*/
const EPS = 1e-7;

struct Point {
    double x, y;
    Point opBinary(alias op)(in Point p) const {
        static if (op == "+") {
            return Point(x + p.x, y + p.y);
        } else if (op == "-") {
            return Point(x - p.x, y - p.y);
        }
    }
    Point opBinary(alias op)(double k) const {
        static if (op == "*") {
            return Point(x * k, y * k);
        } else if (op == "/") {
            return Point(x / k, y / k);
        }
    }
}
double norm(in Point p) {
    return sqrt(p.x * p.x + p.y * p.y);
}

double dot(in Point a, in Point b) {
    return a.x * b.x + a.y * b.y;
}

double cross(in Point a, in Point b) {
    return a.x * b.y - a.y * b.x;
}

int ccw(Point a, Point b, Point c){
    b = b - a; c = c - a;
    if (cross(b, c) > EPS) return +1; 
    if (cross(b, c) < -EPS) return -1;
    if (dot(b, c) < 0) return +2;     
    if (b.norm < c.norm) return -2;  
    return 0;                       
}

double distance(in Point a, in Point b) {
    double dx = a.x - b.x,
           dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}

struct Segment {
    Point a, b;
}

double length(in Segment s) {
    return (s.b - s.a).norm;
}

bool contains(in Segment s, in Point p) {
    Point u = s.a - p,
          v = s.b - p;
    return abs(cross(u, v)) < EPS && dot(u, v) < -EPS;
}

Point projection(in Segment s, in Point p) {
    Point u = s.b - s.a,
          v = p - s.a;
    double n = u.norm;
    return s.a + u * (dot(u, v) / (n * n));
}

double distance(in Segment s, in Point p) {
    auto ret = min(distance(p, s.a), distance(p, s.b));
    Point proj = s.projection(p);
    if (s.contains(proj)) {
        ret = min(ret, (p - proj).norm);
    }
    return ret;
}
double distance(in Point p, in Segment s) {
    return distance(s, p);
}

bool intersect(in Segment s, in Segment t) {
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
           ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

double distance(in Segment s, in Segment t) {
    if (intersect(s, t)) return 0;
    return min( distance(s.a, t), distance(s.b, t),
                distance(s, t.a), distance(s, t.b) );
}

struct Line {
    Point a, b;
}
Point unit(in Line l) {
    /** l縺ョ蜊倅ス阪?繧ッ繝医Ν */
    return l.a * (1.0 / norm(l.b - l.a));
}
bool intersect(in Line m, in Line n) {
    double A = cross(m.b - m.a, n.b - n.a),
           B = cross(m.b - m.a, m.b - n.a);
    return (abs(A) > EPS || abs(B) < EPS);
}
Point intersection(in Line m, in Line n) {
    double A = cross(m.b - m.a, n.b - n.a),
           B = cross(m.b - m.a, m.b - n.a);
    if (abs(A) < EPS) {
        if (abs(B) < EPS) return m.a;
        else assert(0);
    }
    return n.a + (n.b - n.a) * B / A;
}

struct Circle {
    Point o;
    double r;
}

bool contains(in Circle c, in Point p) {
    /** 蜀?縺ォp縺悟性縺セ繧後ｋ縺? 
     *    p縺慶縺ョ蜻ィ荳翫↓縺ゅｋ縺ィ縺阪?蜷ォ縺セ繧後ｋ縺ィ縺ソ縺ェ縺?*/
    return distance(c.o, p) <= c.r + EPS;
}

Line[2] tangent(in Circle c, in Point p) {
    /** p繧帝?繧議縺ョ謗・邱壹ｒ霑斐☆.
     *    霑斐ｊ蛟、縺ョ2逶エ邱嗟, m縺ォ縺、縺?※ l.a == m.a == p */
    double l1 = distance(c.o, p);
    double l2 = sqrt(l1 * l1 - c.r * c.r);
    double d1 = (l2 * l2) / l1;
    double d2 = (c.r * l2) / l1;
    Point u = (c.o - p) / norm(c.o - p);
    Point b = p + u * d1;

    /* u縺ィ逶エ莠、縺吶ｋ蜊倅ス阪?繧ッ繝医Ν */
    Point o1 = Point(u.y, -u.x),
          o2 = Point(-u.y, u.x);

    Point a1 = b + o1 * d2,
          a2 = b + o2 * d2;
    return [ Line(p, a1), Line(p, a2) ];
}

struct Rectangle {
    Point v[4];
}
bool contains(in Rectangle r, in Point p) {
    /** 髟キ譁ケ蠖「r縺ォp縺悟性縺セ繧後ｋ縺? 
     *    r縺ョ蜻ィ荳翫↓p縺後≠繧九→縺阪?蜷ォ縺セ繧後ｋ縺ィ縺ソ縺ェ縺励※縺?↑縺?     *    蜃ク螟夊ァ貞ス「縺ォ荳?握蛹門庄閭ス */
    int c = ccw(p, r.v[0], r.v[1]);
    foreach (i; 0 .. 4) {
        if (c != ccw(p, r.v[i], r.v[(i + 1) % 4])) return false;
    }
    return true;
}

/*-----------------------------------*/

struct R {
    Rectangle r;
    double h;
}

void main() {
    int N;
    Segment course;
    Segment[] ss;
    R[] rs;
    double[2][] hs;

    bool input() {
        scanf("%d\n", &N);
        if (N == 0) return false;
        ss.destroy;
        hs.destroy;
        Point s, e;
        scanf("%lf %lf %lf %lf\n", &s.x, &s.y, &e.x, &e.y);
        rs = new R[N];
        course = Segment(s, e);
        foreach (ref r; rs) {
            double minx, miny, maxx, maxy, h;
            scanf("%lf %lf %lf %lf %lf\n", &minx, &miny, &maxx, &maxy, &h);
            r.r.v = [
                Point(minx, miny),
                Point(minx, maxy),
                Point(maxx, maxy),
                Point(maxx, miny)
            ];
            r.h = h;
        }
        return true;
    }

    double calc() {
        double ans = 1e3;
        foreach (r; rs) {
            foreach (i; 0 .. 4) {
                auto s = Segment(r.r.v[i], r.r.v[(i + 1) % 4]);
                double d2 = distance(s, course);
                if (d2 <= r.h) {
                    ans = min(ans, d2);
                } else {
                    ans = min(ans, (r.h * r.h + d2 * d2) / (2 * r.h));
                }
            }
        }
        return ans;
    }

    void solve() {
        foreach (r; rs) {
            if (r.r.contains(course.a) || r.r.contains(course.b)) {
                writeln(0);
                return;
            }
            foreach (i; 0 .. 4) {
                auto s = Segment(r.r.v[i], r.r.v[(i + 1) % 4]);
                if (course.intersect(s)) {
                    writeln(0);
                    return;
                }
            }
        }

        writefln("%.10f", calc);
    }

    while (input) solve;

}

Measured memory_bytes: 1748