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: Time Limit Exceeded)

using System;
using static System.Console;
using static Atcoder_Template_NetCore3.MyUtil;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace Atcoder_Template_NetCore3
{
    class Program
    {
        private static IList<int> array;
        static void Main()
        {
            array = GetSosuList();

            long input = long.Parse(ReadLine());
            long n = input;
            long ans = 0;

            for(int i = 0; i < array.Count; i++)
            {
                var div = array[i];
                while (true)
                {
                    if (n % div == 0)
                    {
                        ans++;
                        n = n / div;
                        div *= array[i];
                    }
                    else
                    {
                        break;
                    }
                }
            }
            if (input > 1 && ans == 0) ans = 1;
            WriteLine(ans);
        }


        #region 素数計算コード
        private static string GetInitializer(IList<int> list)
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("=new[]{");
            for(int i = 0; i < list.Count - 1; i++)
            {
                stringBuilder.Append(list[i]);
                stringBuilder.Append(",");
            }
            stringBuilder.Append(list[list.Count - 1]);
            stringBuilder.Append("};");

            return stringBuilder.ToString();
        }

        private readonly static int MaxValue = (int)Math.Pow(10, 6);
        private static List<int> GetSosuList()
        {
            List<int> list = new List<int>();
            Parallel.For(2, MaxValue + 1, (int i) =>
            {
                var root = (int)Math.Sqrt(i);
                bool isSosu = true;
                for (int j = 2; j <= root; j++)
                {
                    if (i % j == 0) isSosu = false;
                }
                if (isSosu)
                {
                    lock (list)
                    {
                        list.Add(i);
                    }
                }
            });
            list.Sort();
            return list;
        }
        #endregion
    }

    static class MyUtil
    {
        /// <summary>
        /// 指定の桁のビットを取得します。
        /// </summary>
        /// <param name="num"></param>
        /// <param name="count">取得する桁。</param>
        /// <returns></returns>
        public static int GetBit(this int num, int count)
        {
            int mask = (int)Math.Pow(2, count - 1);
            return (num & mask) == 0 ? 0 : 1;
        }

        /// <summary>
        /// <c>int</c>を2進数ビット配列に変換します。
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static int[] ToBitArray(this int num)
        {
            const int size = sizeof(int) * 8;
            var array = new int[size];
            for (int i = 0; i < size; i++)
            {
                array[i] = num.GetBit(size - i);
            }
            return array;
        }

        #region AutoGeneratedCode 整数読み取り系
        public static ValueTuple<int, int> ReadInt2()
        {
            var input = Console.ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
            return (input[0], input[1]);
        }
        public static ValueTuple<long, long> ReadLong2()
        {
            var input = Console.ReadLine().Split(' ').Select(s => long.Parse(s)).ToArray();
            return (input[0], input[1]);
        }
        public static ValueTuple<int, int, int> ReadInt3()
        {
            var input = Console.ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
            return (input[0], input[1], input[2]);
        }
        public static ValueTuple<long, long, long> ReadLong3()
        {
            var input = Console.ReadLine().Split(' ').Select(s => long.Parse(s)).ToArray();
            return (input[0], input[1], input[2]);
        }
        public static ValueTuple<int, int, int, int> ReadInt4()
        {
            var input = Console.ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
            return (input[0], input[1], input[2], input[3]);
        }
        public static ValueTuple<long, long, long, long> ReadLong4()
        {
            var input = Console.ReadLine().Split(' ').Select(s => long.Parse(s)).ToArray();
            return (input[0], input[1], input[2], input[3]);
        }
        public static ValueTuple<int, int, int, int, int> ReadInt5()
        {
            var input = Console.ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
            return (input[0], input[1], input[2], input[3], input[4]);
        }
        public static ValueTuple<long, long, long, long, long> ReadLong5()
        {
            var input = Console.ReadLine().Split(' ').Select(s => long.Parse(s)).ToArray();
            return (input[0], input[1], input[2], input[3], input[4]);
        }
        public static ValueTuple<int, int, int, int, int, int> ReadInt6()
        {
            var input = Console.ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
            return (input[0], input[1], input[2], input[3], input[4], input[5]);
        }
        public static ValueTuple<long, long, long, long, long, long> ReadLong6()
        {
            var input = Console.ReadLine().Split(' ').Select(s => long.Parse(s)).ToArray();
            return (input[0], input[1], input[2], input[3], input[4], input[5]);
        }
        public static ValueTuple<int, int, int, int, int, int, int> ReadInt7()
        {
            var input = Console.ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
            return (input[0], input[1], input[2], input[3], input[4], input[5], input[6]);
        }
        public static ValueTuple<long, long, long, long, long, long, long> ReadLong7()
        {
            var input = Console.ReadLine().Split(' ').Select(s => long.Parse(s)).ToArray();
            return (input[0], input[1], input[2], input[3], input[4], input[5], input[6]);
        }
        #endregion

        public static int[] ReadintArray()
        {
            return ReadLine().Split(' ').Select(s => int.Parse(s)).ToArray();
        }

        public static long[] ReadlongArray()
        {
            return ReadLine().Split(' ').Select(s => long.Parse(s)).ToArray();
        }

        /// <summary>
        /// <see cref="IEnumerable{T}"/>の各要素を並べてコンソールに出力します。各要素の間には半角スペースが一つ入ります。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ts"></param>
        public static void WriteToConsole<T>(this IEnumerable<T> ts)
        {
            StringBuilder stringBuilder = new StringBuilder();
            foreach (T t in ts)
            {
                stringBuilder.Append(t.ToString());
                stringBuilder.Append(" ");
            }
            stringBuilder.Remove(stringBuilder.Length - 1, 1);
            Console.WriteLine(stringBuilder.ToString());
        }
    }
}