INF = 1.0 / 0.0

def dist(p1, p2)
  return Math.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
end

def bruteForce(px, n)
  min = INF
  n.times{|i|
    (i+1).upto(n-1){|j|
      d = dist(px[i], px[j])
      min = d if d < min
    }
  }
  return min
end

def strip_closest(strip, size, d)
  min = d

  size.times{|i|
    (i+1).upto(size-1){|j|
      break if strip[j][1] - strip[i][1] >= min
      dd = dist(strip[i], strip[j])
      min = dd if dd < min
    }
  }
  return min
end

def closest_util(px, py, n)
#  p [px, py, n]
  return bruteForce(px, n) if n <= 3

  mid = n/2 - 1
  midpoint = px[mid]

  pyl = []
  pyr = []
  n.times{|i|
    if py[i][0] <= midpoint[0]
      pyl << py[i]
    else
      pyr << py[i]
    end
  }

  if pyl.size == n || pyr.size == n
    pyl = py[0,mid].clone
    pyr = py[mid,n-mid].clone
  end
  
  pxl = px[0,pyl.size].clone
  pxr = px[pyl.size, pyr.size].clone

  dl = closest_util(pxl, pyl, pyl.size)
  dr = closest_util(pxr, pyr, pyr.size)

  d = [dl, dr].min

  strip = []
  n.times{|i|
    if (py[i][0] - midpoint[0]).abs < d
      strip << py[i]
    end
  }

  return [d, strip_closest(strip, strip.size, d)].min

end

n = gets.to_i
px = []
n.times{|i|
  px[i] = gets.split.map(&:to_f)
}

px.sort!
py = px.map(&:clone)
py.sort! {|a, b| a[1] <=> b[1]}

puts "%.10f" % closest_util(px, py, px.size)