// sqrt(600_851_475_143) = 775146.09922 ~= 775147

fn get_sqrt_ceil(x: u64) -> u64 {
    let xf: f64 = x as f64;
    let sq: f64 = xf.sqrt().ceil();
    let res: u64 = sq as u64;
    return res;
}

fn get_biggest_div(n: u64) -> u64 {
    // println!("get_biggest_div from {}", n);
    let mut d: u64 = 1u64;
    let sq = get_sqrt_ceil(n);
    for k in 2u64..=sq {
        if n % k == 0 { d = k; }
    }
    if d == 1 { return n; }
    let dd = get_biggest_div(n / d);
    if dd > d {
        return dd;
    } else {
        return d;
    }
}

fn find_biggest_prime_div(n: u64) -> u64 {
    let biggest_div = get_biggest_div(n);
    if biggest_div == n {
        return n;
    }
    let p = find_biggest_prime_div(biggest_div);
    let q = find_biggest_prime_div(n / biggest_div);
    if p > q {
        return p;
    } else {
        return q;
    }
}


fn main() {
    //let r = find_biggest_prime_div(600_851_475_143);
    let r = find_biggest_prime_div(600_851_475_143);
    println!("{}", r);
}