#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;
}




Measured memory_bytes: 4856