Problem:
Score : 300 points

Problem Statement

Takahashi is standing on a multiplication table with infinitely many rows and columns.

The square (i,j) contains the integer i \times j. Initially, Takahashi is standing at (1,1).

In one move, he can move from (i,j) to either (i+1,j) or (i,j+1).

Given an integer N, find the minimum number of moves needed to reach a square that contains N.

Constraints

2 \leq N \leq 10^{12}

N is an integer.

Input

Input is given from Standard Input in the following format:

N

Output

Print the minimum number of moves needed to reach a square that contains the integer N.

Sample Input 1

10

Sample Output 1

5

(2,5) can be reached in five moves. We cannot reach a square that contains 10 in less than five moves.

Sample Input 2

50

Sample Output 2

13

(5, 10) can be reached in 13 moves.

Sample Input 3

10000000019

Sample Output 3

10000000018

Both input and output may be enormous.

Solution in Rust (1.15.1) (judge verdict: Accepted)

#[allow(unused)]
use std::io::Write;
use std::collections::{HashMap, HashSet};

#[allow(unused)]
macro_rules! debug {
    ($($format:tt)*) => (write!(std::io::stderr(), $($format)*).unwrap());
}
#[allow(unused)]
macro_rules! debugln {
    ($($format:tt)*) => (writeln!(std::io::stderr(), $($format)*).unwrap());
}

fn main() {
    let n: usize = {
        let mut s = String::new();
        std::io::stdin().read_line(&mut s).unwrap();
        let s = s.trim_right().to_owned();
        s.parse().unwrap()
    };

    let divs = divisors(n);
    let mut min = std::usize::MAX;
    for d in divs {
        let tmp = d + n / d - 2;
        if tmp < min {
            min = tmp
        }
    }
    println!("{}", min);
}

fn prime_sieve(n: usize) -> Vec<usize> {
    let mut table: Vec<usize> = vec![0; (n + 1) as usize];
    let mut primes: Vec<usize> = Vec::new();

    for i in 2..(n+1) {
        if table[i as usize] == 0 {
            primes.push(i);
            for j in 2..n {
                if i * j > n {
                    break
                }
                table[(i * j) as usize] = 1
            }
        }
    }

    primes
}

fn prime_factor(n: usize) -> HashMap<usize, usize> {
    let mut factors = HashMap::new();

    let primes = prime_sieve((n as f64).sqrt() as usize);
    let mut rest = n;
    for p in primes {
        while rest % p == 0 {
            let count = factors.entry(p).or_insert(0);
            *count += 1;
            rest /= p;
        }
    }
    if rest != 1 {
        factors.insert(rest, 1);
    }

    factors
}

fn divisors(n: usize) -> HashSet<usize> {
    let mut set = HashSet::new();
    set.insert(1);

    prime_factor(n).iter().fold(set, |acc, (&p, &pow)| {
        (0..pow+1).flat_map(|i| acc.iter().map(move |a| a * p.pow(i as u32))).collect()
    })
}