#include <math.h>
#include <assert.h>
#include <algorithm>
#include <set>
#include <iostream>
#include <vector>
#include <iomanip>
#include <queue>
#include <map>
#include <string>
#include <cstring>
#include <functional>
#include <stack>
#include <array>
#include <random>
#include <chrono>
#include <climits>
#include <bitset>
using namespace std ;
#define int long long
#define ii pair<int,int>
#define FAST_IO ios_base::sync_with_stdio(false) ;cin.tie(NULL);cout.tie(NULL)
#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 = 3e5+7 ;
//const int INF = 1e18 ;
//const int MOD = 1e9 + 7 ;
/* Print pair */
template <typename T,typename S>
ostream & operator << (ostream &os , const pair<T,S> &v) {
    os << "(" ;
    os << v.first << "," << v.second << ")" ;
    return os ;
}
/* Print vector */
template <typename T>
ostream & operator << (ostream &os , const vector<T> &v) {
    os << "[" ;
    int sz = v.size() ;
    for(int i = 0 ; i < sz ; ++i) {
        os << v[i] ;
        if(i!=sz-1)os << "," ;
    }
    os << "]\n" ;
    return os ;
}
/* Print set */
template <typename T>
ostream & operator << (ostream &os , const set<T> &v) {
    T last = *v.rbegin() ;
    os << "[" ;
    for(auto it : v) {
        os << it  ;
        if(it != last) os << "," ;
    }
    os << "]\n" ;
    return os ;
}
/* Print Map */
template <typename T,typename S>
ostream & operator << (ostream &os , const map<T,S> &v) {
    for(auto it : v) {
        os << it.first << " : " << it.second << "\n" ;
    }
    return os ;
}
//debug
#define TRACE

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif



struct NumberTheory
{
    vector<int> primes;
    vector<bool> prime;
    vector<int> totient;
    vector<int> mobius;
    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 n) { 
      if (n <= 1) return false; 
      if (n <= 3) return true; 
      if (n % 2 == 0 || n % 3 == 0) return false; 
      for (int i = 5; i * i <= n; i += 6) 
        if (n % i == 0 || n % (i+2) == 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
                }
            }
        }
    }
    
    int getPhi(int n){
        return totient[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));
        }
    }
    
    void getDiv(vector<int>& ans, int x){
        for(int i = 1 ; i*i <= x ; i++){
            if(x%i == 0){
                ans.push_back(i) ;
                ans.push_back(x/i) ;
            }
        }
        sort(all(ans));
        ans.erase(unique(all(ans)),ans.end());
    }    
};
NumberTheory nt ;
int p2[33] ;

void solve(){
    nt.Sieve(1e6+5) ;
    int n ;
    cin >> n ;
    p2[0] =1 ;
    for(int i = 1 ; i <= 32 ; i++){
        p2[i] = 2*p2[i-1] ;
    }
    vector<ii> pf ;
    nt.getpf(pf, n) ;
    //trace(pf) ;
    int ans = 0 ;
    for(auto it : pf){
        int x = 1ll << it.ss ;
        for(int i = 1 ; i <= 32 ; i++){
            ans++ ;
            x /= p2[i] ;
            if(x<=p2[i])
                break ;
        }
    }
    cout << ans << endl ;
}

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


Measured memory_bytes: 4336