Go: package main

import (
	"bufio"
	"fmt"
	"io"
	"math"
	"os"
	"sort"
	"strconv"
)

func main() {
	fmt.Println(resolve(parseProblem(os.Stdin)))
}

func parseProblem(r io.Reader) int {
	const (
		initialBufSize = 100000
		maxBufSize     = 1000000
	)
	buf := make([]byte, initialBufSize)

	sc := bufio.NewScanner(r)
	sc.Buffer(buf, maxBufSize)
	sc.Split(bufio.ScanWords) // bufio.ScanLines

	return scanInt(sc)
}

func resolve(n int) (int, int) {
	ds := enumDivisors(n)
	max := len(ds) - 1

	cand := map[int]struct{}{}
	for _, d := range ds {
		cand[d] = struct{}{}
	}
	delete(cand, n)
	sort.Sort(sort.Reverse(sort.IntSlice(ds)))
	min := 0
	for _, k := range ds {
		if _, ok := cand[k]; !ok {
			continue
		}
		if len(cand) == 0 {
			break
		}
		for _, kk := range enumDivisors(k) {
			delete(cand, kk)
		}
		min++
	}
	return min, max
}

func pow(n, i int) (res int) {
	res = 1
	for i > 0 {
		if i&1 == 1 {
			res *= n
		}
		i >>= 1
		n *= n
	}
	return res
}

func enumDivisors(n int) (r []int) {
	max := int(math.Sqrt(float64(n))) + 1
	for i := 1; i < max; i++ {
		if n%i == 0 {
			r = append(r, i)
			if n/i != i {
				r = append(r, n/i)
			}
		}
	}
	sort.Sort(sort.IntSlice(r))
	return r
}

// snip-scan-funcs
func scanInt(sc *bufio.Scanner) int {
	sc.Scan()
	i, _ := strconv.Atoi(sc.Text())
	return int(i)
}
func scanString(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

Python: import math

n = int(input())
p = list()
m = int(math.sqrt(n)+1)
for i in range(2,m):
    if n%i == 0:
        c = 0
        while n%i == 0:
            c += 1
            n //= i
        p.append(c)
if n != 1:
    p.append(1)
maxi = 1
for x in p:
    maxi *= (x+1)
print(len(p),maxi-1)

Python: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
''' 
------------------------
author : iiou16
------------------------
'''
import copy

def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    divisors.sort()
    return divisors


def main():
    N = int(input())
    yakusu = make_divisors(N)
    max_times = len(yakusu) - 1
    min_times = 0
    result = []
    for i in reversed(yakusu[:-1]):
        if i in result:
            continue
        result.extend(make_divisors(i))
        # print(result)
        min_times += 1
    print(min_times, max_times)


if __name__ == '__main__':
    main()

Python: import sys
sys.setrecursionlimit(10 ** 5 + 10)
def input(): return sys.stdin.readline().strip()

def resolve():
    n=int(input())
    import math
    
    
    # cf. https://qiita.com/suecharo/items/14137fb74c26e2388f1f
    def make_prime_list_2(num):
        if num < 2:
            return []
    
        # 0のものは素数じゃないとする
        prime_list = [i for i in range(num + 1)]
        prime_list[1] = 0  # 1は素数ではない
        num_sqrt = math.sqrt(num)
    
        for prime in prime_list:
            if prime == 0:
                continue
            if prime > num_sqrt:
                break
    
            for non_prime in range(2 * prime, num, prime):
                prime_list[non_prime] = 0
    
        return [prime for prime in prime_list if prime != 0]
    
    
    def prime_factorization_2(num):
        """numの素因数分解
        素因数をkeyに乗数をvalueに格納した辞書型dict_counterを返す"""
    
        if num <= 1:
            # 例えば1を食ったときの対処の仕方は問題によって違うと思うのでそのつど考える。
            # cf. https://atcoder.jp/contests/abc110/submissions/12688244
            return False
        else:
            num_sqrt = math.floor(math.sqrt(num))
            prime_list = make_prime_list_2(num_sqrt)
    
            dict_counter = {}  # 何度もこの関数を呼び出して辞書を更新したい時はこれを引数にして
            # cf. https://atcoder.jp/contests/arc034/submissions/12251452
    
            for prime in prime_list:
                while num % prime == 0:
                    if prime in dict_counter:
                        dict_counter[prime] += 1
                    else:
                        dict_counter[prime] = 1
                    num //= prime
            if num != 1:
                if num in dict_counter:
                    dict_counter[num] += 1
                else:
                    dict_counter[num] = 1
    
            return dict_counter
    d=prime_factorization_2(n)
    val=1
    for v in d.values():
        val*=(v+1)
    print(len(d),val-1)

    
resolve()

Python: import sys
sys.setrecursionlimit(int(1e7))
from collections import deque
def inpl(): return list(map(int, input().split()))

def primes(N):
    sieve = [1]*(N+1)
    sieve[0], sieve[1] = 0, 0
    P = []
    for i in range(2, N+1):
        if sieve[i]:
            P.append(i)
            for j in range(2*i, N+1, i):
                sieve[j] = 0
    return P

N = int(input())
P = primes(10**6 + 10)

factors = [0]*len(P)
for i in range(len(P)):
    p = P[i]
    while N%p == 0:
        factors[i] += 1
        N = N//p

factors += [N!=1]
a = sum([f > 0 for f in factors])
b = 1
for i in range(len(P)+1):
    b *= factors[i] + 1

b -= 1

print(a, b)

Python: #!usr/bin/env python3
from collections import defaultdict
from heapq import heappush, heappop
import sys
import math
import bisect
import random
def LI(): return list(map(int, sys.stdin.readline().split()))
def I(): return int(sys.stdin.readline())
def LS():return list(map(list, sys.stdin.readline().split()))
def S(): return list(sys.stdin.readline())[:-1]
def IR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = I()
    return l
def LIR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = LI()
    return l
def SR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = S()
    return l
def LSR(n):
    l = [None for i in range(n)]
    for i in range(n):l[i] = SR()
    return l
mod = 1000000007

#A
"""
n,m = LI()
a = LI()
b = LI()
li = list(set(a)|set(b))
li2 = list(set(a)&set(b))
li.sort()
li2.sort()
print(len(li2),len(li))
for i in li2:
    print(i)
for i in li:
    print(i)
"""

#B
"""
n = I()
p = LI()
p.append(float("inf"))
ans = ""
i = 0
l = 0
k = [i+1 for i in range(n)]
while i < n:
    if p[i] < p[i+1]:
        a = p[l:i+1][::-1]
        if a != k[l:i+1]:
            print(":(")
            quit()
        l = i+1
        for d in range(len(a)):
            ans += "("
        for d in range(len(a)):
            ans += ")"
    i += 1
print(ans)
"""
#C
def fact(n):
    i = 2
    a = n
    if n < 4:
        return [1,n],[n]
    li = [1,n]
    while i**2 <= a:
        if n%i == 0:
            li.append(i)
            if i != n//i:
                li.append(n//i)
        i += 1
    li.sort()
    i = 2
    if len(li) == 2:
        return li,[a]
    k = []
    b = a
    while i**2 <= b:
        if a%i == 0:
            k.append(i)
            while a%i == 0:
                a//= i
        i += 1
    if a!=1:
        k.append(a)
    return li,k
n = I()
l,k = fact(n)
if len(l) == 2:
    print(1,1)
else:
    print(len(k),len(l)-1)
#D

#E

#F

#G

#H

#I

#J

#K

#L

#M

#N

#O

#P

#Q

#R

#S

#T

C++: #include<bits/stdc++.h>
using namespace std;
using lint = long long;
map<lint, int> factorize(lint n) {
    map<lint, int> res;
    for (lint i = 2; i * i <= n; ++i) {
        while (n % i == 0) {
            ++res[i];
            n /= i;
        }
    }
    if (n != 1) ++res[n];
    return res;
}

int main() {
    lint n; cin >> n;
    auto mp = factorize(n);
    int mn = mp.size(), mx = 1;
    for (const auto& e : mp) {
        mx *= e.second + 1;
    }
    --mx;
    cout << mn << ' ' << mx << '\n';
    return 0;
}