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>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


template<typename T> 
map<T, Int> factorize(T x){
  map<T, Int> res;
  for(Int i=2;i*i<=x;i++){
    while(x%i==0){
      x/=i;
      res[i]++;
    }
  }
  if(x!=1) res[x]++;
  return res;
}


template<typename T>
vector<T> compress(vector<T> v){
  sort(v.begin(),v.end());
  v.erase(unique(v.begin(),v.end()),v.end());
  return v;
}

template<typename T>
map<T, Int> dict(const vector<T> &v){
  map<T, Int> res;
  for(Int i=0;i<(Int)v.size();i++)
    res[v[i]]=i;
  return res;
}

//INSERT ABOVE HERE
signed main(){
  Int n;
  cin>>n;
  vector<Int> v;
  for(Int i=1;i*i<=n;i++){
    if(n%i) continue;
    v.emplace_back(i);
    if(i!=1) v.emplace_back(n/i);
  }
  v=compress(v);
  auto m=factorize(n);
  cout<<m.size()<<" "<<v.size()<<endl;
  return 0;
}

C++: #include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

#define int long long
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = 1'000'000'007;
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

// エラトステネスの篩
vector<char> eratos(int n) {
	vector<char> is_prime(n + 1, true);
	is_prime[0] = is_prime[1] = false;
	for (int i = 2; i*i <= n; i++)
		if (is_prime[i]) {
			int j = i + i;
			while (j <= n) {
				is_prime[j] = false;
				j += i;
			}
		}
	return is_prime;
}
// n以下の素数
vector<int> getPrimes(int n) {
	vector<char> is_prime = eratos(n);
	vector<int> primes;
	for (int i = 0; i < n + 1; i++)
		if (is_prime[i])
			primes.emplace_back(i);
	return primes;
}
// 素因数分解 昇順
// √x以下の素数に対して割り切れるか調べる
vector<int> primeFactorization(int x) {
	vector<int> primes = getPrimes(sqrt(x));
	vector<int> factors;
	for (auto &p : primes) {
		while (x%p == 0) {
			x /= p;
			factors.emplace_back(p);
		}
	}
	if (x != 1)factors.emplace_back(x);
	return factors;
}
vector<int> getDivisors(int x) {
	vector<int> ret;
	int i;
	for (i = 1; i*i < x; i++) {
		if (x%i)continue;
		ret.emplace_back(i);
		ret.emplace_back(x / i);
	}
	if (i*i == x)
		ret.emplace_back(i);
	return ret;
}


signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N; cin >> N;

	vector<int> factors = primeFactorization(N);
	vector<int> divisors = getDivisors(N);

	dump(factors);

	map<int, int> mp;
	for (auto f : factors)mp[f]++;

	int maxi = 0;
	int mini = 0;

	maxi = divisors.size() - 1;
	mini = mp.size();

	cout << mini << " " << maxi << endl;

	return 0;
}

C++: // template version 1.14
using namespace std;
#include <bits/stdc++.h>

// varibable settings
#define int long long
const int INF=1e18;
const int MOD=1e9+7;

// define basic macro {{{
#define _overload3(_1,_2,_3,name,...) name
#define _rep(i,n) repi(i,0,n)
#define repi(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define rep(...) _overload3(__VA_ARGS__,repi,_rep,)(__VA_ARGS__)
#define _rrep(i,n) rrepi(i,0,n)
#define rrepi(i,a,b) for(int i=(int)((b)-1);i>=(int)(a);--i)
#define rrep(...) _overload3(__VA_ARGS__,rrepi,_rrep,)(__VA_ARGS__)
#define each(i,a) for (auto&& i : a)
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define mt(a, b, c) make_tuple(a, b, c)
#define ceil(a,b) ((a)+(b)-1)/(b)
#define is_in(x, a, b) ((a)<=(x) && (x)<(b))
#define uni(x) sort(all(x));x.erase(unique(all(x)),x.end())
#define ub upper_bound
#define lb lower_bound
#define posl(A, x) (lower_bound(all(A), x)-A.begin())
#define posu(A, x) (upper_bound(all(A),x)-A.begin())
template<class T> inline void chmax(T &a, const T &b) { if((a) < (b)) (a) = (b); }
template<class T> inline void chmin(T &a, const T &b) { if((a) > (b)) (a) = (b); }

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef long double ld;
typedef pair<int,int> pii;
typedef tuple<int,int,int> iii;

template<typename T> using PQ = priority_queue<T, vector<T>, greater<T>>;
struct Fast { Fast(){ std::cin.tie(0); ios::sync_with_stdio(false); } } fast;

#if defined(PCM) || defined(LOCAL)
  #include "lib/dump.hpp"
#else
  #define dump(...) 42
  #define dump_1d(...) 42
  #define dump_2d(...) 42
#endif
//}}}

bool is_prime(int n) {/*{{{*/
  for (int i = 2; i * i <= n; i++) {
    if (n % i == 0) return false;
  }
  return n != 1;
}/*}}}*/

signed main() {
  int n;cin>>n;

  set<int> d;
  set<int> d2;
  for(int i=1; i*i<=n; i++){
    if (n%i==0){
      d.insert(i);
      if (is_prime(n/i)) d2.insert(i);

      d.insert(n/i);
      if (is_prime(n/(n/i))) d2.insert(n/i);
    }
  }
  d.erase(n);
  d2.erase(n);
  dump(d);
  dump(d2);

  int M = sz(d);
  int m = sz(d2);
  cout << m << " " << M << endl;
  return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
#define MAX 2000000
#define ll long long
int p[MAX];

void Eratosthenes(){
	for(int i = 0; i < MAX; i++){
		p[i] = 1;
	}
	p[0] = 0; p[1] = 0;
	for(int i = 2; (long)i < sqrt(MAX); i++){
		if(p[i]){
			for(int j = 0; i * (j + 2) < MAX; j++){
				p[i *(j + 2)] = 0;
			}
		}
	}
}
map<ll,ll> prime_factor(ll n){
	map<ll,ll> res;
	for(ll i=2;i*i<=n;i++){
		while(n%i==0){
			res[i]++;
			n/=i;
		}
	}
	if(n!=1)res[n]=1;
	return res;
}

int main(void){
	long long N;
	long long a = 0, b = 1;
	cin >> N;
	map<ll, ll> mp = prime_factor(N);
	for(auto x: mp){
		a++;
		b *= (x.second + 1);
	}
	// Eratosthenes();
	// int sq = sqrt(N);
	// for(int i = 0; i <= sq; ++i){
	// 	if(!p[i]) continue;
	// 	if(N % (long long)i == 0LL){
	// 		a++;
	// 		long long tmp = 1;
	// 		while(N % (long long)i == 0LL){
	// 			tmp++;
	// 			N /= i;
	// 		}
	// 		b *= tmp;
	// 	}
	// 	if(i > sq && a == 0) break;
	// }
	if(a == 0){
		cout << 1 << " " << 1 << endl;
	}else{
		cout << a << " " << b-1 << endl;
	}
	return 0;
}