//accepter by 10245
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
class Point{
public:
  double x,y,r;
  bool operator<(const Point & a)const{
    if ( x != a.x)return x < a.x;
    return y < a.y;
  }
  double dist(Point & a){
    return sqrt((a.x-x)*(a.x-x)+(a.y-y)*(a.y-y))-r-a.r;
  }
};
double min_val=10000;//need to insert Largest value
#define MAXPOINT 1e250
Point BigPoint ={MAXPOINT,MAXPOINT};
double maxr;

void Merge(Point *a,int l,int mid,int r,double midx){
  int n1 = mid-l+1,n2 = r-mid,pr=0,pl=0;
  Point L[n1+1],R[n2+1];
  for(int i=0;i<n1;i++)L[i]=a[l+i];
  for(int i=0;i<n2;i++)R[i]=a[mid+1+i];
  L[n1]=R[n2]=BigPoint;
  for(int i=l;i<r+1;i++){
    if ( L[pl].y < R[pr].y)a[i]=L[pl++];
    else a[i]=R[pr++];
  }

  vector<Point> t;
  for(int i=l;i<r+1;i++){
    if ( abs(midx-a[i].x)< min_val+2*maxr){
      t.push_back(a[i]);
    } 
  }
  for(int i=0;i<t.size();i++){
    for(int j=i+1;j<t.size()&&abs(t[i].y-t[j].y)<min_val+2*maxr;j++){
      min_val=min(min_val,t[i].dist(t[j]));
    }
  }


}


void MergeSort(Point *a,int l,int r){//include r that means <=r
  if ( l<r){
    int q = (r+l)/2;
    double midx = a[q].x;
    MergeSort(a,l,q);
    MergeSort(a,q+1,r);
    Merge(a,l,q,r,midx);
  }
}


int main(){
int n;
  while(cin >>n && n){
    min_val = 1e250;
    Point a[n];
    maxr=0;
    for(int i=0;i<n;i++){
      cin>>a[i].r>>a[i].x>>a[i].y;
      maxr=max(maxr,a[i].r);
    }
    sort(a,a+n);
    MergeSort(a,0,n-1);
    printf("%.10lf\n",min_val);
  }
}