#include <bits/stdc++.h>
#define FOR(i, a, n) for(int (i) = (int)(a); (i) < (int)(n); ++(i))
#define FORe(i, a, n) for(int (i) = (int)(a); (i) <= (int)(n); ++(i))
#define rFOR(i, a, n) for(int (i) = (int)(n)-1; (i) >= (int)(a); --(i))
#define rFORe(i, a, n) for(int (i) = (int)(n); (i) >= (int)(a); --(i))
#define REP(i, n) FOR((i), 0, (n))
#define REPe(i, n) FORe((i), 1, (n))
#define REPo(i, n) FORe((i), 0, (n))
#define rREP(i, n) rFOR((i), 0, (n))
#define rREPe(i, n) rFORe((i), 1, (n))
#define rREPo(i, n) rFORe((i), 0, (n))
#define rep(i, n) FOR((i), 0, (n))
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define fi first
#define se second
#define dup(x, y) (((x)+(y)-1)/(y))
#define vc(T) vector<T>
#define vv(T) v(v(T))
using namespace std;
using ll = long long;
using P = pair<int,int>;
using pll = pair<ll,ll>;
using T = tuple<int,int,int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vl = vector<ll>;
using vs = vector<string>;
using vp = vector<P>;
using vt = vector<T>;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

// Sieve of Eratosthenes
// struct Sieve {
//   ll n;
//   vector<int> f, primes;
//   Sieve(ll n=1):n(n), f(n+1) {
//     f[0] = f[1] = -1;
//     for (ll i = 2; i <= n; ++i) {
//       if (f[i]) continue;
//       primes.push_back(i);
//       f[i] = i;
//       for (ll j = i*i; j <= n; j += i) {
//         if (!f[j]) f[j] = i;
//       }
//     }
//   }
//   ll g(ll x) {return f[x];}
//   bool isPrime(ll x) { return f[x] == x;}
//   vector<ll> factorList(ll x) {
//     vector<ll> res;
//     while (x != 1) {
//       res.push_back(f[x]);
//       x /= f[x];
//     }
//     return res;
//   }
//   vector<pll> factor(int x) {
//     vector<ll> fl = factorList(x);
//     if (fl.size() == 0) return {};
//     vector<pll> res(1, pll(fl[0], 0));
//     for (ll p : fl) {
//       if (res.back().first == p) {
//         res.back().second++;
//       } else {
//         res.emplace_back(p, 1);
//       }
//     }
//     return res;
//   }
// };
// Sieve of Eratosthenes
struct Sieve {
  int n;
  vector<int> f, primes;
  Sieve(int n=1):n(n), f(n+1) {
    f[0] = f[1] = -1;
    for (ll i = 2; i <= n; ++i) {
      if (f[i]) continue;
      primes.push_back(i);
      f[i] = i;
      for (ll j = i*i; j <= n; j += i) {
        if (!f[j]) f[j] = i;
      }
    }
  }
  int g(ll x) {return f[int(x)];}
  bool isPrime(int x) { return f[x] == x;}
  vector<int> factorList(int x) {
    vector<int> res;
    while (x != 1) {
      res.push_back(f[x]);
      x /= f[x];
    }
    return res;
  }
  vector<P> factor(int x) {
    vector<int> fl = factorList(x);
    if (fl.size() == 0) return {};
    vector<P> res(1, P(fl[0], 0));
    for (int p : fl) {
      if (res.back().first == p) {
        res.back().second++;
      } else {
        res.emplace_back(p, 1);
      }
    }
    return res;
  }
};

bool ISP(ll x) {
  for (ll i = 2; i*i<=x; i++) {
    if (x%i == 0) return false;
  }
  return x != 1;
}

int main() {
  ll n;
  cin >> n;
  if (n==1) {
    cout << 0 << endl;
    return 0;
  }
  Sieve sieve(1100000);
  priority_queue<pll, vector<pll>, greater<pll>> q;
  FORe(i, 2, 1100000) {
    if (sieve.isPrime(i)) q.push({ll(i),ll(i)});
  }
  ll ans = 0;
  ll nn = n;
  map<ll, ll> mp;
  while (q.size()) {
    pll p = q.top(); q.pop();
    ll num = p.first;
    ll m = p.second;
    while (n%num == 0) {
      n /= num;
      mp[num]++;
    }
    
    // q.push({num*m, m});
    // mp[num]++;
    // ans++;
    // cout << num << endl;
  }

  for (const auto& u : mp) {
    ll num = u.first;
    ll a = u.second;
    ll i = 1;
    ll res = 0;
    while(a>0) {
      a -= i;
      if (a<0) break;
      i++;
      ans++;
    }
  }
  if (ISP(n) && n>1100000) ans++;
  // cout << n << endl;
  cout << ans << endl;

  return 0;
}

Measured memory_bytes: 10004