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 C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;

namespace CompetitiveProg
{
	class Program
	{
		static void Main(string[] args)
		{
			var n      = long.Parse(Console.ReadLine());
			var fact   = new Factorization(n);
			var primes = fact.Calc().Reverse().ToArray();
			long x = 1, y = 1;
			foreach (var prime in primes)
			{
				if (x < y)
				{
					x *= prime;
				}
				else
				{
					y *= prime;
				}
			}

			Console.WriteLine(x + y - 2);
		}
	}

	public class Factorization
	{
		private static long N;
		public Factorization(long n) { N = n; }

		//最大公約数を返す
		public static long GCD(long a, long b)
		{
			if (a < b) return GCD(b, a);

			long r;

			while (b != 0)
			{
				r = a % b;
				a = b;
				b = r;
			}

			return a;
		}

		//素数判定
		public static bool IsPrime(long n)
		{
			if (n     < 2) return false;
			if (n     == 2) return true;
			if (n % 2 == 0) return false;

			double root = Math.Sqrt(n);

			for (int i = 3; i <= root; i += 2)
			{
				if (n % i == 0) return false;
			}

			return true;
		}

		//試し割り
		private static int[] TryPrimes = new int[]
		{
			2, 3, 5, 7, 11
		};

		public long TryAllocation(long p)
		{
			long count = 0;

			while (N % p == 0)
			{
				count++;
				N /= p;
			}

			return count;
		}

		private int[] xi = new int[]
		{
			13, 17, 19, 23, 29
		};

		private long f(long x, int suffix) { return (xi[suffix % xi.Count()] * x + suffix) % N; }

		//nを分解
		public long PollardsRho(long n, int suffix = 0)
		{
			//素数を渡すと失敗するらしい
			if (IsPrime(n)) return n; //もう素数

			long x = 2, y = 2, d = 1;

			while (d == 1)
			{
				x = f(x, suffix);
				y = f(f(y, suffix), suffix);
				d = GCD(Math.Abs(x - y), n);
			}

			if (d == n)
			{
				//f(x)を変えて試す
				return PollardsRho(n, suffix + 1);
			}

			return d;
		}

		public IEnumerable<long> Calc()
		{
			//小さな素因数の計算
			foreach (var prime in TryPrimes)
			{
				var box = TryAllocation(prime);
				for (int i = 0; i < box; i++) yield return prime;
			}

			//残りをRhoで解く
			while (true)
			{
				if (N == 1) break;

				var ret = PollardsRho(N);
				yield return ret;

				N /= ret;
			}
		}
	}
}