#include <bits/stdc++.h>
using namespace std;

//////////////////////////////   Begin Macros

#define all(x) (x).begin(), (x).end()
#define rep(i, N) for (int i = 0; i < (int)(N); i++)
#define reps(i, s, N) for (int i = (s); i < (int)(N); i++)
#define reprev(i, N) for (int i = N - 1; i >= 0; i--)
#define rep1(i, N) for (int i = 1; i <= N; i++)
#define rep1s(i, s, N) for (int i = 1; i <= N; i++)

using ll = long long int;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

template <typename T>
bool chmax(T &m, const T q)
{
  if (m < q)
  {
    m = q;
    return true;
  }
  else
    return false;
}
template <typename T>
bool chmin(T &m, const T q)
{
  if (m > q)
  {
    m = q;
    return true;
  }
  else
    return false;
}
template <typename T1, typename T2>
pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) { return {l.first + r.first, l.second + r.second}; }
template <typename T1, typename T2>
pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) { return {l.first - r.first, l.second - r.second}; }
template <typename T>
pair<T, T> operator*(const pair<T, T> &l, const T &r) { return {l.first * r, l.second * r}; }
template <typename T>
pair<T, T> operator/(const pair<T, T> &l, const T &r) { return {l.first / r, l.second / r}; }
template <typename T>
istream &operator>>(istream &is, vector<T> &vec)
{
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &vec)
{
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const deque<T> &vec)
{
  os << "deq[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const set<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_set<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const multiset<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_multiset<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &pa)
{
  os << "(" << pa.first << "," << pa.second << ")";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const map<TK, TV> &mp)
{
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp)
{
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}

template <typename T>
void reset(vector<T> &v, const T reset_to)
{
  for (auto &x : v)
    x = reset_to;
}
inline int popcount(const unsigned int x) { return __builtin_popcount(x); }
#define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

const int intinf = numeric_limits<int>::max();
const pii udlr[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

//////////////////////////////   End Macros

#pragma once

#include <algorithm>
#include <vector>
#include <unordered_map>

std::vector<bool> is_primes;
std::vector<unsigned int> primes;

using namespace std;

void set_is_primes(unsigned int n)
{
  //sieve_of_eratosthenes
  //is_primes : [0, n] �̔z��ŁCprimes[i] = true iff i �͑f��
  //O(n log n)
  is_primes.assign(n + 1, true);
  for (unsigned int i = 0; i <= min((unsigned int)1, n); ++i)
    is_primes[i] = false;
  for (unsigned int i = 2; i * i <= n; ++i)
    if (is_primes[i])
      for (unsigned int j = i * i; j <= n; j += i)
        is_primes[j] = false;
  return;
}

void set_primes(unsigned int n)
{
  //sieve_of_eratosthenes
  //primes : n�ȉ��̑f���̃��X�g
  //O(n log n)
  primes.assign(n + 1, 0);
  for (unsigned int i = 2; i <= min((unsigned int)1, n); ++i)
    primes[i] = i;
  for (unsigned int i = 2; i * i <= n; ++i)
    if (primes[i])
      for (unsigned int j = i * i; j <= n; j += i)
        primes[j] = 0;
  primes.erase(remove(primes.begin(), primes.end(), 0), primes.end());
  return;
}

vector<bool> make_is_prime_segments(unsigned long long L, unsigned long long H)
{
  //��Ԃӂ邢
  //is_primes : [L, H] �̔z��ŁCprimes[i] = true iff i �͑f��
  //O((H-L) sqrt( H ) / log(H))
  vector<bool> is_prime_segments(H - L + 1, true);
  for (int i = 0; (unsigned long long)primes[i] * primes[i] <= H; ++i)
  { // O( \sqrt(H) )
    unsigned long long j;
    if (primes[i] >= L)
      j = primes[i] * primes[i];
    else if (L % primes[i] == 0)
      j = L;
    else
      j = L - (L % primes[i]) + primes[i];
    for (; j <= H; j += primes[i])
      is_prime_segments[j - L] = false;
  }
  return is_prime_segments;
}

bool is_prime(const int n, const bool is_using_is_primes)
{
  if (n <= 1)
    return false;
  for (int i = 2; i * i <= n; i++)
  {
    if (is_using_is_primes && !is_primes[i])
      continue;
    if (n % i == 0)
      return false;
  }
  return true;
}

vector<long long> make_divisors(const long long n)
{
  vector<long long> ans;
  for (long long i = 1; i * i <= n; i++)
    if (n % i == 0)
      ans.emplace_back(i);
  vector<long long> latter;
  const auto rit_b = ans.crbegin();
  const bool is_square = (*rit_b * *rit_b == n);
  for (auto rit = rit_b + (is_square ? 1 : 0), rit_e = ans.crend(); rit != rit_e; rit++)
    latter.emplace_back(n / *rit);
  ans.insert(ans.end(), latter.begin(), latter.end());
  return ans;
}

vector<unsigned long long> make_divisors(const unsigned long long n)
{
  vector<unsigned long long> ans;
  for (unsigned long long i = 1; i * i <= n; i++)
    if (n % i == 0)
      ans.emplace_back(i);
  vector<unsigned long long> latter;
  const auto rit_b = ans.crbegin();
  const bool is_square = (*rit_b * *rit_b == n);
  for (auto rit = rit_b + (is_square ? 1 : 0), rit_e = ans.crend(); rit != rit_e; rit++)
    latter.emplace_back(n / *rit);
  ans.insert(ans.end(), latter.begin(), latter.end());
  return ans;
}

unordered_map<unsigned int, unsigned int> make_prime_factors(unsigned int n, const bool is_using_primes)
{
  //O(sqrt(n))
  unordered_map<unsigned int, unsigned int> prime_factors;
  for (unsigned int i = 2; i * i <= n; i++)
  {
    if (is_using_primes && !is_primes[i])
      continue;
    while (n % i == 0)
    {
      ++prime_factors[i];
      n /= i;
    }
  }
  if (n != 1)
    ++prime_factors[n];
  return prime_factors;
}

unordered_map<unsigned long long, unsigned int> make_prime_factors(unsigned long long n, const bool is_using_primes)
{
  //O(sqrt(n))
  unordered_map<unsigned long long, unsigned int> prime_factors;
  for (unsigned long long i = 2; i * i <= n; i++)
  {
    if (is_using_primes && !is_primes[i])
      continue;
    while (n % i == 0)
    {
      ++prime_factors[i];
      n /= i;
    }
  }
  if (n != 1)
    ++prime_factors[n];
  return prime_factors;
}

int calculate_result(ll n, ll k)
{
  while (n % k == 0)
    n /= k;

  return n % k;
}

void solve()
{
  ll N;
  cin >> N;

  ll ans = 0;

  auto divisors = make_divisors(N);
  for (auto d : divisors)
  {
    if (d == 1)
      continue;
    if (calculate_result(N, d) == 1)
      ans++;
  }

  auto divisors2 = make_divisors(N - 1);
  for (auto d : divisors2)
  {
    if (d == 1)
      continue;
    if (calculate_result(N, d) == 1)
      ans++;
  }
  cout << ans << endl;
}

int main()
{
  solve();
  return 0;
}


Measured memory_bytes: 384