Problem:
Score : 400 points

Problem Statement

Given is a positive integer N. Consider repeatedly applying the operation below on N:

First, choose a positive integer z satisfying all of the conditions below:

z can be represented as z=p^e, where p is a prime number and e is a positive integer;

z divides N;

z is different from all integers chosen in previous operations.

Then, replace N with N/z.

Find the maximum number of times the operation can be applied.

Constraints

All values in input are integers.

1 \leq N \leq 10^{12}

Input

Input is given from Standard Input in the following format:

N

Output

Print the maximum number of times the operation can be applied.

Sample Input 1

24

Sample Output 1

3

We can apply the operation three times by, for example, making the following choices:

Choose z=2 (=2^1). (Now we have N=12.)

Choose z=3 (=3^1). (Now we have N=4.)

Choose z=4 (=2^2). (Now we have N=1.)

Sample Input 2

1

Sample Output 2

0

We cannot apply the operation at all.

Sample Input 3

64

Sample Output 3

3

We can apply the operation three times by, for example, making the following choices:

Choose z=2 (=2^1). (Now we have N=32.)

Choose z=4 (=2^2). (Now we have N=8.)

Choose z=8 (=2^3). (Now we have N=1.)

Sample Input 4

1000000007

Sample Output 4

1

We can apply the operation once by, for example, making the following choice:

z=1000000007 (=1000000007^1). (Now we have N=1.)

Sample Input 5

997764507000

Sample Output 5

7

Solution in Rust (1.42.0) (judge verdict: Accepted)

struct Get<R: std::io::BufRead> {
    stdin: R,
    v: Vec<String>,
    i: usize,
}
impl<R: std::io::BufRead> Get<R> {
    pub fn new(stdin: R) -> Self {
        Get {
            stdin: stdin,
            v: Vec::new(),
            i: 0,
        }
    }
    pub fn read_line(&mut self) {
        self.i = 0;
        self.v.clear();
        let mut buf = String::new();
        self.stdin.read_line(&mut buf).unwrap();
        let buf = buf.trim().to_owned();
        let mut iter = buf.split_whitespace();
        loop {
            let x = iter.next();
            if x.is_none() {
                break;
            }
            let x = x.unwrap().to_owned();
            self.v.push(x);
        }
    }
    #[allow(dead_code)]
    pub fn once<T: std::str::FromStr>(&mut self) -> T {
        if self.i == self.v.len() {
            self.read_line();
        }
        let elem = &self.v[self.i];
        self.i += 1;
        elem.parse().unwrap_or_else(|_| panic!())
    }
}
mod prime {
    #[allow(dead_code)]
    pub fn is_prime(n: usize) -> bool {
        match n {
            0 | 1 => false,
            2 => true,
            _ => {
                if n % 2 == 0 {
                    return false;
                }
                let mut i = 3;
                while i <= (n as f64).sqrt() as usize + 1 {
                    if n % i == 0 {
                        return false;
                    }
                    i+=2;
                }
                true
            }
        }
    }
    #[allow(dead_code)]
    pub fn prime_all(n: usize) -> Vec<usize> {
        let mut list = Vec::new();
        for i in 2..n + 1 {
            if is_prime(i) {
                list.push(i);
            }
        }
        list
    }
    #[allow(dead_code)]
    pub fn factorize(mut n: usize) -> Vec<(usize, usize)> {
        let mut list = Vec::new();
        if is_prime(n) {
            list.push((n, 1));
            return list;
        }
        let primes = prime_all((n as f64).sqrt() as usize + 1);
        for x in &primes {
            let x = *x;
            if n % x != 0 {
                continue;
            }
            list.push((x, 0_usize));
            while n % x == 0 {
                n/=x;
                let index = list.len() - 1;
                list[index].1 += 1;
            }
            if is_prime(n) {
                list.push((n,1));
                break;
            }
        }
        list
    }
}
fn main() {
    use std::io;
    let stdin = io::stdin();
    let stdin = io::BufReader::new(stdin.lock());
    let get = Get::new(stdin);
    solve(get);
}

use std::cmp;
fn solve<R: std::io::BufRead>(mut get:Get<R>) {
    let n:usize = get.once();
    let fact_list = prime::factorize(n);
    let mut ans = 0;
    //println!("{:?}",fact_list);
    for (p, e) in &fact_list {
        let mut sum = 0;
        for i in 1.. {
            sum+=i;
            if sum > *e {
                break;
            }
            ans+=1;
        }
    }
    println!("{}",ans);
}