Buggy python submission (verdict: Runtime Error):
import sys
sys.setrecursionlimit(1000000)
def I(): return int(sys.stdin.readline().rstrip())
def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def S(): return sys.stdin.readline().rstrip()
def LS(): return list(sys.stdin.readline().rstrip().split())
n = I()
n_z = n # n/z
prime_e = [] # 素数**自然数のリスト
p = 2 # 最初の素数
e = 1

def fermat_test(q):
    if q == 2: return True
    elif q < 2 or q & 1 == 0: return False   # q & 1 == 0 偶数の場合のFalseを返す意。 


if n == 1:
    print(0)
    sys.exit()


while p * p <= n: # 素数pの2乗がnより大きいと1回も割れない。
    if n_z % p == 0:
        z = p ** e
        while n_z % z == 0:
            if z not in prime_e:
                n_z = int(n_z / z)
                prime_e.append(z)
            e += 1
            z = p ** e
    p += 1
    e = 1
    while fermat_test(p) == False:
        p += 1
print(len(prime_e)

Fixed submission:
import sys
sys.setrecursionlimit(1000000)
def I(): return int(sys.stdin.readline().rstrip())
def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def S(): return sys.stdin.readline().rstrip()
def LS(): return list(sys.stdin.readline().rstrip().split())
from collections import defaultdict
n = I()
def primes(n):
    cnt = defaultdict(int)
    for i in range(2,int(n**0.5)+1): # range(3)だと、0,1,2が出てくる。
        while n % i == 0:
            cnt[i] += 1 # 同じ素数で何回割れるか辞書型で登録しておく
            n //= i # iで割り切った商で更新しておく
    if n > 1: # nの平方根より大きい値があった場合、追加
        cnt[n] += 1
    return cnt
prs = primes(n) #　素数の辞書
ans = 0
for key in prs.keys(): #辞書から素数を抽出して、その素数の指数値をvとして格納する。
    v = prs[key]
    for i in range(100):
        # if (i * (i+1)) // 2 <= v:　これだと何度も足し算してしまう。
        if (i * (i + 1)) // 2 > v: # 指数eを超えた一つ前が目的の計数である。
            ans += (i-1)
            break
print(ans)

Buggy python submission (verdict: Runtime Error):
import sys
sys.setrecursionlimit(1000000)
def input():
    return sys.stdin.readline()[:-1]
n = int(input()) # 素数のリスト
n_z = n # n/z
prime_e = []
p = 2 # 最初の素数
e = 1

def fermat_test(q):
    q = abs(q)
    if q == 2: return True
    elif q < 2 or q & 1 == 0:    # q & 1 == 0 偶数の場合の意。 
    # x(int) & y(int)と表記すると2進数表記にしたときに、各桁のどこかが一致する場合は1、どこも一致しない場合は0を返す。
    # 例えば10→2進数:1010と1→2進数:1を比較するとドコモ一致しないので、0が帰ってくる。
    # 2進数表記の偶数は一番下の桁が0のため、2進数表記の1は一致しないため、0が返ってくる。
        return False

while p * p <= n: # 素数pの2乗がnより大きいと1回も割れない。
    # print("current n_z: {}".format(n_z))
    if n_z % p == 0:
        z = p ** e
        while n_z % z == 0:
            n_z = n_z / z
            prime_e.append(z)
            e += 1
            z = p ** e           
    p += 1
    e = 1
    while fermat_test(p) == False:
        # print("{} is Not Prime".format(p))
        p += 1
print(len(prime_e)#, prime_e)

Fixed submission:
import sys
sys.setrecursionlimit(1000000)
def I(): return int(sys.stdin.readline().rstrip())
def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def S(): return sys.stdin.readline().rstrip()
def LS(): return list(sys.stdin.readline().rstrip().split())
from collections import defaultdict
n = I()
def primes(n):
    cnt = defaultdict(int)
    for i in range(2,int(n**0.5)+1): # range(3)だと、0,1,2が出てくる。
        while n % i == 0:
            cnt[i] += 1 # 同じ素数で何回割れるか辞書型で登録しておく
            n //= i # iで割り切った商で更新しておく
    if n > 1: # nの平方根より大きい値があった場合、追加
        cnt[n] += 1
    return cnt
prs = primes(n) #　素数の辞書
ans = 0
for key in prs.keys(): #辞書から素数を抽出して、その素数の指数値をvとして格納する。
    v = prs[key]
    for i in range(100):
        # if (i * (i+1)) // 2 <= v:　これだと何度も足し算してしまう。
        if (i * (i + 1)) // 2 > v: # 指数eを超えた一つ前が目的の計数である。
            ans += (i-1)
            break
print(ans)