Problem:
Score : 600 points

Problem Statement

Given is a positive integer N.

We will choose an integer K between 2 and N (inclusive), then we will repeat the operation below until N becomes less than K.

Operation: if K divides N, replace N with N/K; otherwise, replace N with N-K.

In how many choices of K will N become 1 in the end?

Constraints

2 \leq N \leq 10^{12}

N is an integer.

Input

Input is given from Standard Input in the following format:

N

Output

Print the number of choices of K in which N becomes 1 in the end.

Sample Input 1

6

Sample Output 1

3

There are three choices of K in which N becomes 1 in the end: 2, 5, and 6.

In each of these choices, N will change as follows:

When K=2: 6 \to 3 \to 1

When K=5: 6 \to 1

When K=6: 6 \to 1

Sample Input 2

3141

Sample Output 2

13

Sample Input 3

314159265358

Sample Output 3

9

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
 
using namespace __gnu_pbds;
using namespace std;
 
#define int 		long long
#define vi 			vector<int>
#define vec(x) 		vector<x>
#define matrix 		vector<vector<int>>
#define pii 		pair<int,int>
#define rep(i,s,e)  for(int i=s;i<e;i++)
#define rrep(i,e,s) for(int i=e;i>=s;i--)
#define MOD			1000000007
#define pb 			push_back
#define ff 			first
#define ss 			second		
#define w(x)		int x; cin>>x; while(x--)
const int INF=1e18;

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
	cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
	const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
 
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
// find_by_order(k-1)  returns iterator to kth element starting from 0; Returns the kth smallest element
// order_of_key(k) returns count of elements strictly smaller than k;Returns the number of elements less than k
// erase,insert same as normal set

vector<int> get_divisors(int num){
	vector<int> div;
	for(int i=2;i*i<=num;i++){
		if(num%i==0){
			if(i*i==num)
				div.pb(i);
			else{
				div.pb(i),div.pb(num/i);
			}
		}
	}
	return div;
}


void solve(){
	int n;
	cin>>n;
	// trace(n);
	if(n==2){
		cout<<1<<'\n';return;
	}

	vector<int> div=get_divisors(n-1);
	set<int> s;
	for(auto c:div){
		s.insert(c);
	}
	int ans=2+div.size();
	//trace(ans);

	div=get_divisors(n);

	//trace(ans);

	for(auto c:div){
		int num=n;
		//trace(num,c);
		if(s.find(c)!=s.end())continue;
		while(num%c==0 && num>=c){
			num=num/c;
		}
		if(num%c==1) ans++;
	}

	cout<<ans<<endl;
	
}
 
int32_t main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
// #ifndef ONLINE_JUDGE
// 	freopen("input.txt","r",stdin);
// 	freopen("output.txt","w",stdout);
// #endif
	int t=1;
	//cin>>t;
	while(t--){
		solve();
	}
}