#include <iostream>
#include <cstdio>
#include <cmath>
#include <complex>
#include <vector>
#include <cfloat>
#include <algorithm>
using namespace std;

#define EPS 1e-9 //許容される誤差の程度

typedef complex<double> point;
typedef vector<point> polygon;
typedef pair<point, point> seg;

double dot(point va, point vb){
	return real(va) * real(vb) + imag(va) * imag(vb);
}

double cross(point va, point vb){
	return real(va) * imag(vb) - imag(va) * real(vb);
}

//直線と点の距離
double distance_l_p(point a, point b, point c){
	return abs(cross(b - a, c - a)) / abs(b - a);
}

//線分と点の距離
double distance_ls_p(point a, point b, point c){
	if( dot(b - a, c - a) <= 0.0 ) return abs(c - a);
	if( dot(a - b, c - b) <= 0.0 ) return abs(c - b);
	return distance_l_p(a, b, c);
}

//多角形と点の内包判定。
//AOJ 0143などで使用。
bool contains(polygon plg, point pt){
	int cnt = 0;
	double y = imag(pt);

	for(int i = 0; i < plg.size(); ++i){
		int j = (i + 1 == plg.size() ? 0: i + 1);

		if( distance_ls_p(plg[i], plg[j], pt) <= EPS ){
			return true;
		}

		double dyi = imag(plg[i]) - y;
		double dyj = y - imag(plg[j]);
		double tx = (dyi * real(plg[j]) + dyj * real(plg[i])) / (dyi + dyj);

		if(imag(plg[i]) >= y && imag(plg[j]) < y){
			if( tx < real(pt) ) ++cnt;
		}
		else if(imag(plg[i]) < y && imag(plg[j]) >= y){
			if( tx < real(pt) ) ++cnt;
		}
	}
	
	return (cnt % 2 != 0);
}

//線分同士の交点判定。
//交点による線分1の内分比を返す。
//交点は (1.0-t)*pa1 + t*pa2 で求められる。
//戻り値が0なら交点はpa1、戻り値が1なら交点はpa2に一致。
//交点がないときはDBL_MAXでも返しておく。
//AOJ 2003で類似のものを使用。
//そこそこ短くて便利なので一応入れてみたけど、要らないかも。
//なお、4点が同一直線上にある場合には正確に判定できない。
double intersectSS2(point pa1, point pa2, point pb1, point pb2){
	point da12 = pa2 - pa1;
	point db21 = pb1 - pb2;
	point dab1 = pb1 - pa1;

	double D = cross(da12, db21);	//符号に注意

	if(abs(D) > EPS){
		double t = cross(dab1, db21) / D;
		double s = cross(da12, dab1) / D;
		
		if( (-EPS < t && t < 1.0 + EPS) && (-EPS < s && s < 1.0 + EPS) ){
			return t;	//前半は交点が線分1に含まれるか、後半は線分2に含まれるかどうか
		}
	}
	return DBL_MAX;
}

// a1,a2を端点とする線分とb1,b2を端点とする線分の距離
//（交差している場合の距離は0）
double distance_ls_ls(point a1, point a2, point b1, point b2)
{
	if( intersectSS2(a1, a2, b1, b2) == DBL_MAX)
		return min( min(distance_ls_p(a1, a2, b1), distance_ls_p(a1, a2, b2)),
					min(distance_ls_p(b1, b2, a1), distance_ls_p(b1, b2, a2)) );
	else
		return 0;
}

double solve(int N, point start, point goal, vector<polygon> blocks, vector<double> heights){
	
	vector<double> maxrad;
	
	for(int i = 0; i < N; i++)
		if( contains(blocks[i], start) && contains(blocks[i], goal) )
			return 0;
	
	for(int i = 0; i < N; i++){
		
		double mindis = 1e9;
		
		for(int j = 0; j < 4; j++)
			mindis = min(mindis, distance_ls_ls(start, goal, blocks[i][j], blocks[i][(j+1)%4]));
		
		if( mindis > heights[i] )
			maxrad.push_back( (mindis*mindis + heights[i]*heights[i])/(2*heights[i]) );
		else
			maxrad.push_back(mindis);
	}
	
	double res = 1e9;
	
	for(int i = 0; i < N; i++)
		res = min(res, maxrad[i]);
		
	return res;
}

int main(){

	int N;
	
	while( cin >> N, N ){
		double ax, ay, bx, by, h;
		point start, goal;
		vector<polygon> blocks;
		vector<double> heights;
		
		blocks.resize(N);
		
		cin >> ax >> ay >> bx >> by;	
		start.real() = ax;	start.imag() = ay;
		goal.real() = bx;	goal.imag() = by;
		
		for(int i = 0; i < N; i++){
			cin >> ax >> ay >> bx >> by >> h;
			
			blocks[i].push_back(point(ax, ay));
			blocks[i].push_back(point(bx, ay));
			blocks[i].push_back(point(bx, by));
			blocks[i].push_back(point(ax, by));
			heights.push_back(h);
		}
		
		cout << solve(N, start, goal, blocks, heights) << endl;
	}
		
	return 0;
}

Measured memory_bytes: 1344