#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <sstream>
#include <set>
#include <map>
#include <queue>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <ctime>

using namespace std;

#define EPS 1e-8

struct Circle
{
    double x, y, r;
};

bool XYorder(Circle P1, Circle P2)
{
	if(P1.x != P2.x) return P1.x < P2.x;
	return P1.y < P2.y;
}
bool YXorder(Circle P1, Circle P2)
{
	if(P1.y != P2.y) return P1.y < P2.y;
	return P1.x < P2.x;
}

double dist(const Circle &A, const Circle &B)
{
	return hypot(A.x - B.x, A.y - B.y) - A.r - B.r;
}

double R;

double closest_recursive(vector <Circle> vx, vector <Circle> vy)
{
	if(vx.size()==1) return 1e20;
	if(vx.size()==2) return dist(vx[0], vx[1]);
	
	Circle cut = vx[vx.size()/2];
	
	vector <Circle> vxL, vxR;
	for(int i=0; i<vx.size(); i++)
		if(vx[i].x < cut.x || (vx[i].x == cut.x && vx[i].y <= cut.y))
			vxL.push_back(vx[i]);
		else vxR.push_back(vx[i]);
	
	vector <Circle> vyL, vyR;
	for(int i=0; i<vy.size(); i++)
		if(vy[i].x < cut.x || (vy[i].x == cut.x && vy[i].y <= cut.y))
			vyL.push_back(vy[i]);
		else vyR.push_back(vy[i]);
	
	double dL = closest_recursive(vxL, vyL);
	double dR = closest_recursive(vxR, vyR);
	double d = min(dL, dR);
	
	vector <Circle> b;
	for(int i=0; i<vy.size(); i++)
		if(abs(vy[i].x - cut.x) <= d + 2*R + EPS)
			b.push_back(vy[i]);
	
	for(int i=0; i<b.size(); i++)
		for(int j=i+1; j<b.size() && (b[j].y - b[i].y) <= d + 2*R + EPS; j++)
			d = min(d, dist(b[i], b[j]));
	
	return d;
}
double closest(vector <Circle> Circles)
{
	vector <Circle> vx = Circles, vy = Circles;
	sort(vx.begin(), vx.end(), XYorder);
	sort(vy.begin(), vy.end(), YXorder);
	return closest_recursive(vx,vy);
}

int main()
{
	int n;
	while(scanf("%d", &n) == 1)
	{
		if(n == 0) break;
		R = 0;
		
		vector <Circle> P(n);
		for(int i=0; i<n; i++){
			scanf("%lf %lf %lf", &P[i].r, &P[i].x, &P[i].y);
			R = max(R, P[i].r);
		}
		printf("%.10lf\n", closest(P));
	}
	
	return 0;
}