macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut iter = s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; }
macro_rules ! input_inner { ( $ iter : expr ) => { } ; ( $ iter : expr , ) => { } ; ( $ iter : expr , mut $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let mut $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , mut $ var : ident $ ( $ r : tt ) * ) => { let mut $ var = $ iter . next ( ) . unwrap ( ) . parse ::< usize > ( ) . unwrap ( ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident $ ( $ r : tt ) * ) => { let $ var = $ iter . next ( ) . unwrap ( ) . parse ::< usize > ( ) . unwrap ( ) ; input_inner ! { $ iter $ ( $ r ) * } } ; }
macro_rules ! read_value { ( $ iter : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ iter , $ t ) ) ,* ) } ; ( $ iter : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ iter , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ iter : expr , chars ) => { read_value ! ( $ iter , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ iter : expr , usize1 ) => { read_value ! ( $ iter , usize ) - 1 } ; ( $ iter : expr , $ t : ty ) => { $ iter . next ( ) . unwrap ( ) . parse ::<$ t > ( ) . unwrap ( ) } ; }
trait Trisect: Copy {
    fn next(self, other: Self) -> (Self, Self);
    fn section_end(self, other: Self) -> bool;
}
// impl Trisect for usize {
//     fn next(self, other: Self) -> (Self, Self) {
//         if self > other {
//             other + (self - other) / 2
//         } else {
//             self + (other - self) / 2
//         }
//     }
//     fn section_end(self, other: Self) -> bool {
//         (if self > other {
//             self - other
//         } else {
//             other - self
//         }) <= 1
//     }
// }
// impl Trisect for i64 {
//     fn next(self, other: Self) -> Self {
//         (self + other) / 2
//     }
//     fn section_end(self, other: Self) -> bool {
//         (self - other).abs() <= 1
//     }
// }
impl Trisect for f64 {
    fn next(self, other: Self) -> (Self, Self) {
        ((self * 2. + other) / 3., (self + other * 2.) / 3.)
    }
    fn section_end(self, other: Self) -> bool {
        (self - other).abs() <= 1e-8
    }
}
fn ternary_search<T: Trisect, F: Fn(T) -> U, U: PartialOrd>(f: F, left: T, right: T) -> T {
    let mut left = left;
    let mut right = right;
    while !left.section_end(right) {
        let (l, r) = left.next(right);
        if f(l) > f(r) {
            left = l;
        } else {
            right = r;
        }
    }
    left
}
fn main() {
    input! { n, xy: [(f64, f64); n] };
    let dist = |x: f64, y: f64| {
        let mut res = 0.;
        for &(x0, y0) in &xy {
            let d = ((x - x0).powf(2.) + (y - y0).powf(2.)).powf(0.5);
            res = if res > d { res } else { d };
        }
        res
    };
    let x = ternary_search(
        |x| {
            let y = ternary_search(|y| dist(x, y), 0., 1000.);
            dist(x, y)
        },
        0.,
        1000.,
    );
    let y = ternary_search(|y| dist(x, y), 0., 1000.);
    let ans = dist(x, y);
    println!("{}", ans);
}


Measured memory_bytes: 4352