Go: package main

import (
	"fmt"
	"math"
)

func main() {
	var on int
	fmt.Scan(&on)
	m := make(map[int]int)
	loop := true
	n := on
	for loop {
		loop = false
		for i := 2; i <= int(math.Sqrt(float64(n))); i++ {
			if n%i == 0 {
				m[i]++
				n /= i
				loop = true
				break
			}
		}
	}
	if n != 1 {
		m[n]++
	}

	var cnt int
	for i := 1; i <= int(math.Sqrt(float64(on))); i++ {
		if on%i == 0 {
			if on/i == i {
				cnt++
			} else {
				cnt += 2
			}
		}
	}

	fmt.Printf("%d %d\n", len(m), cnt-1)
}

C++: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
#define int long long
using namespace std;
typedef pair<int,int>P;
typedef pair<P,int>P2;
#define fi first
#define se second
 
typedef long long ll;
struct NT{
  ll m;  // mod
  vector<bool>ismrime;
  vector<ll> euler;
  vector<ll> fact;
 
  NT(ll MOD){
    m=MOD;
    fact.resize(500009);
    fact[0]=1;
    for(ll i=1;i<500009;i++){
      fact[i]=(fact[i-1]*i)%MOD;
    }
  }
 
  void eratos(int n){
    ismrime.resize(n+1);
    for(int i=0;i<=n;i++) ismrime[i]=true;
    ismrime[0]=0;
    ismrime[1]=0;
    for(int i=2;i<=n;i++){
      if(ismrime[i]){
        for(int j=i+i;j<=n;j+=i) ismrime[j]=false;
      }
    }
  }
 
  // 因数分解 √N
  vector<int> mrime_decommosition(ll x){
    vector<int>res;
    for(int i=2;i*i<=x;i++){
      while(x%i==0){
        x/=i;
        res.push_back(i);
      }
    }
    if(x!=1) res.push_back(x);
    return res;
  }
 
  // 約数列挙 √N
  vector<ll> divisor(ll x){
    vector<ll> res;
    for(ll i=1; i*i<=x ;i++)
      if(x%i==0){
        res.push_back(i);
        if(i*i!=x) res.push_back(x/i);
      }
    sort(res.begin(), res.end());
    return res;
  }
 
  // a*b>LONG_MAX ? 
  bool overflow(ll a,ll b,ll LONGMAX){return a > LONGMAX/b;}
 
  ll extgcd(ll a,ll b,ll& x,ll& y){
    ll d = a ;
    if ( b != 0 ) {
      d = extgcd( b , a%b , y , x ) ;
      y -= ( a / b ) * x ;
    }else{
      x = 1 ; y = 0 ;
    }
    return d;
  }
  ll mod_inverse(ll a){
    ll x , y ;
    extgcd( a , m , x , y ) ;
    return ( m + x % m ) % m ;
  }
 
  // オイラー関数√N
  ll euler_mhi(ll n){
    ll res = n;
    for(ll i=2; i*i <= n ; i++){
      if( n%i == 0 ){
        res = res/i*(i-1);
        for(;n%i==0;n/=i);
      }
    }
    if(n!=1)res=res/n*(n-1);
    return res;
  }
 
  void make_euler_table(int n){
    euler.resize(n+1);
    for(int i=0;i<n;i++) euler[i]=i;
    for(int i=2;i<n;i++){
      if(euler[i]==i){
        for(int j=i;j<n;j+=i){
          euler[j]=euler[j]/i*(i-1);
        }
      }
    }
  }
 
  // n! と nCr 
  // mはmod
  ll mod_fact(ll n,ll& e){
    e=0;
    if(n==0)return 1;
 
    int res = mod_fact(n/m,e);
    e+=n/m;
 
    if(n/m%2 != 0)return res*(m-fact[n%m])%m;
    return res*fact[n%m]%m;
  }
 
  ll combination(ll n,ll k){
    if(n==k||k==0)return 1;
    if(n<0 || k<0 || n<k)return 0;
    ll e1,e2,e3;
    ll a1 = mod_fact(n,e1);
    ll a2 = mod_fact(k,e2);
    ll a3 = mod_fact(n-k,e3);
    return a1*mod_inverse(a2*a3%m)%m;
  }
 
  ll stupid_combination(ll n,ll k){
    if(n==k||k==0)return 1;
    if(n<0 || k<0 || n<k)return 0;
    ll res=1;
    for(ll i=0;i<k;i++){
      res*=(n-i)%m;
      res%=m;
      res*=mod_inverse(i+1);
      res%=m;
    }
    return res;
  }
 
  ll mod_mult(ll a, ll b,ll m) {
    ll res = 0;
    ll exm = a % m;
    while (b) {
      if (b & 1) {
        res += exm;
        if (res > m) res -= m;
      }
      exm <<= 1;
      if (exm > m) exm -= m;
      b >>= 1;
    }
    return res;
  }
 
  ll mod_exm(ll a, ll b,ll m) {
    ll res = 1;
    ll exm = a % m;
    while (b) {
      if (b & 1) res = mod_mult(res, exm,m);
      exm = mod_mult(exm, exm,m);
      b >>= 1;
    }
    return res;
  }
 
  map<ll,ll> moebius(ll n){
    map<ll,ll>res;
    vector<ll>prime;
    for( int i=2; i*i<=n ;i++){
      if(n%i==0){
        prime.push_back(i);
        while(n%i==0)n/=i;
      }
    }
    if(n!=1)prime.push_back(n);
    int m=prime.size();
    for(int i=0;i<(1<<m);i++){
      int mu=1,d=1;
      for(int j=0;j<m;j++){
        mu*=-1;
        d*=prime[j];
      }
      res[d]=mu;
    }
    return res;
  }
 
  // 確率的高速素数判定　
  bool miller_rabin(ll n, ll times=10) {
    if (n < 2) return false;
    if (n == 2) return true;
    if (!(n & 1)) return false;
    ll q = n-1;
    int k = 0;
    while (q % 2 == 0) {
      k++;
      q >>= 1;
    }
    for (int i = 0; i < times; i++) {
      ll a = rand() % (n-1) + 1;
      ll x = mod_exm(a, q, n);
      if (x == 1) continue;
      bool found = false;
      for (int j = 0; j < k; j++) {
        if (x == n-1) {
          found = true;
          break;
        }
        x = mod_mult(x, x, n);
      }
      if (found) continue;
      return false;
    }
    return true;
  }
 
  ll pollard_rho(ll n, int c) {
    ll x = 2;
    ll y = 2;
    ll d = 1;
    while (d == 1) {
      x = mod_mult(x, x, n) + c;
      y = mod_mult(y, y, n) + c;
      y = mod_mult(y, y, n) + c;
      d = __gcd((x-y >= 0 ? x-y : y-x), n);
    }
    if (d == n) return pollard_rho(n, c+1);
    return d;
  }
  ll GCD(ll a,ll b){
    if((a%b)==0)return b;
    return GCD(b,a%b);
  }
  ll LCM(ll a,ll b){
    return a*b/GCD(a,b);
  }
  ll montmort(ll k){  // 完全順列 撹乱順列 indexが全部違う順列
    if( k == 0 ) return 1;
    if( k == 1 ) return 0;
    if( k == 2 ) return 1;
    ll i = 2;
    ll a = 0 , b = 1;
    while( i < k ){
      ll t = ( i * ( ( a + b ) % m ) ) % m;
      a = b; b = t; i++;
    }
    return b;
  }
  vector<ll> monmort_dp(ll k){
    vector<ll> dp(200009);
    dp[0] = 1;
    dp[1] = 0;
    dp[2] = 1;
    for(int i=3;i<200009;i++){
      dp[i] = ( i * ( ( dp[i-1] + dp[i-2] ) % m ) ) %m;
    }
    return dp;
  }
  ll nHr(ll n,ll k){ // 重複組合せ
    return stupid_combination(n+k-1,k);
  }
};
 
signed main(){
  NT N(1000000009);
  long long n;
  cin>>n;
  vector<long long>v=N.mrime_decommosition(n);
  set<long long>s;
  r(i,v.size()){
    s.insert(v[i]);
  }
  vector<long long>V=N.divisor(n);
  cout<<s.size()<<' '<<V.size()-1<<endl;
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

template <typename T>
vector<T> divisor(T n)
{
    vector<T> divisor;
    for (T i = 1; i * i <= n; i++)
    {
        if (n % i == 0)
        {
            divisor.push_back(i);
            if (i * i != n)
                divisor.push_back(n / i);
        }
    }
    return divisor;
}

template <typename T>
map<T, int> prime_factor(T n)
{
    map<T, int> res;
    for (T i = 2; i * i <= n; i++)
    {
        while (n % i == 0)
        {
            res[i]++;
            n /= i;
        }
    }
    if (n != 1)
        res[n]++; //nは素数
    return res;
}

int main()
{
    long long n;
    cin >> n;
    vector<long long> d = divisor(n);
    map<long long, int> mp = prime_factor(n);
    cout << mp.size() << " " << d.size() - 1 << endl;
}

C++: #include <bits/stdc++.h>
  
using namespace std;
  
#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second
  
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 
const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

using Facts = map<ll, int>; 
void factrize(ll n, Facts& mp) {
  if(n < 2) return;
  ll m = sqrt(n);
  REP(i, 2, m+1) {
    int cnt = 0;
    while(n%i == 0) {
      n /= i;
      ++cnt;
    }
    if(cnt > 0) mp[i] += cnt;
  }
  if(n != 1) mp[n]++;
}


int main(){
    ll n;
    cin >> n;
    Facts f;
    factrize(n, f);
    ll x = 1;
    for(auto&& i : f) x *= (i.se+1);
    cout << max(1, (int)f.size()) << " " << x -1 << endl;
    return 0;
}