#include <bits/stdc++.h>
using namespace std;
int main(){
    double n;
    cin >> n;
    double x=0;
    for (double i=1;i<n;i++){
        x+=n/i;
    }
    
    cout << fixed << setprecision(10) << x << endl;
}
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define mod 1000000007
#define F first
#define S second
#define all(v) (v).begin(),(v).end()
#define np next_permutation
#define lp(i,n) for(int i=0;i<n;i++)
#define lps(i,j,n) for(int i=j;i<n;i++)
#define vii vector<vi>
#define vb vector<bool>
#define pr pair<int,int>
#define vl vector<ll>
#define vs vector<string>
#define us unordered_map<int,int>
#define Mpq priority_queue<int>
#define mpq priority_queue<int,vi,greater<int>> 
#define eb emplace_back
#define pr pair<int,int>
#define prl pair<ll,ll>
#define vp vector<pr>
#define vpl vector<prl>
#define mkp make_pair
#define ld long double
#define vii vector<vi>
#define Max(a,b) a=max(a,b)
#define Min(a,b) a=min(a,b)
#define ull unsigned long long
#define prr pair<ll,int>
#define inf (int)1e9+111
 
#include <ext/pb_ds/tree_policy.hpp> 
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
using vi=vector<int>;
 
typedef tree<
pair <int,int>, null_type,
less<pair <int,int>>, rb_tree_tag, tree_order_statistics_node_update>
ordered_set;
ordered_set s;
 
#define F_OR(i, a, b, s) for (int i=(a); (s)>0?i<(b):i>(b); i+=(s))
#define F_OR1(e) F_OR(i, 0, e, 1)
#define F_OR2(i, e) F_OR(i, 0, e, 1)
#define F_OR3(i, b, e) F_OR(i, b, e, 1)
#define F_OR4(i, b, e, s) F_OR(i, b, e, s)
#define GET5(a, b, c, d, e, ...) e
#define F_ORC(...) GET5(__VA_ARGS__, F_OR4, F_OR3, F_OR2, F_OR1)
#define FOR(...) F_ORC(__VA_ARGS__)(__VA_ARGS__)
#define EACH(x, a) for (auto& x: a)
template<class T> using pqg = priority_queue<T,vector<T>,greater<T>>;
 
double epsilon=(double)1e-9;
 
const int N=3e5+123;
ll n,m,k,x,y,t,sum,prev_e,tot,val,pos=1;
ll last_room,rooms;
string pattern,word;
const int Max=(int)1e5;
 
 
int ver[4]={1,-1,0,0},hor[4]={0,0,1,-1};
string MV="DURL",moves;
 
const ll MX=(ll)1e16+123;
 
template<int N> struct Dij{
   ll d[N];
   vector<pair<ll,prl>> g[N];
   pqg<prl> q;
 
   void addEdge(ll a,ll b,ll c,ll d){
      g[a].pb(make_pair(b,make_pair(c,d)));
      g[b].pb(make_pair(a,make_pair(c,d)));
   }
   
   void algo(int s){
      fill_n(d,N,MX);
      q=pqg<prl>();
      q.push({d[s]=0,s});
 
      while(!q.empty()){
         auto x=q.top();
         q.pop();
         if(d[x.S]<x.F) continue;
         for(auto &y:g[x.S]){
            ll distance=ceil((double)x.F/(double)y.S.S)*y.S.S+y.S.F;
            if(distance<d[y.F]){
               q.push({d[y.F]=distance,y.F});
            }
         }
      }
   }
};
 
Dij<N> D;

void solve(){
   int n;
   double ans=0;
   cin>>n;
   lps(i,1,n){
     ans+=(double)n/(double)(n-i);
   }
   cout<<setprecision(15)<<fixed;
   cout<<ans<<"\n";
}
 
int main(){
   ios_base::sync_with_stdio(0);  
   cin.tie(nullptr);
   solve(); 
   return 0;
}
