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 C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Threading;

namespace ForATCODER
{
    public class Program
    {
        ///template
        ///
        /// String[] s = Console.ReadLine().Split(' ');
        ///   long[] nk =  s2larray(Console.ReadLine().Split(' '));
        ///  

       static long now = 0;
        static long z = 0;
       static long count = 0;
        static long N;
       static bool outt=false;
       static  List<long> used = new List<long>();
        public static void Main(string[] args)
        {
          
             N = s2l (Console.ReadLine());
            if (IsPrime(N)) { RESULT("1"); return; };
            if (N == 1) { RESULT("0");return; };
            var factor = PrimeFactors(N).ToArray();
            if (!outt) RESULT(count);

        }



        static bool IsPrime(long num)
        {
            if (num < 2) return false;
            else if (num == 2) return true;
            else if (num % 2 == 0) return false; // 偶数はあらかじめ除く

            double sqrtNum = Math.Sqrt(num);
            for (int i = 3; i <= sqrtNum; i += 2)
            {
                if (num % i == 0)
                {
                    // 素数ではない
                    return false;
                }
            }

            // 素数である
            return true;
        }
        public static IEnumerable<long> PrimeFactors(long n)
        {
            long i = 2;
            long tmp = n;

            while (i * i <= n) //※1
            {
                if (tmp % i == 0)
                {
                   // RESULT("prime:"+i);
                    tmp /= i;
                    if (z == 0)
                    {
                        now = i;
                        z = i;
                        used.Add(now);
                    }
                    else
                    {
                        if (now != i)
                        {
                            z = i;
                            now = i;
                            used.Add(now);
                        }
                        else z *= i;
                    }
                    if (N % z == 0)
                    {
                  //  RESULT(N + ":");
                  //  RESULT(z);
                        N /= z;
                      count++;
                   // RESULT("="+N );
                        if (IsPrime(N))
                        {
                            if (used.IndexOf(N)==-1)
                            RESULT(count+1);
                            else RESULT(count);
                            outt = true;
                            break;
                        }
                        if (N <= 1 || N==z || N<=z)
                        {
                            RESULT(count);
                            outt = true;
                            break;
                        }
                    }
                    yield return i;
                }
                else
                {
                    i++;
                }
            }
            if (tmp != 1)
            {
                if (!outt)
                {
                    if (z == 0)
                    {
                        now = tmp;
                        z = tmp;
                    }
                    else
                    {
                        if (now != tmp)
                        {
                            z = tmp;
                            now = tmp;
                        }
                        else z *= tmp;
                    }
                    if (N % z == 0)
                    {
                        N /= z;
                        count++;
                        if (N <= 1 || N == z)
                        {
                            if (!outt) RESULT(count);
                        }
                    }
                }
                yield return tmp;
            }


        }

        class TreeNode<T>
        {
            List<TreeNode<T>> Children;

            T Item { get; set; }

            public TreeNode(T item)
            {
                Item = item;
            }

            public TreeNode<T> AddChild(T item)
            {
                TreeNode<T> nodeItem = new TreeNode<T>(item);
                Children.Add(nodeItem);
                return nodeItem;
            }
            public void AddChildRelative(TreeNode<T> item)
            {
                Children.Add(item);
            }
            public List<TreeNode<T>> GetChildren(T val)
            {
                if (val.Equals(Item))
                {
                    var l = new List<TreeNode<T>>();
                    l.Add(this);
                    return l;
                }
                return Children.FindAll(x => x.Item.Equals(val));
            }
        }

        static void addarray(long[] arr, int start, int end)
        {
            for (int i = start; i <= end; i++)
            {
                arr[i]++;
            }
        }
        public static decimal Sqrt(decimal x)
        {
            decimal sqrt_x = (decimal)Math.Sqrt((long)x);
            for (int i = 0; i < 10; ++i)
                sqrt_x = 0.5m * (sqrt_x + x / sqrt_x);
            return sqrt_x;
        }
        static long summ(long s)
        {
            if (s == 1) return 1;
            return s + summ(s - 1);
        }
        public static bool checka(int[] a, int m)
        {
            int back = 1;
            for (int i = 0; i < a.Length; i++)
            {
                if (a[i] >= 1 && a[i] <= m)
                {
                    if (a[i] >= back)
                    {
                        back = a[i];
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            return true;
        }
        public static ulong pow(int a, int b)
        {
            ulong res = 1;
            for (int i = 0; i < b; i++)
            {
                res *= (ulong)a;
            }
            return res;
        }
        static int s2i(String s)
        {
            return Convert.ToInt32(s);
        }
        static long s2l(String s)
        {
            return Convert.ToInt64(s);
        }
        static void RESULT(double res)
        {
            Console.WriteLine(res);
        }
        static void RESULT(long res)
        {
            Console.WriteLine(res);
        }
        static void RESULT(ulong res)
        {
            Console.WriteLine(res);
        }
        static void RESULT(int res)
        {
            Console.WriteLine(res);
        }
        static void RESULT(String res)
        {
            Console.WriteLine(res);
        }
        static String[] ReadLineAll(int count)
        {
            String[] res = new String[count];
            for (int i = 0; i < count; i++)
            {
                res[i] = Console.ReadLine();
            }
            return res;
        }

        static int[] s2iarray(String[] src)
        {
            int len = src.Length;
            int[] res = new int[len];
            for (int i = 0; i < len; i++)
            {
                res[i] = Convert.ToInt32(src[i]);
            }
            return res;
        }
        static long[] s2larray(String[] src)
        {
            int len = src.Length;
            long[] res = new long[len];
            for (int i = 0; i < len; i++)
            {
                res[i] = Convert.ToInt64(src[i]);
            }
            return res;
        }
        static decimal[] s2darray(String[] src)
        {
            int len = src.Length;
            decimal[] res = new decimal[len];
            for (int i = 0; i < len; i++)
            {
                res[i] = Convert.ToDecimal(src[i]);
            }
            return res;
        }
        static ulong[] s2larray2(String[] src)
        {
            int len = src.Length;
            ulong[] res = new ulong[len];
            for (int i = 0; i < len; i++)
            {
                res[i] = Convert.ToUInt64(src[i]);
            }
            return res;
        }

        static long C(int n, int r)
        {
            if (n <= 1) return 0;
            if (r > n - r) r = n - r; // because C(n, r) == C(n, n - r)
            long ans = 1;
            int i;

            for (i = 1; i <= r; i++)
            {
                ans *= n - r + i;
                ans /= i;
            }

            return ans;
        }
        static long C(long n, long r)
        {
            if (n <= 1) return 0;
            if (r > n - r) r = n - r; // because C(n, r) == C(n, n - r)
            long ans = 1;
            int i;

            for (i = 1; i <= r; i++)
            {
                ans *= n - r + i;
                ans /= i;
            }

            return ans;
        }
        static ulong C(ulong n, ulong r)
        {
            if (n <= 1) return 0;
            if (r > n - r) r = n - r; // because C(n, r) == C(n, n - r)
            ulong ans = 1;
            ulong i;

            for (i = 1; i <= r; i++)
            {
                ans *= n - r + i;
                ans /= i;
            }

            return ans;
        }


    }

}