/*
自己写的n^2算法...
*/
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 10000;
double X[MAXN];
double Y[MAXN];
int n;
double get_val(double dx, double dy) {
return sqrt(dx*dx + dy*dy);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
while(scanf("%d", &n) && n!=0) {
for(int i=0; i<n; i++) {
scanf("%lf%lf", &X[i], &Y[i]);
}
double min_len = MAXN;
for(int i=0; i<n-1; i++) {
for(int j=i+1; j<n; j++) {
double dx = abs(X[i]-X[j]);
if(dx >= min_len) continue;
double dy = abs(Y[i]-Y[j]);
if(dy >= min_len) continue;
double val = get_val(dx, dy);
if(val < min_len)
min_len = val;
}
}
if(min_len-MAXN > -1e-9) printf("INFINITY\n");
else printf("%.4lf\n", min_len);
}
return 0;
}
/*
n^2算法,排序后剪枝(速度还可以)
*/
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 10000;
struct node{
double x, y;
};
node points[MAXN];
int n;
double get_val(double dx, double dy) {
return sqrt(dx*dx + dy*dy);
}
bool cmp(node a, node b)
{
return a.x < b.x;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
while(scanf("%d", &n) && n!=0) {
for(int i=0; i<n; i++) {
scanf("%lf%lf", &points[i].x, &points[i].y);
}
sort(points, points+n, cmp);
double min_len = MAXN;
for(int i=0; i<n-1; i++) {
for(int j=i+1; j<n; j++) {
double dx = points[j].x - points[i].x;
if(dx >= min_len) break;
double val = get_val(dx, points[i].y-points[j].y);
if(val < min_len)
min_len = val;
}
}
if(min_len-MAXN > -1e-9) printf("INFINITY\n");
else printf("%.4lf\n", min_len);
}
return 0;
}
/*
算法导论33章 分冶法 nlgn算法, 实现的不好...
*/
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 10000;
struct node{
double x, y;
};
node pointx[MAXN]; //按x坐标排序的数组
int pointy[MAXN]; //按y坐标排序的数组
int n;
double get_val(double dx, double dy) {
return sqrt(dx*dx + dy*dy);
}
double get_val(int i, int j) {
double dx = pointx[i].x-pointx[j].x;
double dy = pointx[i].y-pointx[j].y;
return sqrt(dx*dx + dy*dy);
}
bool cmpx(node a, node b)
{
return a.x < b.x;
}
bool cmpy(int a, int b)
{
return pointx[a].y < pointx[b].y;
}
//分冶法
double closePair(int l, int r)
{
if(r-l<=3) { //直接算
double min_len = MAXN;
for(int i=l; i<r-1; i++) {
for(int j=i+1; j<r; j++) {
double val = get_val(i, j);
if(val < min_len) min_len = val;
}
}
return min_len;
}
int cury[MAXN];
memcpy(cury, pointy, sizeof(pointy));
int m = l + (r-l)/2;
int p1=l, p2=m;
for(int i=l; i<r; i++) {
if(cury[i] < m) {
pointy[p1++] = cury[i];
} else {
pointy[p2++] = cury[i];
}
}
double min_val = min(closePair(l, m), closePair(m, r));
int leftx = pointx[m].x - min_val;
int rightx = pointx[m].x + min_val;
int cnt = 0;
for(int i=l; i<r; i++) {
if(pointx[pointy[i]].x >= leftx &&
pointx[pointy[i]].x <= rightx) {
cury[cnt++] = pointy[i];
}
}
for(int i=0; i<cnt-1; i++) {
for(int j=i+1; j<i+8 && j<cnt; j++) {
min_val = min(min_val, get_val(cury[i], cury[j]));
}
}
return min_val;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
while(scanf("%d", &n) && n!=0) {
for(int i=0; i<n; i++) {
scanf("%lf%lf", &pointx[i].x, &pointx[i].y);
}
double min_len = MAXN;
sort(pointx, pointx+n, cmpx);
for(int i=0; i<n; i++) {
pointy[i] = i;
}
sort(pointy, pointy+n, cmpy);
min_len = closePair(0, n);
if(min_len-MAXN > -1e-9) printf("INFINITY\n");
else printf("%.4lf\n", min_len);
}
return 0;
}