// 5/14
// 過去問ガリガリ
#include <bits/stdc++.h>
#include <string>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;
using Graph = vector<vector<int>>;

const int mod = 1000000007;
// const int mod = 998244353;
struct mint {
  ll x; // typedef long long ll;
  mint(ll x=0):x((x%mod+mod)%mod){}
  mint operator-() const { return mint(-x);}
  mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += mod-a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this;}
  mint operator+(const mint a) const { return mint(*this) += a;}
  mint operator-(const mint a) const { return mint(*this) -= a;}
  mint operator*(const mint a) const { return mint(*this) *= a;}
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const { return pow(mod-2);}
  mint& operator/=(const mint a) { return *this *= a.inv();}
  mint operator/(const mint a) const { return mint(*this) /= a;}
};

const int MX = 1000005;

struct Sieve {  // Sieveはふるい。
    int n;  // 最大の数
    vector<int> f, primes;
    // fはふるいの結果。f[x]はxの最小の素因数が入る。f[x] == xの場合、xは素数。
    // primesは素数のリスト。

    // コンストラクタ内でSieveする。
    Sieve(int n=1):n(n), f(n + 1) {
        // ↑↑↑まず冒頭でnとfを初期化している↑↑↑

        // 0と1の場合は特殊なので、-1を入れておく。
        // あとでisPrimeがワークするように。
        f[0] = f[1] = -1;

        // エラストテネスのふるいにかけていく。
        for (ll i = 2; i <= n; ++i) {

            // f[i]が探索済みどうかを判定する。
            // f[i] > 0なら既に判定されているはず。
            if (f[i]) continue;

            // 上のifにハマらなかったら素数。
            f[i] = i;

            // 素数ならprimesにブッコむ。
            primes.push_back(i);

            // ふるいにかける。
            for (ll j = i * i; j <= n; j += i) {
                if (!f[j]) f[j] = i;
                // i = 2の時は2, 4, 6, 8...に2を入れる。
                // i = 3の時は3, 6, 9, 12...に3を入れる。
                // なお６などの公倍数の時は、書き換えない。
                // 最小の素数を入れておくことで、後のfactor関数で小さい順に並ぶようにする。（なるほど。）
            }
        }
    }

    // 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;
    }

    // 普通はfactorというよりも、素因数ごとに頻度を集計したものが欲しいので...by snukeさん。
    // https://youtu.be/UTVg7wzMWQc?t=4518
    vector<P> factor(int x) {
        vector<int> fl = factorList(x);  // 例えば12なら2, 2, 3のvector
        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;
    } 
};

ll calc(ll x) {
    ll res = 0;
    ll n = 1;
    while (true) {
        if (x >= n) {
            res++;
            x -= n;
            n++;
        } else {
            break;
        }
    }
    return res;
}

int main() {
    // ふるいの初期化
    Sieve sieve(1e6);  // 1e6は10^6

    ll N;  // < 1e12
    cin >> N;

    ll n = N;

    map<ll, ll> mp;  // 素因数を格納

    for (ll i = 0; i < 1e6; i++) {
        if (sieve.isPrime(i)) {
            while (n % i == 0) {
                n /= i;
                mp[i]++;
            }
        }

        if (n == 1) {
            break;
        }
    }

    if (n != 1) {
        mp[N]++;
    }

    ll ans = 0;

    for (auto p : mp) {
        // printf("mp[%d] = %d, cals[%d] = %d\n", p.first, p.second, p.second, calc(p.second));

        ans += calc(p.second);
    }

    cout << ans << endl;

    // mint lcm = 1;
    // for (auto p : mp) {
    //     rep(i, p.second) {
    //         lcm *= p.first;
    //     }
    // }

    // mint ans;

    // rep(i, n) {
    //     mint b = lcm / a[i];
    //     ans += b;
    // }

    // cout << ans.x << endl;

    return 0;
}


Measured memory_bytes: 7640