#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
#include <cassert>
#include <bitset>
#include "bits/stdc++.h"
using namespace std;
using LL = long long;

//P型変数(ベクトル)x,yについて、(c=実数)
//x+y,x-yはそのまま
//x*c,x/cもそのまま
//長さはabs(x)、距離はabs(x-y)
//単位ベクトルはx/abs(x)
//法線ベクトルはx*P(0,±1)(+←→-)
//x軸となす角はarg(v)、uとvのなす角はarg(u/v)
//uとvを2辺とする三角形の面積はcross(u,v)*0.5

//complexの仕様：
//real実部　imag虚部　abs絶対値　arg偏角　norm絶対値の２乗
//conj共役　projリーマン球面への射影(?)　polar(r,t)極形式からの変換
using FLOAT = double;
const FLOAT EPS = 1e-8;
const FLOAT INF = 1e12;
typedef complex<FLOAT> P;//点クラス
namespace std {
	bool operator < (const P& a, const P& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}
//FLOAT同士の等しさ
inline bool EQ(FLOAT a, FLOAT b) { return abs(a - b) < EPS; }
//P同士の等しさ
inline bool EQV(P a, P b) { return EQ(a.real(), b.real()) && EQ(a.imag(), b.imag()); }
//外積(a.x*b.y-a.y*b.x)
double cross(const P& a, const P& b) {
	return imag(conj(a)*b);
}
//内積(a.x*b.x+a.y*b.y)
double dot(const P& a, const P& b) {
	return real(conj(a)*b);
}
//線クラス(端点は[0],[1])
struct L : public vector<P> {
	L(const P &a, const P &b) {
		push_back(a); push_back(b);
	}
};
typedef vector<P> G;//多角形クラス
					//円クラス
struct C {
	P p; FLOAT r;
	C(const P &p, FLOAT r) : p(p), r(r) { }
};
//謎関数(軽くて色々できる)
//なんかEPSを適切につけるとよさそう(FLOAT型側につけるのもいいかも？)
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;
}

//直線・線分交差系
//直線＋直線の交差判定
bool intersectLL(const L &l, const L &m) {
	return abs(cross(l[1] - l[0], m[1] - m[0])) > EPS || // non-parallel
		abs(cross(l[1] - l[0], m[0] - l[0])) < EPS;   // same line
}
//直線＋線分の交差判定
bool intersectLS(const L &l, const L &s) {
	return cross(l[1] - l[0], s[0] - l[0])*       // s[0] is left of l
		cross(l[1] - l[0], s[1] - l[0]) < EPS; // s[1] is right of l
}
//直線＋点の交差判定
bool intersectLP(const L &l, const P &p) {
	return abs(cross(l[1] - p, l[0] - p)) < EPS;
}
//線分＋線分の交差判定
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
}

//距離・交点系
//線分への点の射影(下ろした垂線の足)
P projection(const L &l, const P &p) {
	FLOAT t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
	return l[0] + t * (l[0] - l[1]);
}
//線分と対称な点
P reflection(const L &l, const P &p) {
	return p + (projection(l, p) - p) * 2.;
}
//点と直線の距離
FLOAT distanceLP(const L &l, const P &p) {
	return abs(p - projection(l, p));
}
//直線と直線の距離（平行でないときは0）
FLOAT distanceLL(const L &l, const L &m) {
	return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
//直線と線分の距離(交わるときは0)
FLOAT distanceLS(const L &l, const L &s) {
	if (intersectLS(l, s)) return 0;
	return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
//線分と点の距離
FLOAT 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));
}
//線分と線分の距離(交わるときは0)
FLOAT 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 crosspoint(const L &l, const L &m) {
	FLOAT A = cross(l[1] - l[0], m[1] - m[0]);
	FLOAT B = cross(l[1] - l[0], l[1] - m[0]);
	if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
	if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
	return m[0] + B / A * (m[1] - m[0]);
}

//多角形系
//点が多角形の内部/境界/外部のどこにあるかを判定する(O(n))
//凸多角形の場合はより高速な関数がある
enum { OUT, ON, IN };
int contains(const G& poly, const P& point) {
	bool in = false;
	for (int i = 0; i < poly.size(); ++i) {
		P a = poly[i] - point, b = poly[(i + 1) % poly.size()] - point;
		if (imag(a) > imag(b)) swap(a, b);
		if (imag(a) <= 0 && 0 < imag(b))
			if (cross(a, b) < 0) in = !in;
		if (cross(a, b) == 0 && dot(a, b) <= 0) return ON;
	}
	return in ? IN : OUT;
}
//多角形の面積
FLOAT areaOfG(const G& poly) {
	FLOAT A = 0;
	for (int i = 0; i < poly.size(); ++i)
		A += cross(poly[i], poly[(i + 1) % poly.size()]);
	return A / 2;
}

//凸多角形系
//凸包を構成する点集合をグラハムスキャンの亜種で求める
G convexHull(G ps) {
	int n = ps.size(), k = 0;
	assert(n >= 3);//頂点が足りない
	sort(ps.begin(), ps.end());
	G ch(2 * n);
	for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
		while (k >= 2 && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = ps[i--]) // upper-hull
		while (k >= t && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	ch.resize(k - 1);
	return ch;
}
//与えられた多角形が凸かを調べる
bool isConvex(const G& poly) {
	for (int i = 0; i < poly.size(); ++i)
		if (ccw(poly[(i + poly.size() - 1) % poly.size()], poly[i], poly[(i + 1) % poly.size()]))
			return false;
	return true;
}
//凸多角形の直径をキャリパー法で求める(O(n log n))
FLOAT convexDiameter(const G& poly) {
	const int n = poly.size();
	int is = 0, js = 0;
	for (int i = 1; i < n; ++i) {
		if (imag(poly[i]) > imag(poly[is]))is = i;
		if (imag(poly[i]) < imag(poly[js]))js = i;
	}
	FLOAT maxd = norm(poly[is] - poly[js]);
	int i = is, maxi = is;
	int j = js, maxj = js;
	auto diff = [](const G&pol, int i) {
		return pol[(i + 1) % pol.size()] - pol[i];
	};
	do {
		if (cross(diff(poly, i), diff(poly, j)) >= 0)j = (j + 1) % n;
		else i = (i + 1) % n;
		if (norm(poly[i] - poly[j]) > maxd) {
			maxd = norm(poly[i] - poly[j]);
			maxi = i; maxj = j;
		}
	} while (i != is || j != js);
	return maxd;
}
//凸多角形の頂点のうち直線から一番遠いものを二分探索で求める(O(log n))
//一般的な多角形についてしたい場合は、凸にしたうえで使用するとよい
P convexExtreme(const G&poly, const L&l) {
	const int n = poly.size();
	int a = 0, b = n;
	auto d = [&](int k) {
		return dot(poly[k], l[1] - l[0]);
	};
	if (d(0) >= d(n - 1) && d(0) >= d(1))return poly[0];
	while (a < b) {
		int c = (a + b) / 2;
		if (d(c) >= d(c - 1) && d(c) >= d(c + 1))return poly[c];
		if (d(a + 1) > d(a)) {
			if (d(c + 1) <= d(c) || d(a) > d(c))b = c;
			else a = c;
		}
		else {
			if (d(c + 1) > d(c) || d(a) >= d(c))a = c;
			else b = c;
		}
	}
	assert(false);
}
//点が凸多角形の内部/境界/外部のどこにあるかを二分探索を用いて判定する(O(log n))
//enum { OUT, ON, IN };
int convexContains(const G&poly, const P&p) {
	const int n = poly.size();
	P g = (poly[0] + poly[n / 3] + poly[2 * n / 3]) / 3.;//適当な３点の重心をとる
	int a = 0, b = n;
	while (a + 1 < b) {
		int c = (a + b) / 2;
		if (cross(poly[a] - g, poly[c] - g) > 0) {
			if (cross(poly[a] - g, p - g) > 0 && cross(poly[c] - g, p - g) < 0)b = c;
			else a = c;
		}
		else {
			if (cross(poly[a] - g, p - g) < 0 && cross(poly[c] - g, p - g) > 0)a = c;
			else b = c;
		}
	}
	b %= n;
	if (cross(poly[a] - p, poly[b] - p) < 0)return OUT;
	if (cross(poly[a] - p, poly[b] - p) > 0)return IN;
	return ON;
}

//相対変換
//点(a,b)と直線(y=a*x-b)を一対一で対応させる
//言い換えによって解ける問題がある、らしい
//反射性、距離の保存(pとlの距離とl*とp*の距離は等しい)、
//順序の保存(pがlの左/上/右にある⇔l*がp*の左/上/右にある)が成り立つ
L dual(const P&p) {
	return L(P(0, -imag(p)), P(1, real(p) - imag(p)));
}
P dual(const L&l) {
	const P&p = l[0], &q = l[1];
	return P(imag(p - q) / real(p - q), cross(p, q) / real(q - p));
}

int N;
LL x[123456], r[123456];

int main(void)
{
	cin >> N;
	FLOAT lo = 0, hi = 1234567890123456.;
	for (int i = 0; i < N; ++i) {
		cin >> x[i] >> r[i];
		hi = min(hi, (FLOAT)r[i]);
	}
	for (int loop = 0; loop < 50; ++loop) {
		FLOAT mid = (lo + hi) / 2;
		FLOAT lef = -1234567890123456.;
		FLOAT rht = +1234567890123456.;
		for (int i = 0; i < N; ++i) {
			FLOAT dif = sqrt(r[i] * r[i] - mid * mid);
			lef = max(lef,x[i] - dif);
			rht = min(rht,x[i] + dif);
		}
		if (lef > rht) {
			hi = mid;
		}
		else {
			lo = mid;
		}
	}
	cout << fixed << setprecision(10);
	cout << lo << endl;
	return 0;
}



### Prompt

Please formulate a CPP solution to the following problem:

The Aiz Archaeological Society has set out to investigate the ruins of the ancient nation Iwashiro, which sinks in the Hibara Sea. The ruins are somewhere in the Hibara Sea. Therefore, I decided to use an exploration radar to roughly mark the location of the ruins by radar exploration from the coastline and estimate how many meters away from the coastline should be investigated.

<image>


An observation point will be set up on the coastline represented by a straight line as shown above, and an exploration radar will be placed. The exploration radar only knows that there are archaeological sites within a semicircle of a certain size centered on the observation point. However, by combining a plurality of observation data, it is possible to narrow down to a narrower range.

Given some observational data consisting of the location of the observation point and the radius indicated by the exploration radar, write a program to find out how far you need to investigate from the coastline.



Input

The input is given in the following format.


N
x1 r1
x2 r2
::
xN rN


The first line gives the number of data N (1 ≤ N ≤ 100000) measured by the exploration radar. In the next N lines, the integer xi (0 ≤ xi ≤ 1,000,000), which indicates the position of the observation data i on the coastline in meters, and the integer ri (1 ≤), which indicates how many meters the archaeological site is within a radius of that position. ri ≤ 1,000,000) is given. Two or more observation data with the same observation point may be given.

If there are multiple observational data given, it can be considered that there are always points included in all of those semicircles.

Output

Outputs the actual number of meters that need to be investigated from the coastline. However, the error must not exceed plus or minus 0.001 meters. If this condition is satisfied, any number of digits after the decimal point may be displayed.

Examples

Input

2
0 2
1 2


Output

1.936


Input

3
0 3
1 2
2 1


Output

1.0


Input

2
0 1
3 2


Output

0.0

### Response

```cpp
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
#include <cassert>
#include <bitset>
#include "bits/stdc++.h"
using namespace std;
using LL = long long;

//P型変数(ベクトル)x,yについて、(c=実数)
//x+y,x-yはそのまま
//x*c,x/cもそのまま
//長さはabs(x)、距離はabs(x-y)
//単位ベクトルはx/abs(x)
//法線ベクトルはx*P(0,±1)(+←→-)
//x軸となす角はarg(v)、uとvのなす角はarg(u/v)
//uとvを2辺とする三角形の面積はcross(u,v)*0.5

//complexの仕様：
//real実部　imag虚部　abs絶対値　arg偏角　norm絶対値の２乗
//conj共役　projリーマン球面への射影(?)　polar(r,t)極形式からの変換
using FLOAT = double;
const FLOAT EPS = 1e-8;
const FLOAT INF = 1e12;
typedef complex<FLOAT> P;//点クラス
namespace std {
	bool operator < (const P& a, const P& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}
//FLOAT同士の等しさ
inline bool EQ(FLOAT a, FLOAT b) { return abs(a - b) < EPS; }
//P同士の等しさ
inline bool EQV(P a, P b) { return EQ(a.real(), b.real()) && EQ(a.imag(), b.imag()); }
//外積(a.x*b.y-a.y*b.x)
double cross(const P& a, const P& b) {
	return imag(conj(a)*b);
}
//内積(a.x*b.x+a.y*b.y)
double dot(const P& a, const P& b) {
	return real(conj(a)*b);
}
//線クラス(端点は[0],[1])
struct L : public vector<P> {
	L(const P &a, const P &b) {
		push_back(a); push_back(b);
	}
};
typedef vector<P> G;//多角形クラス
					//円クラス
struct C {
	P p; FLOAT r;
	C(const P &p, FLOAT r) : p(p), r(r) { }
};
//謎関数(軽くて色々できる)
//なんかEPSを適切につけるとよさそう(FLOAT型側につけるのもいいかも？)
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;
}

//直線・線分交差系
//直線＋直線の交差判定
bool intersectLL(const L &l, const L &m) {
	return abs(cross(l[1] - l[0], m[1] - m[0])) > EPS || // non-parallel
		abs(cross(l[1] - l[0], m[0] - l[0])) < EPS;   // same line
}
//直線＋線分の交差判定
bool intersectLS(const L &l, const L &s) {
	return cross(l[1] - l[0], s[0] - l[0])*       // s[0] is left of l
		cross(l[1] - l[0], s[1] - l[0]) < EPS; // s[1] is right of l
}
//直線＋点の交差判定
bool intersectLP(const L &l, const P &p) {
	return abs(cross(l[1] - p, l[0] - p)) < EPS;
}
//線分＋線分の交差判定
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
}

//距離・交点系
//線分への点の射影(下ろした垂線の足)
P projection(const L &l, const P &p) {
	FLOAT t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
	return l[0] + t * (l[0] - l[1]);
}
//線分と対称な点
P reflection(const L &l, const P &p) {
	return p + (projection(l, p) - p) * 2.;
}
//点と直線の距離
FLOAT distanceLP(const L &l, const P &p) {
	return abs(p - projection(l, p));
}
//直線と直線の距離（平行でないときは0）
FLOAT distanceLL(const L &l, const L &m) {
	return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
//直線と線分の距離(交わるときは0)
FLOAT distanceLS(const L &l, const L &s) {
	if (intersectLS(l, s)) return 0;
	return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
//線分と点の距離
FLOAT 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));
}
//線分と線分の距離(交わるときは0)
FLOAT 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 crosspoint(const L &l, const L &m) {
	FLOAT A = cross(l[1] - l[0], m[1] - m[0]);
	FLOAT B = cross(l[1] - l[0], l[1] - m[0]);
	if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
	if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
	return m[0] + B / A * (m[1] - m[0]);
}

//多角形系
//点が多角形の内部/境界/外部のどこにあるかを判定する(O(n))
//凸多角形の場合はより高速な関数がある
enum { OUT, ON, IN };
int contains(const G& poly, const P& point) {
	bool in = false;
	for (int i = 0; i < poly.size(); ++i) {
		P a = poly[i] - point, b = poly[(i + 1) % poly.size()] - point;
		if (imag(a) > imag(b)) swap(a, b);
		if (imag(a) <= 0 && 0 < imag(b))
			if (cross(a, b) < 0) in = !in;
		if (cross(a, b) == 0 && dot(a, b) <= 0) return ON;
	}
	return in ? IN : OUT;
}
//多角形の面積
FLOAT areaOfG(const G& poly) {
	FLOAT A = 0;
	for (int i = 0; i < poly.size(); ++i)
		A += cross(poly[i], poly[(i + 1) % poly.size()]);
	return A / 2;
}

//凸多角形系
//凸包を構成する点集合をグラハムスキャンの亜種で求める
G convexHull(G ps) {
	int n = ps.size(), k = 0;
	assert(n >= 3);//頂点が足りない
	sort(ps.begin(), ps.end());
	G ch(2 * n);
	for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
		while (k >= 2 && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = ps[i--]) // upper-hull
		while (k >= t && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	ch.resize(k - 1);
	return ch;
}
//与えられた多角形が凸かを調べる
bool isConvex(const G& poly) {
	for (int i = 0; i < poly.size(); ++i)
		if (ccw(poly[(i + poly.size() - 1) % poly.size()], poly[i], poly[(i + 1) % poly.size()]))
			return false;
	return true;
}
//凸多角形の直径をキャリパー法で求める(O(n log n))
FLOAT convexDiameter(const G& poly) {
	const int n = poly.size();
	int is = 0, js = 0;
	for (int i = 1; i < n; ++i) {
		if (imag(poly[i]) > imag(poly[is]))is = i;
		if (imag(poly[i]) < imag(poly[js]))js = i;
	}
	FLOAT maxd = norm(poly[is] - poly[js]);
	int i = is, maxi = is;
	int j = js, maxj = js;
	auto diff = [](const G&pol, int i) {
		return pol[(i + 1) % pol.size()] - pol[i];
	};
	do {
		if (cross(diff(poly, i), diff(poly, j)) >= 0)j = (j + 1) % n;
		else i = (i + 1) % n;
		if (norm(poly[i] - poly[j]) > maxd) {
			maxd = norm(poly[i] - poly[j]);
			maxi = i; maxj = j;
		}
	} while (i != is || j != js);
	return maxd;
}
//凸多角形の頂点のうち直線から一番遠いものを二分探索で求める(O(log n))
//一般的な多角形についてしたい場合は、凸にしたうえで使用するとよい
P convexExtreme(const G&poly, const L&l) {
	const int n = poly.size();
	int a = 0, b = n;
	auto d = [&](int k) {
		return dot(poly[k], l[1] - l[0]);
	};
	if (d(0) >= d(n - 1) && d(0) >= d(1))return poly[0];
	while (a < b) {
		int c = (a + b) / 2;
		if (d(c) >= d(c - 1) && d(c) >= d(c + 1))return poly[c];
		if (d(a + 1) > d(a)) {
			if (d(c + 1) <= d(c) || d(a) > d(c))b = c;
			else a = c;
		}
		else {
			if (d(c + 1) > d(c) || d(a) >= d(c))a = c;
			else b = c;
		}
	}
	assert(false);
}
//点が凸多角形の内部/境界/外部のどこにあるかを二分探索を用いて判定する(O(log n))
//enum { OUT, ON, IN };
int convexContains(const G&poly, const P&p) {
	const int n = poly.size();
	P g = (poly[0] + poly[n / 3] + poly[2 * n / 3]) / 3.;//適当な３点の重心をとる
	int a = 0, b = n;
	while (a + 1 < b) {
		int c = (a + b) / 2;
		if (cross(poly[a] - g, poly[c] - g) > 0) {
			if (cross(poly[a] - g, p - g) > 0 && cross(poly[c] - g, p - g) < 0)b = c;
			else a = c;
		}
		else {
			if (cross(poly[a] - g, p - g) < 0 && cross(poly[c] - g, p - g) > 0)a = c;
			else b = c;
		}
	}
	b %= n;
	if (cross(poly[a] - p, poly[b] - p) < 0)return OUT;
	if (cross(poly[a] - p, poly[b] - p) > 0)return IN;
	return ON;
}

//相対変換
//点(a,b)と直線(y=a*x-b)を一対一で対応させる
//言い換えによって解ける問題がある、らしい
//反射性、距離の保存(pとlの距離とl*とp*の距離は等しい)、
//順序の保存(pがlの左/上/右にある⇔l*がp*の左/上/右にある)が成り立つ
L dual(const P&p) {
	return L(P(0, -imag(p)), P(1, real(p) - imag(p)));
}
P dual(const L&l) {
	const P&p = l[0], &q = l[1];
	return P(imag(p - q) / real(p - q), cross(p, q) / real(q - p));
}

int N;
LL x[123456], r[123456];

int main(void)
{
	cin >> N;
	FLOAT lo = 0, hi = 1234567890123456.;
	for (int i = 0; i < N; ++i) {
		cin >> x[i] >> r[i];
		hi = min(hi, (FLOAT)r[i]);
	}
	for (int loop = 0; loop < 50; ++loop) {
		FLOAT mid = (lo + hi) / 2;
		FLOAT lef = -1234567890123456.;
		FLOAT rht = +1234567890123456.;
		for (int i = 0; i < N; ++i) {
			FLOAT dif = sqrt(r[i] * r[i] - mid * mid);
			lef = max(lef,x[i] - dif);
			rht = min(rht,x[i] + dif);
		}
		if (lef > rht) {
			hi = mid;
		}
		else {
			lo = mid;
		}
	}
	cout << fixed << setprecision(10);
	cout << lo << endl;
	return 0;
}



```