For given n points in metric space, find the distance of the closest points.

Constraints

* 2 ≤ n ≤ 100,000
* -100 ≤ x, y ≤ 100

Input


n
x0 y0
x1 y1
:
xn-1 yn-1


The first integer n is the number of points.

In the following n lines, the coordinate of the i-th point is given by two real numbers xi and yi. Each value is a real number with at most 6 digits after the decimal point.

Output

Print the distance in a line. The output values should be in a decimal fraction with an error less than 0.000001.

Examples

Input

2
0.0 0.0
1.0 0.0


Output

1.000000


Input

3
0.0 0.0
2.0 0.0
1.0 1.0


Output

1.41421356237

Source: aizu | Difficulty: UNKNOWN_DIFFICULTY


Solutions:
import sys
from operator import itemgetter
from itertools import permutations
from math import sqrt

def solve(a: list):
	length = len(a)
	if length <= 3:
		return min((sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) for (p1, p2) in permutations(a, 2)))
	x_set_len = len(set((x for (x, _) in a)))
	axis = 0 if x_set_len > length / 2 else 1
	a.sort(key=itemgetter(axis))
	mid_index = length // 2
	(left, right) = (a[:mid_index], a[mid_index:])
	delta = min(solve(left), solve(right))
	median = a[mid_index][axis]
	m_a = []
	append = m_a.append
	for p in left[::-1]:
		if p[axis] < median - delta:
			break
		append(p)
	for p in right:
		if p[axis] > median + delta:
			break
		append(p)
	m_a.sort(key=itemgetter(not axis))
	for (i, p1) in enumerate(m_a):
		ub = p1[not axis] + delta
		for (j, p2) in enumerate(m_a[i + 1:]):
			if p2[not axis] > ub:
				break
			dist = sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
			if dist < delta:
				delta = dist
	return delta
N = int(input())
a = [tuple(map(float, l.split())) for l in sys.stdin.readlines()]
print('{:.10f}'.format(solve(a)))


import sys
from operator import attrgetter

class ClosestPair(object):

	def __init__(self):
		_input = sys.stdin.readlines()
		p_num = int(_input[0])
		points = map(lambda x: x.split(), _input[1:])
		p_list = [complex(float(x), float(y)) for (x, y) in points]
		p_list.sort(key=attrgetter('real'))
		ans = self.closest_pair(array=p_list, array_length=p_num)
		print('{:.6f}'.format(ans))

	def closest_pair(self, array, array_length):
		if array_length <= 1:
			return float('inf')
		mid_idx = array_length // 2
		div_line = array[mid_idx].real
		d_min = min(self.closest_pair(array[:mid_idx], mid_idx), self.closest_pair(array[mid_idx:], array_length - mid_idx))
		array.sort(key=attrgetter('imag'))
		min_stack = list()
		for ele in array:
			size = len(min_stack)
			if abs(ele.real - div_line) >= d_min:
				continue
			for j in range(size):
				alt = ele - min_stack[size - j - 1]
				if alt.imag >= d_min:
					break
				d_min = min(d_min, abs(alt))
			min_stack.append(ele)
		return d_min
case = ClosestPair()


import itertools

def _get_distance(p1, p2):
	return ((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) ** 0.5

def _get_min_distance(points):
	min_d = 400
	for (p1, p2) in itertools.combinations(points, 2):
		min_d = min(min_d, _get_distance(p1, p2))
	return min_d

def closest_pair_distance(points, axis):
	n = len(points)
	if n <= 3:
		return _get_min_distance(points)
	else:
		mid = n // 2
		(px, py) = zip(*points)
		if len(set(px)) > len(set(py)):
			if axis:
				points.sort(key=lambda p: p[0])
			axis1 = 0
			axis2 = 1
		else:
			if not axis:
				points.sort(key=lambda p: p[1])
			axis1 = 1
			axis2 = 0
		A_points = points[:mid]
		B_points = points[mid:]
		d_Amin = closest_pair_distance(A_points.copy(), axis1)
		d_Bmin = closest_pair_distance(B_points.copy(), axis1)
		dist = min(d_Amin, d_Bmin)
		min_d = dist
		for ap in A_points[::-1]:
			if B_points[0][axis1] - ap[axis1] >= dist:
				break
			for bp in B_points:
				if bp[axis1] - ap[axis1] >= dist:
					break
				if ap[axis2] - dist < bp[axis2] < ap[axis2] + dist:
					min_d = min(min_d, _get_distance(ap, bp))
		return min_d
import sys
file_input = sys.stdin
n = int(file_input.readline())
P = [tuple(map(float, line.split())) for line in file_input]
P.sort(key=lambda p: p[0])
ans = closest_pair_distance(P, 0)
print('{:f}'.format(ans))


from operator import itemgetter
from math import sqrt

def closest_distance(ps):

	def split(i, j):
		if j - i < 2:
			return float('INF')
		mid = (i + j) // 2
		d = min(split(i, mid), split(mid, j))
		(lv, rv) = (ps[mid][0] - d, ps[mid][0] + d)
		return merge(sorted([p for p in ps[i:j] if lv <= p[0] <= rv], key=itemgetter(1)), d)

	def merge(_ps, d):
		n = len(_ps)
		for i in range(n - 1):
			for j in range(i + 1, n):
				if d < _ps[j][1] - _ps[i][1]:
					break
				d = min(d, distance(_ps[i], _ps[j]))
		return d
	ps.sort(key=itemgetter(0, 1))
	return split(0, len(ps))

def dot(p0, p1):
	(x0, y0) = p0
	(x1, y1) = p1
	return x0 * x1 + y0 * y1

def distance(p0, p1):
	(x0, y0) = p0
	(x1, y1) = p1
	return sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)

def run():
	n = int(input())
	ps = []
	for _ in range(n):
		(x, y) = [float(i) for i in input().split()]
		ps.append((x, y))
	print('{:.10f}'.format(closest_distance(ps)))
run()


import math
from itertools import combinations
from operator import itemgetter
pts = []
line = input()
n = int(line)
for _ in range(0, n):
	line = input()
	(x, y) = list(map(float, line.split()))
	pts += [[x, y]]

def dist(p, q):
	(x1, y1) = p
	(x2, y2) = q
	return (x1 - x2) ** 2 + (y1 - y2) ** 2

def solve(p, axis):
	n = len(p)
	if n <= 3:
		d = 100000
		q1 = q2 = []
		for (p1, p2) in list(combinations(p, 2)):
			d = min(d, dist(p1, p2))
		return d
	mid = n // 2
	(px, py) = zip(*p)
	axis1 = 2 * len(set(px)) <= n
	axis2 = not axis1
	if axis1 != axis:
		p.sort(key=itemgetter(axis1))
	xy0 = p[mid][axis1]
	left = p[:mid]
	right = p[mid:]
	d = min(solve(left, axis1), solve(right, axis1))
	rd = math.sqrt(d)
	Q = []
	for pp in left[::-1]:
		if pp[axis1] < xy0 - rd:
			break
		Q.append(pp)
	for pp in right:
		if pp[axis1] > xy0 + rd:
			break
		Q.append(pp)
	Q.sort(key=itemgetter(axis2))
	for (i, p1) in enumerate(Q):
		dd = p1[axis2] + rd
		for p2 in Q[i + 1:]:
			if p2[axis2] > dd:
				break
			norm = dist(p1, p2)
			if d > norm:
				d = norm
	return d
pts.sort(key=itemgetter(0))
ans = solve(pts, 0)
print('%.16f' % math.sqrt(ans))


INF = 10 ** 16

def ClosestDFS(Points):
	l = len(Points)
	if l <= 1:
		return (INF, Points)
	(d1, nearPoints1) = ClosestDFS(Points[:l // 2])
	(d2, nearPoints2) = ClosestDFS(Points[l // 2:])
	retPoints = []
	ind = 0
	for (p1x, p1y) in nearPoints1:
		while ind != len(nearPoints2) and nearPoints2[ind][1] < p1y:
			retPoints.append(nearPoints2[ind])
			ind += 1
		retPoints.append((p1x, p1y))
	while ind != len(nearPoints2):
		retPoints.append(nearPoints2[ind])
		ind += 1
	d = min(d1, d2)
	B = []
	border_x = Points[l // 2][0]
	for (px, py) in retPoints:
		if abs(border_x - px) > d:
			continue
		for (bx, by) in reversed(B):
			if py - by > d:
				break
			d = min(d, ((px - bx) ** 2 + (py - by) ** 2) ** 0.5)
		B.append((px, py))
	return (d, retPoints)

def ClosestPair(Points):
	Points.sort()
	(d, _) = ClosestDFS(Points)
	return d
import sys
input = sys.stdin.readline

def main():
	N = int(input())
	Points = [list(map(float, input().split())) for _ in range(N)]
	print('{:.8f}'.format(ClosestPair(Points)))
main()


import sys
from operator import itemgetter
from itertools import permutations
from math import sqrt

def solve(a: list):
	length = len(a)
	if length <= 3:
		return min((sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) for (p1, p2) in permutations(a, 2)))
	x_set_len = len(set((x for (x, _) in a)))
	axis = 0 if x_set_len > length / 2 else 1
	a.sort(key=itemgetter(axis))
	mid_index = length // 2
	(left, right) = (a[:mid_index], a[mid_index:])
	delta = min(solve(left), solve(right))
	median = a[mid_index][axis]
	m_a = []
	for p in left[::-1]:
		if p[axis] < median - delta:
			break
		m_a.append(p)
	for p in right:
		if p[axis] > median + delta:
			break
		m_a.append(p)
	m_a.sort(key=itemgetter(not axis))
	for (i, p1) in enumerate(m_a):
		ub = p1[not axis] + delta
		for (j, p2) in enumerate(m_a[i + 1:]):
			if p2[not axis] > ub:
				break
			delta = min(delta, sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2))
	return delta
N = int(input())
a = [tuple(map(float, l.split())) for l in sys.stdin.readlines()]
print('{:.10f}'.format(solve(a)))


import math
import sys
from operator import attrgetter

class ClosestPair(object):

	def __init__(self):
		_input = sys.stdin.readlines()
		p_num = int(_input[0])
		points = map(lambda x: x.split(), _input[1:])
		p_list = [complex(float(x), float(y)) for (x, y) in points]
		p_list.sort(key=attrgetter('real'))
		ans = self.closest_pair(array=p_list, array_length=p_num)
		print('{:.6f}'.format(ans))

	def closest_pair(self, array, array_length):
		if array_length <= 1:
			return float('inf')
		mid = array_length // 2
		mid_real = array[mid].real
		d = min(self.closest_pair(array[:mid], mid).real, self.closest_pair(array[mid:], array_length - mid).real)
		return self.brute_force(array, mid_real, d)

	@staticmethod
	def brute_force(array, mid_real, d=float('inf')):
		array.sort(key=attrgetter('imag'))
		min_stack = list()
		for ele in array:
			size = len(min_stack)
			if abs(ele.real - mid_real) >= d:
				continue
			for j in range(size):
				dx = ele.real - min_stack[size - j - 1].real
				dy = ele.imag - min_stack[size - j - 1].imag
				if dy >= d:
					break
				d = min(d, math.sqrt(dx ** 2 + dy ** 2))
			min_stack.append(ele)
		return d
case = ClosestPair()


from sys import stdin
from operator import attrgetter
readline = stdin.readline

def norm(a):
	return a.real * a.real + a.imag * a.imag

def closest_pair(p):
	if len(p) <= 1:
		return float('inf')
	m = len(p) // 2
	d = min(closest_pair(p[:m]), closest_pair(p[m:]))
	p = [pi for pi in p if p[m].imag - d < pi.imag < p[m].imag + d]
	return brute_force(p, d)

def brute_force(p, d=float('inf')):
	p.sort(key=attrgetter('real'))
	for i in range(1, len(p)):
		for j in reversed(range(i)):
			tmp = p[i] - p[j]
			if d < tmp.real:
				break
			tmp = abs(tmp)
			if d > tmp:
				d = tmp
	return d

def main():
	n = int(readline())
	p = [map(float, readline().split()) for _ in range(n)]
	p = [x + y * 1j for (x, y) in p]
	p.sort(key=attrgetter('imag'))
	print('{:.6f}'.format(closest_pair(p)))
main()


import itertools

def _get_distance(p1, p2):
	return ((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) ** 0.5

def _get_min_distance(points):
	min_d = 400
	for (p1, p2) in itertools.combinations(points, 2):
		min_d = min(min_d, _get_distance(p1, p2))
	return min_d

def closest_pair_distance(points):
	n = len(points)
	if n <= 3:
		return _get_min_distance(points)
	else:
		mid = n // 2
		(px, py) = zip(*points)
		if len(set(px)) > len(set(py)):
			points.sort(key=lambda p: p[0])
			axis1 = 0
			axis2 = 1
		else:
			points.sort(key=lambda p: p[1])
			axis1 = 1
			axis2 = 0
		A_points = points[:mid]
		B_points = points[mid:]
		d_Amin = closest_pair_distance(A_points.copy())
		d_Bmin = closest_pair_distance(B_points.copy())
		dist = min(d_Amin, d_Bmin)
		min_d = dist
		for ap in A_points[::-1]:
			if B_points[0][axis1] - ap[axis1] >= dist:
				break
			for bp in B_points:
				if bp[axis1] - ap[axis1] >= dist:
					break
				if ap[axis2] - dist < bp[axis2] < ap[axis2] + dist:
					min_d = min(min_d, _get_distance(ap, bp))
		return min_d
import sys
file_input = sys.stdin
n = int(file_input.readline())
P = [tuple(map(float, line.split())) for line in file_input]
ans = closest_pair_distance(P)
print('{:f}'.format(ans))


import sys
from operator import itemgetter
from math import hypot
from itertools import takewhile, chain, combinations

def ntp(A: list, axis: int=-1):
	length = len(A)
	if length <= 4:
		return min([hypot(x1 - x2, y1 - y2) for ((x1, y1), (x2, y2)) in combinations(A, 2)])
	x_types = len(set((x for (x, _) in A)))
	axis1 = 2 * x_types <= length
	axis2 = not axis1
	mid_idx = length // 2
	if axis1 != axis:
		A.sort(key=itemgetter(axis1))
	(Al, Ar) = (A[:mid_idx], A[mid_idx:])
	median = A[mid_idx][axis1]
	tmd = min(ntp(Al, axis1), ntp(Ar, axis1))
	midA = [p for p in chain(takewhile(lambda t: median - tmd < t[axis1], Al[::-1]), takewhile(lambda t: median + tmd > t[axis1], Ar))]
	midA.sort(key=itemgetter(axis2))
	for (i, (x1, y1)) in enumerate(midA):
		ub = (x1, y1)[axis2] + tmd
		for (x2, y2) in takewhile(lambda t: t[axis2] < ub, midA[i + 1:]):
			tmd = min(tmd, hypot(x1 - x2, y1 - y2))
	return tmd
n = int(sys.stdin.readline())
Points = [tuple(map(float, sys.stdin.readline().split())) for _ in [0] * n]
print('{:.10f}'.format(ntp(Points)))


import sys
from operator import attrgetter

class ClosestPair(object):

	def __init__(self, in_data):
		self.p_num = int(in_data[0])
		points = map(lambda x: x.split(), in_data[1:])
		p_list = [complex(float(x), float(y)) for (x, y) in points]
		self.p_list = sorted(p_list, key=attrgetter('real'))

	def closest_pair(self, array, array_length):
		if array_length <= 1:
			return float('inf')
		mid_idx = array_length // 2
		div_line = array[mid_idx].real
		d_min = min(self.closest_pair(array[:mid_idx], mid_idx), self.closest_pair(array[mid_idx:], array_length - mid_idx))
		array.sort(key=attrgetter('imag'))
		min_stack = list()
		for ele in array:
			size = len(min_stack)
			if abs(ele.real - div_line) >= d_min:
				continue
			for j in range(size):
				alt = ele - min_stack[size - j - 1]
				if alt.imag >= d_min:
					break
				d_min = min(d_min, abs(alt))
			min_stack.append(ele)
		return d_min

	def solve(self):
		return self.closest_pair(array=self.p_list, array_length=self.p_num)
_input = sys.stdin.readlines()
case = ClosestPair(in_data=_input)
print('{:.6f}'.format(case.solve()))


import sys
from operator import itemgetter
from itertools import combinations, takewhile
from math import sqrt

def solve(a: list, sorted_axis: int=-1):
	length = len(a)
	if length <= 3:
		return sqrt(min(((x1 - x2) ** 2 + (y1 - y2) ** 2 for ((x1, y1), (x2, y2)) in combinations(a, 2))))
	x_set_len = len(set((x for (x, _) in a)))
	axis1 = 0 if x_set_len > length / 2 else 1
	if sorted_axis != axis1:
		a.sort(key=itemgetter(axis1))
	mid_index = length // 2
	(left, right) = (a[:mid_index], a[mid_index:])
	delta = min(solve(left, axis1), solve(right, axis1))
	axis2 = not axis1
	median = a[mid_index][axis1]
	mid_a = sorted([p for _iter in (takewhile(lambda p: median - delta < p[axis1], left[::-1]), takewhile(lambda p: p[axis1] < median + delta, right)) for p in _iter], key=itemgetter(axis2))
	for (i, (x1, y1)) in enumerate(mid_a):
		ub = (x1 if axis1 else y1) + delta
		for (x2, y2) in takewhile(lambda p: p[axis2] < ub, mid_a[i + 1:]):
			delta = min(delta, sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2))
	return delta
N = int(input())
a = [tuple(map(float, l.split())) for l in sys.stdin.readlines()]
print('{:.10f}'.format(solve(a)))


import sys
from operator import itemgetter
from math import hypot
from bisect import bisect_left, bisect_right

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST():
	return list(map(int, input().split()))

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
MOD = 10 ** 9 + 7
N = INT()
A = []
for i in range(N):
	(x, y) = map(float, input().split())
	A.append((i, x, y))
Ax = sorted(A, key=itemgetter(1))
Ay = sorted(A, key=itemgetter(2))

def find_min(li):
	n = len(li)
	mn = INF
	for i in range(n):
		for j in range(i + 1, n):
			(_, x1, y1) = li[i]
			(_, x2, y2) = li[j]
			mn = min(mn, hypot(x1 - x2, y1 - y2))
	return mn

def find_min2(mn, li1, li2):
	li2b = [y for (i, x, y) in li2]
	mn = INF
	for (i1, x1, y1) in li1:
		s = bisect_left(li2b, y1 - mn)
		t = bisect_right(li2b, y1 + mn)
		for i in range(s, t):
			(i2, x2, y2) = li2[i]
			if i1 == i2:
				continue
			mn = min(mn, hypot(x1 - x2, y1 - y2))
	return mn

def find_min3(mn, li1, li2):
	li2b = [x for (i, x, y) in li2]
	mn = INF
	for (i1, x1, y1) in li1:
		s = bisect_left(li2b, x1 - mn)
		t = bisect_right(li2b, x1 + mn)
		for i in range(s, t):
			(i2, x2, y2) = li2[i]
			if i1 == i2:
				continue
			mn = min(mn, hypot(x1 - x2, y1 - y2))
	return mn

def rec(lix, liy, d):
	if len(lix) <= 3:
		return find_min(lix)
	if d % 2 == 0:
		lix2 = lix[:len(lix) // 2]
		lix3 = lix[len(lix) // 2:]
		xset = {x[0] for x in lix2}
		liy2 = []
		liy3 = []
		for (i, x, y) in liy:
			if i in xset:
				liy2.append((i, x, y))
			else:
				liy3.append((i, x, y))
		mn = min(rec(lix2, liy2, d ^ 1), rec(lix3, liy3, d ^ 1))
		midx = (lix2[-1][1] + lix3[0][1]) / 2
		borders1 = []
		borders2 = []
		for i in range(len(lix)):
			if midx - mn <= lix[i][1] <= midx + mn:
				borders1.append(lix[i])
			if midx - mn <= liy[i][1] <= midx + mn:
				borders2.append(liy[i])
		mn = min(mn, find_min2(mn, borders1, borders2))
		return mn
	else:
		liy2 = liy[:len(liy) // 2]
		liy3 = liy[len(liy) // 2:]
		yset = {y[0] for y in liy2}
		lix2 = []
		lix3 = []
		for (i, x, y) in lix:
			if i in yset:
				lix2.append((i, x, y))
			else:
				lix3.append((i, x, y))
		mn = min(rec(lix2, liy2, d ^ 1), rec(lix3, liy3, d ^ 1))
		midy = (liy2[-1][2] + liy3[0][2]) / 2
		borders1 = []
		borders2 = []
		for i in range(len(liy)):
			if midy - mn <= liy[i][1] <= midy + mn:
				borders1.append(liy[i])
			if midy - mn <= lix[i][1] <= midy + mn:
				borders2.append(lix[i])
		mn = min(mn, find_min3(mn, borders1, borders2))
		return mn
print('{:.10f}'.format(rec(Ax, Ay, 0)))


import cmath
import itertools
import math
import os
import sys
from collections import defaultdict
if os.getenv('LOCAL'):
	sys.stdin = open('_in.txt', 'r')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
IINF = 10 ** 18
MOD = 10 ** 9 + 7
PI = cmath.pi
TAU = cmath.pi * 2
EPS = 1e-10

class Point:
	CCW_COUNTER_CLOCKWISE = 1
	CCW_CLOCKWISE = -1
	CCW_ONLINE_BACK = 2
	CCW_ONLINE_FRONT = -2
	CCW_ON_SEGMENT = 0

	def __init__(self, c: complex):
		self.c = c

	@property
	def x(self):
		return self.c.real

	@property
	def y(self):
		return self.c.imag

	@staticmethod
	def from_rect(x: float, y: float):
		return Point(complex(x, y))

	@staticmethod
	def from_polar(r: float, phi: float):
		return Point(cmath.rect(r, phi))

	def __add__(self, p):
		return Point(self.c + p.c)

	def __iadd__(self, p):
		self.c += p.c
		return self

	def __sub__(self, p):
		return Point(self.c - p.c)

	def __isub__(self, p):
		self.c -= p.c
		return self

	def __mul__(self, f: float):
		return Point(self.c * f)

	def __imul__(self, f: float):
		self.c *= f
		return self

	def __truediv__(self, f: float):
		return Point(self.c / f)

	def __itruediv__(self, f: float):
		self.c /= f
		return self

	def __repr__(self):
		return '({}, {})'.format(round(self.x, 10), round(self.y, 10))

	def __neg__(self):
		return Point(-self.c)

	def __eq__(self, p):
		return abs(self.c - p.c) < EPS

	def __abs__(self):
		return abs(self.c)

	@staticmethod
	def ccw(a, b, c):
		b = b - a
		c = c - a
		det = b.det(c)
		if det > EPS:
			return Point.CCW_COUNTER_CLOCKWISE
		if det < -EPS:
			return Point.CCW_CLOCKWISE
		if b.dot(c) < -EPS:
			return Point.CCW_ONLINE_BACK
		if c.norm() - b.norm() > EPS:
			return Point.CCW_ONLINE_FRONT
		return Point.CCW_ON_SEGMENT

	def dot(self, p):
		return self.x * p.x + self.y * p.y

	def det(self, p):
		return self.x * p.y - self.y * p.x

	def dist(self, p):
		return abs(self.c - p.c)

	def norm(self):
		return abs(self.c)

	def phase(self):
		return cmath.phase(self.c)

	def angle(self, p, q):
		return (cmath.phase(q.c - self.c) - cmath.phase(p.c - self.c) + PI) % TAU - PI

	def area(self, p, q):
		return abs((p - self).det(q - self) / 2)

	def projection_point(self, p, q, allow_outer=False):
		diff_q = q - p
		r = (self - p).dot(diff_q) / abs(diff_q)
		phase = diff_q.phase()
		ret = Point.from_polar(r, phase) + p
		if allow_outer or (p - ret).dot(q - ret) < EPS:
			return ret
		return None

	def reflection_point(self, p, q):
		r = abs(self - p)
		angle = p.angle(q, self)
		angle = (q - p).phase() - angle
		return Point.from_polar(r, angle) + p

	def on_segment(self, p, q, allow_side=True):
		if not allow_side and (self == p or self == q):
			return False
		return abs((p - self).det(q - self)) < EPS and (p - self).dot(q - self) < EPS

class Line:

	def __init__(self, a: float, b: float, c: float):
		self.a = a
		self.b = b
		self.c = c

	@staticmethod
	def from_gradient(grad: float, intercept: float):
		return Line(grad, -1, intercept)

	@staticmethod
	def from_segment(p1, p2):
		a = p2.y - p1.y
		b = p1.x - p2.x
		c = p2.y * (p2.x - p1.x) - p2.x * (p2.y - p1.y)
		return Line(a, b, c)

	@property
	def gradient(self):
		return INF if self.b == 0 else -self.a / self.b

	@property
	def intercept(self):
		return INF if self.b == 0 else -self.c / self.b

	def is_parallel_to(self, l):
		return abs(Point.from_rect(self.a, self.b).det(Point.from_rect(l.a, l.b))) < EPS

	def is_orthogonal_to(self, l):
		return abs(Point.from_rect(self.a, self.b).dot(Point.from_rect(l.a, l.b))) < EPS

	def intersection_point(self, l):
		(a1, b1, c1) = (self.a, self.b, self.c)
		(a2, b2, c2) = (l.a, l.b, l.c)
		det = a1 * b2 - a2 * b1
		if abs(det) < EPS:
			return None
		x = (b1 * c2 - b2 * c1) / det
		y = (a2 * c1 - a1 * c2) / det
		return Point.from_rect(x, y)

	def dist(self, p):
		raise NotImplementedError()

	def has_point(self, p):
		return abs(self.a * p.x + self.b * p.y + self.c) < EPS

class Segment:

	def __init__(self, p1, p2):
		self.p1 = p1
		self.p2 = p2

	def norm(self):
		return abs(self.p1 - self.p2)

	def phase(self):
		return cmath.phase(self.p2 - self.p1)

	def is_parallel_to(self, s):
		return abs((self.p1 - self.p2).det(s.p1 - s.p2)) < EPS

	def is_orthogonal_to(self, s):
		return abs((self.p1 - self.p2).dot(s.p1 - s.p2)) < EPS

	def intersects_with(self, s, allow_side=True):
		if self.is_parallel_to(s):
			return s.p1.on_segment(self.p1, self.p2, allow_side) or s.p2.on_segment(self.p1, self.p2, allow_side) or self.p1.on_segment(s.p1, s.p2, allow_side) or self.p2.on_segment(s.p1, s.p2, allow_side)
		else:
			det_upper = EPS if allow_side else -EPS
			ok = True
			ok &= (self.p2 - self.p1).det(s.p1 - self.p1) * (self.p2 - self.p1).det(s.p2 - self.p1) < det_upper
			ok &= (s.p2 - s.p1).det(self.p1 - s.p1) * (s.p2 - s.p1).det(self.p2 - s.p1) < det_upper
			return ok

	def closest_point(self, p):
		d = (p - self.p1).dot(self.p2 - self.p1) / self.norm()
		if d < EPS:
			return self.p1
		if -EPS < d - self.norm():
			return self.p2
		return Point.from_polar(d, (self.p2 - self.p1).phase()) + self.p1

	def dist(self, p):
		return abs(p - self.closest_point(p))

	def dist_segment(self, s):
		if self.intersects_with(s):
			return 0.0
		return min(self.dist(s.p1), self.dist(s.p2), s.dist(self.p1), s.dist(self.p2))

	def has_point(self, p, allow_side=True):
		return p.on_segment(self.p1, self.p2, allow_side=allow_side)

class Polygon:

	def __init__(self, points):
		self.points = points

	def iter2(self):
		return zip(self.points, self.points[1:] + self.points[:1])

	def iter3(self):
		return zip(self.points, self.points[1:] + self.points[:1], self.points[2:] + self.points[:2])

	def area(self):
		dets = []
		for (p, q) in self.iter2():
			dets.append(p.det(q))
		return abs(math.fsum(dets)) / 2

	def is_convex(self, allow_straight=False, allow_collapsed=False):
		ccw = []
		for (a, b, c) in self.iter3():
			ccw.append(Point.ccw(a, b, c))
		ccw = set(ccw)
		if len(ccw) == 1:
			if ccw == {Point.CCW_CLOCKWISE}:
				return True
			if ccw == {Point.CCW_COUNTER_CLOCKWISE}:
				return True
		if allow_straight and len(ccw) == 2:
			if ccw == {Point.CCW_ONLINE_FRONT, Point.CCW_CLOCKWISE}:
				return True
			if ccw == {Point.CCW_ONLINE_FRONT, Point.CCW_COUNTER_CLOCKWISE}:
				return True
		if allow_collapsed and len(ccw) == 3:
			return ccw == {Point.CCW_ONLINE_FRONT, Point.CCW_ONLINE_BACK, Point.CCW_ON_SEGMENT}
		return False

	def has_point_on_edge(self, p):
		for (a, b) in self.iter2():
			if p.on_segment(a, b):
				return True
		return False

	def contains(self, p, allow_on_edge=True):
		angles = []
		for (a, b) in self.iter2():
			if p.on_segment(a, b):
				return allow_on_edge
			angles.append(p.angle(a, b))
		return abs(math.fsum(angles)) > EPS

	@staticmethod
	def convex_hull(points, allow_straight=False):
		points = points[:]
		points.sort(key=lambda p: (p.x, p.y))
		det_lower = -EPS if allow_straight else EPS
		sz = 0
		ret = [None] * (len(points) * 2)
		for p in points:
			while sz > 1 and (ret[sz - 1] - ret[sz - 2]).det(p - ret[sz - 1]) < det_lower:
				sz -= 1
			ret[sz] = p
			sz += 1
		floor = sz
		for p in reversed(points[:-1]):
			while sz > floor and (ret[sz - 1] - ret[sz - 2]).det(p - ret[sz - 1]) < det_lower:
				sz -= 1
			ret[sz] = p
			sz += 1
		ret = ret[:sz - 1]
		if allow_straight and len(ret) > len(points):
			ret = points
		return ret

	@staticmethod
	def diameter(points):
		points = Polygon.convex_hull(points, allow_straight=False)
		if len(points) == 1:
			return 0.0
		if len(points) == 2:
			return abs(points[0] - points[1])
		si = points.index(min(points, key=lambda p: (p.x, p.y)))
		sj = points.index(max(points, key=lambda p: (p.x, p.y)))
		n = len(points)
		ret = 0.0
		(i, j) = (si, sj)
		while i != sj or j != si:
			ret = max(ret, abs(points[i] - points[j]))
			ni = (i + 1) % n
			nj = (j + 1) % n
			if (points[ni] - points[i]).det(points[nj] - points[j]) > 0:
				j = nj
			else:
				i = ni
		return ret

	def convex_cut_by_line(self, line_p1, line_p2):
		n = len(self.points)
		line = Line.from_segment(line_p1, line_p2)
		on_line_points = []
		for (i, p) in enumerate(self.points):
			if line.has_point(p):
				on_line_points.append(i)
		has_on_line_edge = False
		if len(on_line_points) >= 3:
			has_on_line_edge = True
		elif len(on_line_points) == 2:
			has_on_line_edge = abs(on_line_points[0] - on_line_points[1]) in [1, n - 1]
		if has_on_line_edge:
			for p in self.points:
				ccw = Point.ccw(line_p1, line_p2, p)
				if ccw == Point.CCW_COUNTER_CLOCKWISE:
					return (Polygon(self.points[:]), None)
				if ccw == Point.CCW_CLOCKWISE:
					return (None, Polygon(self.points[:]))
		ret_lefts = []
		ret_rights = []
		d = line_p2 - line_p1
		for (p, q) in self.iter2():
			det_p = d.det(p - line_p1)
			det_q = d.det(q - line_p1)
			if det_p > -EPS:
				ret_lefts.append(p)
			if det_p < EPS:
				ret_rights.append(p)
			if det_p * det_q < -EPS:
				intersection = line.intersection_point(Line.from_segment(p, q))
				ret_lefts.append(intersection)
				ret_rights.append(intersection)
		l = Polygon(ret_lefts) if len(ret_lefts) > 1 else None
		r = Polygon(ret_rights) if len(ret_rights) > 1 else None
		return (l, r)

def closest_pair(points):
	assert len(points) >= 2

	def _rec(xsorted):
		n = len(xsorted)
		if n <= 2:
			return (xsorted[0].dist(xsorted[1]), (xsorted[0], xsorted[1]))
		if n <= 3:
			d = INF
			pair = None
			for (p, q) in itertools.combinations(xsorted, r=2):
				if p.dist(q) < d:
					d = p.dist(q)
					pair = (p, q)
			return (d, pair)
		(ld, lp) = _rec(xsorted[:n // 2])
		(rd, rp) = _rec(xsorted[n // 2:])
		if ld <= rd:
			d = ld
			ret_pair = lp
		else:
			d = rd
			ret_pair = rp
		mid_x = xsorted[n // 2].x
		mid_points = []
		for p in xsorted:
			if abs(p.x - mid_x) - d < -EPS:
				mid_points.append(p)
		mid_points.sort(key=lambda p: p.y)
		mid_n = len(mid_points)
		for i in range(mid_n - 1):
			j = i + 1
			p = mid_points[i]
			q = mid_points[j]
			while q.y - p.y - d < -EPS:
				pq_d = p.dist(q)
				if pq_d < d:
					d = pq_d
					ret_pair = (p, q)
				j += 1
				if j >= mid_n:
					break
				q = mid_points[j]
		return (d, ret_pair)
	return _rec(list(sorted(points, key=lambda p: p.x)))

def closest_pair_randomized(points):
	n = len(points)
	assert n >= 2
	if n == 2:
		return (points[0].dist(points[1]), (points[0], points[1]))
	import random
	points = points[:]
	random.shuffle(points)
	DELTA_XY = list(itertools.product([-1, 0, 1], repeat=2))
	grid = defaultdict(list)
	delta = INF
	dist = points[0].dist(points[1])
	ret_pair = (points[0], points[1])
	for i in range(2, n):
		if delta < EPS:
			return (0.0, ret_pair)
		if dist - delta < -EPS:
			delta = dist
			grid = defaultdict(list)
			for a in points[:i]:
				grid[a.x // delta, a.y // delta].append(a)
		else:
			p = points[i - 1]
			grid[p.x // delta, p.y // delta].append(p)
		p = points[i]
		dist = delta
		grid_x = p.x // delta
		grid_y = p.y // delta
		for (dx, dy) in DELTA_XY:
			for q in grid[grid_x + dx, grid_y + dy]:
				d = p.dist(q)
				if d - dist < -EPS:
					dist = d
					ret_pair = (p, q)
	return (min(delta, dist), ret_pair)

def closest_pair_randomized2(points):
	n = len(points)
	assert n >= 2
	if n == 2:
		return (points[0].dist(points[1]), (points[0], points[1]))
	import random
	DIM = 2
	DELTA_XY = list(itertools.product([-1, 0, 1], repeat=2))
	all_points = points
	dist = points[0].dist(points[1])
	while points:
		next_points = []
		pi = random.choice(range(len(points)))
		p = points[pi]
		d = INF
		for (qi, q) in enumerate(points):
			if pi == qi:
				continue
			d = min(d, p.dist(q))
		width = d / (4 * DIM)
		grid = defaultdict(list)
		for p in points:
			grid[p.x // width, p.y // width].append(p)
		for p in points:
			grid_x = p.x // width
			grid_y = p.y // width
			cnt = 0
			for (dx, dy) in DELTA_XY:
				cnt += len(grid[grid_x + dx, grid_y + y])
			if cnt >= 2:
				next_points.append(p)
		dist = d
		points = next_points
	width = dist
	grid = defaultdict(list)
	for p in all_points:
		grid[p.x // width, p.y // width].append(p)
	ret = INF
	for p in all_points:
		grid_x = p.x // width
		grid_y = p.y // width
		for (dx, dy) in DELTA_XY:
			for q in grid[grid_x + dx, grid_y + dy]:
				if p == q:
					continue
				d = p.dist(q)
				if d - ret < -EPS:
					ret = d
					ret_pair = (p, q)
	return (ret, ret_pair)
N = int(sys.stdin.buffer.readline())
XY = [list(map(float, sys.stdin.buffer.readline().split())) for _ in range(N)]
points = []
for (x, y) in XY:
	points.append(Point(complex(x, y)))
(d, (p, q)) = closest_pair_randomized2(points)
print('{:.10f}'.format(d))


import sys
from collections import deque

def closest_pair(points):
	return find_closest(sorted(points)) ** 0.5

def find_closest(points):
	n = len(points)
	if n <= 1:
		return float('inf')
	m = n // 2
	x = points[m][0]
	d = min(find_closest(points[:m]), find_closest(points[m:]))
	points.sort(key=lambda p: p[1])
	b = deque()
	for p in points:
		if (p[0] - x) ** 2 < d:
			for q in b:
				dx = p[0] - q[0]
				dy = p[1] - q[1]
				if dy ** 2 >= d:
					break
				if dx ** 2 + dy ** 2 < d:
					d = dx ** 2 + dy ** 2
			b.appendleft(p)
	return d

def main(args):
	n = int(input())
	points = []
	for _ in range(n):
		(x, y) = map(float, input().split())
		points.append((x, y))
	ans = closest_pair(sorted(points))
	print('{:.10f}'.format(ans))
main(sys.argv[1:])


from math import sqrt
n = int(input())
ps = [list(map(float, input().strip().split())) for i in range(n)]
ps.sort()
INF = 10 ** 9

def cp_rec(ps, i, n):
	if n <= 1:
		return (INF, [ps[i]])
	m = int(n / 2)
	x = ps[i + m][0]
	(d1, qs1) = cp_rec(ps, i, m)
	(d2, qs2) = cp_rec(ps, i + m, n - m)
	d = min(d1, d2)
	qs = [None] * n
	s = t = idx = 0
	while s < m and t < n - m:
		if qs1[s][1] < qs2[t][1]:
			qs[idx] = qs1[s]
			s += 1
		else:
			qs[idx] = qs2[t]
			t += 1
		idx += 1
	while s < m:
		qs[idx] = qs1[s]
		s += 1
		idx += 1
	while t < n - m:
		qs[idx] = qs2[t]
		t += 1
		idx += 1
	b = []
	for i in range(n):
		(ax, ay) = q = qs[i]
		if abs(ax - x) >= d:
			continue
		for j in range(len(b) - 1, -1, -1):
			dx = ax - b[j][0]
			dy = ay - b[j][1]
			if dy >= d:
				break
			d = min(d, sqrt(dx ** 2 + dy ** 2))
		b.append(q)
	return (d, qs)

def closest_pair(ps):
	n = len(ps)
	return cp_rec(ps, 0, n)[0]
print('{:.09f}'.format(closest_pair(ps)))


from operator import itemgetter
from math import sqrt
from typing import List, Tuple

def distance(p: Tuple[float, float], q: Tuple[float, float]) -> float:
	return sqrt((p[0] - q[0]) ** 2 + (p[1] - q[1]) ** 2)

def closest_distance(points: List[Tuple[float, float]]) -> float:

	def split(i: int, j: int) -> float:
		if j - i < 2:
			return float('INF')
		mid = (i + j) // 2
		d = min(split(i, mid), split(mid, j))
		(lv, rv) = (points[mid][0] - d, points[mid][0] + d)
		return merge(sorted([p for p in points[i:j] if lv <= p[0] <= rv], key=itemgetter(1)), d)

	def merge(_points: List[Tuple[float, float]], d: float) -> float:
		n = len(_points)
		for i in range(n - 1):
			for j in range(i + 1, n):
				if d < _points[j][1] - _points[i][1]:
					break
				d = min(d, distance(_points[i], _points[j]))
		return d
	points.sort(key=itemgetter(0, 1))
	return split(0, len(points))
n = int(input())
points = [tuple(map(float, input().split())) for _ in range(n)]
print('{:.6f}'.format(closest_distance(points)))


import sys
from operator import attrgetter

class ClosestPair(object):

	def __init__(self):
		_input = sys.stdin.readlines()
		p_num = int(_input[0])
		points = map(lambda x: x.split(), _input[1:])
		p_list = [complex(float(x), float(y)) for (x, y) in points]
		p_list.sort(key=attrgetter('real'))
		ans = self.closest_pair(array=p_list, array_length=p_num)
		print('{:.6f}'.format(ans))

	def closest_pair(self, array, array_length):
		if array_length <= 1:
			return float('inf')
		mid = array_length // 2
		mid_real = array[mid].real
		d = min(self.closest_pair(array[:mid], mid), self.closest_pair(array[mid:], array_length - mid))
		array.sort(key=attrgetter('imag'))
		min_stack = list()
		for ele in array:
			size = len(min_stack)
			if abs(ele.real - mid_real) >= d:
				continue
			for j in range(size):
				alt = ele - min_stack[size - j - 1]
				if alt.imag >= d:
					break
				d = min(d, abs(alt))
			min_stack.append(ele)
		return d
case = ClosestPair()