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()
}

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;
}