#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <utility>
#include <numeric>
#include <algorithm>
#include <functional>
#include <cctype>
#include <complex>
#include <string>
#include <cstring>
#include <sstream>

using namespace std;

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

typedef long long ll;
typedef complex<double> point;
typedef pair<int,int> pii;

// →↑←↓
const int dx[] = {1,0,-1,0};
const int dy[] = {0,-1,0,1};

const double EPS = 1e-9;

struct Block{
    vector<point> ps;
    double h;
    Block(double minx,
          double miny,
          double maxx,
          double maxy,
          double th){
        ps.push_back(point(minx,miny));
        ps.push_back(point(maxx,miny));
        ps.push_back(point(maxx,maxy));
        ps.push_back(point(minx,maxy));
        h = th;
    }
};

double dot(point a,point b){
    return real(conj(a)*b);
}
double cross(point a,point b){
    return imag(conj(a)*b);
}

bool is_intersected_linesegment(point a1,point a2,point b1,point b2){
    if(max(a1.real(),a2.real()) + EPS < min(b1.real(),b2.real())) return false;
    if(max(b1.real(),b2.real()) + EPS < min(a1.real(),a2.real())) return false;
    if(max(a1.imag(),a2.imag()) + EPS < min(b1.imag(),b2.imag())) return false;
    if(max(b1.imag(),b2.imag()) + EPS < min(a1.imag(),a2.imag())) return false;

    return (cross(a2-a1,b1-a1)*cross(a2-a1,b2-a1) < EPS and
            cross(b2-b1,a1-b1)*cross(b2-b1,a2-b1) < EPS);

}

// 直線と点の最短距離を実現する直線の点(すいせんの足)
point nearest_point_line_and_point(point a1,point a2,point b){
    return b - ((cross(a2-a1,b-a1) / abs(a2-a1)) * (a2-a1) / abs(a2-a1));
}

// 線分と点の最短距離を実現する線分嬢の点
point nearest_point_linesegment_and_point(point a1,point a2,point b){
    if(dot(a2-a1,b-a1) < EPS) return a1;
    if(dot(a1-a2,b-a2) < EPS) return a2;
    return nearest_point_line_and_point(a1,a2,b);
}

int ccw(point a,point b,point c){
    b -= a; c -= a;
    if(cross(b,c) > 0) return +1;
    if(cross(b,c) < 0) return -1;
    if(dot(b,c) < 0) return +2;
    if(norm(b) < norm(c)) return -2;
    return 0;
}
bool is_inner_point_vertex(vector<point> ps,point a){
    int cc = ccw(ps[0],ps[1],a);
    if(not (cc == 1 or cc == -1)) return false;
    for(int i=0;i<ps.size();i++){
        if(cc != ccw(ps[i],ps[(i+1)%ps.size()],a)) return false;
    }
    return true;
}

double solve(point s,point e,vector<Block> blocks){
    int N = blocks.size();
    for(int i=0;i<N;i++){
        for(int j=0;j<4;j++){
            if(is_intersected_linesegment(s,e,blocks[i].ps[j],
                                              blocks[i].ps[(j+1)%4])){
                return 0;
            }else if(is_inner_point_vertex(blocks[i].ps,s) and
                     is_inner_point_vertex(blocks[i].ps,e)){
                return 0;
            }
        }
    }
    double lower = 0;
    double upper = 1000;

    for(int lp=0;lp<100;lp++){
        double mid = (lower+upper) / 2;
        bool ok = true;
        for(int i=0;i<N;i++){
            for(int j=0;j<4;j++){
                point reg = nearest_point_linesegment_and_point(s,e,blocks[i].ps[j]);
                double re = abs(reg-blocks[i].ps[j]);
                if(re > mid) continue;
                if(blocks[i].h < (mid - sqrt(mid*mid - re*re))) continue;
                ok = false;
            }
        }
        for(int i=0;i<N;i++){
            for(int j=0;j<4;j++){
                point a1 = blocks[i].ps[j],a2 = blocks[i].ps[(j+1)%4];
                point reg = nearest_point_linesegment_and_point(a1,a2,s);
                double re = abs(reg-s);
                if(re > mid) continue;
                if(blocks[i].h < (mid - sqrt(mid*mid - re*re))) continue;
                ok = false;
            }
        }
        for(int i=0;i<N;i++){
            for(int j=0;j<4;j++){
                point a1 = blocks[i].ps[j],a2 = blocks[i].ps[(j+1)%4];
                point reg = nearest_point_linesegment_and_point(a1,a2,e);
                double re = abs(reg-e);
                if(re > mid) continue;
                if(blocks[i].h < (mid - sqrt(mid*mid - re*re))) continue;
                ok = false;
            }
        }

        if(ok){
            lower = mid;
        }else{
            upper = mid;
        }
    }
    return lower;
}

int main(){
    cout << fixed << setprecision(10);
    while(true){
        int N;
        cin >> N;
        if(N == 0) break;
        double sx,sy,ex,ey;
        cin >> sx >> sy >> ex >> ey;
        vector<Block> blocks;
        for(int i=0;i<N;i++){
            double minx,miny,maxx,maxy,h;
            cin >> minx >> miny >> maxx >> maxy >> h;
            blocks.push_back(Block(minx,miny,maxx,maxy,h));
        }
        cout << solve(point(sx,sy),point(ex,ey),blocks) << endl;
    }
    return 0;
}

Measured memory_bytes: 1320