#![allow(unused_imports)]
use {
   proconio::{fastout, input, marker::*},
   std::cmp::*,
   std::collections::*,
};

use std::ops::*;
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
struct Point<T> {
   x: T,
   y: T,
}
impl<T: Add<Output = T>> Add for Point<T> {
   type Output = Point<T>;
   fn add(self, other: Self) -> Self::Output {
      Point {
         x: self.x + other.x,
         y: self.y + other.y,
      }
   }
}
impl<T: Sub<Output = T>> Sub for Point<T> {
   type Output = Point<T>;
   fn sub(self, other: Self) -> Self::Output {
      Point {
         x: self.x - other.x,
         y: self.y - other.y,
      }
   }
}
impl<T: Copy + Clone + Mul<Output = T>> Mul<T> for Point<T> {
   type Output = Point<T>;
   fn mul(self, other: T) -> Self::Output {
      Point {
         x: self.x * other,
         y: self.y * other,
      }
   }
}
impl<T: Copy + Clone + Div<Output = T>> Div<T> for Point<T> {
   type Output = Point<T>;
   fn div(self, other: T) -> Self::Output {
      Point {
         x: self.x / other,
         y: self.y / other,
      }
   }
}
impl<T: Copy + Clone + Add<Output = T> + Mul<Output = T>> Point<T> {
   fn new(x: T, y: T) -> Self { Point { x: x, y: y } }
   fn dot(self, other: Self) -> T { self.x * other.x + self.y * other.y }
   fn pow(self) -> T { self.dot(self) }
}
impl Point<f64> {
   fn abs(self) -> f64 { self.dot(self).sqrt() }
   fn rot(self, theta: f64) -> Self {
      Point {
         x: self.x * theta.cos() - self.y * theta.sin(),
         y: self.x * theta.sin() + self.y * theta.cos(),
      }
   }
}

use std::f64::consts::PI;
fn intersection(r: f64, p1: Point<f64>, p2: Point<f64>) -> Option<(Point<f64>, Point<f64>)> {
   let pm = (p1 + p2) / 2.0;
   let pd = p1 - p2;
   let dr = pd.abs();
   if dr <= 2.0 * r {
      let h = (r * r - dr * dr / 4.0).sqrt();
      let ph = pd.rot(PI / 2.0) / dr * h;
      return Some((pm + ph, pm - ph));
   }
   None
}

fn main() {
   input! {
      n:usize,
      xy: [(f64, f64); n]
   }
   let ps: Vec<_> = xy.iter().map(|&(x, y)| Point::new(x, y)).collect();

   let mut low = 0f64;
   let mut high = 1000f64;
   let mut pm = vec![];
   for i in 0..n {
      for j in i + 1..n {
         pm.push((ps[i] + ps[j]) / 2.0);
      }
   }

   for &p1 in pm.iter() {
      let mut mx = 0f64;
      for &p2 in ps.iter() {
         let r = (p1 - p2).abs();
         if mx < r {
            mx = r;
         }
      }
      if mx < high {
         high = mx;
      }
   }

   'outer: for _ in 0..100 {
      let r = (high + low) / 2.0;
      let mut points = pm.clone();
      for i in 0..n - 1 {
         for j in i + 1..n {
            if let Some((p1, p2)) = intersection(r, ps[i], ps[j]) {
               points.push(p1);
               points.push(p2);
            } else {
               low = r;
               continue 'outer;
            }
         }
      }
      let mut flag = false;
      let mut rm = 0f64;
      'outer1: for &p1 in points.iter() {
         for &p2 in ps.iter() {
            let rn = (p1 - p2).abs();
            if rn > r {
               continue 'outer1;
            }
            if rn > rm {
               rm = rn;
            }
         }
         flag = true;
         break;
      }
      if flag {
         high = rm;
      } else {
         low = r;
      }
   }
   println!("{0:.10}", high);
}


Measured memory_bytes: 2288