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 (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int IsPrime(long long n)//0なら素数
{
    if (n == 2)
    {
        return 0;
    }
    else if (n % 2 == 0 || n < 2)
    {
        return 1;
    }
    else
    {
        for (long long i = 3; i <= sqrt(n); i += 2)
        {
            if (n % i == 0)
            {
                return 1;
            }
        }
    }
    return 0;
}

int IsSemiPrime(long long prim, long long N)
{
    if (IsPrime(prim) != 0)
        return (1);
    if (N % prim == 0)
    {
        if (IsPrime(N/prim) == 0)
        {
            printf("%lld", N / prim + (prim - 2));
            return (0);
        }
    }
    return (1);
}

int search(long long prim, long long N)
{
    if (IsPrime(prim) != 0)
        return (1);
    if (N % prim == 0)
    {
        if (IsPrime(N/prim) == 0)
        {
            printf("%lld", N / prim + (prim - 2));
            return (0);
        }
        else
        {
            search(prim + 2, N);
        }
    }
    return (1);
}

int	main(void)
{
  	long long N;
  	double r;
  	int	num;
  	long long	i;
  	long long   j;
  	long long   k;
  
  	num = scanf("%lld", &N);
  	if (num != 1)
      	return (0);
  
  	if (IsPrime(N) == 0)
  	{
  	    printf("%lld", N - 1);
  	    return (0);
  	}

  	r = sqrt(N);
  	i = ceil(r);
  	j = floor(r);
  	
  	if (IsSemiPrime(2, N) == 0)
  	    return (0);
  	    
//  	search(N, 3);
  	
  	for (k=3;k<100;k+=2)
  	{
  	    if (IsSemiPrime(k, N) == 0)
  	        return (0);
  	}

    while (i * j != N)
    {
        if (i * j > N)
            j--;
        else if (i * j < N)
            i++;
        else
            break ;
    }
    
    if(i * j == N)
    {
        printf("%lld", i + j - 2);
        return (0);
    }
}