Problem:
Problem E:
Roll-A-Big-Ball
ACM University holds its sports day in every July. The "Roll-A-Big-Ball" 
is the highlight of the day.  In the game, players roll a ball
on a straight course drawn on the ground.  There are 
rectangular parallelepiped blocks on the ground as obstacles, which are fixed on the ground.
During the game, the ball may not collide with any blocks.
The bottom point of the ball may not leave the course.
To have more fun, the university wants to use the largest possible ball
for the game.  You must
write a program that finds the largest radius of the ball that can reach
the goal without colliding any obstacle block.
The ball is a perfect sphere, and the ground is a plane.
Each block is a rectangular parallelepiped.  The four edges of its bottom rectangle are on the ground, and parallel to either x- or y-axes. 
The course is given as a line segment from a start point to an end point.
The ball starts with its bottom point touching the start point, and goals when
its bottom point touches the end point.
The positions of the ball and a block can be like in Figure E-1 (a) and (b).
Figure E-1: Possible positions of the ball and a block
Input
The input consists of a number of datasets. 
Each dataset is formatted as follows.
N
sx
sy
ex
ey
minx
1
miny
1
maxx
1
maxy
1
h
1
minx
2
miny
2
maxx
2
maxy
2
h
2
...
minx
N
miny
N
maxx
N
maxy
N
h
N
A dataset begins with a line with an integer
N
, the number of
blocks (1 ≤
N
≤ 50). The next line consists of four integers,
delimited by a space,
indicating the start point (
sx
,
sy
) and the end point (
ex
,
ey
).

The following
N
lines give the placement of blocks. 
Each line, representing a block, consists of five integers delimited by a space.  These integers indicate the two vertices (
minx
,
miny
), (
maxx
,
maxy
) of the 
bottom surface and the height
h
of the block.




The integers
sx
,
sy
,
ex
,
ey
,
minx
,
miny
,
maxx
,
maxy
and
h
satisfy the following conditions.
-10000 ≤
sx
,
sy
,
ex
,
ey
≤ 10000
-10000 ≤
minx
i
<
maxx
i
≤ 10000
-10000 ≤
miny
i
<
maxy
i
≤ 10000
1 ≤
h
i
≤ 1000
The last dataset is followed by a line with a single zero in it.
Output
For each dataset, output a separate line containing the largest radius. 
You may assume that the largest radius never exceeds 1000 for each dataset.
If there are any blocks on the course line, the largest radius is defined to be zero.
The value may contain an error less than or equal to 0.001.
You may print any number of digits after the decimal point.
Sample Input
2
-40 -40 100 30
-100 -100 -50 -30 1
30 -70 90 -30 10
2
-4 -4 10 3
-10 -10 -5 -3 1
3 -7 9 -3 1
2
-40 -40 100 30
-100 -100 -50 -30 3
30 -70 90 -30 10
2
-400 -400 1000 300
-800 -800 -500 -300 7
300 -700 900 -300 20
3
20 70 150 70
0 0 50 50 4
40 100 60 120 8
130 80 200 200 1
3
20 70 150 70
0 0 50 50 4
40 100 60 120 10
130 80 200 200 1
3
20 70 150 70
0 0 50 50 10
40 100 60 120 10
130 80 200 200 3
1
2 4 8 8
0 0 10 10 1
1
1 4 9 9
2 2 7 7 1
0
Output for the Sample Input
30
1
18.16666666667
717.7
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

double EPS = 1e-9;
typedef complex<double> P;

struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a); push_back(b);
  }
};
double cross(const P& a, const P& b) {
  return imag(conj(a)*b);
}
double dot(const P& a, const P& b) {
  return real(conj(a)*b);
}
int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (cross(b, c) > 0)   return +1;       // counter clockwise
  if (cross(b, c) < 0)   return -1;       // clockwise
  if (dot(b, c) < 0)     return +2;       // c--a--b on line
  if (norm(b) < norm(c)) return -2;       // a--b--c on line
  return 0;
}

P projection(const L &l, const P &p) {
  double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
  return l[0] + t*(l[0]-l[1]);
}
bool intersectSS(const L &s, const L &t) {
  return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 &&
         ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
}
bool intersectSP(const L &s, const P &p) {
  return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality
}
double distanceSP(const L &s, const P &p) {
  const P r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s[0] - p), abs(s[1] - p));
}

double distanceSS(const L &s, const L &t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
             min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}

P A[100],B[100];
double H[100];
P s,e;
P in(){
	double x,y;
	cin >> x >> y;
	return P(x,y);
}

int N;

bool f(double R){
	for(int i = 0 ; i < N ; i++){
		double h = min(R,H[i]);
		P a = A[i];
		P b = P(B[i].real(),A[i].imag());
		P c = B[i];
		P d = P(A[i].real(),B[i].imag());
		L l[] = {L(a,b),L(b,c),L(c,d),L(d,a)};
		for(int j = 0 ; j < 4 ; j++){
			double rd = sqrt(R*R-(h-R)*(h-R));
			if( distanceSS(L(s,e),l[j]) < rd ){
				return 0;
			}
		}
	}
	return 1;
}
int main(){
	while( cin >> N and N > 0 ){
		
		s = in();
		e = in();
		bool ff = 0;
		for(int i = 0 ; i < N ; i++){
			A[i] = in();
			B[i] = in();
			cin >> H[i];
			if( A[i].real() <= s.real() and s.real() <= B[i].real()
				and  A[i].imag() <= s.imag() and s.imag() <= B[i].imag() 
			or A[i].real() <= e.real() and e.real() <= B[i].real()
				and  A[i].imag() <= e.imag() and e.imag() <= B[i].imag() ){
				ff = 1;
			}
		}
		
		if(ff){
			cout << 0 << endl;
			continue;
		}
		
		double l = 0, r = 100000;
		for(int i = 0 ; i < 128 ; i++){
			double m = (l+r) / 2;
			if( f(m) ){
				l = m;
			}else{
				r = m;
			}
		}
		printf("%.10lf\n",l);
		
	}
}
accuracy: 1
time_ms: 330
memory_kb: 3508
final_rank: 10

code_snippet: #pragma region Macros
#include <bits/stdc++.h>
using namespace std;
using lint = long long;
using ull = unsigned long long;
using ld = long double;
using int128 = __int128_t;
#define all(x) (x).begin(), (x).end()
#define uniqv(v) v.erase(unique(all(v)), v.end())
#define OVERLOAD_REP(_1, _2, _3, name, ...) name
#define REP1(i, n) for (auto i = std::decay_t<decltype(n)>{}; (i) != (n); ++(i))
#define REP2(i, l, r) for (auto i = (l); (i) != (r); ++(i))
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
#define log(x) cout << x << endl
#define logfixed(x) cout << fixed << setprecision(10) << x << "\n";
#define logy(bool)         \
  if (bool) {              \
    cout << "Yes" << endl; \
  } else {                 \
    cout << "No" << endl;  \
  }

ostream &operator<<(ostream &dest, __int128_t value) {
  ostream::sentry s(dest);
  if (s) {
    __uint128_t tmp = value < 0 ? -value : value;
    char buffer[128];
    char *d = end(buffer);
    do {
      --d;
      *d = "0123456789"[tmp % 10];
      tmp /= 10;
    } while (tmp != 0);
    if (value < 0) {
      --d;
      *d = '-';
    }
    int len = end(buffer) - d;
    if (dest.rdbuf()->sputn(d, len) != len) {
      dest.setstate(ios_base::badbit);
    }
  }
  return dest;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < (int)v.size(); i++) {
    os << v[i] << (i + 1 != (int)v.size() ? " " : "");
  }
  return os;
}

template <typename T>
ostream &operator<<(ostream &os, const set<T> &set_var) {
  for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
    os << *itr;
    ++itr;
    if (itr != set_var.end()) os << " ";
    itr--;
  }
  return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
  for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
    os << itr->first << " -> " << itr->second << "\n";
  }
  return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}

void out() { cout << '\n'; }
template <class T, class... Ts>
void out(const T &a, const Ts &...b) {
  cout << a;
  (cout << ... << (cout << ' ', b));
  cout << '\n';
}

template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (T &in : v) is >> in;
  return is;
}

inline void in(void) { return; }
template <typename First, typename... Rest>
void in(First &first, Rest &...rest) {
  cin >> first;
  in(rest...);
  return;
}

template <typename T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

vector<lint> dx8 = {1, 1, 0, -1, -1, -1, 0, 1};
vector<lint> dy8 = {0, 1, 1, 1, 0, -1, -1, -1};
vector<lint> dx4 = {1, 0, -1, 0};
vector<lint> dy4 = {0, 1, 0, -1};

#pragma endregion

#define EPS (1e-10)
#define equals(a, b) (fabsl((a) - (b)) < EPS)

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;
static const int CONTAIN = 2;
static const int CONTAIN_LINE = 1;
static const int NOT_CONTAIN = 0;
static const int CIRCUMSCRIPTION = 3;
static const int INSCRIPTION = 1;
static const int INTERSECT = 2;
static const int CONNOTATION = 0;
static const int NOT_CONNOTATION = 4;

struct Point {
 public:
  long double x, y;
  Point(long double x = 0, long double y = 0) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(long double a) { return Point(a * x, a * y); }
  Point operator/(long double a) { return Point(x / a, y / a); }
  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }
  bool operator>(const Point &p) const { return x != p.x ? x > p.x : y > p.y; }
  bool operator==(const Point &p) const { return fabsl(x - p.x) < EPS and fabsl(y - p.y) < EPS; }

  long double abs() { return sqrtl(norm()); }
  long double norm() { return x * x + y * y; }
};

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

using Vector = Point;

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

long double abs(Vector a) {
  return sqrtl(norm(a));
}

struct Segment {
  Point p1, p2;
  Segment(Point x, Point y) {
    p1 = x;
    p2 = y;
  }
};

using Line = Segment;

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

using Polygon = vector<Point>;

// ベクトル aとbの内積を返す
long double dot(Vector a, Vector b) {
  return a.x * b.x + a.y * b.y;
}

// ベクトル aとbの外積を返す
long double cross(Vector a, Vector b) {
  return a.x * b.y - a.y * b.x;
}

// ベクトル aとbが直交かどうかを返す
bool isOrthogonal(Vector a, Vector b) {
  return equals(dot(a, b), 0.0);
}

// 点　a1,a2からなるベクトルと b1,b2からなるベクトルが直交かどうかを返す
bool isOrthogonal(Point a1, Point a2, Point b1, Point b2) {
  return isOrthogonal(a1 - a2, b1 - b2);
}

// 線分 aとbが直交かどうかを返す
bool isOrthogonal(Segment s1, Segment s2) {
  return equals(dot(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
}

// ベクトル aとbが平行かどうかを返す
bool isParallel(Vector a, Vector b) {
  return equals(cross(a, b), 0.0);
}

// 点　a1,a2からなるベクトルと b1,b2からなるベクトルが平行かどうかを返す
bool isParallel(Point a1, Point a2, Point b1, Point b2) {
  return isParallel(a1 - a2, b1 - b2);
}

// 線分 aとbが平行かどうかを返す
bool isParallel(Segment s1, Segment s2) {
  return equals(cross(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
}

// 点pから線分sに垂線を下ろした時の交点（射影）を返す
Point project(Segment s, Point p) {
  Vector base = s.p2 - s.p1;
  long double r = dot(p - s.p1, base) / norm(base);
  return s.p1 + base * r;
}

// 線分sを対称軸として、点pと線対称の位置にある点（反射）を返す
Point reflect(Segment s, Point p) {
  return p + (project(s, p) - p) * 2.0;
}

// 2点間の距離を返す
long double Distance(Point a, Point b) {
  return abs(a - b);
}

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

// 点pと線分lの距離を返す
long double 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 DistanceLP(s, p);
}

// 点の位置関係を調べる
int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1 - p0;
  Vector b = p2 - p0;
  // p0->p1を反時計回りに回転させる方向にp2が存在する
  if (cross(a, b) > EPS) return COUNTER_CLOCKWISE;
  // p0->p1を時計回りに回転させる方向にp2が存在する
  if (cross(a, b) < -EPS) return CLOCKWISE;
  // 3点は同一直線上に存在し、2点に挟まれている点はp0
  if (dot(a, b) < -EPS) return ONLINE_BACK;
  // 3点は同一直線上に存在し、2点に挟まれている点はp1
  if (a.norm() < b.norm()) return ONLINE_FRONT;
  // 3点は同一直線上に存在し、2点に挟まれている点はp2
  return ON_SEGMENT;
}

// 点p1,p2からなる線分とp3,p4からなる線分が交差するかどうかを返す
bool intersect(Point p1, Point p2, Point p3, Point p4) {
  return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);
}

// 線分 s1とs2が交差するかどうかを返す
bool intersect(Segment s1, Segment s2) {
  return intersect(s1.p1, s1.p2, s2.p1, s2.p2);
}

// 円 c1とc2の位置関係を調べる
int intersect(Circle c1, Circle c2) {
  long double d = abs((c1.c - c2.c));
  // 2つの円は離れている（内包していない）
  if (d > c1.r + c2.r + EPS) {
    return NOT_CONNOTATION;
  }
  // 外接している
  if (equals(d, c1.r + c2.r)) {
    return CIRCUMSCRIPTION;
  }
  // 内接している
  if (equals(d, abs(c1.r - c2.r))) {
    return INSCRIPTION;
  }
  // 内包している
  if (d < abs(c1.r - c2.r) - EPS) {
    return CONNOTATION;
  }
  // 2点で交わる
  return INTERSECT;
}

// 点 a,b,cからなる三角形の内接円を返す
Circle inCircle(Point a, Point b, Point c) {
  long double A = abs(b - c);
  long double B = abs(a - c);
  long double C = abs(a - b);
  Point p((A * a.x) + (B * b.x) + (C * c.x), (A * a.y) + (B * b.y) + (C * c.y));
  p = p / (A + B + C);
  long double r = DistanceLP({a, b}, p);
  return Circle(p, r);
}

// 線分 s1とs2の距離を返す
long double Distance(Segment s1, Segment s2) {
  if (intersect(s1, s2)) return 0.0;
  return min({DistanceSP(s1, s2.p1), DistanceSP(s1, s2.p2), DistanceSP(s2, s1.p1), DistanceSP(s2, s1.p2)});
}

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

// 円 cと、直線lの交点を返す
template <class T>
pair<T, T> CrossPoints(Circle c, Line l) {
  Vector pr = project(l, c.c);
  Vector e = (l.p2 - l.p1) / abs(l.p2 - l.p1);
  long double base = sqrtl(c.r * c.r - norm(pr - c.c));
  return {Point(pr + e * base), Point(pr - e * base)};
}

long double arg(Vector p) { return atan2l(p.y, p.x); }
Vector polar(long double a, long double r) { return Point(cosl(r) * a, sinl(r) * a); }

// 円 c1とc2の交点を返す
template <class T>
pair<T, T> CrossPoints(Circle c1, Circle c2) {
  long double d = abs(c1.c - c2.c);
  long double a = acosl((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
  long double t = arg(c2.c - c1.c);
  return {c1.c + polar(c1.r, t + a), c1.c + polar(c1.r, t - a)};
}

// 点 pを通る、円cの接線を求め、その接点を返す pは円の外側だと仮定する
template <class T>
pair<T, T> tangentToCircle(Circle c, Point p) {
  return CrossPoints<Point>(c, Circle(p, sqrtl(norm(c.c - p) - c.r * c.r)));
}

// 点 pが、多角形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 and dot(a, b) < EPS) return CONTAIN_LINE;
    if (a.y > b.y) swap(a, b);
    if (a.y < EPS and EPS < b.y and cross(a, b) > EPS) x = !x;
  }
  return (x ? CONTAIN : NOT_CONTAIN);
}

// 多角形pの面積を返す
long double PolygonArea(const vector<Point> &p) {
  long double res = 0;
  int n = p.size();
  for (int i = 0; i < n - 1; i++) {
    res += cross(p[i], p[i + 1]);
  }
  res += cross(p[n - 1], p[0]);
  return res * 0.5;
}

// 多角形pが凸多角形かどうか返す
bool isConvex(const vector<Point> &p) {
  int n = p.size();
  int now, pre, nxt;
  for (int i = 0; i < n; i++) {
    pre = (i - 1 + n) % n;
    nxt = (i + 1) % n;
    now = i;
    if (ccw(p[pre], p[now], p[nxt]) == CLOCKWISE) {
      return false;
    }
  }
  return true;
}

// 凸包
Polygon andrewScan(Polygon s, bool on_line = 0) {
  Polygon u, l;
  if (s.size() < 3) return s;
  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]);
  if (on_line) {
    for (int i = 2; i < s.size(); i++) {
      for (int n = u.size(); n >= 2 and ccw(u[n - 2], u[n - 1], s[i]) == COUNTER_CLOCKWISE; 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 and ccw(l[n - 2], l[n - 1], s[i]) == COUNTER_CLOCKWISE; n--) {
        l.pop_back();
      }
      l.push_back(s[i]);
    }
  } else {
    for (int i = 2; i < s.size(); i++) {
      for (int n = u.size(); n >= 2 and ccw(u[n - 2], u[n - 1], s[i]) != CLOCKWISE; 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 and ccw(l[n - 2], l[n - 1], s[i]) != CLOCKWISE; 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;
}

int main() {
  cin.tie(0)->sync_with_stdio(0);
  int n;
  while (1) {
    in(n);
    if (n == 0) break;
    ld sx, sy, ex, ey;
    in(sx, sy, ex, ey);

    vector<Segment> seg;
    vector<ld> height;

    vector<tuple<ld, ld, ld>> ps;
    bool fin = 0;

    rep(i, n) {
      ld lx, ly, rx, ry, h;
      in(lx, ly, rx, ry, h);

      if (lx <= sx and sx <= rx and ly <= sy and sy <= ry) {
        fin = 1;
      }

      if (lx <= ex and ex <= rx and ly <= ey and ey <= ry) {
        fin = 1;
      }

      ps.emplace_back(lx, ly, h);
      ps.emplace_back(lx, ry, h);
      ps.emplace_back(rx, ly, h);
      ps.emplace_back(rx, ry, h);

      seg.emplace_back(Point(lx, ly), Point(lx, ry));
      seg.emplace_back(Point(lx, ly), Point(rx, ly));
      seg.emplace_back(Point(rx, ly), Point(rx, ry));
      seg.emplace_back(Point(lx, ry), Point(rx, ry));
      height.push_back(h);
      height.push_back(h);
      height.push_back(h);
      height.push_back(h);
    }

    Segment path(Point(sx, sy), Point(ex, ey));

    for (auto s : seg) {
      if (intersect(path, s)) {
        fin = 1;
      }
    }
    if (fin) {
      out(0);
      continue;
    }

    ld ok = 0;
    ld ng = 1010;
    ld r;

    int lim = 100;
    rep(z, lim) {
      r = (ok + ng) / 2;

      bool res = true;
      for (auto [x, y, h] : ps) {
        ld d = DistanceSP(path, Point(x, y));
        if(d > r) continue;
        res &= (r - sqrtl(r*r - d*d)) > h;
      }

      rep(i, 4 * n) {
        Segment s = seg[i];
        ld h = height[i];
        ld d = DistanceSP(s, Point(sx, sy));
        if(d > r) continue;
        res &= (r - sqrtl(r*r - d*d)) > h;
      }

      rep(i, 4 * n) {
        Segment s = seg[i];
        ld h = height[i];
        ld d = DistanceSP(s, Point(ex, ey));
        if(d > r) continue;
        res &= (r - sqrtl(r*r - d*d)) > h;
      }

      if (res) {
        ok = r;
      } else {
        ng = r;
      }
    }
    logfixed(ok);
  }
}
accuracy: 1
time_ms: 90
memory_kb: 3840
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

// 書きかけの幾何ライブラリ
// バグがあるかも

namespace geometry {

using Real = long double;
constexpr Real eps = 1e-12;
constexpr Real PI = acosl(-1);
constexpr Real INF_REAL = numeric_limits<Real>::max();

bool equal_eps(Real a, Real b) {
    return abs(a - b) < eps;
}

int sgn(Real a) {
    return equal_eps(a, 0) ? 0 : a > 0 ? 1 : -1;
}

struct Point {
    Real x, y;
    constexpr Point() : Point(0, 0) {}
    constexpr Point(Real _x, Real _y) : x(_x), y(_y) {}
    constexpr Point(const pair<Real, Real> &p) : x(p.first), y(p.second) {}
    Point &operator+=(const Point &p) {
        x += p.x;
        y += p.y;
        return *this;
    }
    Point &operator-=(const Point &p) {
        x -= p.x;
        y -= p.y;
        return *this;
    }
    Point &operator*=(const Real &r) {
        x *= r;
        y *= r;
        return *this;
    }
    Point &operator/=(const Real &r) {
        assert(!equal_eps(r, 0));
        x /= r;
        y /= r;
        return *this;
    }
    Point operator+(const Point &p) const { return Point(*this) += p; }
    Point operator-(const Point &p) const { return Point(*this) -= p; }
    Point operator*(const Real &r) const { return Point(*this) *= r; }
    Point operator/(const Real &r) const { return Point(*this) /= r; }
    Point operator-() const { return Point() - *this; }
    bool operator==(const Point &p) const {
        return equal_eps(x, p.x) && equal_eps(y, p.y);
    }
    bool operator!=(const Point &p) const {
        return !equal_eps(x, p.x) || !equal_eps(y, p.y);
    }
    Point rotate(Real rad) const {
        Real c = cosl(rad), s = sinl(rad);
        Real tx = x * c - y * s;
        Real ty = x * s + y * c;
        return Point(tx, ty);
    }
    Point unit() const {
        return (*this) / metric();
    }
    Real Re() const { return x; }
    Real Im() const { return y; }
    Real norm() const { return x * x + y * y; }
    Real metric() const { return sqrtl(norm()); }
    Real arg() const { return atan2l(y, x); }
    Real arg(Point q1, Point q2) const {
        q1 -= *this, q2 -= *this;
        return abs(q1.arg() - q2.arg());
    }
    friend Point operator*(Real r, const Point &p) {
        return p * r;
    }
    friend Point operator/(Real r, const Point &p) {
        return p / r;
    }
};

Real Re(const Point &p) { return p.Re(); }
Real Im(const Point &p) { return p.Im(); }
Real dot(const Point &p, const Point &q) {
    return p.x * q.x + p.y * q.y;
}
Real cross(const Point &p, const Point &q) {
    return p.x * q.y - p.y * q.x;
}
Real norm(const Point &p) {
    return p.norm();
}
Real metric(const Point &p) {
    return p.metric();
}
Real metric(const Point &p, const Point &q) {
    return metric(p - q);
}
Real arg(const Point &p) {
    return p.arg();
}

bool equal_point(const Point &p, const Point &q) {
    return equal_eps(p.x, q.x) && equal_eps(p.y, q.y);
}

constexpr Point INF_POINT = Point(INF_REAL, INF_REAL);

// a を基準にした b と c の位置関係
int ccw(const Point &a, const Point &b, const Point &c) {
    Point p = b - a, q = c - a;
    if (cross(p, q) > eps) return 1; // a, b, c の順で反時計回り
    if (cross(p, q) < -eps) return -1; // a, b, c の順で時計回り
    if (min(norm(p), norm(q)) < eps * eps) return 0; // a = c or b = c
    if (dot(p, q) < eps) return 2; // c, a, b の順で一直線
    if (norm(p) < norm(q)) return -2; // a, b, c の順で一直線
    return 0; // a, c, b の順で一直線
}

istream &operator>>(istream &is, Point& p) {
    Real x, y;
    is >> x >> y;
    p = Point(x, y);
    return is;
}

} // namespace geometry

namespace geometry {

struct Line {
    // Line : ax + by = c
    Real a, b, c;
    constexpr Line() = default;
    constexpr Line(Real _a, Real _b, Real _c) : a(_a), b(_b), c(_c) {}
    constexpr Line(const Point &p, const Point &q) : a(q.y - p.y), b(p.x - q.x), c(p.x * q.y - p.y * q.x) {}
    constexpr Line(Real _a, const Point &p) : a(_a), b(-1), c(_a * p.x - p.y) {}
    bool online(const Point &p) const {
        return equal_eps(a * p.x + b * p.y, c);
    }
    Real get_x(Real y) const {
        if (equal_eps(a, 0)) return INF_REAL;
        return (c - b * y) / a;
    }
    Real get_y(Real x) const {
        if (equal_eps(b, 0)) return INF_REAL;
        return (c - a * x) / b;
    }
    Line perpendicular(const Point &p) const {
        if (equal_eps(a, 0)) return Line(1, 0, p.x);
        if (equal_eps(0, b)) return Line(0, 1, p.y);
        return Line(b / a, p);
    }
    Point crossppoint(const Line &l) const {
        if (equal_eps(a * l.b, l.a * b)) return INF_POINT;
        Real d = a * l.b - l.a * b;
        return Point(l.b * c - b * l.c, l.c * a - c * l.a) / d;
    }
    Point projection(const Point &p) const {
        return crossppoint(perpendicular(p));
    }
    Point reflection(const Point &p) const {
        Point q = projection(p);
        return 2 * q - p;
    }
    Point unit() const {
        if (equal_eps(b, 0)) {
            return Point(0, 1);
        }
        Point p(0, get_y(0)), q(1, get_y(1));
        return (p - q) / metric(p - q);
    }
    bool is_orthogonal(const Line &l) const {
        return equal_eps(a * l.a + b * l.b, 0);
    }
    bool is_parallel(const Line &l) const {
        return equal_eps(a * l.b, l.a * b);
    }
    Real dist(const Point &p) const {
        Point q = projection(p);
        return metric(p - q);
    }
};

bool is_orthogonal(const Line &l1, const Line &l2) {
    return l1.is_orthogonal(l2);
}
bool is_parallel(const Line &l1, const Line &l2) {
    return l1.is_parallel(l2);
}
Point crosspoint(const Line &l1, const Line &l2) {
    return l1.crossppoint(l2);
}

} // namespace geometry

namespace geometry {

struct Segment {
    Line l;
    Point p, q;
    Segment() = default;
    Segment(const Point &_p, const Point &_q) : l(_p, _q), p(_p), q(_q) {}
    bool cross(const Segment &s) const {
        bool f1 = ccw(p, q, s.p) * ccw(p, q, s.q) <= 0;
        bool f2 = ccw(s.p, s.q, p) * ccw(s.p, s.q, q) <= 0;
        return f1 && f2;
    }
    Point crosspoint(const Segment &s) const {
        if (cross(s)) return l.crossppoint(s.l);
        return INF_POINT;
    }
    Real dist(const Point &r) const {
        if (dot(q - p, r - p) < eps) return (r - p).metric();
        if (dot(p - q, r - q) < eps) return (r - q).metric();
        return l.dist(r);
    }
    Real dist(const Segment &s) const {
        if (cross(s)) return 0;
        Real res = INF_REAL;
        res = min(res, dist(s.p));
        res = min(res, dist(s.q));
        res = min(res, s.dist(p));
        res = min(res, s.dist(q));
        return res;
    }
};

bool cross(const Segment &s, const Segment &t) {
    return s.cross(t);
}

Point crosspoint(const Segment &s, const Segment &t) {
    return s.crosspoint(t);
}

Real dist(const Segment &s, const Segment &t) {
    return s.dist(t);
}

} // nemespace geometry

namespace geometry {

// { x in R^2 | |x - p| = r}
struct circle {
    Point p;
    Real r;
    circle() = default;
    circle(const Point _p, Real _r) : p(_p), r(_r) {}
    int count_common_tangent(const circle &c) const {
        Real d = metric(p - c.p);
        if (d > r + c.r + eps) return 4;
        if (equal_eps(d, r + c.r)) return 3;
        if (equal_eps(d, abs(r - c.r))) return 1;
        if (d < abs(r - c.r) - eps) return 0;
        return 2;
    }
    vector<Point> crosspoints(const Line &l) const {
        Real d = l.dist(p);
        if (d > r + eps) return {};
        Point q = l.projection(p);
        if (equal_eps(d, r)) {
            return {q};
        }
        Point e = l.unit();
        Real t = sqrtl(r * r - d * d);
        return {q - t * e, q + t * e};
    }
    vector<Point> crosspoints(const circle &c) const {
        int t = count_common_tangent(c);
        if (t == 0 || t == 4) return {};
        Real d = metric(p - c.p);
        if (t == 1) {
            if (c.r < r - eps) {
                return {p + (c.p - p) * (r / d)};
            } else {
                return {c.p + (p - c.p) * (c.r / d)};
            }
        } else if (t == 3) {
            geometry::Real s = r / (r + c.r);
            return {p + (c.p - p) * s};
        } else {
            geometry::Real la = 2 * (p.x - c.p.x);
            geometry::Real lb = 2 * (p.y - c.p.y);
            geometry::Real lc = (p.x + c.p.x) * (p.x - c.p.x) + (p.y + c.p.y) * (p.y - c.p.y) + (r + c.r) * (c.r - r);
            return crosspoints(Line(la, lb, lc));
        }
    }
    vector<Point> points_of_tangency(const Point &q) const {
        Real d = metric(p - q);
        if (d < r - eps) return {};
        if (equal_eps(d, r)) return {q};
        return crosspoints(circle(q, sqrtl(d * d - r * r)));
    }
    vector<Point> points_of_common_tangency(const circle &c) const {
        Real d = metric(p - c.p);
        if (equal_eps(d, 0)) return {};
        Point u = (c.p - p).unit();
        Point v = u.rotate(PI / 2);
        vector<Point> res;
        for (int s : {-1, 1}) {
            Real h = (r + s * c.r) / d;
            if (equal_eps(h * h, 1)) {
                res.push_back(p + (h > 0 ? u : -u) * r);
            } else if (1 - h * h > 0) {
                Point u2 = u * h, v2 = v * sqrtl(1 - h * h);
                res.push_back(p + (u2 + v2) * r);
                res.push_back(p + (u2 - v2) * r);
            }
        }
        return res;
    }
};

} // namespace geometry
using namespace geometry;

bool solve() {
    int N;
    cin >> N;
    if (N == 0) return false;
    Point s, t;
    cin >> s >> t;
    Segment S(s, t);
    auto sub = [&] (Point a, Point b, Real h) -> Real {
        Real d = S.dist(Segment(a, b));
        Line L(Point(d, 0), Point(d, h));
        Real l = 0, r = 1e9;
        for (int t = 0; t < 100; t++) {
            Real m = (l + r) / 2;
            ([&] {
                for (auto p : circle(Point(0, m), m).crosspoints(L)) {
                    if (p.y < h + eps) return true;
                }
                return false;
            } () ? r : l) = m;
        }
        return r;
    };
    Real ans = INF_REAL;
    while (N--) {
        Real x1, y1, x2, y2, h;
        cin >> x1 >> y1 >> x2 >> y2 >> h;
        Point a(x1, y1), b(x1, y2), c(x2, y2), d(x2, y1);
        if (S.cross(Segment(a, b))) ans = 0;
        if (S.cross(Segment(b, c))) ans = 0;
        if (S.cross(Segment(c, d))) ans = 0;
        if (S.cross(Segment(d, a))) ans = 0;
        if (x1 <= s.x && s.x <= x2 && y1 <= s.y && s.y <= y2) ans = 0;
        if (x1 <= t.x && t.x <= x2 && y1 <= t.y && t.y <= y2) ans = 0;
        ans = min(ans, sub(a, b, h));
        ans = min(ans, sub(b, c, h));
        ans = min(ans, sub(c, d, h));
        ans = min(ans, sub(d, a, h));
    }
    cout << fixed << setprecision(16) << ans << endl;
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 50
memory_kb: 3840
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define rrep(i,start,end) for (ll i = start;i >= (ll)(end);i--)
#define repn(i,end) for(ll i = 0; i <= (ll)(end); i++)
#define reps(i,start,end) for(ll i = start; i < (ll)(end); i++)
#define repsn(i,start,end) for(ll i = start; i <= (ll)(end); i++)
#define each(p,a) for(auto &p:a)
typedef vector<ll> vll;
typedef vector<pair<ll ,ll>> vpll;
typedef vector<vector<ll>> vvll;
typedef set<ll> sll;
typedef map<ll , ll> mpll;
typedef pair<ll ,ll> pll;
typedef tuple<ll , ll , ll> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (ll)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1LL << 60;
const ld EPS = 1e-9;
 
ll lceil(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b)+1;}else{return -((-a)/b);}}
ll lfloor(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b);}else{return -((-a)/b)-1;}}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
//0indexed
inline ll topbit(ll a){assert(a != 0);return 63 - __builtin_clzll(a);}
inline ll smlbit(ll a){assert(a != 0);return __builtin_ctzll(a);}
template<class T> bool chmin(T& a, T b){if(a > b){a = b;return true;}return false;}
template<class T> bool chmax(T& a, T b){if(a < b){a = b;return true;}return false;}
template<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
template <class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v) e++;return v;}
template <class T> vector<T> operator++(vector<T> &v, signed) {auto res = v;for(auto &e : v) e++;return res;}
template <class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v) e--;return v;}
template <class T> vector<T> operator--(vector<T> &v, signed) {auto res = v;for(auto &e : v) e--;return res;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;


//参考 https://github.com/saphmitchy/deliair-lib
// 型名
// R:Real, P:Point, L:Line, S:Segment, C:Circle, VP:vector<Point>

#define X(p) real(p)
#define Y(p) imag(p)

using R = ld;
using P = complex<R>;
using VP = vector<P>;

//const R EPS = 1e-9; // ここは適宜調節する,いつものやつから消す
const R pi = acos(-1.0);

int sgn(R a) {
    return (a < -EPS) ? -1 : (a > EPS) ? 1 : 0;
} // 符号関数

bool eq(R a, R b) {//実数の一致判定
    return sgn(b - a) == 0;
}

P operator*(P p, R d) {//ベクトルのd倍
    return P(X(p) * d, Y(p) * d);
}

P operator/(P p, R d) {//ベクトルの1/d倍
    return p * (1 / d);
}

istream &operator>>(istream &is, P &p) {
    // R a, b; // 入力が小数
    int a, b; // 入力が整数
    is >> a >> b;
    p = P(a, b);
    return is;
}

ostream &operator<<(ostream &os, P p) {
    return os << X(p) << ' ' << Y(p);
}

R getarg(P b,P a){//ベクトルbはベクトルaを何radian回転させる必要があるか
  assert(sgn(abs(a)) != 0);//長さが0はだめ
  return arg(b/a);
}

bool cp_x(P p, P q) {//ベクトルの比較x軸で比較->y軸で比較
    if (!eq(X(p), X(q)))
        return X(p) < X(q);
    return Y(p) < Y(q);
}

bool cp_y(P p, P q) {//ベクトルの比較y軸で比較->x軸で比較
    if (!eq(Y(p), Y(q)))
        return Y(p) < Y(q);
    return X(p) < X(q);
}

struct L {//直線ab
    P a, b;
    L() {}
    L(P a, P b) : a(a), b(b) {}

    // 入出力（必要なら）
    friend ostream &operator<<(ostream &os, L &l) {
        return os << l.a << ' ' << l.b;
    }
    friend istream &operator>>(istream &is, L &l) {
        return is >> l.a >> l.b;
    }
};

struct S : L {//線分ab
    S() {}
    S(P a, P b) : L(a, b) {}
};

struct C {//中心p 半径rの円
    P p;
    R r;
    C() {}
    C(P p, R r) : p(p), r(r) {}
};

P rot(P p, R t) {//ベクトルの回転
    return p * P(cos(t), sin(t));
}

//2つのベクトルの内積
R dot(P p, P q) {
    return X(p) * X(q) + Y(p) * Y(q);
}

//2つのベクトルの外積
R det(P p, P q) {
    return X(p) * Y(q) - Y(p) * X(q);
}

// https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C&lang=jp
int ccw(P a, P b, P c) { // 線分 ab に対する c の位置関係 
    b -= a, c -= a;//ベクトルab,ベクトルacにした
    if (sgn(det(b, c)) == 1)//外積右ねじ正
        return +1; // COUNTER_CLOCKWISE a,b,cが反時計回り
    if (sgn(det(b, c)) == -1)
        return -1; // CLOCKWISE
    if (dot(b, c) < 0.0)
        return +2; // ONLINE_BACK
    if (norm(b) < norm(c))
        return -2; // ONLINE_FRONT
    return 0;      // ON_SEGMENT
}

bool para(L a, L b) { // 平行判定
    return eq(det(a.b - a.a, b.b - b.a), 0.0);
}

bool orth(L a, L b) { // 垂直判定
    return eq(dot(a.b - a.a, b.b - b.a), 0.0);
}

P proj(L l, P p) { // 垂線の足
    R t = dot(p - l.a, l.b - l.a) / norm(l.b - l.a);
    return l.a + (l.b - l.a) * t;
}

// これいる？
// P proj(S s, P p) {
//     R t = dot(p - s.a, s.b - s.a) / norm(s.b - s.a);
//     return s.a + (s.b - s.a) * t;
// }

P refl(L l, P p) { // 線対称の位置にある点
    return p + (proj(l, p) - p) * 2.0;
}

bool inter(L l, P p) { // 交点を持つか判定
    return abs(ccw(l.a, l.b, p)) != 1;
}

bool inter(S s, P p) {
    return ccw(s.a, s.b, p) == 0;
}

bool inter(L l, L m) {
    if (!eq(det(l.b - l.a, m.b - m.a), 0.0))
        return true;
    return eq(det(l.b - l.a, m.b - l.a), 0.0);
}

bool inter(L l, S s) {
    return sgn(det(l.b - l.a, s.a - l.a) * det(l.b - l.a, s.b - l.a)) <= 0;
}

bool inter(S s, L l) {
    return inter(l, s);
}

bool inter(S s, S t) {
    if (ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) > 0)
        return false;
    return ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

R dist(P p, P q) {
    return abs(q - p);
}

R dist(L l, P p) {
    return abs(p - P(proj(l, p)));
}

//R dist(S s, P p) {
//    P h = proj(s, p);
//    if (inter(s, h))
//        return abs(h - p);
//    return min(abs(s.a - p), abs(s.b - p));
//}

R dist(S s, P p) {
    P h = proj(s, p);
    if(dot(p-s.a,s.b-s.a) <= 0) return abs(s.a-p);
    if(dot(p-s.b,s.a-s.b) <= 0) return abs(s.b-p);
    return abs(p - h);
}

R dist(L l, L m) {
    return inter(l, m) ? 0.0 : dist(l, m.a);
}

R dist(S s, S t) {
    if (inter(s, t))
        return 0.0;
    return min({dist(s, t.a), dist(s, t.b), dist(t, s.a), dist(t, s.b)});
}

R dist(L l, S s) {
    if (inter(l, s))
        return 0.0;
    return min(dist(l, s.a), dist(l, s.b));
}

R dist(S s, L l) {
    return dist(l, s);
}

bool inter(C c, L l) {
    return sgn(c.r - dist(l, c.p)) >= 0;
}

bool inter(C c, P p) {
    return eq(abs(p - c.p), c.r);
}

// 共通接線の本数
// 交点なし:4
// 外接:3
// 2点で交わる:2
// 内接:1
// 一方がもう一方を内包:0
int inter(C c1, C c2) {
    if (c1.r < c2.r)
        swap(c1, c2);
    R d = abs(c1.p - c2.p);
    int a = sgn(d - c1.r - c2.r);
    if (a >= 0)
        return 3 + a;
    return 1 + sgn(d - c1.r + c2.r);
}

VP crosspoint(L l, L m) {
    VP ret;
    if (!inter(l, m))
        return ret;
    R A = det(l.b - l.a, m.b - m.a);
    R B = det(l.b - l.a, l.b - m.a);
    if (eq(A, 0.0) && eq(B, 0.0)) {
        ret.emplace_back(m.a);
    } else {
        ret.emplace_back(m.a + (m.b - m.a) * B / A);
    }
    return ret;
}

VP crosspoint(S s, S t) {
    return inter(s, t) ? crosspoint(L(s), L(t)) : VP();
}

VP crosspoint(C c, L l) {//円と直線の交点
    P h = proj(l, c.p);
    P e = (l.b - l.a) / abs(l.b - l.a);
    VP ret;
    if (!inter(c, l))
        return ret;
    if (eq(dist(l, c.p), c.r)) {
        ret.emplace_back(h);
    } else {
        R b = sqrt(c.r * c.r - norm(h - c.p));
        ret.push_back(h + e * b), ret.push_back(h - e * b);
    }
    return ret;
}

VP crosspoint(C c, S s) {//円と線分の交点
    P h = proj(s, c.p);
    P e = (s.b - s.a) / abs(s.b - s.a);
    VP ret;
    if (!inter(c, s))
        return ret;
    if (eq(dist(s, c.p), c.r)) {
        ret.emplace_back(h);
    } else {
        R b = sqrt(c.r * c.r - norm(h - c.p));
        if(ccw(s.a,s.b,h - e * b) == 0){//s.aに近い方から線分上なら追加する
          ret.push_back(h - e * b);
        }
        if(ccw(s.a,s.b,h + e * b)==0){
          ret.push_back(h + e * b);
        }
    }
    return ret;
}

VP crosspoint(C c1, C c2) {//2つの円の交わる点
    R d = abs(c1.p - c2.p);
    R a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    R t = atan2(Y(c2.p) - Y(c1.p), X(c2.p) - X(c1.p));
    VP ret;
    if (inter(c1, c2) % 4 == 0) // 交わらないとき
        return ret;
    if (eq(a, 0.0)) {
        ret.emplace_back(P(c1.p + rot(P(c1.r, 0.0), t)));
    } else {
        P p1 = c1.p + rot(P(c1.r, 0.0), t + a);
        P p2 = c1.p + rot(P(c1.r, 0.0), t - a);
        ret.emplace_back(p1), ret.emplace_back(p2);
    }
    return ret;
}

VP cut(VP p, L l, bool border = true) { // 直線が多角形に切り取られる区間
    int n = sz(p);
    p.emplace_back(p[0]), p.emplace_back(p[1]);
    VP ret;
    rep(i, n) {
        if (!eq(dist(l, p[i]), 0) && !eq(dist(l, p[i + 1]), 0)) {
            S s(p[i], p[i + 1]);
            if (eq(dist(l, s), 0)) {
                auto res = crosspoint(l, s);
                ret.emplace_back(res[0]);
            }
        }
        if (eq(dist(l, p[i + 1]), 0)) {
            if ((eq(dist(l, p[i]), 0) || eq(dist(l, p[i + 2]), 0)) && !border)
                continue;
            S s(p[i], p[i + 2]);
            if (eq(dist(l, s), 0))
                ret.emplace_back(p[i + 1]);
        }
    }
    return ret;
}

VP rectangle(S s, R r) { // sを軸とした幅rの長方形
    P d = (s.a - s.b) * P(0, 1);
    d *= r / sqrt(norm(d));
    return VP{s.a + d, s.a - d, s.b - d, s.b + d};
}

L vertical_bisector(P p, P q) { // 垂直二等分線
    L l;
    l.a = (p + q) * 0.5;
    l.b = l.a + rot(q - p, pi * 0.5);
    return l;
}

L angle_bisector(P a,P b,P c){//角abcの二等分線(角bの２等分線)
  L l;
  l.a = b;
  R ang = atan2(Y(c-b),X(c-b)) - atan2(Y(a-b),X(a-b));//なす角
  ang/=2.0;
  l.b = l.a + rot(a-b,ang);
  return l;
}

C Apollonius(P p, P q, R a, R b) { // アポロニウスの円
    P p1 = (p * b + q * a) / (a + b), p2 = (-p * b + q * a) / (a - b);
    C c;
    c.p = (p1 + p2) * 0.5;
    c.r = abs(p1 - p2) * 0.5;
    return c;
}

R area(VP p) { // 多角形の面積
    R ret = 0.0;
    int n = sz(p);
    rep(i, n) ret += det(p[i], p[(i + 1) % n]);
    return abs(ret * 0.5);
}

int in_polygon(VP p, P q) { // IN:2, ON:1, OUT:0
    int n = sz(p);
    int ret = 0;
    rep(i, n) {
        P a = p[i] - q, b = p[(i + 1) % n] - q;
        if (eq(det(a, b), 0.0) && sgn(dot(a, b)) <= 0)
            return 1;
        if (Y(a) > Y(b))
            swap(a, b);
        if (sgn(Y(a)) <= 0 && sgn(Y(b)) == 1 && sgn(det(a, b)) == 1)
            ret ^= 2;
    }
    return ret;
}

VP tangent(C c, P p) { // 点 p を通る円 c の接線と c の接点
    return crosspoint(c, C(p, sqrt(norm(p - c.p) - c.r * c.r)));
}

vector<L> tangent(C c1, C c2) { // 共通接線
    vector<L> ret;
    if (c1.r < c2.r)
        swap(c1, c2);
    R r = abs(c2.p - c1.p);
    if (eq(r, 0.0))
        return ret;
    P u = (c2.p - c1.p) / r;
    P v = rot(u, pi * 0.5);
    for (R s : {1.0, -1.0}) {
        R h = (c1.r + c2.r * s) / r;
        if (eq(abs(h), 1.0)) {
            ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
        } else if (abs(h) < 1.0) {
            P uu = u * h, vv = v * sqrt(1.0 - h * h);
            ret.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s);
            ret.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s);
        }
    }
    return ret;
}

VP convex_hull(VP p) { // 凸包
    sort(all(p), cp_x);
    p.erase(unique(all(p)), end(p));
    int n = sz(p), k = 0;
    if (n == 1)
        return p;
    VP ch(2 * n);
    for (int i = 0; i < n; ch[k++] = p[i++]) {
        while (k >= 2 && sgn(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) <= 0)
            k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
        while (k >= t && sgn(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) <= 0)
            k--;
    }
    ch.resize(k - 1);
    return ch;
}

R closest_pair(VP p) { // 最近点対の距離
    if (sz(p) <= 1)
        return 1e18;
    sort(all(p), cp_x);
    VP memo(sz(p));

    function<R(int, int)> rec = [&](int l, int r) {
        if (r - l <= 1)
            return R(1e18);
        int m = (l + r) >> 1;
        R x = X(p[m]);
        R ret = min(rec(l, m), rec(m, r));
        inplace_merge(p.begin() + l, p.begin() + m, p.begin() + r, cp_y);
        int cnt = 0;
        reps(i, l, r) {
            if (abs(X(p[i]) - x) >= ret)
                continue;
            rep(j, cnt) {
                P d = p[i] - memo[cnt - j - 1];
                if (Y(d) >= ret)
                    break;
                chmin(ret, abs(d));
            }
            memo[cnt++] = p[i];
        }
        return ret;
    };

    return rec(0, sz(p));
}

R farthest_pair(VP p) {//最遠点対の距離
  VP ps = convex_hull(p);
  ll n = ps.size();
  if(n == 2){//凸包が潰れてる
    return dist(ps[0],ps[1]);
  }
  ll i = 0,j = 0;
  rep(k,n){//x軸方向に最も遠い点対を求める
    if(cp_x(ps[k],ps[i]))i = k;
    if(cp_x(ps[j],ps[k]))j = k;
  }
  R ret = 0;
  ll si = i,sj = j;
  while(i != sj || j != si){//180度反転しきるまで
    ret = max(ret,dist(ps[i],ps[j]));
    if(det(ps[(i+1)%n] - ps[i],ps[(j+1)%n]-ps[j]) < 0){
      i = (i + 1) % n;
    }else{
      j = (j + 1) % n;
    }
  }
  return ret;
}

// 原点, 点 a, 点 b とで囲まれる領域の面積 (三角形 ver と扇型 ver)
R calc_element(P a, P b, R cr,bool triangle){
  if(triangle)return det(a,b)/2;
  else{
    P tmp = b * (P(X(a),-Y(a)));
    R ang = atan2(Y(tmp),X(tmp));
    return cr * cr * ang/2;
  }
}

// 円 C と、三角形 ((0, 0), ia, ib) との共通部分の面積
R common_area(C c, P ia,P ib){
  P a = ia - c.p , b = ib - c.p;
  if(eq(abs(a-b),0))return 0;
  bool isin_a = (sgn(c.r - abs(a))>= 0);
  bool isin_b = (sgn(c.r - abs(b))>= 0);
  if(isin_a && isin_b)return calc_element(a,b,c.r,true);//aもbも円の中

  C oc(P(0,0),c.r);
  S seg(a,b);
  VP cr = crosspoint(oc,seg);
  if(cr.empty())return calc_element(a,b,c.r,false);
  P s = cr[0],t = cr.back();
  return calc_element(s,t,c.r,true) + calc_element(a,s,c.r,isin_a) + calc_element(t,b,c.r,isin_b);

}


R common_area(C c, VP vp){// 円cと多角形の共通部分の面積
  R ret = 0;
  ll n = vp.size();
  rep(i,n){
    ret += common_area(c,vp[i],vp[(i+1)%n]);
  }
  return ret;
}

R common_area(C p, C q) {// 円と円の共通部分の面積
    R d = abs(p.p - q.p);
    if (d >= p.r + q.r - EPS) return 0;
    else if (d <= abs(p.r - q.r) + EPS) return min(p.r, q.r) * min(p.r, q.r) * pi;
    R pcos = (p.r*p.r + d*d - q.r*q.r) / (p.r*d*2);
    R pang = acosl(pcos);
    R parea = p.r*p.r*pang - p.r*p.r*sin(pang*2)/2;
    R qcos = (q.r*q.r + d*d - p.r*p.r) / (q.r*d*2);
    R qang = acosl(qcos);
    R qarea = q.r*q.r*qang - q.r*q.r*sin(qang*2)/2;
    return parea + qarea;
}

vector<VP> divisions(vector<L> lf, R lim = 1e9) {
    vector<L> ls;
    each(l, lf) {
        bool ok = true;
        each(m, ls) {
            if (para(l, m) & inter(l, m.a)) {
                ok = false;
                break;
            }
        }
        if (ok)
            ls.emplace_back(l);
    }
    VP lc{P(-lim, -lim), P(lim, -lim), P(lim, lim), P(-lim, lim)};
    rep(i, 4) ls.emplace_back(lc[i], lc[(i + 1) % 4]);
    int m = sz(ls);
    VP ps;
    vector<vector<int>> lp(m);
    rep(i, m) {
        reps(j, i + 1, m) {
            each(p, crosspoint(ls[i], ls[j])) {
                if (max(abs(X(p)), abs(Y(p))) < lim + EPS) {
                    lp[i].emplace_back(sz(ps)), lp[j].emplace_back(sz(ps));
                    ps.emplace_back(p);
                }
            }
        }
    }
    int n = sz(ps);
    vector<int> id(n, -1), to;
    vector<R> rg;
    vector<vector<pair<R, int>>> li(n);
    rep(i, m) {
        sort(all(lp[i]), [&ps](int a, int b) { return cp_x(ps[a], ps[b]); });
        vector<int> q;
        rep(j, sz(lp[i])) {
            int me = id[lp[i][j]], st = j;
            auto np = ps[lp[i][j]];
            while (j + 1 < sz(lp[i])) {
                if (abs(ps[lp[i][j + 1]] - np) < EPS) {
                    j++;
                    if (id[lp[i][j]] != -1)
                        me = id[lp[i][j]];
                } else
                    break;
            }
            if (me == -1)
                me = lp[i][st];
            reps(k, st, j + 1) id[lp[i][k]] = me;
            q.emplace_back(me);
        }
        rep(i, sz(q) - 1) {
            P d = ps[q[i + 1]] - ps[q[i]];
            R s = atan2(Y(d), X(d)), t = atan2(-Y(d), -X(d));
            int x = q[i], y = q[i + 1];
            li[x].emplace_back(s, sz(to));
            li[x].emplace_back(s + pi * 2, sz(to));
            to.emplace_back(y), rg.emplace_back(t);
            li[y].emplace_back(t, sz(to));
            li[y].emplace_back(t + pi * 2, sz(to));
            to.emplace_back(x), rg.emplace_back(s);
        }
    }
    rep(i, n) sort(all(li[i]));
    vector<bool> u(sz(to), false);
    vector<VP> ret;
    rep(i, n) {
        each(l, li[i]) {
            int ns = l.second;
            if (u[ns])
                continue;
            VP nv;
            int no = ns;
            bool ok = true;
            while (1) {
                if (sz(nv) > 1) {
                    P x = nv[sz(nv) - 2], y = nv[sz(nv) - 1], z = ps[to[no]];
                    int c = ccw(x, y, z);
                    if (c == 1)
                        ok = false;
                    if (c != -1)
                        nv.pop_back();
                }
                nv.emplace_back(ps[to[no]]);
                u[no] = true;
                no = upper_bound(all(li[to[no]]), pair(rg[no] + EPS, -1))->second;
                if (no == ns)
                    break;
            }
            if (ok)
                ret.emplace_back(nv);
        }
    }
    return ret;
}

//ref https://github.com/drken1215/algorithm/blob/master/Geometry/arg_sort.cpp
//verify https://atcoder.jp/contests/abc139/submissions/me
//点列を偏角ソート
void arg_sort(VP &v){
  //原点=0,(pi,2pi] = -1  (0pi,pi] = 1
  auto sign = [&](const P &p){
    if(sgn(X(p)) == 0 && sgn(Y(p)) == 0){
      return 0;
    }else if(sgn(Y(p)) == -1 || (sgn(Y(p)) == 0 && sgn(X(p)) == 1)){
      return -1;
    }else{
      return 1;
    }
  };
  auto cp = [&](const P &p,const P &q){
    if(sign(p) != sign(q)){
      return sign(p) < sign(q);
    }else{//外積>0で判定
      //同じ向きにあるときは未定義、それぞれ決める
      return X(p) * Y(q) - Y(p) * X(q) > 0;
    }
  };
  sort(v.begin(),v.end(),cp);
}

using tpl5 = tuple<ll,ll,ll,ll,ll>;
void solve(ll n){
  LL(sx,sy,ex,ey);
  vector<tpl5> xyxyh(n);
  rep(i,n){
    LL(mx,my,Mx,My,h);
    xyxyh[i] ={mx,my,Mx,My,h};
  }
  S route(P(sx,sy),P(ex,ey));
  //一番近い点
  vector<R> vp(n,1<<30);
  rep(i,n){
    auto [mx,my,Mx,My,h] = xyxyh[i];
    VP nodes;
    nodes.emplace_back(mx,my);
    nodes.emplace_back(Mx,my);
    nodes.emplace_back(Mx,My);
    nodes.emplace_back(mx,My);
    if(in_polygon(nodes,P(sx,sy))> 0 or in_polygon(nodes,P(sx,sy)) > 0){
      cout << 0 << endl;
      return ;
    }
    rep(j,4){
      S l(nodes[j],nodes[(j+1)%4]);
      R d = dist(l,route);
      if(eq(d,0)){
        cout << 0 << endl;
        return ;
      }else{
        chmin(vp[i],d);
      }
    }
  }
  ld ng = 1001;//条件を満たさない値
  ld ok = 0;//条件を満たす値
  auto f = [&](ld x)->bool{
    //半径xが行けるか
    P cir(0,x);
    bool able = true;
    rep(i,n){
      P btm(vp[i],0);
      P top(vp[i],get<4>(xyxyh[i]));
      if(sgn(dist(S(top,btm),cir)-x) <0){
        able = false;
      }
    }
    return able;
  };
  rep(z,100){
    ld mid = (ok + ng)/2;
    if(f(mid)){
      ok = mid;
    }else{
      ng = mid;
    }
  }
  cout << std::fixed << std::setprecision(10) << ok << endl;
}

 
int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  while(true){
    LL(n);
    if(n == 0)break;
    solve(n);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3968
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
using ull=unsigned long long;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define loop(n) for (int tjh = 0; tjh < (int)(n); tjh++)
#define y0 ytmp0
signed main() {
  cin.tie(0)->sync_with_stdio(0);//NOLINT
  cout<<fixed<<setprecision(16);
  double sx,sy,ex,ey;
  double minx,miny,maxx,maxy,h;
  double dx,dy,d,res;
  double l,m1,m2,r,d1,d2;
  auto f=[&](double v)->double {
    double x=sx+v*dx;
    double y=sy+v*dy;
    double x0=minx<=x&&x<=maxx?0:min(abs(x-minx),abs(x-maxx));
    double y0=miny<=y&&y<=maxy?0:min(abs(y-miny),abs(y-maxy));
    return hypot(x0,y0);
  };
  for (int N;cin>>N,N;) {
    cin>>sx>>sy>>ex>>ey;
    dx=ex-sx;dy=ey-sy;
    res=1000;
    rep(i,N) {
      cin>>minx>>miny>>maxx>>maxy>>h;
      l=0,m1=1.0/3.0,m2=2.0/3.0,r=1;
      loop(100){
        d1=f(m1);d2=f(m2);
        if (d1<=d2)r=m2;
        else l=m1;
        m1=l+(r-l)/3.0;
        m2=m1+(r-l)/3.0;
      }
      d=f(m1);
      if (d<=h) {
        if (d<=res)res=d;
      }else {
        d=(h*h+d*d)/(h*2.0);
        if (d<=res)res=d;
      }
    }
    cout<<res<<"\n";
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3840
final_rank: 13

code_snippet: #include <bits/stdc++.h>

#define rep(i, N) for(ll i = 0; i < (ll)(N); ++i)
#define per(i, N) for(ll i = (ll)(N) - 1; i >= 0; --i)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define bit(n, k) (((n) >> (k)) & 1)
#define pcnt(n) (bitset<64>(n).count())
#define endl '\n'
#define fi first
#define se second
#define mkpr make_pair
#define mktpl make_tuple
#define eb emplace_back
template <class T> std::istream& operator>>(std::istream& is, std::vector<T>& V) {
    for (auto& it : V) is >> it;
    return is;
}
template <class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& V) {
    for (int i = 0 ; i < (int)V.size() ; i++) {
        os << V[i] << (i + 1 == (int)V.size() ? "" : " ");
    }
    return os;
}
using namespace std;

using ld = long double;


using namespace std;

namespace geometry{
    using Real = long double;
    using Point = complex<Real>;
    constexpr Real EPS = 1e-10;
    Real Pi = acos(-1);

    istream& operator>>(istream& is, Point& p){
        Real a, b; is >> a >> b;
        p = Point(a, b);
        return is;
    }
    ostream& operator<<(ostream& os, const Point& p){
        return os << real(p) << " " << imag(p);
    }
    bool equals(const Real& a, const Real& b){
        return fabs(a - b) < EPS;
    }
    Point operator*(const Point& p, const Real& d){
        return Point(real(p) * d, imag(p) * d);
    }
    Real cross(const Point& a, const Point& b){
        return real(a) * imag(b) - imag(a) * real(b);
    }
    Real dot(const Point& a, const Point& b){
        return real(a) * real(b) + imag(a) * imag(b);
    }
    int sign(const Real &x){
        return x >= EPS ? +1 : x <= -EPS ? -1 : 0;
    }
    int ccw(const Point &a, const Point &b, const Point &p){
        if(sign(cross(b - a, p - a)) == +1) return +1; // conter clockwise
        if(sign(cross(b - a, p - a)) == -1) return -1; // clockwise
        if(sign(dot(b - a, p - a)) == -1) return +2;   // p--a--b online back
        if(sign(dot(a - b, p - b)) == -1) return -2;   // a--b--p online front
        return 0;                                      // a--p--b on segment
    }
    Point projection(const Point& a, const Point& b, const Point& p){
        Real t = dot(p - a, a - b) / norm(a - b);
        return a + (a - b) * t;
    }
    Point reflection(const Point& a, const Point& b, const Point& p){
        return p + (projection(a, b, p) - p) * 2;
    }
}

using namespace std;

// Required geometry
namespace geometry{
    struct Line{
        Point a, b;
        Line() = default;
        Line(const Point& a, const Point& b) : a(a), b(b) {}
        Line(const Real& A, const Real& B, const Real& C){ // Ax+By=C
            if(equals(A, 0)){
                assert(!equals(B, 0));
                a = Point(0, C / B), b = Point(1, C / B);
            }
            else if(equals(B, 0)){
                a = Point(C / A, 0), b = Point(C / A, 1);
            }
            else{
                a = Point(0, C / B), b = Point(C / A, 0);
            }
        }
        friend istream& operator>>(istream& is, Line& l) {
            return is >> l.a >> l.b;
        }
        friend ostream& operator<<(ostream& os, Line& l) {
            return os << l.a << " to " << l.b;
        }
    };
    bool isOrthogonal(const Line& p, const Line& q){
        return equals(dot(p.b - p.a, q.b - q.a), 0.0);
    }
    bool isParallel(const Line& p, const Line& q){
        return equals(cross(p.b - p.a, q.b - q.a), 0.0);
    }
    Point cross_point(const Line &l, const Line &m){
        Real A = cross(l.b - l.a, m.b - m.a);
        Real B = cross(l.b - l.a, l.b - m.a);
        if(equals(abs(A), 0.0) && equals(abs(B), 0.0)) return m.a;
        assert(!equals(abs(A), 0.0));
        return m.a + (m.b - m.a) * B / A;
    }
}
using namespace std;

// Required geometry
// Required Line
namespace geometry{
    struct Segment : Line{
        Segment() = default;
        using Line::Line;
    };
    bool is_intersect_sp(const Segment &s, const Point &p){
        return ccw(s.a, s.b, p) == 0;
    }  
    bool is_intersect_ss(const Segment &s, const 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;
    }
    Real distance_sp(const Segment &s, const Point &p){
        Point r = projection(s.a, s.b, p);
        if(is_intersect_sp(s, r)) return abs(r - p);
        return min(abs(s.a - p), abs(s.b - p));
    }
    Real distance_ss(const Segment &a, const Segment &b){
        if(is_intersect_ss(a, b)) return 0;
        return min({distance_sp(a, b.a), distance_sp(a, b.b),
                    distance_sp(b, a.a), distance_sp(b, a.b)});
    }
}
using namespace geometry;

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    while(1){
        int N; cin >> N;
        if(N == 0) break;
        ld sx, sy, ex, ey; cin >> sx >> sy >> ex >> ey;
        vector<Segment> Segs(N * 4);
        vector<ld> H(N);

        bool covered = false;
        for(int i = 0; i < N; i++){
            ld mnx, mny, mxx, mxy; cin >> mnx >> mny >> mxx >> mxy;
            cin >> H[i];

            Point P1(mnx, mny), P2(mxx, mny), P3(mxx, mxy), P4(mnx, mxy);
            Segs[i * 4 + 0] = Segment(P1, P2);
            Segs[i * 4 + 1] = Segment(P2, P3);
            Segs[i * 4 + 2] = Segment(P3, P4);
            Segs[i * 4 + 3] = Segment(P4, P1);

            if(mnx <= sx && sx <= mxx && mny <= sy && sy <= mxy){
                covered = true;
            }
        }

        if(covered){
            cout << 0.00000 << endl;
            continue;
        }

        Segment stoe(Point(sx, sy), Point(ex, ey));

        //for (int i = 0 ; i < 4 * N ; i++) {
        //    cout << distance_ss(stoe, Segs[i]) << "! " << Segs[i] << endl;
        //}

        auto check{[&](ld mid) -> bool {
            bool flag = true;
            for(int i = 0; i < N * 4; i++){
                ld d = distance_ss(stoe, Segs[i]);
                ld h = H[i / 4];
                ld R = mid;

                if(h <= R){
                    ld Lval = (R - h) * (R - h) + d * d;
                    ld Rval = R * R;
                    if(!(Lval >= Rval)) flag = false;
                }
                else{
                    if(d <= R) flag = false;
                }
            }
            return flag;
        }};

        ld ok = 0, ng = 1001.0;
        for (int _ = 0 ; _ < 40 ; _++) {
            ld mid = (ok + ng) / 2;
            if(check(mid)) ok = mid;
            else ng = mid;
        }

        cout << fixed << setprecision(6);
        cout << ok << endl;
    }
}
accuracy: 1
time_ms: 220
memory_kb: 3676
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
using Real = long double;
const Real EPS = 1e-8, PI = acos(Real(-1.0));
int sign(const Real& r) {
    if(r <= -EPS) return -1;
    if(r >= +EPS) return +1;
    return 0;
}
bool eq(const Real& a, const Real& b) {
    return sign(a - b) == 0;
}
using Point = complex<Real>;
istream& operator>>(istream& is, Point& p) {
    Real a, b;
    is >> a >> b;
    p = Point(a, b);
    return is;
}
ostream& operator<<(ostream& os, const Point& p) {
    return os << p.real() << " " << p.imag();
}
Point operator*(const Point& p, const Real& d) {
    return Point(p.real() * d, p.imag() * d);
}
Point operator/(const Point& p, const Real& d) {
    return Point(p.real() / d, p.imag() / d);
}
Point rot(const Point& p, Real theta) {
    return p * Point(cos(theta), sin(theta));
}
Real dot(const Point& p1, const Point& p2) {
    return (conj(p1) * p2).real();
}
Real cross(const Point& p1, const Point& p2) {
    return (conj(p1) * p2).imag();
}
Real dist(const Point& p1, const Point& p2) {
    return abs(p1 - p2);
}
bool comp_x(const Point& p1, const Point& p2) {
    return eq(p1.real(), p2.real()) ? p1.imag() < p2.imag() : p1.real() < p2.real();
}
bool comp_y(const Point& p1, const Point& p2) {
    return eq(p1.imag(), p2.imag()) ? p1.real() < p2.real() : p1.imag() < p2.imag();
}
bool comp_arg(const Point& p1, const Point& p2) {
    return arg(p1) < arg(p2);
}
int ccw(const Point& a, Point b, Point c) {
    b -= a;
    c -= a;
    if(sign(cross(b, c)) == 1) return 1;
    if(sign(cross(b, c)) == -1) return -1;
    if(sign(dot(b, c)) == -1) return +2;
    if(norm(b) < norm(c)) return -2;
    return 0;
}
Real closest_pair(vector<Point> ps) {
    if((int)ps.size() <= 1) return 1e18;
    sort(ps.begin(), ps.end(), comp_x);
    vector<Point> memo(ps.size());
    auto func = [&](auto& func, int l, int r) -> Real {
        if(r - l <= 1) return 1e18;
        int m = (l + r) >> 1;
        Real x = ps[m].real();
        Real res = min(func(func, l, m), func(func, m, r));
        inplace_merge(ps.begin() + l, ps.begin() + m, ps.begin() + r, comp_y);
        int cnt = 0;
        for(int i = l; i < r; ++i) {
            if(abs(ps[i].real() - x) >= res) continue;
            for(int j = 0; j < cnt; ++j) {
                Point d = ps[i] - memo[cnt - j - 1];
                if(d.imag() >= res) break;
                res = min(res, abs(d));
            }
            memo[cnt++] = ps[i];
        }
        return res;
    };
    return func(func, 0, (int)ps.size());
}
struct Line {
    Point a, b;
    Line() = default;
    Line(const Point& a, const Point& b)
        : a(a), b(b) {}
};
using Segment = Line;
bool is_parallel(const Line& a, const Line& b) {
    return eq(cross(a.b - a.a, b.b - b.a), 0.0);
}
bool is_orthogonal(const Line& a, const Line& b) {
    return eq(dot(a.b - a.a, b.b - b.a), 0.0);
}
Point projection(const Line& l, const Point& p) {
    Real t = dot(p - l.a, l.b - l.a) / norm(l.b - l.a);
    return l.a + (l.b - l.a) * t;
}
Point reflection(const Line& l, const Point& p) {
    return p + (projection(l, p) - p) * 2.0;
}
bool is_intersect_lp(const Line& l, const Point& p) {
    return abs(ccw(l.a, l.b, p)) != 1;
}
bool is_intersect_sp(const Segment& s, const Point& p) {
    return ccw(s.a, s.b, p) == 0;
}
bool is_intersect_ll(const Line& l1, const Line& l2) {
    if(!eq(cross(l1.b - l1.a, l2.b - l2.a), 0.0)) return true;
    return eq(cross(l1.b - l1.a, l2.b - l1.a), 0.0);
}
bool is_intersect_ls(const Line& l, const Segment& s) {
    return sign(cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a)) <= 0;
}
bool is_intersect_sl(const Segment& s, const Line& l) {
    return is_intersect_ls(l, s);
}
bool is_intersect_ss(const Segment& s1, const Segment& s2) {
    if(ccw(s1.a, s1.b, s2.a) * ccw(s1.a, s1.b, s2.b) > 0) return false;
    return ccw(s2.a, s2.b, s1.a) * ccw(s2.a, s2.b, s1.b) <= 0;
}
vector<Point> intersection_ll(const Line& l1, const Line& l2) {
    vector<Point> res;
    if(!is_intersect_ll(l1, l2)) return res;
    Real a = cross(l1.b - l1.a, l2.b - l2.a);
    Real b = cross(l1.b - l1.a, l1.b - l2.a);
    if(eq(a, 0.0) and eq(b, 0.0)) {
        res.push_back(l2.a);
    } else {
        res.push_back(l2.a + (l2.b - l2.a) * b / a);
    }
    return res;
}
vector<Point> intersection_ss(const Segment& s1, const Segment& s2) {
    return is_intersect_ss(s1, s2) ? intersection_ll(Line(s1), Line(s2)) : vector<Point>();
}
Real dist_lp(const Line& l, const Point& p) {
    return abs(p - projection(l, p));
}
Real dist_sp(const Segment& s, const Point& p) {
    Point h = projection(s, p);
    if(is_intersect_sp(s, h)) return abs(h - p);
    return min(abs(s.a - p), abs(s.b - p));
}
Real dist_ll(const Line& l1, const Line& l2) {
    if(is_intersect_ll(l1, l2)) return 0.0;
    return dist_lp(l1, l2.a);
}
Real dist_ss(const Segment& s1, const Segment& s2) {
    if(is_intersect_ss(s1, s2)) return 0.0;
    return min({dist_sp(s1, s2.a), dist_sp(s1, s2.b), dist_sp(s2, s1.a), dist_sp(s2, s1.b)});
}
Real dist_ls(const Line& l, const Segment& s) {
    if(is_intersect_ls(l, s)) return 0.0;
    return min(dist_lp(l, s.a), dist_lp(l, s.b));
}
Real dist_sl(const Segment& s, const Line& l) {
    return dist_ls(l, s);
}
int main(void) {
    while(1) {
        int n;
        cin >> n;
        if(n == 0) break;
        Point s, t;
        cin >> s >> t;
        Segment route(s, t);
        vector<vector<Point>> b(n, vector<Point>(2));
        vector<int> h(n);
        rep(i, 0, n) {
            cin >> b[i][0] >> b[i][1] >> h[i];
        }
        long double lower = 0.0, upper = 1005.0;
        rep(_, 0, 100) {
            long double r = (lower + upper) / 2;
            bool flag = true;
            rep(i, 0, n) {
                if(b[i][0].real() <= s.real() and b[i][0].imag() <= s.imag() and s.real() <= b[i][1].real() and s.imag() <= b[i][1].imag()) {
                    flag = false;
                    continue;
                }
                rep(j, 0, 2) {
                    rep(k, 0, 2) {
                        Point p1 = b[i][j];
                        Point p2 = {b[i][k].real(), b[i][1 - k].imag()};
                        Segment seg(p1, p2);
                        long double d = dist_ss(route, seg);
                        if(r > h[i]) {
                            d *= d;
                            d += (r - h[i]) * (r - h[i]);
                            d = sqrtl(d);
                        }
                        if(d < r) {
                            flag = false;
                        }
                    }
                }
            }
            if(flag) {
                lower = r;
            } else {
                upper = r;
            }
        }
        cout << lower << '\n';
    }
}
accuracy: 1
time_ms: 820
memory_kb: 3624
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rng(i, l, r) for(int i = int(l); i < int(r); i++)
#define rep(i, n) rng(i, 0, n)
#define sz(v) int(v.size())
#define foa(s, v) for(auto& s : v)
#define all(v) v.begin(), v.end()
template <class T>
using V = vector<T>;

template <class T>
bool chmax(T& a, T b) {
	return a < b ? a = b, 1 : 0;
}
template <class T>
bool chmin(T& a, T b) {
	return a > b ? a = b, 1 : 0;
}

using R = long double;
constexpr R eps = 1e-8;
const R pi(acosl(-1));
using pt = complex<R>;

using seg = pair<pt, pt>;

R dot(pt a, pt b) { return a.real() * b.real() + a.imag() * b.imag(); }

R cross(pt a, pt b) { return a.real() * b.imag() - a.imag() * b.real(); }

pt projection(seg s, pt p) { return s.first + (s.first - s.second) * dot(p - s.first, s.first - s.second) / norm(s.first - s.second); }

R distance(pt a, pt b) { return abs(a - b); }

enum {
	counter_clockwize = 1,
	clockwize = -1,
	on_segment = 0,
	online_front = -2,
	online_back = 2,
};
int ccw(pt a, pt b, pt c) {
	b -= a;
	c -= a;
	R crs = cross(b, c);

	if(crs > eps) return counter_clockwize;
	if(crs < -eps) return clockwize;
	if(dot(b, c) < -eps) return online_back;
	if(norm(b) + eps < norm(c)) return online_front;
	return on_segment;
}

int intersect(seg s, pt p) { return ccw(s.first, s.second, p) == on_segment; }

R distance(pt p, seg s) {
	pt r = projection(s, p);
	return intersect(s, r) ? distance(r, p) : std::min(distance(s.first, p), distance(s.second, p));
}

R distance(seg s, pt p) { return distance(p, s); }

struct line {
	pt a, b;
	line(pt x, pt y) : a(x), b(y) {}
};

namespace std {
bool operator<(pt a, pt b) { return a.real() < b.real() || (a.real() == b.real() && a.imag() < b.imag()); }
}  // namespace std

int intersect(line ln, pt p) { return ccw(ln.a, ln.b, p) % 2 == 0; }

int intersect(seg s, seg t) {
	if(intersect(line(s.first, s.second), t.first) && intersect(line(s.first, s.second), t.second)) {
		if(std::max(std::min(s.first, s.second), std::min(t.first, t.second)) <
		   std::min(std::max(s.first, s.second), std::max(t.first, t.second)))
			return -1;
	}
	return int(ccw(s.first, s.second, t.first) * ccw(s.first, s.second, t.second) <= 0 &&
			   ccw(t.first, t.second, s.first) * ccw(t.first, t.second, s.second) <= 0);
}

R distance(seg s, seg b) {
	if(intersect(s, b)) return R(0);
	return std::min({
		distance(s, b.first),
		distance(s, b.second),
		distance(b, s.first),
		distance(b, s.second),
	});
}

pt input_pt() {
	R x, y;
	cin >> x >> y;
	return pt(x, y);
}

int n;
void solve() {
	pt s = input_pt();
	pt g = input_pt();
	seg ball_seg(s, g);

	R ans = 1e10;

	auto upd = [&](R val) { return chmin(ans, val); };

	auto rad_max = [&](R minx, R maxx, R miny, R maxy, R height) -> void {
		auto inside = [&](pt p) { return (minx <= p.real()) && p.real() <= maxx && miny <= p.imag() && p.imag() <= maxy; };
		if(inside(g) || inside(s)) {
			upd(0);
			return;
		}

		vector<pt> pts = {
			pt(minx, maxy),
			pt(maxx, maxy),
			pt(maxx, miny),
			pt(minx, miny),
		};

		rep(i, sz(pts)) {
			pt p = pts[i];
			int j = i + 1;
			if(j == sz(pts)) j = 0;
			pt r = pts[j];

			R d = distance(seg(p, r), ball_seg);

			if(height >= d)
				upd(d);
			else {
				R radius = powl(height, 2) + powl(d, 2);
				radius /= 2 * height;
				upd(radius);
			}
		}
		return;
	};

	rep(j, n) {
		R minx, miny, maxx, maxy;
		R h;
		cin >> minx >> miny >> maxx >> maxy >> h;
		rad_max(minx, maxx, miny, maxy, h);
	}

	cout << ans << endl;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(15);
	// srand((unsigned)time(NULL));
	while(cin >> n && n) solve();
}
accuracy: 1
time_ms: 10
memory_kb: 3596
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;


//---------------------------- テンプレゾーン --------------------------------//

const long long INF = 1000000010;
const long long INFL = 1000000000000000010;
const double MYPI = 3.14159265358979;
const double epsilon = 1e-10;



typedef long long ll;
typedef __int128_t lll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pl;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<vvd> vvvd;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<vvb> vvvb;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<vvc> vvvc;
typedef vector<pl> vp;
typedef tuple<ll, ll, ll> tt;
typedef vector<tuple<ll, ll, ll>> vt;
typedef vector<string> vs;

#define overload3(a, b, c, d, ...) d
#define overload4(a, b, c, d, e, ...) e
#define overload5(a, b, c, d, e, f, ...) f
#define overload6(a, b, c, d, e, f, g, ...) g
#define pb push_back
#define eb emplace_back
#define MP make_pair
#define REP_0(n) for(int _=0;_<(n);_++)
#define REP_1(i, n) for(int i=0;i<(n);i++)
#define REP_2(i, l, r) for(int i=(l);i<(r);i++)
#define REP_3(i, l, r, d) for(int i=(l);i<(r);i+=(d))
#define REP(...) overload4(__VA_ARGS__, REP_3, REP_2, REP_1, REP_0)(__VA_ARGS__)
#define REPP(i, n) for(int i=1;i<=(n);i++)
#define RREP_1(i, n) for(int i=(n)-1;i>=0;i--)
#define RREP_2(i, l, r) for(int i=(r)-1;i>=(l);i--)
#define RREP_3(i, l, r, d) for(int i=(r)-1;i>=(l);i-=(d))
#define RREP(...) overload4(__VA_ARGS__, RREP_3, RREP_2, RREP_1)(__VA_ARGS__)
#define RREPP(i, n) for(int i=(n);i>0;i--)
#define EACH1(e, a) for(auto &e : a)
#define EACH2(x, y, a) for(auto &[x, y] : a)
#define EACH3(x, y, z, a) for(auto &[x, y, z] : a)
#define EACH(...) overload4(__VA_ARGS__, EACH3, EACH2, EACH1)(__VA_ARGS__)
#define ALL1(x) begin(x), end(x)
#define ALL2(x, a) begin(x), begin(x) + a
#define ALL3(x, a, b) begin(x) + a, begin(x) + b
#define ALL(...) overload3(__VA_ARGS__, ALL3, ALL2, ALL1)(__VA_ARGS__)
#define RALL1(i) (i).rbegin(), (i).rend()
#define RALL2(i, a) (i).rend() - a, (i).rend()
#define RALL3(i, a, b) (i).rend() - b, (i).rend() - a
#define RALL(...) overload3(__VA_ARGS__, RALL3, RALL2, RALL1)(__VA_ARGS__)
#define sz(x) (long long)x.size()
#define LB(a, x) (lower_bound(a.begin(), a.end(), x) - a.begin())
#define UB(a, x) (upper_bound(a.begin(), a.end(), x) - a.begin())
#define FLG(x, i) (((x)>>(i)) & 1)
#define CNTBIT(x) __builtin_popcountll(x)
#define TOPBIT(t) (t == 0 ? -1 : 63 - __builtin_clzll(t))
#define BTMBIT(t) (t == 0 ? 64 : __builtin_ctzll(t))
#define IN(x, a, b) ((a) <= (x) && (x) < (b))
#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHAR(...) char __VA_ARGS__; input(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) long double __VA_ARGS__; input(__VA_ARGS__)
#define VL1(a, n) vector<long long> a(n); for(int I=0;I<(n);I++)cin >> a[I]
#define VL2(a, b, n) vector<long long> a(n), b(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I]
#define VL3(a, b, c, n) vector<long long> a(n), b(n), c(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I]
#define VL4(a, b, c, d, n) vector<long long> a(n), b(n), c(n), d(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I]
#define VL5(a, b, c, d, e, n) vector<long long> a(n), b(n), c(n), d(n), e(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I] >> e[I]
#define VL(...) overload6(__VA_ARGS__, VL5, VL4, VL3, VL2, VL1)(__VA_ARGS__)
#define VD1(a, n) vector<double> a(n); for(int I=0;I<(n);I++)cin >> a[I]
#define VD2(a, b, n) vector<double> a(n), b(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I]
#define VD3(a, b, c, n) vector<double> a(n), b(n), c(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I]
#define VD4(a, b, c, d, n) vector<double> a(n), b(n), c(n), d(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I]
#define VD5(a, b, c, d, e, n) vector<double> a(n), b(n), c(n), d(n), e(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I] >> e[I]
#define VD(...) overload6(__VA_ARGS__, VD5, VD4, VD3, VD2, VD1)(__VA_ARGS__)
#define VVL(a, n, m) vector<vector<long long> > a(n, vector<long long>(m)); for(int I=0;I<(n);I++)for(int J=0;J<(m);J++)cin >> a[I][J]
#define VVC(s, n, m) vector<vector<char> > s(n, vector<char>(m)); for(int I=0;I<(n);I++)for(int J=0;J<(m);J++)cin >> s[I][J]
#define VS(s, n) vector<string> s(n); for(int I=0;I<(n);I++)cin >> s[I];

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a){
  return os << a.first << " " << a.second;
}
template <typename T1, typename T2, typename T3>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3> &a){
  return os << get<0>(a) << " " << get<1>(a) << " " << get<2>(a);
}

struct IoSetup{
  IoSetup() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(15);
  }
} iosetup;

#ifdef LOCAL
#  include <debug_print.hpp>
#  define debug(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#else
#  define debug(...) (static_cast<void>(0))
#endif

template <typename T>
using minheap = priority_queue<T, vector<T>, greater<T>>;
 
template <typename T>
using maxheap = priority_queue<T>;

template<class... T>
void input(T&... a){
  (cin >> ... >> a);
}

template <typename... T>
constexpr auto min(T... a){
  return min(initializer_list<common_type_t<T...>>{a...});
}
template <typename... T>
constexpr auto max(T... a){
  return max(initializer_list<common_type_t<T...>>{a...});
}

template <typename T1, typename T2>
bool chmax(T1 &x, const T2 &y){
  return x < y ? x = y, true : false;
}
template <typename T1, typename T2>
bool chmin(T1 &x, const T2 &y){
  return x > y ? x = y, true : false;
}

void OUT(){cout << "\n";}

template <typename T, typename... Ts>
void OUT(const T &a, const Ts&... b){
  cout << a;
  (cout << ... << (cout << " ", b));
  cout << "\n";
}

template <typename T>
void OUT(const vector<T> &res){
  for(int i=0;i<(int)res.size();i++){
    cout << res[i] << " ";
  }
  cout << "\n";
}

template <typename T>
void OUT_(const T &a){
  cout << a << " ";
}

template <typename T>
void OUTN(const vector<T> &res, long long margin = 0){
  for(int i=0;i<(int)res.size();i++){
    cout << res[i] + (T)margin << "\n";
  }
}

template <typename T>
void OUTN_(const vector<T> &res, long long margin = 0){
  for(int i=0;i<(int)res.size();i++){
    cout << res[i] + (T)margin << " ";
  }
  cout << "\n";
}

template <typename T>
void OUTNN(const vector<vector<T>> &res, long long margin = 0){
  for(int i=0;i<(int)res.size();i++){
    for(int j=0;j<(int)res[i].size();j++){
      cout << res[i][j] + (T)margin << " ";
    }
    cout << "\n";
  }
}

void YES(const bool &res = true, bool Capital = false){
  if(Capital) cout << (res ? "YES" : "NO") << "\n";
  else cout << (res ? "Yes" : "No") << "\n";
}

void FIRST(const bool &res = true, bool Capital = false){
  if(Capital) cout << (res ? "FIRST" : "SECOND") << "\n";
  else cout << (res ? "First" : "Second") << "\n";
}

template <typename T>
void DEC(vector<T> &a, long long dif = 1){
  for(auto &x : a)x -= (T)dif;
}
template <typename T>
void DEC(vector<T> &a, vector<T> &b, long long dif = 1){
  for(auto &x : a)x -= (T)dif;
  for(auto &x : b)x -= (T)dif;
}
template <typename T>
void DEC(vector<vector<T>> &a, long long dif = 1){
  for(auto &v : a)for(auto &x : v)x -= (T)dif;
}

template <typename T>
void INC(vector<T> &a, long long dif = 1){
  for(auto &x : a)x += (T)dif;
}
template <typename T>
void INC(vector<T> &a, vector<T> &b, long long dif = 1){
  for(auto &x : a)x += (T)dif;
  for(auto &x : b)x += (T)dif;
}
template <typename T>
void INC(vector<vector<T>> &a, long long dif = 1){
  for(auto &v : a)for(auto &x : v)x += (T)dif;
}

template <typename T>
T SUM(const vector<T> &a){
  return accumulate(a.begin(), a.end(), (T)0);
}
template <typename T>
T SUM(const vector<vector<T>> &a){
  T ret = 0;
  for(int i=0;i<(int)a.size();i++)ret += accumulate(a[i].begin(), a[i].end(), (T)0);
  return ret;
}

template <typename T>
T MAX(const vector<T> &a){
  return *max_element(a.begin(), a.end());
}
template <typename T>
T MAX(const vector<vector<T>> &a){
  T ret = -INFL;
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(ret < a[i][j])ret = a[i][j];
  return ret;
}

template <typename T>
int ARGMAX(const vector<T> &a){
  int ret = 0;
  for(int i=1;i<(int)a.size();i++)if(a[ret] < a[i])ret = i;
  return ret;
}
template <typename T>
pair<int, int> ARGMAX(const vector<vector<T>> &a){
  pair<int, int> ret = {0, 0};
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(a[ret.first][ret.second] < a[i][j])ret = {i, j};
  return ret;
}

template <typename T>
T MIN(const vector<T> &a){
  return *min_element(a.begin(), a.end());
}
template <typename T>
T MIN(const vector<vector<T>> &a){
  T ret = INFL;
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(ret > a[i][j])ret = a[i][j];
  return ret;
}

template <typename T>
int ARGMIN(const vector<T> &a){
  int ret = 0;
  for(int i=1;i<(int)a.size();i++)if(a[ret] > a[i])ret = i;
  return ret;
}
template <typename T>
pair<int, int> ARGMIN(const vector<vector<T>> &a){
  pair<int, int> ret = {0, 0};
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(a[ret.first][ret.second] > a[i][j])ret = {i, j};
  return ret;
}

template <typename T>
int SIGN(const T &a){
  if(abs(a) < epsilon)return 0;
  return a > 0 ? 1 : -1;
}

template <typename T>
vector<T> UNIQ(vector<T> a){
  sort(a.begin(), a.end());
  a.erase(unique(a.begin(), a.end()), a.end());
  return a;
}

template <typename T>
vector<T> sorted(vector<T> a, bool Descending = false){
  sort(a.begin(), a.end());
  if(Descending)reverse(a.begin(), a.end());
  return a;
}

template <typename T>
vector<T> cumsum(const vector<T> &a){
  int n = (int)a.size();
  vector<T> ret(n+1, (T)0);
  for(int i=0;i<n;i++)ret[i+1] = ret[i] + a[i];
  return ret;
}
template <typename T>
vector<vector<T>> cumsum(const vector<vector<T>> &a){
  int n = (int)a.size(), m = (int)a[0].size();
  vector<vector<T>> ret(n+1, vector<T>(m+1, (T)0));
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)ret[i+1][j+1] = ret[i+1][j] + a[i][j];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)ret[i+1][j+1] += ret[i][j+1];
  return ret;
}
template <typename T>
vector<vector<vector<T>>> cumsum(const vector<vector<vector<T>>> &a){
  int n = (int)a.size(), m = (int)a[0].size(), l = (int)a[0][0].size();
  vector<vector<vector<T>>> ret(n+1, vector<vector<T>>(m+1, vector<T>(l+1, (T)0)));
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)ret[i+1][j+1][k+1] = ret[i+1][j+1][k] + a[i][j][k];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)ret[i+1][j+1][k+1] += ret[i][j+1][k+1];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)ret[i+1][j+1][k+1] += ret[i+1][j][k+1];
  return ret;
}
template <typename T>
void cumsum_inplace(vector<T> &a){
  int n = (int)a.size();
  for(int i=0;i<n-1;i++)a[i+1] += a[i];
}
template <typename T>
void cumsum_inplace(vector<vector<T>> &a){
  int n = (int)a.size(), m = (int)a[0].size();
  for(int i=0;i<n-1;i++)for(int j=0;j<m;j++)a[i+1][j] += a[i][j];
  for(int i=0;i<n;i++)for(int j=0;j<m-1;j++)a[i][j+1] += a[i][j];
}
template <typename T>
void cumsum_inplace(vector<vector<vector<T>>> &a){
  int n = (int)a.size(), m = (int)a[0].size(), l = (int)a[0][0].size();
  for(int i=0;i<n-1;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)a[i+1][j][k] += a[i][j][k];
  for(int i=0;i<n;i++)for(int j=0;j<m-1;j++)for(int k=0;k<l;k++)a[i][j+1][k] += a[i][j][k];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l-1;k++)a[i][j][k+1] += a[i][j][k];
}

template< typename T = long long >
struct Edge {
  long long from, to;
  T cost;
  long long idx;
  Edge() = default;
  Edge(long long from, long long to, T cost = 1, long long idx = -1) : from(from), to(to), cost(cost), idx(idx) {}
  operator int() const { return to; }
};

template< typename T = long long >
struct Graph {
  vector< vector< Edge< T > > > g, ginv;
  vector<int> indeg, outdeg;
  long long es;
  Graph() = default;
  explicit Graph(long long n) : g(n), ginv(n), indeg(n, 0), outdeg(n, 0), es(0) {}
  size_t size() const {
    return g.size();
  }
  void add_directed_edge(long long from, long long to, T cost = 1) {
    indeg[to]++, outdeg[from]++;
    //ginv[to].emplace_back(to, from, cost, es);
    g[from].emplace_back(from, to, cost, es++);
  }
  void add_edge(long long from, long long to, T cost = 1) {
    indeg[from]++, outdeg[from]++, indeg[to]++, outdeg[to]++;
    g[from].emplace_back(from, to, cost, es);
    g[to].emplace_back(to, from, cost, es++);
  }
  inline vector< Edge< T > > &operator[](const int &k) {
    return g[k];
  }
  inline const vector< Edge< T > > &operator[](const int &k) const {
    return g[k];
  }
};

template< typename T = long long >
using Edges = vector< Edge< T > >;

template< typename T >
struct Enumeration {
private:
  static vector< T > _fact, _finv, _inv;
  inline static void expand(size_t sz) {
    if(_fact.size() < sz + 1) {
      int pre_sz = max(1, (int) _fact.size());
      _fact.resize(sz + 1, T(1));
      _finv.resize(sz + 1, T(1));
      _inv.resize(sz + 1, T(1));
      for(int i = pre_sz; i <= (int) sz; i++) {
        _fact[i] = _fact[i - 1] * T(i);
      }
      _finv[sz] = T(1) / _fact[sz];
      for(int i = (int) sz - 1; i >= pre_sz; i--) {
        _finv[i] = _finv[i + 1] * T(i + 1);
      }
      for(int i = pre_sz; i <= (int) sz; i++) {
        _inv[i] = _finv[i] * _fact[i - 1];
      }
    }
  }
public:
  explicit Enumeration(size_t sz = 0) { expand(sz); }
  static inline T fact(int k) {
    expand(k);
    return _fact[k];
  }
  static inline T finv(int k) {
    expand(k);
    return _finv[k];
  }
  static inline T inv(int k) {
    expand(k);
    return _inv[k];
  }
  static T P(int n, int r) {
    if(r < 0 || n < r) return 0;
    return fact(n) * finv(n - r);
  }
  static T C(int p, int q) {
    if(q < 0 || p < q) return 0;
    return fact(p) * finv(q) * finv(p - q);
  }
};

template< typename T >
vector< T > Enumeration< T >::_fact = vector< T >();
template< typename T >
vector< T > Enumeration< T >::_finv = vector< T >();
template< typename T >
vector< T > Enumeration< T >::_inv = vector< T >();

template <typename T>
T norm1(const pair<T, T> &a, const pair<T, T> &b = {(T)0, (T)0}){
  return abs(a.first - b.first) + abs(a.second - b.second);
}
template <typename T>
T norm22(const pair<T, T> &a, const pair<T, T> &b = {(T)0, (T)0}){
  return (a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second);
}
template <typename T>
double norm2(const pair<T, T> &a, const pair<T, T> &b = {(T)0, (T)0}){
  return sqrt(norm22(a, b));
}

long long powll(long long a, long long n){
  assert(n >= 0);
  if(n == 0)return 1;
  long long ret = 1;
  while(n){
    if(n & 1)ret *= a;
    a *= a;
    n >>= 1;
  }
  return ret;
}

vector<long long> str_to_vl(const string &s){
  vector<long long> ret(s.size());
  if(s.size() == 0)return ret;
  if(0 <= s[0]-'A' && s[0]-'A' < 26) for(int i=0;i<(int)s.size();i++) ret[i] = s[i] - 'A';
  else if(0 <= s[0]-'a' && s[0]-'a' < 26) for(int i=0;i<(int)s.size();i++) ret[i] = s[i] - 'a';
  else if(0 <= s[0]-'0' && s[0]-'0' < 10) for(int i=0;i<(int)s.size();i++) ret[i] = s[i] - '0';
  else assert(0);
  return ret;
}

// 0-indexed
long long TOPDIGIT(long long x){
  assert(x >= 0);
  long long ret = 0;
  while(x >= 10){x /= 10; ret++;}
  return ret;
}

template <typename T>
vector<pair<T, int>> sorti(const vector<T> &a){
  vector<pair<T, int>> ret(a.size());
  for(int i=0;i<(int)a.size();i++){
    ret[i] = {a[i], i};
  }
  sort(ret.begin(), ret.end());
  return ret;
}
template <typename T1, typename T2>
vector<tuple<T1, T2, int>> sorti(const vector<T1> &a, const vector<T2> &b){
  assert(a.size() == b.size());
  vector<tuple<T1, T2, int>> ret(a.size());
  for(int i=0;i<(int)a.size();i++){
    ret[i] = {a[i], b[i], i};
  }
  sort(ret.begin(), ret.end());
  return ret;
}
template <typename T1, typename T2, typename T3>
vector<tuple<T1, T2, T3, int>> sorti(const vector<T1> &a, const vector<T2> &b, const vector<T3> &c){
  assert(a.size() == b.size() && a.size() == c.size());
  vector<tuple<T1, T2, T3, int>> ret(a.size());
  for(int i=0;i<(int)a.size();i++){
    ret[i] = {a[i], b[i], c[i], i};
  }
  sort(ret.begin(), ret.end());
  return ret;
}

// 高々小数第 k 位までの実数を 10^k 倍して整数化
ll decimal_to_ll(const string &s, int k){
  int n = s.size();
  for(int i=0;i<n;i++){
    if(s[i] == '.'){
      ll ret = stoll(s.substr(0, i) + s.substr(i + 1));
      for(int j=0;j<k-(n-1-i);j++)ret *= 10;
      return ret;
    }
  }
  ll ret = stoll(s);
  for(int i=0;i<k;i++)ret *= 10;
  return ret;
}

long long max(const int &a, const long long &b){return max((long long)a, b);}
long long min(const int &a, const long long &b){return min((long long)a, b);}

const vector<long long> dy = {1, 0, -1, 0, 1, -1, -1, 1};
const vector<long long> dx = {0, 1, 0, -1, 1, 1, -1, -1};

random_device seed_gen;
mt19937_64 rnd;

// [low, high] の範囲の値を持つ長さ len のランダムベクトルを生成
vector<long long> random_vl(int len, long long low, long long high){
  uniform_int_distribution<long long> dist(low, high);
  vector<long long> ret(len);
  for(int i=0;i<len;i++)ret[i] = dist(rnd);
  return ret;
};

vector<long long> random_permutation(int len){
  uniform_int_distribution<int> dist(1, len);
  vector<long long> ret(len);
  set<int> se;
  for(int i=0;i<len;i++){
    int tmp = dist(rnd);
    while(se.count(tmp))tmp = dist(rnd);
    ret[i] = tmp;
    se.insert(ret[i]);
  }
  return ret;
};

//--------------------------- テンプレゾーン終 -------------------------------//

//----------------------------- コピペゾーン ---------------------------------//

/*
memo

abs(Point): Point の絶対値
norm(Point): Point の絶対値の二乗
EXTERNAL: 0, ON: 1, INTERNAL: 2
ピックの定理: 多角形の面積を S, 辺上の格子点数を b, 内部の格子点数を i とすると、S = i +
b/2 - 1 が成立
*/

using Real = ld;
using Point = complex<Real>;
const Real EPS = 1e-10, PI = acos(-1);

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C
enum { EXTERNAL, ON, INTERNAL };

inline bool eq(Real a, Real b) { return fabs(b - a) < EPS; }

Point operator*(const Point &p, const Real &d) {
    return Point(real(p) * d, imag(p) * d);
}

// rotate point p counterclockwise by theta rad
Point rotate(Real theta, const Point &p) {
    return Point(cos(theta) * p.real() - sin(theta) * p.imag(),
                 sin(theta) * p.real() + cos(theta) * p.imag());
}

Real radian_to_degree(Real r) { return (r * 180.0 / PI); }

Real degree_to_radian(Real d) { return (d * PI / 180.0); }

// 修正済み
// smaller angle of the a-b-c
Real get_angle(const Point &a, const Point &b, const Point &c) {
    const Point v(a - b), w(c - b);
    Real alpha = atan2(v.imag(), v.real()), beta = atan2(w.imag(), w.real());
    if (alpha > beta) swap(alpha, beta);
    Real theta = (beta - alpha);
    return min(theta, 2 * acos(-1) - theta);
}

namespace std {
bool operator<(const Point &a, const Point &b) {
    return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
}
}  // namespace std

struct Line {
    Point a, b;

    Line() = default;

    Line(Point a, Point b) : a(a), b(b) {}

    Line(Real A, Real B, Real C)  // Ax + By = C
    {
        if (eq(A, 0))
            a = Point(0, C / B), b = Point(1, C / B);
        else if (eq(B, 0))
            a = Point(C / A, 0), b = Point(C / A, 1);
        else
            a = Point(0, C / B), b = Point(C / A, 0);
    }

    friend ostream &operator<<(ostream &os, Line &p) {
        return os << p.a << " to " << p.b;
    }

    friend istream &operator>>(istream &is, Line &a) { return is >> a.a >> a.b; }
};

struct Segment : Line {
    Segment() = default;

    Segment(Point a, Point b) : Line(a, b) {}
};

struct Circle {
    Point p;
    Real r;

    Circle() = default;

    Circle(Point p, Real r) : p(p), r(r) {}
    // 追加 線分 p-q を直径とする円
    Circle(Point p, Point q) : p((p + q) / 2.0L), r(abs(p - (p + q) / 2.0L)) {}
};

using Points = vector<Point>;
using Polygon = vector<Point>;
using Segments = vector<Segment>;
using Lines = vector<Line>;
using Circles = vector<Circle>;

Real cross(const Point &a, const Point &b) {
    return real(a) * imag(b) - imag(a) * real(b);
}

Real dot(const Point &a, const Point &b) {
    return real(a) * real(b) + imag(a) * imag(b);
}

// 線分 a-b に対して c がどの位置にいるか
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
int ccw(const Point &a, Point b, Point c) {
    b = b - a, c = c - a;
    if (cross(b, c) > EPS) return +1;   // "COUNTER_CLOCKWISE"
    if (cross(b, c) < -EPS) return -1;  // "CLOCKWISE"
    if (dot(b, c) < 0) return +2;       // "ONLINE_BACK" c-a-b
    if (norm(b) < norm(c)) return -2;   // "ONLINE_FRONT" a-b-c
    return 0;                           // "ON_SEGMENT" a-c-b
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool parallel(const Line &a, const Line &b) {
    return eq(cross(a.b - a.a, b.b - b.a), 0.0);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool orthogonal(const Line &a, const Line &b) {
    return eq(dot(a.a - a.b, b.a - b.b), 0.0);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
Point projection(const Line &l, const Point &p) {
    double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}

Point projection(const Segment &l, const Point &p) {
    double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
Point reflection(const Line &l, const Point &p) {
    return p + (projection(l, p) - p) * 2.0;
}

bool intersect(const Line &l, const Point &p) { return abs(ccw(l.a, l.b, p)) != 1; }

bool intersect(const Line &l, const Line &m) {
    return abs(cross(l.b - l.a, m.b - m.a)) > EPS ||
           abs(cross(l.b - l.a, m.b - l.a)) < EPS;
}

bool intersect(const Segment &s, const Point &p) { return ccw(s.a, s.b, p) == 0; }

bool intersect(const Line &l, const Segment &s) {
    return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}

Real distance(const Line &l, const Point &p);

bool intersect(const Circle &c, const Line &l) { return distance(l, c.p) <= c.r + EPS; }

bool intersect(const Circle &c, const Point &p) {
    return abs(abs(p - c.p) - c.r) < EPS;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B
bool intersect(const Segment &s, const 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;
}

int intersect(const Circle &c, const Segment &l) {
    if (norm(projection(l, c.p) - c.p) - c.r * c.r > EPS) return 0;
    auto d1 = abs(c.p - l.a), d2 = abs(c.p - l.b);
    if (d1 < c.r + EPS && d2 < c.r + EPS) return 0;
    if (d1 < c.r - EPS && d2 > c.r + EPS || d1 > c.r + EPS && d2 < c.r - EPS) return 1;
    const Point h = projection(l, c.p);
    if (dot(l.a - h, l.b - h) < 0) return 2;
    return 0;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A&lang=jp
int intersect(Circle c1, Circle c2) {
    if (c1.r < c2.r) swap(c1, c2);
    Real d = abs(c1.p - c2.p);
    if (c1.r + c2.r < d) return 4;
    if (eq(c1.r + c2.r, d)) return 3;
    if (c1.r - c2.r < d) return 2;
    if (eq(c1.r - c2.r, d)) return 1;
    return 0;
}

Real distance(const Point &a, const Point &b) { return abs(a - b); }

Real distance(const Line &l, const Point &p) { return abs(p - projection(l, p)); }

Real distance(const Line &l, const Line &m) {
    return intersect(l, m) ? 0 : distance(l, m.a);
}

Real distance(const Segment &s, const Point &p) {
    Point r = projection(s, p);
    if (intersect(s, r)) return abs(r - p);
    return min(abs(s.a - p), abs(s.b - p));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
Real distance(const Segment &a, const Segment &b) {
    if (intersect(a, b)) return 0;
    return min(
        {distance(a, b.a), distance(a, b.b), distance(b, a.a), distance(b, a.b)});
}

Real distance(const Line &l, const Segment &s) {
    if (intersect(l, s)) return 0;
    return min(distance(l, s.a), distance(l, s.b));
}

// Verified at https://atcoder.jp/contests/abc151/tasks/abc151_f
Point crosspoint(const Line &l, const Line &m) {
    Real A = cross(l.b - l.a, m.b - m.a);
    Real B = cross(l.b - l.a, l.b - m.a);
    if (eq(abs(A), 0.0) && eq(abs(B), 0.0)) return m.a;
    return m.a + (m.b - m.a) * B / A;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C
Point crosspoint(const Segment &l, const Segment &m) {
    return crosspoint(Line(l), Line(m));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D
pair<Point, Point> crosspoint(const Circle &c, const Line l) {
    Point pr = projection(l, c.p);
    Point e = (l.b - l.a) / abs(l.b - l.a);
    if (eq(distance(l, c.p), c.r)) return {pr, pr};
    double base = sqrt(c.r * c.r - norm(pr - c.p));
    return {pr - e * base, pr + e * base};
}

pair<Point, Point> crosspoint(const Circle &c, const Segment &l) {
    Line aa = Line(l.a, l.b);
    if (intersect(c, l) == 2) return crosspoint(c, aa);
    auto ret = crosspoint(c, aa);
    if (dot(l.a - ret.first, l.b - ret.first) < 0)
        ret.second = ret.first;
    else
        ret.first = ret.second;
    return ret;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E
pair<Point, Point> crosspoint(const Circle &c1, const Circle &c2) {
    Real d = abs(c1.p - c2.p);
    Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real());
    Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r);
    Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r);
    return {p1, p2};
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F
// tangent of circle c through point p
pair<Point, Point> tangent(const Circle &c1, const Point &p2) {
    return crosspoint(c1, Circle(p2, sqrt(norm(c1.p - p2) - c1.r * c1.r)));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_G
// common tangent of circles c1 and c2
Lines tangent(Circle c1, Circle c2) {
    Lines ret;
    if (c1.r < c2.r) swap(c1, c2);
    Real g = norm(c1.p - c2.p);
    if (eq(g, 0)) return ret;
    Point u = (c2.p - c1.p) / sqrt(g);
    Point v = rotate(PI * 0.5, u);
    for (int s : {-1, 1}) {
        Real h = (c1.r + s * c2.r) / sqrt(g);
        if (eq(1 - h * h, 0)) {
            ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
        } else if (1 - h * h > 0) {
            Point uu = u * h, vv = v * sqrt(1 - h * h);
            ret.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s);
            ret.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s);
        }
    }
    return ret;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B
// Verified at https://atcoder.jp/contests/typical90/tasks/typical90_ao
bool is_convex(const Polygon &p) {
    int n = (int)p.size();
    for (int i = 0; i < n; i++) {
        if (ccw(p[(i + n - 1) % n], p[i], p[(i + 1) % n]) == -1) return false;
    }
    return true;
}



//---------------------------- コピペゾーン終 --------------------------------//

/*
#include <atcoder/all>
using namespace atcoder;
using mint1 = modint998244353;
*/
#define int long long

void solve(){
  vd ans;
  while(1){
    INT(n);
    if(n == 0)break;
    INT(sx, sy, ex, ey);
    VVL(mxy, n, 5);
    bool zero = false;
    Segment seg(Point(sx, sy), Point(ex, ey));
    REP(i, n){
      if(intersect(seg, Segment(Point(mxy[i][0], mxy[i][1]), Point(mxy[i][2], mxy[i][3]))))zero = true;
      if(intersect(seg, Segment(Point(mxy[i][0], mxy[i][3]), Point(mxy[i][2], mxy[i][1]))))zero = true;
    }
    if(zero){
      ans.pb(0);
      continue;
    }
    auto is_ok = [&](double mid){
      bool ret = true;
      REP(i, n){
        REP(j, 2){
          auto dist = distance(seg, Segment(Point(mxy[i][j<<1], mxy[i][1]), Point(mxy[i][j<<1], mxy[i][3])));
          dist = sqrt(dist * dist + max(0.0, mid - mxy[i][4]) * max(0.0, mid - mxy[i][4]));
          if(dist < mid)ret = false;
        }
        REP(j, 2){
          auto dist = distance(seg, Segment(Point(mxy[i][0], mxy[i][1+(j<<1)]), Point(mxy[i][2], mxy[i][1+(j<<1)])));
          dist = sqrt(dist * dist + max(0.0, mid - mxy[i][4]) * max(0.0, mid - mxy[i][4]));
          if(dist < mid)ret = false;
        }
      }
      return ret;
    };
    double ok = 0, ng = 1000;
    while(abs(ok - ng) > epsilon){
      double mid = (ok + ng) / 2;
      if(is_ok(mid))ok = mid;
      else ng = mid;
    }
    ans.pb(ok);
  }
  OUTN(ans);
}

int solve_test(int n, vl a){

  return 0;
}

int solve_naive(int n, vl a){

  return 0;
}

void random_test(){
  rnd.seed(seed_gen());

  uniform_int_distribution<int> dist_n(4, 10), dist_m(4, 10), dist_a(1, 20), dist_b(1, 20);  

  for(int test = 1; test <= 100; test++){
    int n = dist_n(rnd), m = dist_m(rnd);
    vl a = random_vl(n, 3, 20);
    auto Output = solve_test(n, a), Answer = solve_naive(n, a);
    if(Output != Answer){
      cout << "Wrong Answer on Test #" << test << '\n';
      debug(n);
      debug(a);
      debug(Answer);
      debug(Output);
      break;
    }
  }
}

signed main(){
  int T = 1;
  // cin >> T;

  while(T--) solve();

  // random_test();

  return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 3692
final_rank: 14

code_snippet: //#define _GLIBCXX_DEBUG

#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define lfs cout<<fixed<<setprecision(10)
#define ALL(a)  (a).begin(),(a).end()
#define ALLR(a)  (a).rbegin(),(a).rend()
#define UNIQUE(a) (a).erase(unique((a).begin(),(a).end()),(a).end())
#define spa << " " <<
#define fi first
#define se second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
using ll = long long;
using ld = long double;
const ll MOD1 = 1e9+7;
const ll MOD9 = 998244353;
const ll INF = 1e18;
using P = pair<ll, ll>;
template<typename T> using PQ = priority_queue<T>;
template<typename T> using QP = priority_queue<T,vector<T>,greater<T>>;
template<typename T1, typename T2>bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}
template<typename T1, typename T2>bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}
ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
template<typename T1,typename T2>void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}  
template<typename T1,typename T2,typename T3>void anss(T1 x,T2 y,T3 z){ans(x!=y,x,z);};  
template<typename T>void debug(const T &v,ll h,ll w,string sv=" "){for(ll i=0;i<h;i++){cout<<v[i][0];for(ll j=1;j<w;j++)cout<<sv<<v[i][j];cout<<endl;}};
template<typename T>void debug(const T &v,ll n,string sv=" "){if(n!=0)cout<<v[0];for(ll i=1;i<n;i++)cout<<sv<<v[i];cout<<endl;};
template<typename T>void debug(const vector<T>&v){debug(v,v.size());}
template<typename T>void debug(const vector<vector<T>>&v){for(auto &vv:v)debug(vv,vv.size());}
template<typename T>void debug(stack<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(queue<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(deque<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop_front();}cout<<endl;}
template<typename T>void debug(PQ<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(QP<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(const set<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T>void debug(const multiset<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T,size_t size>void debug(const array<T, size> &a){for(auto z:a)cout<<z<<" ";cout<<endl;}
template<typename T,typename V>void debug(const map<T,V>&v){for(auto z:v)cout<<"["<<z.first<<"]="<<z.second<<",";cout<<endl;}
template<typename T>vector<vector<T>>vec(ll x, ll y, T w){vector<vector<T>>v(x,vector<T>(y,w));return v;}
ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}
//vector<ll>dx={1,-1,0,0,1,1,-1,-1};vector<ll>dy={0,0,1,-1,1,-1,1,-1};
template<typename T>vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
template<typename... Ts>auto make_v(size_t a,Ts... ts){return vector<decltype(make_v(ts...))>(a,make_v(ts...));}
template<typename T1, typename T2>ostream &operator<<(ostream &os, const pair<T1, T2>&p){return os << p.first << " " << p.second;}
template<typename T>ostream &operator<<(ostream &os, const vector<T> &v){for(auto &z:v)os << z << " ";cout<<"|"; return os;}
template<typename T>void rearrange(vector<int>&ord, vector<T>&v){
  auto tmp = v;
  for(int i=0;i<tmp.size();i++)v[i] = tmp[ord[i]];
}
template<typename Head, typename... Tail>void rearrange(vector<int>&ord,Head&& head, Tail&&... tail){
  rearrange(ord, head);
  rearrange(ord, tail...);
}
template<typename T> vector<int> ascend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return v[i]<v[j];});
  return ord;
}
template<typename T> vector<int> descend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return v[i]>v[j];});
  return ord;
}
template<typename T> vector<T> inv_perm(const vector<T>&ord){
  vector<T>inv(ord.size());
  for(int i=0;i<ord.size();i++)inv[ord[i]] = i;
  return inv;
}
ll FLOOR(ll n,ll div){assert(div>0);return n>=0?n/div:(n-div+1)/div;}
ll CEIL(ll n,ll div){assert(div>0);return n>=0?(n+div-1)/div:n/div;}
ll digitsum(ll n){ll ret=0;while(n){ret+=n%10;n/=10;}return ret;}
ll modulo(ll n,ll d){return (n%d+d)%d;};
template<typename T>T min(const vector<T>&v){return *min_element(v.begin(),v.end());}
template<typename T>T max(const vector<T>&v){return *max_element(v.begin(),v.end());}
template<typename T>T acc(const vector<T>&v){return accumulate(v.begin(),v.end(),T(0));};
template<typename T>T reverse(const T &v){return T(v.rbegin(),v.rend());};
//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
int popcount(ll x){return __builtin_popcountll(x);};
int poplow(ll x){return __builtin_ctzll(x);};
int pophigh(ll x){return 63 - __builtin_clzll(x);};
template<typename T>T poll(queue<T> &q){auto ret=q.front();q.pop();return ret;};
template<typename T>T poll(priority_queue<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(QP<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(stack<T> &s){auto ret=s.top();s.pop();return ret;};
ll MULT(ll x,ll y){if(LLONG_MAX/x<=y)return LLONG_MAX;return x*y;}
ll POW2(ll x, ll k){ll ret=1,mul=x;while(k){if(mul==LLONG_MAX)return LLONG_MAX;if(k&1)ret=MULT(ret,mul);mul=MULT(mul,mul);k>>=1;}return ret;}
ll POW(ll x, ll k){ll ret=1;for(int i=0;i<k;i++){if(LLONG_MAX/x<=ret)return LLONG_MAX;ret*=x;}return ret;}
template< typename T = int >
struct edge {
  int to;
  T cost;
  int id;
  edge():id(-1){};
  edge(int to, T cost = 1, int id = -1):to(to), cost(cost), id(id){}
  operator int() const { return to; }
};

template<typename T>
using Graph = vector<vector<edge<T>>>;
template<typename T>
Graph<T>revgraph(const Graph<T> &g){
  Graph<T>ret(g.size());
  for(int i=0;i<g.size();i++){
    for(auto e:g[i]){
      int to = e.to;
      e.to = i;
      ret[to].push_back(e);
    }
  }
  return ret;
}
template<typename T>
Graph<T> readGraph(int n,int m,int indexed=1,bool directed=false,bool weighted=false){
  Graph<T> ret(n);
  for(int es = 0; es < m; es++){
    int u,v;
    T w=1;
    cin>>u>>v;u-=indexed,v-=indexed;
    if(weighted)cin>>w;
    ret[u].emplace_back(v,w,es);
    if(!directed)ret[v].emplace_back(u,w,es);
  }
  return ret;
}
template<typename T>
Graph<T> readParent(int n,int indexed=1,bool directed=true){
  Graph<T>ret(n);
  for(int i=1;i<n;i++){
    int p;cin>>p;
    p-=indexed;
    ret[p].emplace_back(i);
    if(!directed)ret[i].emplace_back(p);
  }
  return ret;
}

template <typename F>
class
#if defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
  [[nodiscard]]
#endif  // defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
FixPoint final : private F
{
public:
  template <typename G>
  explicit constexpr FixPoint(G&& g) noexcept
    : F{std::forward<G>(g)}
    {}

  template <typename... Args>
  constexpr decltype(auto)
  operator()(Args&&... args) const
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 9
  noexcept(noexcept(F::operator()(std::declval<FixPoint>(), std::declval<Args>()...)))
#endif  // !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 9
  {
    return F::operator()(*this, std::forward<Args>(args)...);
  }
};  // class FixPoint


#if defined(__cpp_deduction_guides)
template <typename F>
FixPoint(F&&)
  -> FixPoint<std::decay_t<F>>;
#endif  // defined(__cpp_deduction_guides)


namespace
{
  template <typename F>
#if !defined(__has_cpp_attribute) || !__has_cpp_attribute(nodiscard)
#  if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4)
  __attribute__((warn_unused_result))
#  elif defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_Check_return_)
  _Check_return_
#  endif  // defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#endif  // !defined(__has_cpp_attribute) || !__has_cpp_attribute(nodiscard)
  inline constexpr decltype(auto)
  makeFixPoint(F&& f) noexcept
{
  return FixPoint<std::decay_t<F>>{std::forward<std::decay_t<F>>(f)};
}
}  // namespace

using Real = long double;
using Point = complex<Real>;
const Real EPS = 1e-10, PI = acos((Real)(-1.0));

inline bool eq(Real a, Real b) { return fabs(b - a) < EPS; }
inline bool eq(Point a, Point b) { return fabs(b - a) < EPS; }

Point operator*(const Point &p, const Real &d) {
  return Point(real(p) * d, imag(p) * d);
}

istream &operator>>(istream &is, Point &p) {
  Real a, b;
  is >> a >> b;
  p = Point(a, b);
  return is;
}

ostream &operator<<(ostream &os, Point &p) {
  return os << fixed << setprecision(10) << p.real() << " " << p.imag();
}

Point rotate(Real theta, const Point &p) {
  return Point(cos(theta) * p.real() - sin(theta) * p.imag(), sin(theta) * p.real() + cos(theta) * p.imag());
}

namespace std {
  bool operator<(const Point& a, const Point& b) {
    return !eq(a.real(), b.real()) ? a.real() < b.real() : a.imag() < b.imag();
  }
}

struct Line {
  Point a, b;
  Line() = default;
  Line(Point a, Point b): a(a), b(b) {}

  friend ostream &operator<<(ostream &os, Line &p) {
    return os << p.a << " to " << p.b;
  }

  friend istream &operator>>(istream &is, Line &a) {
    return is >> a.a >> a.b;
  }
};

struct Circle {
  Point c;
  Real r;
  Circle() = default;
  Circle(Point c, Real r): c(c), r(r) {}

  friend ostream &operator<<(ostream &os, Circle &c) {
    return os << c.c << ": " << c.r;
  }

  friend istream &operator>>(istream &is, Circle &c) {
    return is >> c.c >> c.r;
  }
};

Real cross(const Point &a, const Point &b) {
  return real(a) * imag(b) - real(b) * imag(a);
}

Real dot(const Point &a, const Point &b) {
  return real(a) * real(b) + imag(a) * imag(b);
}

struct Segment : Line {
  Segment() = default;
  Segment(Point a, Point b) : Line(a, b) {}
};

int ccw(const Point &a, Point b, Point c) {
  b = b - a, c = c - a;
  if (cross(b, c) > EPS) return +1; // COUNTER_CLOCKWISE
  if (cross(b, c) < -EPS) return -1; // CLOCKWISE
  if (dot(b, c) < 0) return +2; // ONLINE_BACK
  if (norm(b) < norm(c)) return -2; // ONLINE_FRONT
  return 0; // ON_SEGMENT
}

bool intersect(const Segment &s, const Point &p) {
  return ccw(s.a, s.b, p) == 0;
}

bool intersect(const Segment &s, const 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;
}

bool intersect(const Line &l, const Segment& s) {
  return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}

int intersect(const Circle &c, const Circle &d) {
  Real dis = fabs(c.c - d.c);

  if (dis > c.r + d.r + EPS) return 4;
  else if (eq(dis, c.r + d.r)) return 3;
  else if (eq(dis, abs(c.r - d.r))) return 1;
  else if (dis + min(c.r, d.r) < max(c.r, d.r) - EPS) return 0;
  else return 2;
}

bool parallel(const Line &a, const Line &b) {
  return abs(cross(a.b - a.a, b.b - b.a)) < EPS;
}

bool orthogonal(const Line &a, const Line &b) {
  return abs(dot(a.b - a.a, b.b - b.a)) < EPS;
}

Point projection(const Line& s, const Point &p) {
  double t = dot(p - s.a, s.b - s.a) / norm(s.b - s. a);
  return s.a + (s.b - s.a) * t;
}

Point projection(const Segment& l, const Point &p) {
  return projection(Line(l), p);
}

Point reflection(const Line &l, const Point &p) {
  Point r = projection(l, p);
  return p + (r - p) * 2;
}

Real distance(const Line &l, const Point &p) {
  Point r = projection(l, p);
  return fabs(p - r);
}

Real distance(const Segment&s, const Point &p) {
  Point r = projection(s, p);
  if (intersect(s, r)) return abs(r - p);
  return min(abs(s.a - p), abs(s.b - p));
}

Real distance(const Segment& a, const Segment& b) {
  if (intersect(a, b)) return 0;
  return min({
    distance(a, b.a),
    distance(a, b.b),
    distance(b, a.a),
    distance(b, a.b)
  });
}

Point crosspoint(const Line &l, const Line &m) {
  Real A = cross(l.b - l.a, m.b - m.a);
  Real B = cross(l.b - l.a, l.b - m.a);
  if (eq(abs(A), 0.0) && eq(abs(B), 0.0)) return m.a;
  return m.a + (m.b - m.a) * B / A;
}

Point crosspoint(const Segment& l, const Segment& m) {
  return crosspoint(Line(l), Line(m));
}

Line bisector_of_angle(const Point& a, const Point& b, const Point& c) {
  Real d_ab = fabs(a - b);
  Real d_bc = fabs(b - c);
  Point c_ = b + (c - b) * d_ab / d_bc;

  return Line(b, (a + c_) * 0.5);
}

Line bisector(const Point& a, const Point& b) {
  Point c = (a + b) * 0.5;
  Point d = c + rotate(PI / 2, b - c);

  return Line(c, d);
}

int intersect(const Circle &c, const Line &l) {
  Real d = distance(l, c.c);

  if (d > c.r + EPS) return 0;
  if (eq(d, c.r)) return 1;
  return 2;
}

pair<Point, Point> crosspoint(const Circle& c, const Line& l) {
  Real d = distance(l, c.c);

  Point p = projection(l, c.c);
  if (intersect(c, l) == 1) return { p, p };

  Real d2 = sqrt(c.r * c.r - d * d);
  Point v = (l.a - l.b) * (1.0 / fabs(l.a - l.b));

  return { p + d2 * v, p - d2 * v };
}

pair<Point, Point> crosspoint(const Circle &c1, const Circle &c2) {
  Real d = fabs(c1.c - c2.c);
  Real x1 = (c1.r * c1.r + d * d - c2.r * c2.r) / 2 / d;
  Real y = sqrt(c1.r * c1.r - x1 * x1);

  Point base = (c2.c * x1 + c1.c * (d - x1)) * (1.0 / d);
  Point v = rotate(PI / 2, c1.c - base);
  v = v / fabs(v);

  return { base + v * y, base - v * y };
}

pair<Point, Point> tangent(const Circle &c, const Point &p) {
  Real d = fabs(c.c - p);
  Real d2 = sqrt(d * d - c.r * c.r);
  Real a = acos(d2 / d);


  Point q = c.c - p;
  q = q / fabs(q);

//  cout << d << " " << d2 << " " << a << " " << q << endl;
  return {
    p + rotate(a, q) * d2,
    p + rotate(-a, q) * d2
  };
}

vector<Segment> common_tangent(Circle c1, Circle c2) {
  int isect = intersect(c1, c2);
  Real d = fabs(c1.c - c2.c);
  Point v = (c2.c - c1.c) / d;

  vector<Segment> res;

  if (isect == 0) {
    return {};
  } else if (isect == 1) {
    auto [p1, p2] = crosspoint(c1, Line(c1.c, c2.c));
    if (eq(fabs(p2 - c2.c), c2.r)) swap(p1, p2);

    Point v = p1 + rotate(PI/2, c2.c - p1);
    return { Segment(p1, v) };
  } else if (isect == 2) {
  } else if (isect == 3) {
    auto [p1, p2] = crosspoint(c1, c2);
    res.emplace_back(p1, rotate(PI / 2, c1.c - p1) + p1);
  } else {
    Real a = d * c1.r / (c1.r + c2.r);
    Point p = c1.c + v * a;

    Real d1 = sqrt(a * a - c1.r * c1.r), d2 = sqrt(norm(p - c2.c) - c2.r * c2.r);
    Real theta = acos(d1 / a);

//    cout << d << endl;
//    cout << a << " " << d1 << " " << d2 << " " << theta << ": " << p << endl;

    Point e = (c1.c - p) * (1.0 / fabs(c1.c - p));
    Point e1 = rotate(theta, e), e2 = rotate(-theta, e);

    res.emplace_back(p + e1 * d1, p - e1 * d2);
    res.emplace_back(p + e2 * d1, p - e2 * d2);
  }

  if (eq(c1.r, c2.r)) {
    Point e = rotate(PI / 2, v);
    res.push_back(Segment(c1.c + e * c1.r, c2.c + e * c1.r));
    res.push_back(Segment(c1.c - e * c1.r, c2.c - e * c1.r));
    return res;
  }

  if (c1.r > c2.r) swap(c1, c2);

  v = c1.c - c2.c;
  Point p = v * (1.0 / (c2.r - c1.r)) * c2.r + c2.c;

  auto [q1, q2] = tangent(c1, p);
  res.emplace_back(q1, crosspoint(c2, Line(p, q1)).first);
  res.emplace_back(q2, crosspoint(c2, Line(p, q2)).first);

  return res;
}

using Polygon = vector<Point>;

istream& operator>>(istream& is, Polygon &p) {
  for (int i = 0; i < p.size(); i++) is >> p[i];
  return is;
}

ostream& operator<<(ostream& os, Polygon &p) {
  for (int i = 0; i < p.size(); i++) os << p[i];
  return os;
}

Real area(const Polygon& p) {
  Real res = 0;
  for (int i = 0; i < p.size(); i++) {
    res += cross(p[i], p[(i + 1) % p.size()]);
  }
  return abs(res)/2;
}

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(fabs(cross(a,b)) < EPS and dot(a,b) < EPS) return 1;
    if(a.imag()>b.imag()) swap(a,b);
    if(a.imag() < EPS and EPS < b.imag() and cross(a,b) > EPS ) {
      cout << a << " --- " << b << ": " << cross(a, b) << endl;
      x = !x;
    }
  }
  return (x?2:0);
}

Polygon convex_hull(Polygon Q) {
  sort(ALL(Q));

  Polygon upper({Q[0]}), lower({Q[0]});

  rep(i, 1, Q.size()) {
    while (upper.size() >= 2) {
      int _ccw = ccw(upper[upper.size() - 2], upper[upper.size() - 1], Q[i]);
      if (_ccw == 1) {
        upper.pop_back();
      } else {
        break;
      }
    }
    if (upper.size() <= 1) {
      upper.push_back(Q[i]);
    } else if (upper.size() > 1) {
      int _ccw = ccw(upper[upper.size() - 2], upper[upper.size() - 1], Q[i]);
      if (_ccw == -1 || _ccw == -2) {
        upper.push_back(Q[i]);
      }
    }
  }
  rep(i, 1, Q.size()) {
    while (lower.size() >= 2) {
      int _ccw = ccw(lower[lower.size() - 2], lower[lower.size() - 1], Q[i]);
      if (_ccw == -1) {
        lower.pop_back();
      } else {
        break;
      }
    }

    if (lower.size() <= 1) {
      lower.push_back(Q[i]);
    } else if (lower.size() > 1) {
      int _ccw = ccw(lower[lower.size() - 2], lower[lower.size() - 1], Q[i]);
      if (_ccw == 1 || _ccw == -2) {
        lower.push_back(Q[i]);
      }
    }
  }

  Polygon ret;

  rep(i, 0, lower.size()) {
    ret.push_back(lower[i]);
//    cout << lower[i] << endl;
  }

//  cout << " | " << endl;

  rrep(i, 0, upper.size()) {
    if (!eq(lower[0], upper[i]) && !eq(lower.back(), upper[i]))
      ret.push_back(upper[i]);
//    cout << upper[i] << endl;
  }

  int start = 0;

//  cout << ret.size() << endl;
  rep(i, 0, ret.size()) {
    if (ret[i].imag() < ret[start].imag() || (eq(ret[i].imag(), ret[start].imag()) && ret[i].real() < ret[start].real())) {
      start = i;
    }
  }

  cout << ret.size() << endl;
  rep(i, 0, ret.size()) {
    auto p = ret[(i + start) % ret.size()];
    cout << (int)p.real() << " " << (int)p.imag() << endl;
  }

  return ret;
}

Real closest_pair(vector<Point> &pts, int l, int r) {
  int m = (l + r) / 2;
  if (r - l <= 1) {
    return INF;
  } else if (r - l == 2) {
    if (imag(pts[l]) > imag(pts[l + 1])) swap(pts[l], pts[l + 1]);
    return fabs(pts[l] - pts[l + 1]);
  }

  Real mid = pts[m].real();
  Real d = min(closest_pair(pts, l, m), closest_pair(pts, m, r));

  inplace_merge(pts.begin() + l, pts.begin() + m, pts.begin() + r, [](const Point &a, const Point& b) {
    return a.imag() < b.imag();
  });

  vector<Point> ret;

  for (int i = l; i < r; i++) {
    if (fabs(pts[i].real() - mid) >= d) continue;

    for (int j = ret.size() - 1; j >= 0; j--) {
      if (fabs(imag(ret[j]) - imag(pts[i])) >= d) break;
      chmin(d, fabs(ret[j] - pts[i]));
    }

    ret.emplace_back(pts[i]);
  }

  return d;
}

int main() {
  cout << fixed << setprecision(10);

  int n;
  while (cin >> n && n) {
    Segment s;
    cin >> s;
    vector<pair<Point, Point>> rect(n);
    vector<Real> h(n);
    rep(i, 0, n) {
      cin >> rect[i].fi >> rect[i].se >> h[i];
    }

    Real res = 1000;

    rep(i, 0, n) {
      vector<Point> pts({
        Point(rect[i].fi.real(), rect[i].fi.imag()),
        Point(rect[i].fi.real(), rect[i].se.imag()),
        Point(rect[i].se.real(), rect[i].fi.imag()),
        Point(rect[i].se.real(), rect[i].se.imag()),
      });

      rep(j, 0, 4) {
        Real d = distance(s, Segment(pts[j], pts[(j + 1) % 4]));

//        cout << i << ": " << d << endl;
        if (d < h[i] + EPS) {
          chmin(res, d);
        } else {
          chmin(res, (d * d + h[i] * h[i]) / 2 / h[i]);
        }
        /*
         * (x)^2 = d^2 + (x - h)^2
         * 2hx = d^2 + h^2
         * x = (d^2 + h^2) / 2h
         */
      }
    }
    cout << res << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3472
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
#include <unordered_set>
#include <random>
//#define int long long
#define REP(i,m,n) for(int i=(m);i<(n);i++)
#define rep(i,n) REP(i,0,n)
#define pb push_back
#define all(a) a.begin(),a.end()
#define rall(c) (c).rbegin(),(c).rend()
#define mp make_pair
#define endl '\n'
//#define vec vector<ll>
//#define mat vector<vector<ll> >
#define fi first
#define se second
#define double long double
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
//typedef long double ld;
typedef complex<double> Complex;
const ll INF=1e9+7;
const ll MOD=INF;
const ll inf=INF*INF;
const ll mod=MOD;
const ll inv2=499122177;
const ll MAX=10000010;
const double PI=acos(-1.0);
typedef vector<vector<ll> > mat;
typedef vector<ll> vec;

//ll dx[]={0,1,0,-1,-1,-1,1,1};
//ll dy[]={1,0,-1,0,-1,1,-1,1};

int Dx[]={0,1,1,0,-1,-1};
int Dy[]={1,0,-1,-1,-1,0};
#line 2 "geometry/base.hpp"

namespace geometry {
  using Real = double;
  const Real EPS = 1e-8;
  const Real PI = acos(static_cast< Real >(-1));

  enum {
    OUT, ON, IN
  };

  inline int sign(const Real &r) {
    return r <= -EPS ? -1 : r >= EPS ? 1 : 0;
  }

  inline bool equals(const Real &a, const Real &b) {
    return sign(a - b) == 0;
  }
}
#line 3 "geometry/point.hpp"

namespace geometry {
  using Point = complex< Real >;

  istream &operator>>(istream &is, Point &p) {
    Real a, b;
    is >> a >> b;
    p = Point(a, b);
    return is;
  }

  ostream &operator<<(ostream &os, const Point &p) {
    return os << real(p) << " " << imag(p);
  }

  Point operator*(const Point &p, const Real &d) {
    return Point(real(p) * d, imag(p) * d);
  }

  // rotate point p counterclockwise by theta rad
  Point rotate(Real theta, const Point &p) {
    return Point(cos(theta) * real(p) - sin(theta) * imag(p), sin(theta) * real(p) + cos(theta) * imag(p));
  }

  Real cross(const Point &a, const Point &b) {
    return real(a) * imag(b) - imag(a) * real(b);
  }

  Real dot(const Point &a, const Point &b) {
    return real(a) * real(b) + imag(a) * imag(b);
  }

  bool compare_x(const Point &a, const Point &b) {
    return equals(real(a), real(b)) ? imag(a) < imag(b) : real(a) < real(b);
  }

  bool compare_y(const Point &a, const Point &b) {
    return equals(imag(a), imag(b)) ? real(a) < real(b) : imag(a) < imag(b);
  }

  using Points = vector< Point >;
}
#line 3 "geometry/line.hpp"

namespace geometry {
  struct Line {
    Point a, b;

    Line() = default;

    Line(const Point &a, const Point &b) : a(a), b(b) {}

    Line(const Real &A, const Real &B, const Real &C) { // Ax+By=C
      if(equals(A, 0)) {
        assert(!equals(B, 0));
        a = Point(0, C / B);
        b = Point(1, C / B);
      } else if(equals(B, 0)) {
        a = Point(C / A, 0);
        b = Point(C / A, 1);
      } else {
        a = Point(0, C / B);
        b = Point(C / A, 0);
      }
    }

    friend ostream &operator<<(ostream &os, Line &l) {
      return os << l.a << " to " << l.b;
    }

    friend istream &operator>>(istream &is, Line &l) {
      return is >> l.a >> l.b;
    }
  };

  using Lines = vector< Line >;
}
#line 3 "geometry/segment.hpp"

namespace geometry {
  struct Segment : Line {
    Segment() = default;

    using Line::Line;
  };

  using Segments = vector< Segment >;
}
#line 3 "geometry/ccw.hpp"

namespace geometry {
  // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
  constexpr int COUNTER_CLOCKWISE = +1;
  constexpr int CLOCKWISE = -1;
  constexpr int ONLINE_BACK = +2; // c-a-b
  constexpr int ONLINE_FRONT = -2; // a-b-c
  constexpr int ON_SEGMENT = 0; // a-c-b
  int ccw(const Point &a, Point b, Point c) {
    b = b - a, c = c - a;
    if(sign(cross(b, c)) == +1) return COUNTER_CLOCKWISE;
    if(sign(cross(b, c)) == -1) return CLOCKWISE;
    if(sign(dot(b, c)) == -1) return ONLINE_BACK;
    if(norm(b) < norm(c)) return ONLINE_FRONT;
    return ON_SEGMENT;
  }
}
#line 4 "geometry/is_intersect_ss.hpp"


namespace geometry {
  bool is_intersect_ss(const Segment &s, const 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;
  }
}
#line 2 "geometry/projection.hpp"

#line 5 "geometry/projection.hpp"

namespace geometry {
  // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
  Point projection(const Line &l, const Point &p) {
    auto t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
  }
}
#line 4 "geometry/is_intersect_sp.hpp"

namespace geometry {
  bool is_intersect_sp(const Segment &s, const Point &p) {
    return ccw(s.a, s.b, p) == ON_SEGMENT;
  }
}
#line 5 "geometry/distance_sp.hpp"

namespace geometry {
  Real distance_sp(const Segment &s, const Point &p) {
    Point r = projection(s, p);
    if(is_intersect_sp(s, r)) return abs(r - p);
    return min(abs(s.a - p), abs(s.b - p));
  }
}
#line 4 "geometry/distance_ss.hpp"

namespace geometry {
  // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
  Real distance_ss(const Segment &a, const Segment &b) {
    if(is_intersect_ss(a, b)) return 0;
    return min({distance_sp(a, b.a), distance_sp(a, b.b), distance_sp(b, a.a), distance_sp(b, a.b)});
  }
}
using namespace geometry;

void solve(){
    while(1){
        int N;
        cin >> N;
        if(N == 0)break;
        double sx, sy, ex, ey;
        cin >> sx >> sy >> ex >> ey;
        Point s(sx,sy),e(ex,ey);
        Segment L(s,e);
        double ans = inf;
        rep(i,N){
            double x1, y1, x2, y2, h;
            cin >> x1 >> y1 >> x2 >> y2 >> h;
            double mi = inf;
            Point a(x1,y1),b(x2,y1),c(x2,y2),d(x1,y2);
            Segment l1(a,b),l2(b,c),l3(c,d),l4(d,a);
            mi = min(mi, distance_ss(L,l1));
            //cout<<mi<<endl;
            mi = min(mi, distance_ss(L,l2));
            //cout<<mi<<endl;
            mi = min(mi, distance_ss(L,l3));
            //cout<<mi<<endl;
            mi = min(mi, distance_ss(L,l4));
            //cout<<mi<<endl;
            if(mi == 0 || sx >= x1 && sx <= x2 && sy >= y1 && sy <= y2 && ex >= x1 && ex <= x2 && ey >= y1 && ey <= y2) ans=0;
            if(mi>h)ans=min(ans,(mi*mi+h*h)/(h*2.0));
            else ans=min(ans,mi);
        }
        cout<<fixed<<setprecision(10)<<ans<<endl;
    }
}

signed main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    solve();
}
accuracy: 1
time_ms: 10
memory_kb: 3640
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

using T = double;
using Vec = std::complex<T>;

const T PI = std::acos(-1);

constexpr T eps = 1e-12;
inline bool eq(T a, T b) { return std::abs(a - b) <= eps; }
inline bool eq(Vec a, Vec b) { return std::abs(a - b) <= eps; }
inline bool lt(T a, T b) { return a < b - eps; }
inline bool leq(T a, T b) { return a <= b + eps; }

std::istream& operator>>(std::istream& is, Vec& p) {
    T x, y;
    is >> x >> y;
    p = {x, y};
    return is;
}

struct Line {
    Vec p1, p2;
    Line() = default;
    Line(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Segment {
    Vec p1, p2;
    Segment() = default;
    Segment(const Vec& p1, const Vec& p2) : p1(p1), p2(p2) {}
    Vec dir() const { return p2 - p1; }
};

struct Circle {
    Vec c;
    T r;
    Circle() = default;
    Circle(const Vec& c, T r) : c(c), r(r) {}
};

using Polygon = std::vector<Vec>;

T dot(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).real();
}

T cross(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).imag();
}

Vec rot(const Vec& a, T ang) {
    return a * Vec(std::cos(ang), std::sin(ang));
}

Vec perp(const Vec& a) {
    return Vec(-a.imag(), a.real());
}

Vec projection(const Line& l, const Vec& p) {
    return l.p1 + dot(p - l.p1, l.dir()) * l.dir() / std::norm(l.dir());
}

Vec reflection(const Line& l, const Vec& p) {
    return T(2) * projection(l, p) - p;
}

// 0: collinear
// 1: counter-clockwise
// 2: clockwise
int ccw(const Vec& a, const Vec& b, const Vec& c) {
    if (eq(cross(b - a, c - a), 0)) return 0;
    if (lt(cross(b - a, c - a), 0)) return -1;
    return 1;
}

void sort_by_arg(std::vector<Vec>& pts) {
    std::sort(pts.begin(), pts.end(), [&](auto& p, auto& q) {
        if ((p.imag() < 0) != (q.imag() < 0)) return (p.imag() < 0);
        if (cross(p, q) == 0) {
            if (p == Vec(0, 0)) return !(q.imag() < 0 || (q.imag() == 0 && q.real() > 0));
            if (q == Vec(0, 0)) return  (p.imag() < 0 || (p.imag() == 0 && p.real() > 0));
            return (p.real() > q.real());
        }
        return (cross(p, q) > 0);
    });
}

bool intersect(const Segment& s, const Vec& p) {
    Vec u = s.p1 - p, v = s.p2 - p;
    return eq(cross(u, v), 0) && leq(dot(u, v), 0);
}

// 0: outside
// 1: on the border
// 2: inside
int intersect(const Polygon& poly, const Vec& p) {
    const int n = poly.size();
    bool in = 0;
    for (int i = 0; i < n; ++i) {
        auto a = poly[i] - p, b = poly[(i+1)%n] - p;
        if (eq(cross(a, b), 0) && (lt(dot(a, b), 0) || eq(dot(a, b), 0))) return 1;
        if (a.imag() > b.imag()) std::swap(a, b);
        if (leq(a.imag(), 0) && lt(0, b.imag()) && lt(cross(a, b), 0)) in ^= 1;
    }
    return in ? 2 : 0;
}

int intersect(const Segment& s, const Segment& t) {
    auto a = s.p1, b = s.p2;
    auto c = t.p1, d = t.p2;
    if (ccw(a, b, c) != ccw(a, b, d) && ccw(c, d, a) != ccw(c, d, b)) return 2;
    if (intersect(s, c) || intersect(s, d) || intersect(t, a) || intersect(t, b)) return 1;
    return 0;
}

// true if they have positive area in common or touch on the border
bool intersect(const Polygon& poly1, const Polygon& poly2) {
    const int n = poly1.size();
    const int m = poly2.size();
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (intersect(Segment(poly1[i], poly1[(i+1)%n]), Segment(poly2[j], poly2[(j+1)%n]))) {
                return true;
            }
        }
    }
    return intersect(poly1, poly2[0]) || intersect(poly2, poly1[0]);
}

// 0: inside
// 1: inscribe
// 2: intersect
// 3: circumscribe
// 4: outside
int intersect(const Circle& c1, const Circle& c2) {
    T d = std::abs(c1.c - c2.c);
    if (lt(d, std::abs(c2.r - c1.r))) return 0;
    if (eq(d, std::abs(c2.r - c1.r))) return 1;
    if (eq(c1.r + c2.r, d)) return 3;
    if (lt(c1.r + c2.r, d)) return 4;
    return 2;
}

T dist(const Segment& s, const Vec& p) {
    if (lt(dot(p - s.p1, s.dir()), 0)) return std::abs(p - s.p1);
    if (lt(dot(p - s.p2, -s.dir()), 0)) return std::abs(p - s.p2);
    return std::abs(cross(p - s.p1, s.dir())) / std::abs(s.dir());
}

T dist(const Segment& s, const Segment& t) {
    if (intersect(s, t)) return T(0);
    return std::min({dist(s, t.p1), dist(s, t.p2), dist(t, s.p1), dist(t, s.p2)});
}




int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    while (true) {
        int N;
        cin >> N;
        if (N == 0) break;
        Vec s, e;
        cin >> s >> e;
        Segment seg(s, e);
        vector<vector<T>> x(N, vector<T>(2)), y(N, vector<T>(2));
        vector<T> h(N);
        rep(i,0,N) cin >> x[i][0] >> y[i][0] >> x[i][1] >> y[i][1] >> h[i];
        T lb = 0, ub = 1000;
        bool ok = true;
        rep(i,0,N) {
            if (x[i][0] <= seg.p1.real() && seg.p1.real() <= x[i][1] && y[i][0] <= seg.p1.imag() && seg.p1.imag() <= y[i][1]) {
                ok = false;
            }
            if (x[i][0] <= seg.p2.real() && seg.p2.real() <= x[i][1] && y[i][0] <= seg.p2.imag() && seg.p2.imag() <= y[i][1]) {
                ok = false;
            }
            rep(j1,0,2) rep(k1,0,2) rep(j2,0,2) rep(k2,0,2) {
                Segment seg2(Vec(x[i][j1], y[i][k1]), Vec(x[i][j2], y[i][k2]));
                if (intersect(seg, seg2)) ok = false;
            }
            if (!ok) break;
        }
        if (!ok) {
            cout << 0 << endl;
            continue;
        }
        rep(_,0,100) {
            T m = (lb + ub) / 2;
            bool ok = true;
            rep(i,0,N) {
                rep(j1,0,2) rep(k1,0,2) rep(j2,0,2) rep(k2,0,2) {
                    Segment seg2(Vec(x[i][j1], y[i][k1]), Vec(x[i][j2], y[i][k2]));
                    T d = dist(seg, seg2);
                    if (leq(m, d)) continue;
                    if (leq(m, h[i])) {
                        ok = false;
                        break;
                    } else if (lt(m-sqrt(m*m-d*d), h[i])) {
                        ok = false;
                        break;
                    }
                }
                if (!ok) break;
            }
            if (ok) lb = m;
            else ub = m;
        }
        cout << lb << "\n";
    }
}
accuracy: 1
time_ms: 300
memory_kb: 3552
final_rank: 11

code_snippet: #include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
double INF = 1000000;
double EPS = 0.000000001;
int sign(double x){
  if (x >= EPS){
    return 1;
  } else if (x <= - EPS){
    return -1;
  } else {
    return 0;
  }
}
struct point{
  double x, y;
  point(){
  }
  point(double x, double y): x(x), y(y){
  }
  point operator +(point P){
    return point(x + P.x, y + P.y);
  }
  point operator -(point P){
    return point(x - P.x, y - P.y);
  }
  point operator *(double k){
    return point(x * k, y * k);
  }
  point operator /(double k){
    return point(x / k, y / k);
  }
};
double abs(point P){
  return sqrt(pow(P.x, 2) + pow(P.y, 2));
}
double dist(point P, point Q){
  return abs(Q - P);
}
double dot(point P, point Q){
  return P.x * Q.x + P.y * Q.y;
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
struct line{
  point A, B;
  line(){
  }
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
double is_parallel(line L1, line L2){
  return sign(cross(vec(L1), vec(L2))) == 0;
}
point line_intersection(line L1, line L2){
  return L1.A + vec(L1) * cross(L2.A - L1.A, vec(L2)) / cross(vec(L1), vec(L2));
}
bool on_segment(point P, line L){
  return sign(dot(P - L.A, vec(L))) > 0 && sign(dot(P - L.B, vec(L))) < 0;
}
double point_line_distance(point P, line L){
  return abs(cross(P - L.A, vec(L))) / abs(vec(L));
}
double point_segment_distance(point P, line L){
  if (sign(dot(P - L.A, vec(L))) < 0){
    return dist(P, L.A);
  } else if (sign(dot(P - L.B, vec(L))) > 0){
    return dist(P, L.B);
  } else {
    return point_line_distance(P, L);
  }
}
double segment_distance(line L1, line L2){
  if (!is_parallel(L1, L2)){
    point P = line_intersection(L1, L2);
    if (on_segment(P, L1) && on_segment(P, L2)){
      return 0;
    }
  }
  double ans = INF;
  ans = min(ans, point_segment_distance(L1.A, L2));
  ans = min(ans, point_segment_distance(L1.B, L2));
  ans = min(ans, point_segment_distance(L2.A, L1));
  ans = min(ans, point_segment_distance(L2.B, L1));
  return ans;
}

int main() {
  int n;
while (scanf("%d", &n) == 1) {
  if (n == 0) break;
  double sx, sy, tx, ty;
  scanf("%lf%lf%lf%lf", &sx, &sy, &tx, &ty);
  vector<double> minx(n), miny(n), maxx(n), maxy(n), h(n);
  for (int i = 0; i < n; i++) {
    cin >> minx[i] >> miny[i] >> maxx[i] >> maxy[i] >> h[i];
  }
  //printf("ok\n");
  auto path = line(point(sx, sy), point(tx, ty));
  double ans = -1.0;
  double L = 0.0, R = 1e9;
  for (int it = 0; it < 60; it++) {
    if (L > R) break;
    double M = (L + R) * 0.5;
    // printf("M = %.9f\n", M);
    int ok = 1;
    for (int i = 0; i < n; i++) {
      double len = M;
      if (h[i] < len) len = sqrt(M*M - (M-h[i])*(M-h[i]));
      if (minx[i] <= sx && maxx[i] >= sx && miny[i] <= sy && maxy[i] >= sy) ok = 0;
      if (minx[i] <= tx && maxx[i] >= tx && miny[i] <= ty && maxy[i] >= ty) ok = 0;
      auto u = point(minx[i], miny[i]);
      auto v = point(maxx[i], miny[i]);
      auto w = point(maxx[i], maxy[i]);
      auto x = point(minx[i], maxy[i]);
      if (segment_distance(path, line(u, v)) < len) ok = 0;
      if (segment_distance(path, line(v, w)) < len) ok = 0;
      if (segment_distance(path, line(w, x)) < len) ok = 0;
      if (segment_distance(path, line(x, u)) < len) ok = 0;
    }
    if (ok) {
      ans = M;
      L = M + EPS; 
    } else {
      R = M - EPS; 
    }
  }
  if (ans < 0) printf("0\n");
  else printf("%.9f\n", ans);
}
  return 0; 
}
accuracy: 1
time_ms: 20
memory_kb: 3564
final_rank: 6

code_snippet: #line 1 "main.cpp"
#include <algorithm>
#include <cassert>
#include <cfloat>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using lint  = int64_t;
using uint  = uint32_t;
using ulint = uint64_t;

template <class T>
using vector2d = vector<vector<T>>;

template <class T>
bool UpdateMax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  } else {
    return false;
  }
}

template <class T>
bool UpdateMin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  } else {
    return false;
  }
}

template <class T>
void OutVec(const vector<T> &vec) {
  for (int i = 0; i < vec.size() - 1; ++i) {
    cout << vec[i] << " ";
  }
  cout << vec.back() << endl;
}

template <class T>
void OutVec2d(const vector2d<T> &vec) {
  for (auto v : vec) {
    OutVec(v);
  }
}

#line 2 "/home/arc/project/comppro/cplib/geometry/distance.cpp"

#line 2 "/home/arc/project/comppro/cplib/geometry/base.cpp"

namespace geometry {

const double EPS = 1e-8;
/**
 * @brief double比較用関数
 *
 * @param a
 * @param b
 * @return int a>bなら1, a<bなら-1, a=bなら0
 */
int doubleComp(double a, double b) {
  if (a > b + EPS)
    return 1;
  else if (b > a + EPS) {
    return -1;
  }
  return 0;
}

bool equals(double a, double b) {
  return doubleComp(a, b)==0;
}
} // namespace geometry
#line 2 "/home/arc/project/comppro/cplib/geometry/line.cpp"

#line 2 "/home/arc/project/comppro/cplib/geometry/vector.cpp"

#include <complex>
#include <limits>

#line 7 "/home/arc/project/comppro/cplib/geometry/vector.cpp"

namespace geometry {
using Vector2 = std::complex<double>;

/**
 * @brief aとbの内積　|a||b|cosΘ　を求める　
 *
 * @param a
 * @param b
 * @return double
 */
double dot(const Vector2 &a, const Vector2 &b) {
  return a.real() * b.real() + a.imag() * b.imag();
}

/**
 * @brief aとbの外積　|a||b|sinΘ　を求める
 *
 * @param a
 * @param b
 * @return double
 */
double cross(const Vector2 &a, const Vector2 &b) {
  return a.real() * b.imag() - a.imag() * b.real();
}

/**
 * @brief pを反時計回りにrad回転したベクトルを求める
 *
 * @param p 元のベクトル
 * @param rad 回転角(単位ラジアン)
 * @return Vector2 回転後のベクトル
 */
Vector2 rotate(const Vector2 &p, const double rad) {
  double c = cos(rad), s = sin(rad);
  return Vector2(c * p.real() - s * p.imag(), s * p.real() + c * p.imag());
}

/**
 * @brief aを基準点としたb, cの位置関係を調べる
 *
 * @param a
 * @param b
 * @param c
 * @return int
 *  cがbの反時計回りの位置: 1
 *  時計回りの位置: -1
 *  c,a,bがこの順番で同一直線上: 2
 *  a,b,cがこの順番で同一直線上: -2
 *  cが線分ab上: 0
 */
int ccw(const Vector2 &a, Vector2 b, Vector2 c) {
  b -= a;
  c -= a;
  if (doubleComp(cross(b, c), 0) == 1) {
    return 1;
  }
  if (doubleComp(cross(b, c), 0) == -1) {
    return -1;
  }
  if (doubleComp(dot(b, c), 0) == -1) {
    return 2;
  }
  if (norm(b) < norm(c)) {
    return -2;
  }
  return 0;
}

bool isNaN(const Vector2 &a) {
  return std::isnan(a.imag()) || std::isnan(a.real());
}

Vector2 unitVector(const Vector2 &a) {
  return a / std::abs(a);
}

Vector2 normalVector(const Vector2 &a) {
  return a * Vector2(0, 1);
}

static double nan = std::numeric_limits<double>::quiet_NaN();
const Vector2 NaN = Vector2(nan, nan);
}  // namespace geometry
#line 5 "/home/arc/project/comppro/cplib/geometry/line.cpp"

namespace geometry {
struct Line {
  Vector2 a, b;
  Line() = default;
  Line(Vector2 _a, Vector2 _b) : a(_a), b(_b) {
  }

  /**
   * @brief ax+by=cの直線を作成
   *
   * @param a
   * @param b
   * @param c
   */
  Line(double _a, double _b, double _c) {
    if (equals(_a, 0)) {
      a = Vector2(0, _c / _b);
      b = Vector2(1, _c / _b);
    } else if (equals(_b, 0)) {
      a = Vector2(_c / _a, 0);
      b = Vector2(_c / _a, 1);
    } else {
      a = Vector2(0, _c / _b);
      b = Vector2(_c / _a, 0);
    }
  }

  Vector2 vector() const {
    return b - a;
  }
};

struct Segment : Line {
  Segment() = default;
  Segment(Vector2 a, Vector2 b) : Line(a, b) {
  }
};

/**
 * @brief 2直線が平行であるかを返します
 *
 * @param s
 * @param t
 * @return true
 * @return false
 */
bool isParallel(const Line &s, const Line &t) {
  return equals(0, cross(s.vector(), t.vector()));
}

/**
 * @brief 2直線が垂直であるかを返します
 *
 * @param s
 * @param t
 * @return true
 * @return false
 */
bool isOrthogonal(const Line &s, const Line &t) {
  return equals(0, dot(s.vector(), t.vector()));
}

/**
 * @brief 2線分が交差しているかを返します
 *
 * @param s
 * @param t
 * @return true
 * @return false
 */
bool hasIntersect(const Segment &s, const 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;
}

}  // namespace geometry
#line 6 "/home/arc/project/comppro/cplib/geometry/distance.cpp"

namespace geometry {
double distance(const Vector2 &a, const Vector2 &b) {
  double x = a.real() - b.real();
  double y = a.imag() - b.imag();
  return sqrt(x * x + y * y);
}

/**
 * @brief 点と直線の距離を求めます
 *
 * @param p 点
 * @param l 直線
 * @return double 点と直線の距離
 */
double distance(const Vector2 &p, const Line &l) {
  return std::abs(cross(l.vector(), p - l.a) / abs(l.vector()));
}

/**
 * @brief 点と線分の距離を求めます
 * 
 * @param p 点
 * @param l 線分
 * @return double 点と線分の距離 
 */
double distance(const Vector2 &p, const Segment &l) {
  if (dot(l.b - l.a, p - l.a) < EPS) {
    return abs(p-l.a);
  }
  if (dot(l.a - l.b, p - l.b) < EPS) {
    return abs(p-l.b);
  }
  return std::abs(cross(l.vector(), p - l.a) / abs(l.vector()));
}

/**
 * @brief 線分間の最短距離を求めます
 * 
 * @param s 
 * @param t 
 * @return double 
 */
double distance(const Segment &s, const Segment &t) {
  if (hasIntersect(s, t)) {
    return (double)0;
  }
  double ans = distance(t.a, s);
  ans = std::min(ans, distance(t.b, s));
  ans = std::min(ans, distance(s.a, t));
  ans = std::min(ans, distance(s.b, t));
  return ans;
}

} // namespace geometry
#line 2 "/home/arc/project/comppro/cplib/geometry/polygon.cpp"

#line 5 "/home/arc/project/comppro/cplib/geometry/polygon.cpp"

#line 7 "/home/arc/project/comppro/cplib/geometry/polygon.cpp"
namespace geometry {

using Polygon = std::vector<Vector2>;

/**
 * @brief 多角形の面積を求めます
 *
 * @param p 多角形の頂点を反時計回りに並べたもの
 * @return double
 */
double area(const Polygon &p) {
  double res = 0;
  int n      = p.size();
  for (int i = 0; i < n - 1; i++) {
    res += cross(p[i], p[i + 1]);
  }
  res += cross(p[n - 1], p[0]);
  return res * 0.5;
}

/**
 * @brief 多角形が凸かどうか判定します
 *
 * @param p 多角形の頂点を反時計回りに並べたもの
 * @return true 凸である場合
 * @return false 凸でない場合
 */
bool isConvex(const Polygon &p) {
  int n = p.size();
  int now, pre, nxt;
  for (int i = 0; i < n; i++) {
    pre = (i - 1 + n) % n;
    nxt = (i + 1) % n;
    now = i;
    if (ccw(p[pre], p[now], p[nxt]) == -1) {
      return false;
    }
  }
  return true;
}

/**
 * @brief 多角形に点が含まれているか判定します
 *
 * @param g 多角形の頂点を反時計回りに並べたもの
 * @param p 対象の点
 * @return int 含まれるなら2, 辺上にあるなら1, それ以外なら0
 */
int isContained(const Polygon &g, const Vector2 &p) {
  bool in = false;
  int n   = (int)g.size();
  for (int i = 0; i < n; i++) {
    Vector2 a = g[i] - p, b = g[(i + 1) % n] - p;
    if (imag(a) > imag(b)) {
      swap(a, b);
    }
    if (imag(a) <= EPS && EPS < imag(b) && cross(a, b) < -EPS) {
      in = !in;
    }
    if (equals(cross(a, b), 0) && doubleComp(dot(a, b), 0) <= 0) {
      return 1;
    }
  }
  return (in ? 2 : 0);
}

/**
 * @brief 凸包を求めます (O(N log N))
 *
 * @param p 多角形の頂点を反時計回りに並べたもの
 * @return Polygon pの凸包
 */
Polygon convexHull(Polygon &p) {
  int n = (int)p.size(), k = 0;
  std::sort(p.begin(), p.end(), [](const Vector2 &a, const Vector2 &b) {
    return (!equals(a.real(), b.real()) ? a.real() < b.real()
                                        : a.imag() < b.imag());
  });
  Polygon ch(2 * n);
  // 一直線上の3点を含める -> (< -EPS)
  // 含めない -> (< EPS)
  for (int i = 0; i < n; ch[k++] = p[i++]) {  // lower
    while (k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < EPS) --k;
  }
  for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {  // upper
    while (k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < EPS) --k;
  }
  ch.resize(k - 1);
  return ch;
}

}  // namespace geometry
#line 67 "main.cpp"

using namespace geometry;

bool canPassPoint(Segment l, Vector2 p, double h, double r) {
  double e = (r <= h) ? r : sqrt(2 * r * h - h * h);
  double d = distance(p, l);
  return d > e;
}

bool canPassAll(Vector2 s, Vector2 end, vector<Polygon> obstacles,
                vector<double> h, double r) {
  Segment l(s, end);

  for (int i = 0; i < obstacles.size(); i++) {
    for (auto p : obstacles[i]) {
      if (!canPassPoint(l, p, h[i], r)) return false;
    }
    for (int j = 0; j < 4; j++) {
      int k = j + 1;
      if (k == 4) k = 0;
      Segment edge(obstacles[i][j], obstacles[i][k]);
      if (!canPassPoint(edge, s, h[i], r)) {
        return false;
      }
      if (!canPassPoint(edge, end, h[i], r)) {
        return false;
      }
      if (hasIntersect(l, edge)) {
        return false;
      }
    }
    if (isContained(obstacles[i], s) >= 1 ||
        isContained(obstacles[i], end) >= 1) {
      return false;
    }
  }
  return true;
}

double solve(Vector2 s, Vector2 e, vector<Polygon> obstacles,
             vector<double> h) {
  double min = 0;
  double max = 1000;
  double mid = 500;
  while (max - min > 0.001) {
    if (canPassAll(s, e, obstacles, h, mid)) {
      min = mid;
    } else {
      max = mid;
    }
    mid = (min + max) / 2;
  }
  return min;
}

int main() {
  cout << std::fixed << std::setprecision(16);
  cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  while (true) {
    int n;
    cin >> n;
    if (n == 0) break;
    int sx, sy, ex, ey;
    cin >> sx >> sy >> ex >> ey;
    Vector2 s(sx, sy), e(ex, ey);

    vector<Polygon> obstacles;
    vector<double> h;
    for (int i = 0; i < n; i++) {
      int minx, miny, maxx, maxy, _h;
      cin >> minx >> miny >> maxx >> maxy >> _h;
      obstacles.push_back(vector<Vector2>{
          Vector2(minx, miny),
          Vector2(maxx, miny),
          Vector2(maxx, maxy),
          Vector2(minx, maxy),

      });
      h.push_back(_h);
    }

    cout << solve(s, e, obstacles, h) << endl;
    // cout << canPassAll(s, e, obstacles, h, 19) << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3576
final_rank: 7

code_snippet: #line 1 "main.cpp"
#pragma region Macros
#include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

struct Setup {
    Setup() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
    }
} __Setup;

using ll = long long;
#define OVERLOAD3(_1, _2, _3, name, ...) name
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define REP1(i, n) for(int i = 0; i < (n); i++)
#define REP2(i, a, b) for(int i = (a); i < int(b); i++)
#define REP(...) OVERLOAD3(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
constexpr int MOD = 1000000007;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

void Case(int i) { cout << "Case #" << i << ": "; }
int popcount(int x) { return __builtin_popcount(x); }
ll popcount(ll x) { return __builtin_popcountll(x); }
#pragma endregion Macros

#line 1 "/home/siro53/kyo-pro/compro_library/geometry/geometry.hpp"
namespace geometry {
    // Point : 複素数型を位置ベクトルとして扱う
    // 実軸(real)をx軸、挙軸(imag)をy軸として見る
    using D = double;
    using Point = complex<D>;
    const D EPS = 1e-7;
    const D PI = acosl(-1);

    inline bool equal(const D &a, const D &b) { return fabs(a - b) < EPS; }

    // 単位ベクトル(unit vector)を求める
    Point unitVector(const Point &a) { return a / abs(a); }

    // 法線ベクトル(normal vector)を求める
    // 90度回転した単位ベクトルをかける
    // -90度がよければPoint(0, -1)をかける
    Point normalVector(const Point &a) { return a * Point(0, 1); }

    // 内積(dot product) : a・b = |a||b|cosΘ
    D dot(const Point &a, const Point &b) {
        return (a.real() * b.real() + a.imag() * b.imag());
    }

    // 外積(cross product) : a×b = |a||b|sinΘ
    D cross(const Point &a, const Point &b) {
        return (a.real() * b.imag() - a.imag() * b.real());
    }

    // 点pを反時計回りにtheta度回転
    // thetaはラジアン！！！
    Point rotate(const Point &p, const D &theta) {
        return Point(cos(theta) * p.real() - sin(theta) * p.imag(),
                     sin(theta) * p.real() + cos(theta) * p.imag());
    }

    // ラジアン->度
    D radianToDegree(const D &radian) { return radian * 180.0 / PI; }

    // 度->ラジアン
    D degreeToRadian(const D &degree) { return degree * PI / 180.0; }

    // 点の回転方向
    // 点a, b, cの位置関係について(aが基準点)
    int ccw(const Point &a, Point b, Point c) {
        b -= a, c -= a;
        // 点a, b, c が
        // 反時計回りの時、
        if(cross(b, c) > EPS) return 1;
        // 時計回りの時、
        if(cross(b, c) < -EPS) return -1;
        // c, a, bがこの順番で同一直線上にある時、
        if(dot(b, c) < 0) return 2;
        // a, b, cがこの順番で同一直線上にある場合、
        if(norm(b) < norm(c)) return -2;
        // cが線分ab上にある場合、
        return 0;
    }

    // Line : 直線を表す構造体
    // b - a で直線・線分を表せる
    struct Line {
        Point a, b;
        Line() = default;
        Line(Point a, Point b) : a(a), b(b) {}
        // Ax+By=C
        Line(D A, D B, D C) {
            if(equal(A, 0)) {
                a = Point(0, C / B), b = Point(1, C / B);
            } else if(equal(B, 0)) {
                b = Point(C / A, 0), b = Point(C / A, 1);
            } else {
                a = Point(0, C / B), b = Point(C / A, 0);
            }
        }
    };

    // Segment : 線分を表す構造体
    // Lineと同じ
    struct Segment : Line {
        Segment() = default;

        Segment(Point a, Point b) : Line(a, b) {}
    };

    // Circle : 円を表す構造体
    // pが中心の位置ベクトル、rは半径
    struct Circle {
        Point p;
        D r;

        Circle() = default;

        Circle(Point p, D r) : p(p), r(r) {}
    };

    // 2直線の直交判定 : a⊥b <=> dot(a, b) = 0
    bool isOrthogonal(const Line &a, const Line &b) {
        return equal(dot(a.b - a.a, b.b - b.a), 0);
    }
    // 2直線の平行判定 : a//b <=> cross(a, b) = 0
    bool isParallel(const Line &a, const Line &b) {
        return equal(cross(a.b - a.a, b.b - b.a), 0);
    }

    // 点cが直線ab上にあるか
    bool isPointOnLine(const Point &a, const Point &b, const Point &c) {
        return isParallel(Line(a, b), Line(a, c));
    }

    // 点cが"線分"ab上にあるか
    bool isPointOnSegment(const Point &a, const Point &b, const Point &c) {
        // |a-c| + |c-b| <= |a-b| なら線分上
        return (abs(a - c) + abs(c - b) < abs(a - b) + EPS);
    }

    // 直線lと点pの距離を求める
    D distanceBetweenLineAndPoint(const Line &l, const Point &p) {
        return abs(cross(l.b - l.a, p - l.a)) / abs(l.b - l.a);
    }

    // 線分lと点pの距離を求める
    // 定義：点pから「線分lのどこか」への最短距離
    D distanceBetweenSegmentAndPoint(const Segment &l, const Point &p) {
        if(dot(l.b - l.a, p - l.a) < EPS) return abs(p - l.a);
        if(dot(l.a - l.b, p - l.b) < EPS) return abs(p - l.b);
        return abs(cross(l.b - l.a, p - l.a)) / abs(l.b - l.a);
    }

    // 直線s, tの交点の計算
    Point crossPoint(const Line &s, const Line &t) {
        D d1 = cross(s.b - s.a, t.b - t.a);
        D d2 = cross(s.b - s.a, s.b - t.a);
        if(equal(abs(d1), 0) && equal(abs(d2), 0)) return t.a;
        return t.a + (t.b - t.a) * (d2 / d1);
    }

    // 線分s, tの交点の計算
    Point crossPoint(const Segment &s, const Segment &t) {
        return crossPoint(Line(s), Line(t));
    }

    // 線分sと線分tが交差しているかどうか
    // bound:線分の端点を含むか
    bool isIntersect(const Segment &s, const Segment &t, bool bound) {
        return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) < bound &&
               ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) < bound;
    }

    // 線分sとtの距離
    D distanceBetweenSegments(const Segment &s, const Segment &t) {
        if(isIntersect(s, t, 1)) return (D)(0);
        D ans = distanceBetweenSegmentAndPoint(s, t.a);
        chmin(ans, distanceBetweenSegmentAndPoint(s, t.b));
        chmin(ans, distanceBetweenSegmentAndPoint(t, s.a));
        chmin(ans, distanceBetweenSegmentAndPoint(t, s.b));
        return ans;
    }

    // 射影(projection)
    // 直線(線分)lに点pから引いた垂線の足を求める
    Point projection(const Line &l, const Point &p) {
        D t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
        return l.a + (l.a - l.b) * t;
    }

    Point projection(const Segment &l, const Point &p) {
        D t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
        return l.a + (l.a - l.b) * t;
    }

    // 反射(reflection)
    // 直線lを対称軸として点pと線対称の位置にある点を求める
    Point reflection(const Line &l, const Point &p) {
        return p + (projection(l, p) - p) * (D)2.0;
    }

    // 2つの円の交差判定
    // 返り値は共通接線の数
    int isIntersect(const Circle &c1, const Circle &c2) {
        D d = abs(c1.p - c2.p);
        // 2つの円が離れている場合
        if(d > c1.r + c2.r + EPS) return 4;
        // 外接している場合
        if(equal(d, c1.r + c2.r)) return 3;
        // 内接している場合
        if(equal(d, abs(c1.r - c2.r))) return 1;
        // 内包している場合
        if(d < abs(c1.r - c2.r) - EPS) return 0;
        return 2;
    }

    // 2つの円の交点
    vector<Point> crossPoint(const Circle &c1, const Circle &c2) {
        vector<Point> res;
        int mode = isIntersect(c1, c2);
        // 2つの中心の距離
        D d = abs(c1.p - c2.p);
        // 2円が離れている場合
        if(mode == 4) return res;
        // 1つの円がもう1つの円に内包されている場合
        if(mode == 0) return res;
        // 2円が外接する場合
        if(mode == 3) {
            D t = c1.r / (c1.r + c2.r);
            res.emplace_back(c1.p + (c2.p - c1.p) * t);
            return res;
        }
        // 内接している場合
        if(mode == 1) {
            if(c2.r < c1.r - EPS) {
                res.emplace_back(c1.p + (c2.p - c1.p) * (c1.r / d));
            } else {
                res.emplace_back(c2.p + (c1.p - c2.p) * (c2.r / d));
            }
            return res;
        }
        // 2円が重なる場合
        D rc1 = (c1.r * c1.r + d * d - c2.r * c2.r) / (2 * d);
        D rs1 = sqrt(c1.r * c1.r - rc1 * rc1);
        if(c1.r - abs(rc1) < EPS) rs1 = 0;
        Point e12 = (c2.p - c1.p) / abs(c2.p - c1.p);
        res.emplace_back(c1.p + rc1 * e12 + rs1 * e12 * Point(0, 1));
        res.emplace_back(c1.p + rc1 * e12 + rs1 * e12 * Point(0, -1));
        return res;
    }

    // 点pが円cの内部(円周上も含む)に入っているかどうか
    bool isInCircle(const Circle &c, const Point &p) {
        D d = abs(c.p - p);
        return (equal(d, c.r) || d < c.r - EPS);
    }

    // 円cと直線lの交点
    vector<Point> crossPoint(const Circle &c, const Line &l) {
        vector<Point> res;
        D d = distanceBetweenLineAndPoint(l, c.p);
        // 交点を持たない
        if(d > c.r + EPS) return res;
        // 接する
        Point h = projection(l, c.p);
        if(equal(d, c.r)) {
            res.emplace_back(h);
            return res;
        }
        Point e = unitVector(l.b - l.a);
        D ph = sqrt(c.r * c.r - d * d);
        res.emplace_back(h - e * ph);
        res.emplace_back(h + e * ph);
        return res;
    }

    // 点pを通る円cの接線
    // 2本あるので、接点のみを返す
    vector<Point> tangentToCircle(const Point &p, const Circle &c) {
        return crossPoint(c, Circle(p, sqrt(norm(c.p - p) - c.r * c.r)));
    }

    // 円の共通接線
    vector<Line> tangent(const Circle &a, const Circle &b) {
        vector<Line> ret;
        // 2円の中心間の距離
        D g = abs(a.p - b.p);
        // 円が内包されている場合
        if(equal(g, 0)) return ret;
        Point u = unitVector(b.p - a.p);
        Point v = rotate(u, PI / 2);
        for(int s : {-1, 1}) {
            D h = (a.r + b.r * s) / g;
            if(equal(h * h, 1)) {
                ret.emplace_back(a.p + (h > 0 ? u : -u) * a.r,
                                 a.p + (h > 0 ? u : -u) * a.r + v);

            } else if(1 - h * h > 0) {
                Point U = u * h, V = v * sqrt(1 - h * h);
                ret.emplace_back(a.p + (U + V) * a.r,
                                 b.p - (U + V) * (b.r * s));
                ret.emplace_back(a.p + (U - V) * a.r,
                                 b.p - (U - V) * (b.r * s));
            }
        }
        return ret;
    }

    // 多角形の面積を求める
    D PolygonArea(const vector<Point> &p) {
        D res = 0;
        int n = p.size();
        for(int i = 0; i < n - 1; i++) res += cross(p[i], p[i + 1]);
        res += cross(p[n - 1], p[0]);
        return res * 0.5;
    }

    // 凸多角形かどうか
    bool isConvex(const vector<Point> &p) {
        int n = p.size();
        int now, pre, nxt;
        for(int i = 0; i < n; i++) {
            pre = (i - 1 + n) % n;
            nxt = (i + 1) % n;
            now = i;
            if(ccw(p[pre], p[now], p[nxt]) == -1) return false;
        }
        return true;
    }

    // 凸包 O(NlogN)
    vector<Point> ConvexHull(vector<Point> &p) {
        int n = (int)p.size(), k = 0;
        sort(ALL(p), [](const Point &a, const Point &b) {
            return (real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b));
        });
        vector<Point> ch(2 * n);
        // 一直線上の3点を含める -> (< -EPS)
        // 含め無い -> (< EPS)
        for(int i = 0; i < n; ch[k++] = p[i++]) { // lower
            while(k >= 2 &&
                  cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < EPS)
                --k;
        }
        for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) { // upper
            while(k >= t &&
                  cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < EPS)
                --k;
        }
        ch.resize(k - 1);
        return ch;
    }

    // 多角形gに点pが含まれているか?
    // 含まれる:2, 辺上にある:1, 含まれない:0
    int isContained(const vector<Point> &g, const Point &p) {
        bool in = false;
        int n = (int)g.size();
        for(int i = 0; i < n; i++) {
            Point a = g[i] - p, b = g[(i + 1) % n] - p;
            if(imag(a) > imag(b)) swap(a, b);
            if(imag(a) <= EPS && EPS < imag(b) && cross(a, b) < -EPS) in = !in;
            if(cross(a, b) == 0 && dot(a, b) <= 0) return 1;
        }
        return (in ? 2 : 0);
    }

} // namespace geometry
#line 75 "main.cpp"
using namespace geometry;

bool solve() {
    int N;
    cin >> N;
    if(N == 0) return false;
    int sx, sy, gx, gy;
    cin >> sx >> sy >> gx >> gy;
    Segment base(Point(sx, sy), Point(gx, gy));
    vector<pair<Segment, double>> kouho;
    bool f = true;
    REP(i, N) {
        int min_x, min_y, max_x, max_y, h;
        cin >> min_x >> min_y >> max_x >> max_y >> h;
        kouho.emplace_back(Segment(Point(min_x, min_y), Point(max_x, min_y)), h);
        kouho.emplace_back(Segment(Point(min_x, min_y), Point(min_x, max_y)), h);
        kouho.emplace_back(Segment(Point(max_x, min_y), Point(max_x, max_y)), h);
        kouho.emplace_back(Segment(Point(min_x, max_y), Point(max_x, max_y)), h);
        vector<Point> ps(4);
        ps[0] = Point(min_x, min_y);
        ps[1] = Point(min_x, max_y);
        ps[2] = Point(max_x, min_y);
        ps[3] = Point(max_x, max_y);
        if(isContained(ps, Point(sx, sy)) or isContained(ps, Point(gx, gy))) {
            f = false;
        }
    }
    if(!f) {
        cout << 0 << '\n';
        return true;
    }

    for(const auto& [l, h] : kouho) {
        if(isIntersect(base, l, true)) {
            cout << 0 << '\n';
            return true;
        }
    }

    double ok = 0.0, ng = 1000.1;
    REP(_, 30) {
        double mid = (ok + ng) / 2.0;
        bool judge = true;
        for(const auto& [l, h] : kouho) {
            double d = distanceBetweenSegments(base, l);
            double x;
            if(mid > h) {
                x = sqrt(mid*mid - (mid-h)*(mid-h));
            } else {
                x = mid;
            }
            if(x > d) {
                judge = false;
                break;
            }
        }
        (judge ? ok : ng) = mid;
    }
    cout << ok << '\n';
    return true;
}

int main() {
    while(solve());
}
accuracy: 1
time_ms: 10
memory_kb: 3440
final_rank: 4

code_snippet: #include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf 1000000000

const double eps = 1e-10;

template <typename T>
struct vector_2d{
	T x,y,rad,dir;
	
	vector_2d(T a=0.0,T b=0.0){
		x = a;
		y = b;
		fix_rd();
	}
	
	void update_x(T a,T b){
		x = a*x + b;
		fix_rd();
	}
	
	void update_x(T a){
		update_x(0.0,a);
	}
	
	void update_y(T a,T b){
		y = a*y + b;
		fix_rd();
	}
	
	void update_y(T a){
		update_y(0.0,a);
	}
	
	void update_rad(T a,T b){
		rad = a*rad + b;
		fix_xy();
	}
	
	void update_rad(T a){
		update_rad(0.0,a);
	}
	
	void update_dir(T a,T b){
		dir = a*dir + b;
		fix_xy();
	}

	void update_dir(T a){
		update_dir(0.0,a);
	}
	
	void fix_xy(){
		x = rad * cos(dir);
		y = rad * sin(dir);
		fix_rd();
	}
	
	void fix_rd(){
		rad = hypot(x,y);
		if(rad==0.0)dir=0.0;
		else dir = atan2(y,x);
		fix_zero();
	}
	
	void fix_zero(){
		if(abs(x)<eps)x = 0.0;
		if(abs(y)<eps)y = 0.0;
		if(abs(rad)<eps)rad = 0.0;
		if(abs(dir)<eps)dir = 0.0;
	}
	
	void normalize(){
		T s = size();
		update_x(1.0/s,0.0);
		update_y(1.0/s,0.0);
	}
	
	
	T get_dis(vector_2d<T> V){
		return hypot(x-V.x,y-V.y);
	}
	
	T size(){
		return get_dis(vector_2d<T>());
	}
	
	T angle_difference(vector_2d<T> V){
		double ret = dir - V.dir;
		if(ret<-acos(-1.0))ret = acos(-1.0)*2.0+ret;
		if(ret>acos(-1.0))ret=-acos(-1.0)*2.0+ret;
		return ret;
	}
	
	//中点
	vector_2d get_midpoint(vector_2d<T> V){
		V.update_x(0.5,x/2.0);
		V.update_y(0.5,y/2.0);
		return V;
	}
	
	T get_inner_product(vector_2d<T> V){
		return x*V.x+y*V.y;
	}
	
	T get_cross_product(vector_2d<T> V){
		return x*V.y-y*V.x;
	}
	
	vector_2d &operator+=(const vector_2d<T> &another){
		update_x(1,another.x);
		update_y(1,another.y);
		return (*this);
	}
	
	vector_2d &operator-=(const vector_2d<T> &another){
		update_x(1,-another.x);
		update_y(1,-another.y);
		return (*this);
	}
	
	vector_2d operator+(const vector_2d<T> &another)const{
		return (vector_2d(*this)+=another);
	}
	
	vector_2d operator-(const vector_2d<T> &another)const{
		return (vector_2d(*this)-=another);
	}
	
	void show(){
		cout<<x<<','<<y<<endl;
	}
};

//ax+by+c=0
template <typename T>
struct line{
	vector_2d<T> a,t;
	
	line(vector_2d<T> V1,vector_2d<T> V2){
		a=V1;
		t=V2-V1;
	}

	T get_signed_dis(vector_2d<T> V){
		vector_2d<double> PA = a-V;
		return PA.get_cross_product(t)/t.size();
	}
	
	T get_dis(vector_2d<T> V){
		return abs(get_signed_dis(V));
	}
	
	vector_2d<T> get_projection(vector_2d<T> P){
		T r = t.get_inner_product(P-a)/t.size();
		vector_2d<T> temp = t;
		temp.update_rad(0.0,r);
		return a+temp;
	}	
	
	vector_2d<T> get_cross_point(line<T> L){
		vector_2d<T> ret(1e20,1e20);
		if((t-L.t).size()<eps)return ret;
		
		T d0 = L.get_signed_dis(a);
		T d1 = L.get_signed_dis(a+t);
		vector_2d<T> temp = t;
		temp.x *= d0/(d1-d0);
		temp.y *= d0/(d1-d0);
		ret = a - temp;
		return ret;
	}
	
};

template <typename T>
struct segment{
	vector_2d<T> V1,V2;
	segment(vector_2d<T> a=vector_2d<T>(),vector_2d<T> b=vector_2d<T>()){
		V1=a;
		V2=b;
	}
	
	T get_dis(vector_2d<T> P){
		T ret = 1e20;
		line<T> L(V1,V2);
		vector_2d<T> Q = L.get_projection(P);
		if(Q.x+eps>min(V1.x,V2.x)&&Q.y+eps>min(V1.y,V2.y)
		&&Q.x<max(V1.x,V2.x)+eps&&Q.y<max(V1.y,V2.y)+eps)ret = min(ret,Q.get_dis(P));
		else{
			ret = min(ret,P.get_dis(V1));
			ret = min(ret,P.get_dis(V2));
		}
		return ret;
	}
	
	T get_dis(segment<T> l){
		if(get_cross_point(l).x<1e20)return 0.0;
		return min({get_dis(l.V1),get_dis(l.V2),l.get_dis(V1),l.get_dis(V2)});
	}
	
	vector_2d<T> get_cross_point(segment<T> l){
		line<T> L1(V1,V2),L2(l.V1,l.V2);
		vector_2d<T> P = L1.get_cross_point(L2);
		if(get_dis(P)<eps&&l.get_dis(P)<eps)return P;
		return vector_2d<T> (1e20,1e20);
	}
};

int main(){
	
	while(true){
		
		int N;
		cin>>N;
		if(N==0)break;
		double sx,sy,ex,ey;
		
		cin>>sx>>sy>>ex>>ey;
		
		vector<double> mx(N),my(N),Mx(N),My(N),h(N);
		rep(i,N){
			cin>>mx[i]>>my[i]>>Mx[i]>>My[i]>>h[i];
		}
		
		vector<vector<segment<double>>> s(N);
		rep(i,N){
			s[i].push_back(segment<double>(vector_2d<double>(mx[i],my[i]),vector_2d<double>(mx[i],My[i])));
			s[i].push_back(segment<double>(vector_2d<double>(mx[i],My[i]),vector_2d<double>(Mx[i],My[i])));
			s[i].push_back(segment<double>(vector_2d<double>(Mx[i],My[i]),vector_2d<double>(Mx[i],my[i])));
			s[i].push_back(segment<double>(vector_2d<double>(Mx[i],my[i]),vector_2d<double>(mx[i],my[i])));
		}
		
		segment<double> S(vector_2d<double>(sx,sy),vector_2d<double>(ex,ey));
		
		double ok = 0.0,ng = 1000.0;
		
		rep(_,60){
			double mid = (ok+ng)/2.0;
			
			bool f = true;
			
			rep(i,N){
				double dmin = 1e9;
				rep(j,4){
					dmin = min(dmin,S.get_dis(s[i][j]));
				}
				if(h[i]<=mid){
					dmin *= dmin;
					dmin += pow(mid-h[i],2.0);
					dmin = sqrt(dmin);
					if(dmin<mid){
						f=false;
						break;
					}
				}
				else{
					if(dmin<mid){
						f=false;
						break;
					}
				}
			}
			
			
			if(f)ok = mid;
			else ng = mid;
		}
		
		rep(i,N){
			double t = 1.0;
			bool f0 = false,f1 = false;
			rep(j,2){
				line<double> L(s[i][j*2].V1,s[i][j*2].V2);
				t *= L.get_signed_dis(S.V1);
			}
			if(t>=0.0)f0=true;
			t = 1.0;
			rep(j,2){
				line<double> L(s[i][j*2+1].V1,s[i][j*2+1].V2);
				t *= L.get_signed_dis(S.V1);
			}
			if(t>=0.0)f1=true;
			if(f0&&f1){
				ok = 0.0;
				break;
			}
			f0 = false;
			f1 = false;
			t = 1.0;
			rep(j,2){
				line<double> L(s[i][j*2].V1,s[i][j*2].V2);
				t *= L.get_signed_dis(S.V2);
			}
			if(t>=0.0)f0=true;
			t = 1.0;
			rep(j,2){
				line<double> L(s[i][j*2+1].V1,s[i][j*2+1].V2);
				t *= L.get_signed_dis(S.V2);
			}
			if(t>=0.0)f1=true;
			if(f0&&f1){
				ok = 0.0;
				break;
			}
		}
		
		cout<<fixed<<setprecision(10)<<ok<<endl;
		
	}
	
	return 0;
}
accuracy: 1
time_ms: 820
memory_kb: 3892
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

/**
 * @brief geometry
 * @docs docs/geometry/geometry.md
 */
const double EPS = 1e-8, PI = acos(-1);
inline bool EQ(double a, double b) { return fabs(b - a) < EPS; }

struct Point {
    double x, y;
    Point() {}
    Point(double x, double y) : x(x), y(y) {}
    Point operator-() const { return Point(-x, -y); }
    Point operator+(Point p) const { return Point(x + p.x, y + p.y); }
    Point operator-(Point p) const { return Point(x - p.x, y - p.y); }
    Point operator*(double t) const { return Point(x * t, y * t); }
    Point operator*(Point p) const { return Point(x * p.x - y * p.y, x * p.y + y * p.x); }
    Point operator/(double t) const { return Point(x / t, y / t); }
    bool operator<(const Point& p) const { return x != p.x ? x < p.x : y < p.y; }
    bool operator==(const Point& p) const { return EQ(x, p.x) && EQ(y, p.y); }
    friend istream& operator>>(istream& is, Point& p) {
        is >> p.x >> p.y;
        return is;
    }
    friend ostream& operator<<(ostream& os, Point p) {
        os << fixed << setprecision(10) << p.x << ' ' << p.y;
        return os;
    }
};

struct Line {
    Point a, b;
    Line() {}
    Line(Point a, Point b) : a(a), b(b) {}
    friend istream& operator>>(istream& is, Line& l) {
        is >> l.a >> l.b;
        return is;
    }
    friend ostream& operator<<(ostream& os, Line l) {
        os << l.a << " to " << l.b;
        return os;
    }
};

struct Segment : Line {
    Segment() {}
    Segment(Point a, Point b) : Line(a, b) {}
};

struct Circle {
    Point c;
    double r;
    Circle() {}
    Circle(Point c, double r) : c(c), r(r) {}
    friend istream& operator>>(istream& is, Circle& c) {
        is >> c.c >> c.r;
        return is;
    }
    friend ostream& operator<<(ostream& os, Circle& c) {
        os << c.c << ' ' << c.r;
        return os;
    }
};

using Polygon = vector<Point>;

double dot(const Point&, const Point&);
double cross(const Point&, const Point&);
double norm(const Point&);
double abs(const Point&);
Point projection(const Line&, const Point&);
Point reflection(const Line&, const Point&);
double arg(const Point&);
double radian_to_degree(const double&);
double degree_to_radian(const double&);
Point polar(const double&, const double&);
Point rotate(const Point&, const double&);
double get_angle(const Point&, const Point&, const Point&);
enum { COUNTER_CLOCKWISE = 1, CLOCKWISE = -1, ONLINE_BACK = 2, ONLINE_FRONT = -2, ON_SEGMENT = 0 };
int ccw(const Point&, Point, Point);
bool orthogonal(const Point&, const Point&);
bool orthogonal(const Point&, const Point&, const Point&, const Point&);
bool orthogonal(const Line&, const Line&);
bool parallel(const Point&, const Point&);
bool parallel(const Point&, const Point&);
bool parallel(const Point&, const Point&, const Point&, const Point&);
bool parallel(const Line&, const Line&);
bool intersect(const Line&, const Point&);
bool intersect(const Line&, const Line&);
bool intersect(const Line&, const Segment&);
bool intersect(const Segment&, const Point&);
bool intersect(const Segment&, const Segment&);
bool intersect(const Circle&, const Line&);
int intersect(const Circle&, const Segment&);
bool intersect(Circle, Circle);
int count_tangent(Circle, Circle);
double distance(const Point&, const Point&);
double distance(const Line&, const Point&);
double distance(const Line&, const Line&);
double distance(const Segment&, const Point&);
double distance(const Segment&, const Segment&);
double distance(const Line&, const Segment&);
Point crosspoint(const Line&, const Line&);
Point crosspoint(const Segment&, const Segment&);
pair<Point, Point> crosspoint(const Circle&, const Line&);
pair<Point, Point> crosspoint(const Circle&, const Segment&);
pair<Point, Point> crosspoint(const Circle&, const Circle&);
Circle circumcenter(Point, Point, const Point&);
pair<Point, Point> center_given_radius(const Point&, const Point&, const double&);
pair<Point, Point> tangent(const Circle&, const Point&);
vector<Line> common_tangent(Circle, Circle);
double area(const Polygon&);
enum { OUT, ON, IN };
int contain(const Polygon&, const Point&);
int contain(const Circle&, const Point&);
bool is_convex(const Polygon&);
Polygon convex_hull(Polygon, bool);
double convex_diameter(Polygon);
Polygon convex_cut(const Polygon&, const Line&);

double dot(const Point& a, const Point& b) { return a.x * b.x + a.y * b.y; }
double cross(const Point& a, const Point& b) { return a.x * b.y - a.y * b.x; }
double norm(const Point& p) { return p.x * p.x + p.y * p.y; }
double abs(const Point& p) { return sqrt(norm(p)); }

Point projection(const Line& l, const Point& p) {
    double t = dot(p - l.a, l.b - l.a) / norm(l.b - l.a);
    return l.a + (l.b - l.a) * t;
}
Point reflection(const Line& l, const Point& p) { return p + (projection(l, p) - p) * 2.0; }

double arg(const Point& p) { return atan2(p.y, p.x); }
double radian_to_degree(const double& r) { return r * 180.0 / PI; }
double degree_to_radian(const double& d) { return d * PI / 180.0; }
Point polar(const double& r, const double& theta) { return Point(cos(theta), sin(theta)) * r; }
Point rotate(const Point& p, const double& theta) {
    return Point(cos(theta) * p.x - sin(theta) * p.y, sin(theta) * p.x + cos(theta) * p.y);
}
double get_angle(const Point& a, const Point& b, const Point& c) {
    const Point v = b - a, w = c - b;
    double alpha = arg(v), beta = arg(w);
    if (alpha > beta) swap(alpha, beta);
    double theta = beta - alpha;
    return min(theta, 2 * PI - theta);
}

int ccw(const Point& a, Point b, Point c) {
    b = b - a, c = c - a;
    if (cross(b, c) > EPS) return COUNTER_CLOCKWISE;
    if (cross(b, c) < -EPS) return CLOCKWISE;
    if (dot(b, c) < 0) return ONLINE_BACK;
    if (norm(b) < norm(c)) return ONLINE_FRONT;
    return ON_SEGMENT;
}

bool orthogonal(const Point& a, const Point& b) { return EQ(dot(a, b), 0.0); }
bool orthogonal(const Point& a, const Point& b, const Point& c, const Point& d) { return orthogonal(b - a, d - c); }
bool orthogonal(const Line& l, const Line& m) { return EQ(dot(l.b - l.a, m.b - m.a), 0.0); }
bool parallel(const Point& a, const Point& b) { return EQ(cross(a, b), 0.0); }
bool parallel(const Point& a, const Point& b, const Point& c, const Point& d) { return parallel(b - a, d - c); }
bool parallel(const Line& l, const Line& m) { return EQ(cross(l.b - l.a, m.b - m.a), 0.0); }

bool intersect(const Line& l, const Point& p) { return abs(ccw(l.a, l.b, p)) != COUNTER_CLOCKWISE; }
bool intersect(const Line& l, const Line& m) {
    return abs(cross(l.b - l.a, m.b - m.a)) > EPS || abs(cross(l.b - l.a, m.b - l.a)) < EPS;
}
bool intersect(const Line& l, const Segment& s) {
    return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}
bool intersect(const Segment& s, const Point& p) { return ccw(s.a, s.b, p) == ON_SEGMENT; }
bool intersect(const Segment& s, const 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;
}
bool intersect(const Circle& c, const Line& l) { return distance(l, c.c) <= c.r + EPS; }
int intersect(const Circle& c, const Segment& s) {
    Point h = projection(s, c.c);
    double d1 = abs(c.c - s.a), d2 = abs(c.c - s.b);
    if (norm(h - c.c) - c.r * c.r > EPS) return 0;
    if (d1 < c.r + EPS && d2 < c.r + EPS) return 0;
    if ((d1 < c.r - EPS && d2 > c.r + EPS) || (d1 > c.r + EPS && d2 < c.r - EPS)) return 1;
    if (dot(s.a - h, s.b - h) < 0) return 2;
    return 0;
}
bool intersect(Circle a, Circle b) {
    int c = count_tangent(a, b);
    return 1 <= c && c <= 3;
}
int count_tangent(Circle a, Circle b) {
    if (a.r < b.r) swap(a, b);
    double d = abs(a.c - b.c);
    if (a.r + b.r < d) return 4;
    if (EQ(a.r + b.r, d)) return 3;
    if (a.r - b.r < d) return 2;
    if (EQ(a.r - b.r, d)) return 1;
    return 0;
}

double distance(const Point& a, const Point& b) { return abs(b - a); }
double distance(const Line& l, const Point& p) { return distance(p, projection(l, p)); }
double distance(const Line& l, const Line& m) { return intersect(l, m) ? 0 : distance(l, m.a); }
double distance(const Segment& s, const Point& p) {
    Point h = projection(s, p);
    return intersect(s, h) ? distance(p, h) : min(distance(p, s.a), distance(p, s.b));
}
double distance(const Segment& s, const Segment& t) {
    return intersect(s, t) ? 0 : min({distance(s, t.a), distance(s, t.b), distance(t, s.a), distance(t, s.b)});
}
double distance(const Line& l, const Segment& s) {
    return intersect(l, s) ? 0 : min(distance(l, s.a), distance(l, s.b));
}

Point crosspoint(const Line& l, const Line& m) {
    assert(intersect(l, m));
    double d1 = cross(l.b - l.a, m.b - m.a), d2 = cross(l.b - l.a, l.b - m.a);
    if (EQ(abs(d1), 0.0) && EQ(abs(d2), 0.0)) return m.a;
    return m.a + (m.b - m.a) * d2 / d1;
}
Point crosspoint(const Segment& s, const Segment& t) {
    assert(intersect(s, t));
    return crosspoint(Line(s), Line(t));
}
pair<Point, Point> crosspoint(const Circle& c, const Line& l) {
    assert(intersect(c, l));
    Point h = projection(l, c.c);
    Point e = (l.b - l.a) / abs(l.b - l.a) * sqrt(c.r * c.r - norm(h - c.c));
    return minmax(h - e, h + e);
}
pair<Point, Point> crosspoint(const Circle& c, const Segment& s) {
    assert(intersect(c, s));
    auto res = crosspoint(c, Line(s));
    if (intersect(c, s) == 2) return res;
    return intersect(s, res.first) ? make_pair(res.first, res.first) : make_pair(res.second, res.second);
}
pair<Point, Point> crosspoint(const Circle& a, const Circle& b) {
    assert(intersect(a, b));
    double d = distance(a.c, b.c);
    double alpha = acos((a.r * a.r + d * d - b.r * b.r) / (2 * a.r * d));
    double theta = arg(b.c - a.c);
    return minmax(a.c + polar(a.r, theta + alpha), a.c + polar(a.r, theta - alpha));
}

Circle circumcenter(Point a, Point b, const Point& c) {
    a = (a - c) * 0.5;
    b = (b - c) * 0.5;
    Point center = c + crosspoint(Line(a, a * Point(1.0, 1.0)), Line{b, b * Point(1.0, 1.0)});
    return Circle{center, abs(c - center)};
}
pair<Point, Point> center_given_radius(const Point& a, const Point& b, const double& r) {
    Point m = (b - a) * 0.5;
    double d1 = abs(m);
    assert(!(EQ(d1, 0.0) || d1 > r));
    double d2 = sqrt(r * r - d1 * d1);
    Point n = m * Point(0.0, 1.0) * d2 / d1;
    return minmax(a + m - n, a + m + n);
}
pair<Point, Point> tangent(const Circle& c, const Point& p) {
    return crosspoint(c, Circle(p, sqrt(norm(c.c - p) - c.r * c.r)));
}
vector<Line> common_tangent(Circle a, Circle b) {
    vector<Line> res;
    if (a.r < b.r) swap(a, b);
    double g = distance(a.c, b.c);
    if (EQ(g, 0.0)) return res;
    Point u = (b.c - a.c) / g;
    Point v = rotate(u, PI * 0.5);
    for (int s : {-1, 1}) {
        double h = (a.r + s * b.r) / g;
        if (EQ(1.0 - h * h, 0.0))
            res.emplace_back(a.c + u * a.r, a.c + (u + v) * a.r);
        else if (1.0 - h * h > 0.0) {
            Point U = u * h, V = v * sqrt(1 - h * h);
            res.emplace_back(a.c + (U + V) * a.r, b.c - (U + V) * b.r * s);
            res.emplace_back(a.c + (U - V) * a.r, b.c - (U - V) * b.r * s);
        }
    }
    return res;
}

double area(const Polygon& P) {
    int n = P.size();
    double res = 0;
    for (int i = 0; i < n; i++) res += cross(P[i], P[(i + 1) % n]);
    return res * 0.5;
}

int contain(const Polygon& P, const Point& p) {
    int n = P.size();
    bool in = false;
    for (int i = 0; i < n; i++) {
        Point a = P[i] - p, b = P[(i + 1) % n] - p;
        if (a.y > b.y) swap(a, b);
        if (a.y <= 0 && 0 < b.y && cross(a, b) < 0) in = !in;
        if (cross(a, b) == 0 && dot(a, b) <= 0) return ON;
    }
    return in ? IN : OUT;
}
int contain(const Circle& c, const Point& p) {
    double d = distance(c.c, p);
    return EQ(d, c.r) ? ON : d < c.r ? IN : OUT;
}

bool is_convex(const Polygon& P) {
    int n = P.size();
    for (int i = 0; i < n; i++) {
        if (ccw(P[(i + n - 1) % n], P[i], P[(i + 1) % n]) == CLOCKWISE) {
            return false;
        }
    }
    return true;
}
Polygon convex_hull(Polygon P, bool ONSEG) {
    int n = P.size(), k = 0;
    if (n <= 2) return P;
    sort(P.begin(), P.end());
    Polygon ch(2 * n);
    for (int i = 0; i < n; ch[k++] = P[i++]) {
        if (ONSEG)
            while (k >= 2 && ccw(ch[k - 2], ch[k - 1], P[i]) == CLOCKWISE) k--;
        else
            while (k >= 2 && ccw(ch[k - 2], ch[k - 1], P[i]) != COUNTER_CLOCKWISE) k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = P[i--]) {
        if (ONSEG)
            while (k >= t && ccw(ch[k - 2], ch[k - 1], P[i]) == CLOCKWISE) k--;
        else
            while (k >= t && ccw(ch[k - 2], ch[k - 1], P[i]) != COUNTER_CLOCKWISE) k--;
    }
    ch.resize(k - 1);
    int start = 0;
    for (int i = 1; i < k - 1; i++) {
        if (EQ(ch[i].y, ch[start].y) ? ch[i].x < ch[start].x : ch[i].y < ch[start].y) start = i;
    }
    rotate(ch.begin(), ch.begin() + start, ch.end());
    return ch;
}

double convex_diameter(Polygon P) {
    if (!is_convex(P)) P = convex_hull(P, false);
    int n = P.size();
    int is = 0, js = 0;
    for (int i = 1; i < n; i++) {
        if (P[i].y > P[is].y) is = i;
        if (P[i].y < P[js].y) js = i;
    }
    double maxd = norm(P[is] - P[js]);
    int i, maxi, j, maxj;
    i = maxi = is;
    j = maxj = js;
    do {
        if (cross(P[(i + 1) % n] - P[i], P[(j + 1) % n] - P[j]) >= 0)
            j = (j + 1) % n;
        else
            i = (i + 1) % n;
        if (maxd < norm(P[i] - P[j])) {
            maxd = norm(P[i] - P[j]);
            maxi = i;
            maxj = j;
        }
    } while (i != is || j != js);
    return sqrt(maxd);
}

Polygon convex_cut(const Polygon& P, const Line& l) {
    int n = P.size();
    Polygon res;
    for (int i = 0; i < n; i++) {
        Point cur = P[i], nxt = P[(i + 1) % n];
        if (ccw(l.a, l.b, cur) != CLOCKWISE) res.emplace_back(cur);
        if (ccw(l.a, l.b, cur) * ccw(l.a, l.b, nxt) < 0) res.emplace_back(crosspoint(Segment(cur, nxt), l));
    }
    return res;
}

void solve(int N) {
    Point s, t;
    cin >> s >> t;
    vector<vector<Point>> P(N);
    vector<int> h(N);
    bool ok = true;
    for (int i = 0; i < N; i++) {
        vector<int> x(2), y(2);
        for (int j = 0; j < 2; j++) cin >> x[j] >> y[j];
        if (x[0] <= s.x && s.x <= x[1] && y[0] <= s.y && s.y <= y[1]) ok = false;
        if (x[0] <= t.x && t.x <= x[1] && y[0] <= t.y && t.y <= y[1]) ok = false;
        P[i].emplace_back(x[0], y[0]);
        P[i].emplace_back(x[1], y[0]);
        P[i].emplace_back(x[1], y[1]);
        P[i].emplace_back(x[0], y[1]);
        cin >> h[i];
    }

    if (!ok) {
        cout << 0 << '\n';
        return;
    }

    auto check = [&](double x) {
        for (int i = 0; i < N; i++) {
            double Min = 1e9;
            for (int j = 0; j < 4; j++) {
                Min = min(Min, distance(Segment(s, t), Segment(P[i][j], P[i][(j + 1) % 4])));
            }
            if (x < Min) continue;
            if (x < h[i]) return false;
            Min = sqrt(Min * Min + (x - h[i]) * (x - h[i]));
            if (x > Min) return false;
        }
        return true;
    };

    double lb = 0, ub = 1e6;
    for (int _ = 0; _ < 100; _++) {
        double mid = (ub + lb) / 2;
        (check(mid) ? lb : ub) = mid;
    }

    cout << lb << '\n';
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    int N;
    while (cin >> N, N) solve(N);
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3240
final_rank: 3

code_snippet: #define LOCAL
#include <bits/stdc++.h>
using namespace std;
#pragma region Macros
typedef long long ll;
typedef __int128_t i128;
typedef unsigned int uint;
typedef unsigned long long ull;
#define ALL(x) (x).begin(), (x).end()

template <typename T> istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v) is >> x;
    return is;
}
template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <typename T, typename U, typename V> ostream& operator<<(ostream& os, const tuple<T, U, V>& t) {
    os << '(' << get<0>(t) << ',' << get<1>(t) << ',' << get<2>(t) << ')';
    return os;
}
template <typename T, typename U, typename V, typename W> ostream& operator<<(ostream& os, const tuple<T, U, V, W>& t) {
    os << '(' << get<0>(t) << ',' << get<1>(t) << ',' << get<2>(t) << ',' << get<3>(t) << ')';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const unordered_map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const unordered_set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const deque<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    }
    return os;
}

void debug_out() { cerr << '\n'; }
template <class Head, class... Tail> void debug_out(Head&& head, Tail&&... tail) {
    cerr << head;
    if (sizeof...(Tail) > 0) cerr << ", ";
    debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                                   \
    cerr << " ";                                                                     \
    cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << '\n'; \
    cerr << " ";                                                                     \
    debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

template <class T1, class T2> inline bool chmin(T1& a, T2 b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T1, class T2> inline bool chmax(T1& a, T2 b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
#pragma endregion

/**
 * @brief geometry
 * @docs docs/geometry/geometry.md
 */
const double EPS = 1e-8, PI = acos(-1);
inline bool EQ(double a, double b) { return fabs(b - a) < EPS; }

struct Point {
    double x, y;
    Point() {}
    Point(double x, double y) : x(x), y(y) {}
    Point operator-() const { return Point(-x, -y); }
    Point operator+(Point p) const { return Point(x + p.x, y + p.y); }
    Point operator-(Point p) const { return Point(x - p.x, y - p.y); }
    Point operator*(double t) const { return Point(x * t, y * t); }
    Point operator*(Point p) const { return Point(x * p.x - y * p.y, x * p.y + y * p.x); }
    Point operator/(double t) const { return Point(x / t, y / t); }
    bool operator<(const Point& p) const { return x != p.x ? x < p.x : y < p.y; }
    bool operator==(const Point& p) const { return EQ(x, p.x) && EQ(y, p.y); }
    friend istream& operator>>(istream& is, Point& p) {
        is >> p.x >> p.y;
        return is;
    }
    friend ostream& operator<<(ostream& os, Point p) {
        os << fixed << setprecision(10) << p.x << ' ' << p.y;
        return os;
    }
};

struct Line {
    Point a, b;
    Line() {}
    Line(Point a, Point b) : a(a), b(b) {}
    friend istream& operator>>(istream& is, Line& l) {
        is >> l.a >> l.b;
        return is;
    }
    friend ostream& operator<<(ostream& os, Line l) {
        os << l.a << " to " << l.b;
        return os;
    }
};

struct Segment : Line {
    Segment() {}
    Segment(Point a, Point b) : Line(a, b) {}
};

struct Circle {
    Point c;
    double r;
    Circle() {}
    Circle(Point c, double r) : c(c), r(r) {}
    friend istream& operator>>(istream& is, Circle& c) {
        is >> c.c >> c.r;
        return is;
    }
    friend ostream& operator<<(ostream& os, Circle& c) {
        os << c.c << ' ' << c.r;
        return os;
    }
};

using Polygon = vector<Point>;

double dot(const Point&, const Point&);
double cross(const Point&, const Point&);
double norm(const Point&);
double abs(const Point&);
Point projection(const Line&, const Point&);
Point reflection(const Line&, const Point&);
double arg(const Point&);
double radian_to_degree(const double&);
double degree_to_radian(const double&);
Point polar(const double&, const double&);
Point rotate(const Point&, const double&);
double get_angle(const Point&, const Point&, const Point&);
enum { COUNTER_CLOCKWISE = 1, CLOCKWISE = -1, ONLINE_BACK = 2, ONLINE_FRONT = -2, ON_SEGMENT = 0 };
int ccw(const Point&, Point, Point);
bool orthogonal(const Point&, const Point&);
bool orthogonal(const Point&, const Point&, const Point&, const Point&);
bool orthogonal(const Line&, const Line&);
bool parallel(const Point&, const Point&);
bool parallel(const Point&, const Point&);
bool parallel(const Point&, const Point&, const Point&, const Point&);
bool parallel(const Line&, const Line&);
bool intersect(const Line&, const Point&);
bool intersect(const Line&, const Line&);
bool intersect(const Line&, const Segment&);
bool intersect(const Segment&, const Point&);
bool intersect(const Segment&, const Segment&);
bool intersect(const Circle&, const Line&);
int intersect(const Circle&, const Segment&);
bool intersect(Circle, Circle);
int count_tangent(Circle, Circle);
double distance(const Point&, const Point&);
double distance(const Line&, const Point&);
double distance(const Line&, const Line&);
double distance(const Segment&, const Point&);
double distance(const Segment&, const Segment&);
double distance(const Line&, const Segment&);
Point crosspoint(const Line&, const Line&);
Point crosspoint(const Segment&, const Segment&);
pair<Point, Point> crosspoint(const Circle&, const Line&);
pair<Point, Point> crosspoint(const Circle&, const Segment&);
pair<Point, Point> crosspoint(const Circle&, const Circle&);
Circle circumcenter(Point, Point, const Point&);
pair<Point, Point> center_given_radius(const Point&, const Point&, const double&);
pair<Point, Point> tangent(const Circle&, const Point&);
vector<Line> common_tangent(Circle, Circle);
double area(const Polygon&);
enum { OUT, ON, IN };
int contain(const Polygon&, const Point&);
int contain(const Circle&, const Point&);
bool is_convex(const Polygon&);
Polygon convex_hull(Polygon, bool);
double convex_diameter(Polygon);
Polygon convex_cut(const Polygon&, const Line&);

double dot(const Point& a, const Point& b) { return a.x * b.x + a.y * b.y; }
double cross(const Point& a, const Point& b) { return a.x * b.y - a.y * b.x; }
double norm(const Point& p) { return p.x * p.x + p.y * p.y; }
double abs(const Point& p) { return sqrt(norm(p)); }

Point projection(const Line& l, const Point& p) {
    double t = dot(p - l.a, l.b - l.a) / norm(l.b - l.a);
    return l.a + (l.b - l.a) * t;
}
Point reflection(const Line& l, const Point& p) { return p + (projection(l, p) - p) * 2.0; }

double arg(const Point& p) { return atan2(p.y, p.x); }
double radian_to_degree(const double& r) { return r * 180.0 / PI; }
double degree_to_radian(const double& d) { return d * PI / 180.0; }
Point polar(const double& r, const double& theta) { return Point(cos(theta), sin(theta)) * r; }
Point rotate(const Point& p, const double& theta) {
    return Point(cos(theta) * p.x - sin(theta) * p.y, sin(theta) * p.x + cos(theta) * p.y);
}
double get_angle(const Point& a, const Point& b, const Point& c) {
    const Point v = b - a, w = c - b;
    double alpha = arg(v), beta = arg(w);
    if (alpha > beta) swap(alpha, beta);
    double theta = beta - alpha;
    return min(theta, 2 * PI - theta);
}

int ccw(const Point& a, Point b, Point c) {
    b = b - a, c = c - a;
    if (cross(b, c) > EPS) return COUNTER_CLOCKWISE;
    if (cross(b, c) < -EPS) return CLOCKWISE;
    if (dot(b, c) < 0) return ONLINE_BACK;
    if (norm(b) < norm(c)) return ONLINE_FRONT;
    return ON_SEGMENT;
}

bool orthogonal(const Point& a, const Point& b) { return EQ(dot(a, b), 0.0); }
bool orthogonal(const Point& a, const Point& b, const Point& c, const Point& d) { return orthogonal(b - a, d - c); }
bool orthogonal(const Line& l, const Line& m) { return EQ(dot(l.b - l.a, m.b - m.a), 0.0); }
bool parallel(const Point& a, const Point& b) { return EQ(cross(a, b), 0.0); }
bool parallel(const Point& a, const Point& b, const Point& c, const Point& d) { return parallel(b - a, d - c); }
bool parallel(const Line& l, const Line& m) { return EQ(cross(l.b - l.a, m.b - m.a), 0.0); }

bool intersect(const Line& l, const Point& p) { return abs(ccw(l.a, l.b, p)) != COUNTER_CLOCKWISE; }
bool intersect(const Line& l, const Line& m) {
    return abs(cross(l.b - l.a, m.b - m.a)) > EPS || abs(cross(l.b - l.a, m.b - l.a)) < EPS;
}
bool intersect(const Line& l, const Segment& s) {
    return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}
bool intersect(const Segment& s, const Point& p) { return ccw(s.a, s.b, p) == ON_SEGMENT; }
bool intersect(const Segment& s, const 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;
}
bool intersect(const Circle& c, const Line& l) { return distance(l, c.c) <= c.r + EPS; }
int intersect(const Circle& c, const Segment& s) {
    Point h = projection(s, c.c);
    double d1 = abs(c.c - s.a), d2 = abs(c.c - s.b);
    if (norm(h - c.c) - c.r * c.r > EPS) return 0;
    if (d1 < c.r + EPS && d2 < c.r + EPS) return 0;
    if ((d1 < c.r - EPS && d2 > c.r + EPS) || (d1 > c.r + EPS && d2 < c.r - EPS)) return 1;
    if (dot(s.a - h, s.b - h) < 0) return 2;
    return 0;
}
bool intersect(Circle a, Circle b) {
    int c = count_tangent(a, b);
    return 1 <= c && c <= 3;
}
int count_tangent(Circle a, Circle b) {
    if (a.r < b.r) swap(a, b);
    double d = abs(a.c - b.c);
    if (a.r + b.r < d) return 4;
    if (EQ(a.r + b.r, d)) return 3;
    if (a.r - b.r < d) return 2;
    if (EQ(a.r - b.r, d)) return 1;
    return 0;
}

double distance(const Point& a, const Point& b) { return abs(b - a); }
double distance(const Line& l, const Point& p) { return distance(p, projection(l, p)); }
double distance(const Line& l, const Line& m) { return intersect(l, m) ? 0 : distance(l, m.a); }
double distance(const Segment& s, const Point& p) {
    Point h = projection(s, p);
    return intersect(s, h) ? distance(p, h) : min(distance(p, s.a), distance(p, s.b));
}
double distance(const Segment& s, const Segment& t) {
    return intersect(s, t) ? 0 : min({distance(s, t.a), distance(s, t.b), distance(t, s.a), distance(t, s.b)});
}
double distance(const Line& l, const Segment& s) {
    return intersect(l, s) ? 0 : min(distance(l, s.a), distance(l, s.b));
}

Point crosspoint(const Line& l, const Line& m) {
    assert(intersect(l, m));
    double d1 = cross(l.b - l.a, m.b - m.a), d2 = cross(l.b - l.a, l.b - m.a);
    if (EQ(abs(d1), 0.0) && EQ(abs(d2), 0.0)) return m.a;
    return m.a + (m.b - m.a) * d2 / d1;
}
Point crosspoint(const Segment& s, const Segment& t) {
    assert(intersect(s, t));
    return crosspoint(Line(s), Line(t));
}
pair<Point, Point> crosspoint(const Circle& c, const Line& l) {
    assert(intersect(c, l));
    Point h = projection(l, c.c);
    Point e = (l.b - l.a) / abs(l.b - l.a) * sqrt(c.r * c.r - norm(h - c.c));
    return minmax(h - e, h + e);
}
pair<Point, Point> crosspoint(const Circle& c, const Segment& s) {
    assert(intersect(c, s));
    auto res = crosspoint(c, Line(s));
    if (intersect(c, s) == 2) return res;
    return intersect(s, res.first) ? make_pair(res.first, res.first) : make_pair(res.second, res.second);
}
pair<Point, Point> crosspoint(const Circle& a, const Circle& b) {
    assert(intersect(a, b));
    double d = distance(a.c, b.c);
    double alpha = acos((a.r * a.r + d * d - b.r * b.r) / (2 * a.r * d));
    double theta = arg(b.c - a.c);
    return minmax(a.c + polar(a.r, theta + alpha), a.c + polar(a.r, theta - alpha));
}

Circle circumcenter(Point a, Point b, const Point& c) {
    a = (a - c) * 0.5;
    b = (b - c) * 0.5;
    Point center = c + crosspoint(Line(a, a * Point(1.0, 1.0)), Line{b, b * Point(1.0, 1.0)});
    return Circle{center, abs(c - center)};
}
pair<Point, Point> center_given_radius(const Point& a, const Point& b, const double& r) {
    Point m = (b - a) * 0.5;
    double d1 = abs(m);
    assert(!(EQ(d1, 0.0) || d1 > r));
    double d2 = sqrt(r * r - d1 * d1);
    Point n = m * Point(0.0, 1.0) * d2 / d1;
    return minmax(a + m - n, a + m + n);
}
pair<Point, Point> tangent(const Circle& c, const Point& p) {
    return crosspoint(c, Circle(p, sqrt(norm(c.c - p) - c.r * c.r)));
}
vector<Line> common_tangent(Circle a, Circle b) {
    vector<Line> res;
    if (a.r < b.r) swap(a, b);
    double g = distance(a.c, b.c);
    if (EQ(g, 0.0)) return res;
    Point u = (b.c - a.c) / g;
    Point v = rotate(u, PI * 0.5);
    for (int s : {-1, 1}) {
        double h = (a.r + s * b.r) / g;
        if (EQ(1.0 - h * h, 0.0))
            res.emplace_back(a.c + u * a.r, a.c + (u + v) * a.r);
        else if (1.0 - h * h > 0.0) {
            Point U = u * h, V = v * sqrt(1 - h * h);
            res.emplace_back(a.c + (U + V) * a.r, b.c - (U + V) * b.r * s);
            res.emplace_back(a.c + (U - V) * a.r, b.c - (U - V) * b.r * s);
        }
    }
    return res;
}

double area(const Polygon& P) {
    int n = P.size();
    double res = 0;
    for (int i = 0; i < n; i++) res += cross(P[i], P[(i + 1) % n]);
    return res * 0.5;
}

int contain(const Polygon& P, const Point& p) {
    int n = P.size();
    bool in = false;
    for (int i = 0; i < n; i++) {
        Point a = P[i] - p, b = P[(i + 1) % n] - p;
        if (a.y > b.y) swap(a, b);
        if (a.y <= 0 && 0 < b.y && cross(a, b) < 0) in = !in;
        if (cross(a, b) == 0 && dot(a, b) <= 0) return ON;
    }
    return in ? IN : OUT;
}
int contain(const Circle& c, const Point& p) {
    double d = distance(c.c, p);
    return EQ(d, c.r) ? ON : d < c.r ? IN : OUT;
}

bool is_convex(const Polygon& P) {
    int n = P.size();
    for (int i = 0; i < n; i++) {
        if (ccw(P[(i + n - 1) % n], P[i], P[(i + 1) % n]) == CLOCKWISE) {
            return false;
        }
    }
    return true;
}
Polygon convex_hull(Polygon P, bool ONSEG) {
    int n = P.size(), k = 0;
    if (n <= 2) return P;
    sort(P.begin(), P.end());
    Polygon ch(2 * n);
    for (int i = 0; i < n; ch[k++] = P[i++]) {
        if (ONSEG)
            while (k >= 2 && ccw(ch[k - 2], ch[k - 1], P[i]) == CLOCKWISE) k--;
        else
            while (k >= 2 && ccw(ch[k - 2], ch[k - 1], P[i]) != COUNTER_CLOCKWISE) k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = P[i--]) {
        if (ONSEG)
            while (k >= t && ccw(ch[k - 2], ch[k - 1], P[i]) == CLOCKWISE) k--;
        else
            while (k >= t && ccw(ch[k - 2], ch[k - 1], P[i]) != COUNTER_CLOCKWISE) k--;
    }
    ch.resize(k - 1);
    int start = 0;
    for (int i = 1; i < k - 1; i++) {
        if (EQ(ch[i].y, ch[start].y) ? ch[i].x < ch[start].x : ch[i].y < ch[start].y) start = i;
    }
    rotate(ch.begin(), ch.begin() + start, ch.end());
    return ch;
}

double convex_diameter(Polygon P) {
    if (!is_convex(P)) P = convex_hull(P, false);
    int n = P.size();
    int is = 0, js = 0;
    for (int i = 1; i < n; i++) {
        if (P[i].y > P[is].y) is = i;
        if (P[i].y < P[js].y) js = i;
    }
    double maxd = norm(P[is] - P[js]);
    int i, maxi, j, maxj;
    i = maxi = is;
    j = maxj = js;
    do {
        if (cross(P[(i + 1) % n] - P[i], P[(j + 1) % n] - P[j]) >= 0)
            j = (j + 1) % n;
        else
            i = (i + 1) % n;
        if (maxd < norm(P[i] - P[j])) {
            maxd = norm(P[i] - P[j]);
            maxi = i;
            maxj = j;
        }
    } while (i != is || j != js);
    return sqrt(maxd);
}

Polygon convex_cut(const Polygon& P, const Line& l) {
    int n = P.size();
    Polygon res;
    for (int i = 0; i < n; i++) {
        Point cur = P[i], nxt = P[(i + 1) % n];
        if (ccw(l.a, l.b, cur) != CLOCKWISE) res.emplace_back(cur);
        if (ccw(l.a, l.b, cur) * ccw(l.a, l.b, nxt) < 0) res.emplace_back(crosspoint(Segment(cur, nxt), l));
    }
    return res;
}

const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};
const long long MOD = 1000000007;
// const long long MOD = 998244353;

void solve(int N) {
    Point s, t;
    cin >> s >> t;
    vector<vector<Point>> P(N);
    vector<int> h(N);
    bool ok = true;
    for (int i = 0; i < N; i++) {
        vector<int> x(2), y(2);
        for (int j = 0; j < 2; j++) cin >> x[j] >> y[j];
        if (x[0] <= s.x && s.x <= x[1] && y[0] <= s.y && s.y <= y[1]) ok = false;
        if (x[0] <= t.x && t.x <= x[1] && y[0] <= t.y && t.y <= y[1]) ok = false;
        P[i].emplace_back(x[0], y[0]);
        P[i].emplace_back(x[1], y[0]);
        P[i].emplace_back(x[1], y[1]);
        P[i].emplace_back(x[0], y[1]);
        cin >> h[i];
    }

    if (!ok) {
        cout << 0 << '\n';
        return;
    }

    auto check = [&](double x) {
        for (int i = 0; i < N; i++) {
            double Min = INF;
            for (int j = 0; j < 4; j++) {
                Min = min(Min, distance(Segment(s, t), Segment(P[i][j], P[i][(j + 1) % 4])));
            }
            if (x < Min) continue;
            if (x < h[i]) return false;
            Min = sqrt(Min * Min + (x - h[i]) * (x - h[i]));
            if (x > Min) return false;
        }
        return true;
    };

    double lb = 0, ub = 100000;
    for (int _ = 0; _ < 100; _++) {
        double mid = (ub + lb) / 2;
        (check(mid) ? lb : ub) = mid;
    }

    cout << lb << '\n';
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    int N;
    while (cin >> N, N) solve(N);
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3164
final_rank: 1

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
const double EPS = 1e-6;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;
    template<class t>
    void output(t a){
        if(was_output)cout << " ";
        cout << a;
        was_output = true;
    }
    void outendl(){
        was_output = false;
        cout << endl;
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    void out(t x){
        cout << x;
    }


    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }
}

using namespace templates;
class vector2 {
public:
    double x;
    double y;
    vector2():x(0),y(0){}
    vector2(double a, double b):x(a),y(b){}
    vector2(const vector2 &o):x(o.x),y(o.y){}
    vector2 inv(){return vector2(x,-y)/(x*x+y*y);}

    vector2 &operator+=(vector2 o){x+=o.x;y+=o.y;return *this;}
    vector2& operator-=(vector2 o){x-=o.x;y-=o.y;return *this;}
    vector2 &operator*=(double o){x*=o;y*=o;return *this;}
    vector2& operator*=(vector2 o){return (*this)=vector2(x*o.x-y*o.y,x*o.y+y*o.x);}
    vector2 &operator/=(double o){x/=o;y/=o;return *this;}
    vector2& operator/=(vector2 o){return (*this)*=o.inv();}

    vector2 operator+(vector2 o){return vector2(*this)+=o;}
    vector2 operator-(vector2 o){return vector2(*this)-=o;}
    vector2 operator*(double o) {return vector2(*this)*=o;}
    vector2 operator*(vector2 o){return vector2(*this)*=o;}
    vector2 operator/(double o) {return vector2(*this)/=o;}
    vector2 operator/(vector2 o){return vector2(*this)/=o;}
    bool operator==(vector2 o){return std::abs(x-o.x)<=EPS and std::abs(y-o.y)<=EPS;}

    static vector2 polar(double rad,double r=1){return vector2(r*cos(rad),r*sin(rad));}
    double mag(){return x*x + y* y;}
    double abs(){return sqrt(mag());}
    vector2 normal(){return (*this)/abs();}
    double dot(vector2 o){return x*o.x+y*o.y;}
    double cross(vector2 o){return x*o.y-y*o.x;}
};

ostream& operator<<(ostream &os,vector2 v){
    os << v.x << " " << v.y;
    return os;
}
istream& operator>>(istream &is,vector2 &v){
    is >> v.x >> v.y;
    return is;
}

vector2 polar(double rad,double r=1) {return vector2::polar(rad,r);}
double mag(vector2 x){return x.mag();}
double abs(vector2 x){return x.abs();}
vector2 normal(vector2 x){return x.normal();}
double dot(vector2 x,vector2 y){return x.dot(y);}
double cross(vector2 x,vector2 y){return x.cross(y);}


double func(int n){
    vector2 start = in<vector2>();
    vector2 end = in<vector2>();
    vvector<double> xs(n,vector<double>(2));
    vvector<double> ys(n,vector<double>(2));
    vector<double> hs(n);
    rep(i,n){
        rep(j,2){
            xs[i][j] = in<double>();
            ys[i][j] = in<double>();
        }
        hs[i] = in<double>();
    }
    method(compres,vector2,vector2 p,vector2 from,vector2 end){
        vector2 v1 = p - from;
        vector2 v2 = end - from;
        vector2 n = normal(v2);
        double dis = dot(n,v1);
        chmin(dis,abs(v2));
        chmax(dis,0);
        return p - n * dis;
    };
    method(dist,double,vector2 p,double r,int n){
        rep(i,2){
            p = compres(p,vector2(xs[n][0],ys[n][0]),vector2(xs[n][1-i],ys[n][i]));
        }
        double d = max<double>(0,r-hs[n]);

        return sqrt(mag(p-vector2(xs[n][0],ys[n][0]))+d*d);
    };
    method(calc,vector2,double t){
        return start + (end - start) * t;
    };
    method(check,bool,double r){
        rep(i,n){
            double lp = 0;
            double rp = 1;
            rep(j,100){
                double mid1 = (lp + lp + rp) / 3;
                double mid2 = (lp + rp + rp) / 3;
                if(dist(calc(mid1),r,i)<dist(calc(mid2),r,i)){
                    rp = mid2;
                }else{
                    lp = mid1;
                }
            }
            if(dist(calc(lp),r,i)<r+1e-6)return false;
        }
        return true;
    };
    double lp = 0;
    double rp = 10000;
    rep(i,100){
        double mid = (lp + rp) / 2;
        if(check(mid)){
            lp = mid;
        }else{
            rp = mid;
        }
    }
    return lp;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    while(true){
        int n = in();
        if(n==0)break;
        printf("%.20lf\n",func(n));
    }
    return 0;
}
accuracy: 1
time_ms: 1410
memory_kb: 3540
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1<<30;
const ll linf = 1LL<<62;
const int MAX = 510000;
ll dy[8] = {0,-1,0,1,1,-1,-1,1};
ll dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
const int mod = 1e9 + 7;
//const int mod = 998244353;

namespace geometry {
    // Point : 複素数型を位置ベクトルとして扱う
    // 実軸(real)をx軸、挙軸(imag)をy軸として見る
    using D = double;
    using Point = complex<D>;
    const D EPS = 1e-7;
    const D PI = acosl(-1);

    inline bool equal(const D &a, const D &b) { return fabs(a - b) < EPS; }

    // 単位ベクトル(unit vector)を求める
    Point unitVector(const Point &a) { return a / abs(a); }

    // 法線ベクトル(normal vector)を求める
    // 90度回転した単位ベクトルをかける
    // -90度がよければPoint(0, -1)をかける
    Point normalVector(const Point &a) { return a * Point(0, 1); }

    // 内積(dot product) : a・b = |a||b|cosΘ
    D dot(const Point &a, const Point &b) {
        return (a.real() * b.real() + a.imag() * b.imag());
    }

    // 外積(cross product) : a×b = |a||b|sinΘ
    D cross(const Point &a, const Point &b) {
        return (a.real() * b.imag() - a.imag() * b.real());
    }

    // 点pを反時計回りにtheta度回転
    // thetaはラジアン！！！
    Point rotate(const Point &p, const D &theta) {
        return Point(cos(theta) * p.real() - sin(theta) * p.imag(),
                     sin(theta) * p.real() + cos(theta) * p.imag());
    }

    // ラジアン->度
    D radianToDegree(const D &radian) { return radian * 180.0 / PI; }

    // 度->ラジアン
    D degreeToRadian(const D &degree) { return degree * PI / 180.0; }

    // 点の回転方向
    // 点a, b, cの位置関係について(aが基準点)
    int ccw(const Point &a, Point b, Point c) {
        b -= a, c -= a;
        // 点a, b, c が
        // 反時計回りの時、
        if(cross(b, c) > EPS) return 1;
        // 時計回りの時、
        if(cross(b, c) < -EPS) return -1;
        // c, a, bがこの順番で同一直線上にある時、
        if(dot(b, c) < 0) return 2;
        // a, b, cがこの順番で同一直線上にある場合、
        if(norm(b) < norm(c)) return -2;
        // cが線分ab上にある場合、
        return 0;
    }

    // Line : 直線を表す構造体
    // b - a で直線・線分を表せる
    struct Line {
        Point a, b;
        Line() = default;
        Line(Point a, Point b) : a(a), b(b) {}
        // Ax+By=C
        Line(D A, D B, D C) {
            if(equal(A, 0)) {
                a = Point(0, C / B), b = Point(1, C / B);
            } else if(equal(B, 0)) {
                b = Point(C / A, 0), b = Point(C / A, 1);
            } else {
                a = Point(0, C / B), b = Point(C / A, 0);
            }
        }
    };

    // Segment : 線分を表す構造体
    // Lineと同じ
    struct Segment : Line {
        Segment() = default;

        Segment(Point a, Point b) : Line(a, b) {}
    };

    // Circle : 円を表す構造体
    // pが中心の位置ベクトル、rは半径
    struct Circle {
        Point p;
        D r;

        Circle() = default;

        Circle(Point p, D r) : p(p), r(r) {}
    };

    // 2直線の直交判定 : a⊥b <=> dot(a, b) = 0
    bool isOrthogonal(const Line &a, const Line &b) {
        return equal(dot(a.b - a.a, b.b - b.a), 0);
    }
    // 2直線の平行判定 : a//b <=> cross(a, b) = 0
    bool isParallel(const Line &a, const Line &b) {
        return equal(cross(a.b - a.a, b.b - b.a), 0);
    }

    // 点cが直線ab上にあるか
    bool isPointOnLine(const Point &a, const Point &b, const Point &c) {
        return isParallel(Line(a, b), Line(a, c));
    }

    // 点cが"線分"ab上にあるか
    bool isPointOnSegment(const Point &a, const Point &b, const Point &c) {
        // |a-c| + |c-b| <= |a-b| なら線分上
        return (abs(a - c) + abs(c - b) < abs(a - b) + EPS);
    }

    // 直線lと点pの距離を求める
    D distanceBetweenLineAndPoint(const Line &l, const Point &p) {
        return abs(cross(l.b - l.a, p - l.a)) / abs(l.b - l.a);
    }

    // 線分lと点pの距離を求める
    // 定義：点pから「線分lのどこか」への最短距離
    D distanceBetweenSegmentAndPoint(const Segment &l, const Point &p) {
        if(dot(l.b - l.a, p - l.a) < EPS) return abs(p - l.a);
        if(dot(l.a - l.b, p - l.b) < EPS) return abs(p - l.b);
        return abs(cross(l.b - l.a, p - l.a)) / abs(l.b - l.a);
    }

    // 直線s, tの交点の計算
    Point crossPoint(const Line &s, const Line &t) {
        D d1 = cross(s.b - s.a, t.b - t.a);
        D d2 = cross(s.b - s.a, s.b - t.a);
        if(equal(abs(d1), 0) && equal(abs(d2), 0)) return t.a;
        return t.a + (t.b - t.a) * (d2 / d1);
    }

    // 線分s, tの交点の計算
    Point crossPoint(const Segment &s, const Segment &t) {
        return crossPoint(Line(s), Line(t));
    }

    // 線分sと線分tが交差しているかどうか
    bool isIntersect(const Segment &s, const 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;
    }

    // 線分sとtの距離
    D distanceBetweenSegments(const Segment &s, const Segment &t) {
        if(isIntersect(s, t)) return (D)(0);
        D ans = distanceBetweenSegmentAndPoint(s, t.a);
        chmin(ans, distanceBetweenSegmentAndPoint(s, t.b));
        chmin(ans, distanceBetweenSegmentAndPoint(t, s.a));
        chmin(ans, distanceBetweenSegmentAndPoint(t, s.b));
        return ans;
    }

    // 射影(projection)
    // 直線(線分)lに点pから引いた垂線の足を求める
    Point projection(const Line &l, const Point &p) {
        D t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
        return l.a + (l.a - l.b) * t;
    }

    Point projection(const Segment &l, const Point &p) {
        D t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
        return l.a + (l.a - l.b) * t;
    }

    // 反射(reflection)
    // 直線lを対称軸として点pと線対称の位置にある点を求める
    Point reflection(const Line &l, const Point &p) {
        return p + (projection(l, p) - p) * 2.0;
    }

    // 2つの円の交差判定
    // 返り値は共通接線の数
    int isIntersect(const Circle &c1, const Circle &c2) {
        D d = abs(c1.p - c2.p);
        // 2つの円が離れている場合
        if(d > c1.r + c2.r + EPS) return 4;
        // 外接している場合
        if(equal(d, c1.r + c2.r)) return 3;
        // 内接している場合
        if(equal(d, abs(c1.r - c2.r))) return 1;
        // 内包している場合
        if(d < abs(c1.r - c2.r) - EPS) return 0;
        return 2;
    }

    // 2つの円の交点
    vector<Point> crossPoint(const Circle &c1, const Circle &c2) {
        vector<Point> res;
        int mode = isIntersect(c1, c2);
        // 2つの中心の距離
        D d = abs(c1.p - c2.p);
        // 2円が離れている場合
        if(mode == 4) return res;
        // 1つの円がもう1つの円に内包されている場合
        if(mode == 0) return res;
        // 2円が外接する場合
        if(mode == 3) {
            D t = c1.r / (c1.r + c2.r);
            res.emplace_back(c1.p + (c2.p - c1.p) * t);
            return res;
        }
        // 内接している場合
        if(mode == 1) {
            if(c2.r < c1.r - EPS) {
                res.emplace_back(c1.p + (c2.p - c1.p) * (c1.r / d));
            } else {
                res.emplace_back(c2.p + (c1.p - c2.p) * (c2.r / d));
            }
            return res;
        }
        // 2円が重なる場合
        D rc1 = (c1.r * c1.r + d * d - c2.r * c2.r) / (2 * d);
        D rs1 = sqrt(c1.r * c1.r - rc1 * rc1);
        if(c1.r - abs(rc1) < EPS) rs1 = 0;
        Point e12 = (c2.p - c1.p) / abs(c2.p - c1.p);
        res.emplace_back(c1.p + rc1 * e12 + rs1 * e12 * Point(0, 1));
        res.emplace_back(c1.p + rc1 * e12 + rs1 * e12 * Point(0, -1));
        return res;
    }

    // 点pが円cの内部(円周上も含む)に入っているかどうか
    bool isInCircle(const Circle &c, const Point &p) {
        D d = abs(c.p - p);
        return (equal(d, c.r) || d < c.r - EPS);
    }

    // 円cと直線lの交点
    vector<Point> crossPoint(const Circle &c, const Line &l) {
        vector<Point> res;
        D d = distanceBetweenLineAndPoint(l, c.p);
        // 交点を持たない
        if(d > c.r + EPS) return res;
        // 接する
        Point h = projection(l, c.p);
        if(equal(d, c.r)) {
            res.emplace_back(h);
            return res;
        }
        Point e = unitVector(l.b - l.a);
        D ph = sqrt(c.r * c.r - d * d);
        res.emplace_back(h - e * ph);
        res.emplace_back(h + e * ph);
        return res;
    }

    // 点pを通る円cの接線
    // 2本あるので、接点のみを返す
    vector<Point> tangentToCircle(const Point &p, const Circle &c) {
        return crossPoint(c, Circle(p, sqrt(norm(c.p - p) - c.r * c.r)));
    }

    // 円の共通接線
    vector<Line> tangent(const Circle &a, const Circle &b) {
        vector<Line> ret;
        // 2円の中心間の距離
        D g = abs(a.p - b.p);
        // 円が内包されている場合
        if(equal(g, 0)) return ret;
        Point u = unitVector(b.p - a.p);
        Point v = rotate(u, PI / 2);
        for(int s : {-1, 1}) {
            D h = (a.r + b.r * s) / g;
            if(equal(h * h, 1)) {
                ret.emplace_back(a.p + (h > 0 ? u : -u) * a.r,
                                 a.p + (h > 0 ? u : -u) * a.r + v);

            } else if(1 - h * h > 0) {
                Point U = u * h, V = v * sqrt(1 - h * h);
                ret.emplace_back(a.p + (U + V) * a.r,
                                 b.p - (U + V) * (b.r * s));
                ret.emplace_back(a.p + (U - V) * a.r,
                                 b.p - (U - V) * (b.r * s));
            }
        }
        return ret;
    }

    // 多角形の面積を求める
    D PolygonArea(const vector<Point> &p) {
        D res = 0;
        int n = p.size();
        for(int i = 0; i < n - 1; i++) res += cross(p[i], p[i + 1]);
        res += cross(p[n - 1], p[0]);
        return res * 0.5;
    }

    // 凸多角形かどうか
    bool isConvex(const vector<Point> &p) {
        int n = p.size();
        int now, pre, nxt;
        for(int i = 0; i < n; i++) {
            pre = (i - 1 + n) % n;
            nxt = (i + 1) % n;
            now = i;
            if(ccw(p[pre], p[now], p[nxt]) == -1) return false;
        }
        return true;
    }

    // 凸包 O(NlogN)
    vector<Point> ConvexHull(vector<Point> &p) {
        int n = (int)p.size(), k = 0;
        sort(all(p), [](const Point &a, const Point &b) {
            return (real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b));
        });
        vector<Point> ch(2 * n);
        // 一直線上の3点を含める -> (< -EPS)
        // 含め無い -> (< EPS)
        for(int i = 0; i < n; ch[k++] = p[i++]) { // lower
            while(k >= 2 &&
                  cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < EPS)
                --k;
        }
        for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) { // upper
            while(k >= t &&
                  cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < EPS)
                --k;
        }
        ch.resize(k - 1);
        return ch;
    }

    // 多角形gに点pが含まれているか?
    // 含まれる:2, 辺上にある:1, 含まれない:0
    int isContained(const vector<Point> &g, const Point &p) {
        bool in = false;
        int n = (int)g.size();
        for(int i = 0; i < n; i++) {
            Point a = g[i] - p, b = g[(i + 1) % n] - p;
            if(imag(a) > imag(b)) swap(a, b);
            if(imag(a) <= EPS && EPS < imag(b) && cross(a, b) < -EPS) in = !in;
            if(cross(a, b) == 0 && dot(a, b) <= 0) return 1;
        }
        return (in ? 2 : 0);
    }

} // namespace geometry

using namespace geometry;

int main(){
    while(1){
        int n; cin >> n;
        if(!n) break;
        int sx,sy,gx,gy; cin >> sx >> sy >> gx >> gy;
        Segment s = Segment(Point(sx,sy),Point(gx,gy));
        vector<Segment> seg;
        vector<int> h;
        bool zero = false;
        rep(i,n){
            int x,y,X,Y,H; cin >> x >> y >> X >> Y >> H;
            if(x <= sx && y <= sy && X >= sx && Y >= sy) zero = true;
            vector<Point> p(4);
            p[0] = {(double)x,(double)y};
            p[1] = {(double)X,(double)y};
            p[2] = {(double)X,(double)Y};
            p[3] = {(double)x,(double)Y};
            rep(j,4){
                seg.emplace_back(p[j],p[(j+1)%4]);
                h.push_back(H);
            }
        }
        if(zero){
            cout << "0.0000" << "\n";
            continue;
        }
        D ok = 0.0, ng = 1000.0;
        rep(z,50){
            D r = (ok+ng) / 2.0;
            bool f = true;
            rep(i,4*n){
                double di = distanceBetweenSegments(s,seg[i]);
                if(h[i] >= r){
                    if(di < r) f = false; 
                }else{
                    if(2.0*r*h[i] - h[i]*h[i] > di*di) f = false;
                }
            }
            if(f) ok = r;
            else ng = r;
        }
        printf("%.6f\n",ok);
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3244
final_rank: 2