#include <math.h>
#include <algorithm>
#include <set>
#include <iostream>
#include <vector>
#include <queue>
#include <map>
#include <string>
#include <cstring>
#include <functional>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <chrono>
#include <climits>
using namespace std ;
#define ld long double
#define int long long
#define ii pair<int,int>
#define _ ios_base::sync_with_stdio(false) ;cin.tie(NULL);cout.tie(NULL);
#define dbg(x) cerr << #x << " is " << x << endl;
#define ms(x,a) memset(x,(int)(a),sizeof(x))
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define vi vector<int >
#define pb push_back
#define endl '\n'
#define ff first
#define ss second
const int N = 1e6+7 ;
const int INF = 1e9 ;
const int MOD = INF + 7 ;
string s ;
struct NumberTheory
{
	vector<int> primes;
	vector<bool> prime;
	vector<int> totient;
	vector<int> sumdiv;
	vector<int> mobius;
	vector<int> bigdiv;
	void Sieve(int n)
	{
		prime.assign(n+1, 1);
		prime[1] = false;
		for(int i = 2; i <= n; i++)
		{
			if(prime[i])
			{
				primes.pb(i);
				for(int j = i*2; j <= n; j += i)
				{
					prime[j] = false;
				}
			}
		}
	}
	
	int phi(int x)
	{
		map<int,int> pf;
		int num = 1; int num2 = x;
		for(int i = 0; primes[i]*primes[i] <= x; i++)
		{
			if(x%primes[i]==0)
			{
				num2/=primes[i];
				num*=(primes[i]-1);
			}
			while(x%primes[i]==0)
			{
				x/=primes[i];
				pf[primes[i]]++;
			}
		}
		if(x>1)
		{
			pf[x]++; num2/=x; num*=(x-1);
		}
		x = 1;
		num*=num2;
		return num;
	}
	
	bool isprime(int x)
	{
		if(x==1) return false;
		for(int i = 0; primes[i]*primes[i] <= x; i++)
		{
			if(x%primes[i]==0) return false;
		}
		return true;
	}
 
	void SievePhi(int n)
	{
		totient.resize(n+1);
		for (int i = 1; i <= n; ++i) totient[i] = i;
		for (int i = 2; i <= n; ++i)
		{
			if (totient[i] == i)
			{
				for (int j = i; j <= n; j += i)
				{
					totient[j] -= totient[j] / i;
				}
			}
		}
	}
	void SieveMob(int n)
	{
		mobius.resize(n+1,0);
		mobius[1] = 1;
		for (int i = 2; i <= n; ++i) {
			if (prime[i]) {
				mobius[i] = -1;				//i is prime
			}
			for (int j = 0; j < primes.size () && i * primes[j] <= n; ++j) {
				if (i % primes[j] == 0) {
					mobius[i * primes[j]] = 0;//prime[j] divides i
					break;
				} else {
					mobius[i * primes[j]] = mobius[i] * -1;	//prime[j] does not divide i
				}
			}
		}
	}
	
	void SieveSumDiv(int n)
	{
		sumdiv.resize(n+1);
		for(int i = 1; i <= n; ++i)
		{
			for(int j = i; j <= n; j += i)
			{
				sumdiv[j] += i;
			}
		}
	}
	
	int getPhi(int n)
	{
		return totient[n];
	}
	
	int getSumDiv(int n)
	{
		return sumdiv[n];
	}
	
	int modpow(int a, int b, int mod)
	{
		int r = 1;
		if(b < 0) b += mod*100000LL;
		while(b)
		{
			if(b&1) r = (r*a)%mod;
			a = (a*a)%mod;
			b>>=1;
		}
		return r;
	}
	
	int inv(int a, int mod)
	{
		return modpow(a, mod - 2, mod);
	}
	
	int invgeneral(int a, int mod)
	{
		int ph = phi(mod);
		ph--;
		return modpow(a, ph, mod);
	}
	
	void getpf(vector<ii>& pf, int n)
	{
		for(int i = 0; primes[i]*primes[i] <= n; i++)
		{
			int cnt = 0;
			while(n%primes[i]==0)
			{
				n/=primes[i]; cnt++;
			}
			if(cnt>0) pf.pb(ii(primes[i], cnt));
		}
		if(n>1)
		{
			pf.pb(ii(n, 1));
		}
	}
 
	//int op;
	void getDiv(vector<int>& div, vector<ii>& pf, int n, int i)
	{
		//op++;
		int x, k;
		if(i >= pf.size()) return ;
		x = n;
		for(k = 0; k <= pf[i].ss; k++)
		{
			if(i==(int)pf.size()-1) div.pb(x);
			getDiv(div, pf, x, i + 1);
			x *= pf[i].ff;
		}
	}
};
NumberTheory nt ;

void solve(){	
	int n ;
	cin >> n ;
	vector<int> a ;
	for(int i = 1 ; i*i <= n ; i++){
		if(n%i == 0){
			a.pb(i+(n/i)) ;
		}
	}
	int t = *min_element(all(a)) ;
	cout << t-2 << endl ;
}

int32_t main(){_
	int t = 1 ;
//	cin >> t ;
	while(t--){
		solve() ;
	}

}


Measured memory_bytes: 384