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)

use std::io::{self, BufRead, BufWriter, Write};

fn solve<R, W>(reader: R, mut writer: W)
where
    R: BufRead,
    W: Write,
{
    let mut lines = reader.lines();
    let n: i64 = lines.next().unwrap().unwrap().parse().unwrap();
    // let mut factrized = prime_factorization(n);

    // let mut x: i64 = 1;
    // let mut y: i64 = 1;
    // for (i, n) in factrized {
    //     for _ in 0..n {
    //         if x < y {
    //             x *= i;
    //         } else {
    //             y *= i;
    //         }
    //     }
    // }
    // let ans: i64 = x - 1 + y - 1;

    let mut ans = 0;
    let s: i64 = (n as f64).sqrt() as i64;
    for i in 0..s {
        if n % (s - i) == 0 {
            ans = (s - i) + n / (s - i) - 2;
            break;
        }
    }

    writeln!(&mut writer, "{}", ans).unwrap();
}

fn main() {
    let stdio = io::stdin();
    let input = stdio.lock();

    let stdout = io::stdout();
    let output = BufWriter::new(stdout.lock());

    solve(input, output);
}

fn prime_factorization(mut n: i64) -> Vec<(i64, i64)> {
    let s: i64 = (n as f64).sqrt() as i64;
    let mut result = vec![];
    for i in 2..s + 1 {
        if (n % i) == 0 {
            let mut r = 0;
            loop {
                r += 1;
                n = n / i;
                if !((n % i) == 0) {
                    break;
                }
            }
            result.push((i, r));
        }
    }
    if n > s {
        result.push((n, 1));
    }
    result
}

#[cfg(test)]
mod tests {
    use super::*;

    const TESTS: &'static [(&'static [u8], &'static [u8])] = &[
        (
            br"10", br"5
",
        ),
        (
            br"50", br"13
",
        ),
        (
            br"10000000019",
            br"10000000018
",
        ),
        (
            br"4", br"2
",
        ),
        (
            br"1", br"0
",
        ),
        (
            br"15241383936",
            br"246910
",
        ),
        (
            br"852770983936",
            br"1846910
",
        ),
        (
            br"29524500",
            br"14578
",
        ),
        (
            br"3804953495641",
            br"3901256
",
        ),
        (
            br"1565912117761",
            br"2509568
",
        ),
        (
            br"549755813888",
            br"1572862
",
        ),
    ];

    #[test]
    fn test_c() {
        for &(input, expected) in TESTS {
            let mut output = Vec::new();
            solve(input, &mut output);
            let expected_str = String::from_utf8(expected.to_vec()).unwrap();
            let output_str = String::from_utf8(output).unwrap();
            assert_eq!(expected_str, output_str);
        }
    }
}