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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace ABC161
{
    public class Solve
    {
        public static void Main(string[] args)
        {
            new ABC_F();
        }
    }
    public class ABC_A
    {
        public ABC_A()
        {
            var i = Ex.ReadIntArray();
            Ex.Cw($"{i[2]} {i[0]} {i[1]}");
        }
    }
    public class ABC_B
    {
        public ABC_B()
        {
            var l1 = Ex.ReadIntArray();
            var arr = Ex.ReadLongArray();
            // N 種類の商品
            var n = l1[0];
            // M個を選べる
            var m = l1[1];
            // 総投票数の1/4M未満である
            long d = arr.Sum();
            var c = arr.Count(v => d <= v * 4 * m);
            Ex.Cw(m <= c);
        }
    }
    public class ABC_C
    {
        public ABC_C()
        {
            var l1 = Ex.ReadLongArray();
            // Nの初期値
            var n = l1[0];
            // Kの差の絶対値で置き換える
            var k = l1[1];

            var a = n % k;
            Ex.Cw(Math.Min(a, Math.Abs(a - k)));
        }
    }
    public class ABC_D
    {
        /// <summary>
        /// 小さい方からK番目のルンルン数
        /// </summary>
        long k;
        long end = 0;
        char[] arr;
        long cou = 0;

        public ABC_D()
        {
            k = Ex.ReadLong;

            long idx = 0;

            while (cou < k)
            {
                idx++;
                end = idx;
                arr = new char[end];
                for (int i = 1; i <= 9; i++)
                {
                    dfs(0, i);
                }
            }
        }

        void dfs(long idx, int t)
        {
            if (cou >= k)
            {
                return;
            }

            arr[idx] = (char)('0' + t);
            if (end == (idx + 1))
            {
                cou++;
                if (cou == k)
                {
                    Console.WriteLine(arr);
                }
                return;
            }

            for (int i = -1; i <= 1; i++)
            {
                var next = t + i;
                if (next < 0 || 9 < next) continue;
                dfs(idx + 1, next);
            }
        }
    }
    public class ABC_E
    {
        // N日間のうち
        long n;
        // K日を選んで働く
        long k;
        // ある日働いたら、その直後の C 日間は働かない 
        long c;
        // S の i 文字目が x のとき、今日から i 日後には働かない
        bool[] s;

        long[] l;
        long[] r;

        public ABC_E()
        {
            Input();

            Check();

            // 必ず働く日をすべて
        }

        void Check()
        {
            List<int> list = s
                .Select((item, index) => new { item, index })
                .Where(v => v.item)
                .Select(v => v.index).ToList();

            l = getPositions().ToArray();
            Array.Reverse(s);
            r = getPositions().Select(v => n - 1 - v).ToArray();
            Array.Reverse(s);

            int[] lastL = Enumerable.Repeat(-1, (int)n + 1).ToArray();
            for (int i = 0; i < k; i++) lastL[l[i] + 1] = i;
            for (int i = 0; i < n; i++)
            {
                if (lastL[i + 1] == -1) lastL[i + 1] = lastL[i];
            }
            int[] lastR = Enumerable.Repeat(-1, (int)n + 1).ToArray();
            for (int i = 0; i < k; i++) lastR[r[i]] = i;
            for (int i = (int)n - 1; i >= 0; --i)
            {
                if (lastR[i] == -1) lastR[i] = lastR[i + 1];
            }

            foreach (var i in list)
            {
                int li = lastL[i];
                int ri = lastR[i + 1];
                int cnt = 0;
                if (li != -1) cnt += li + 1;
                if (ri != -1) cnt += ri + 1;
                if (li != -1 && ri != -1 && r[ri] - l[li] <= c)
                {
                    --cnt;
                }
                if (cnt < k)
                {
                    Ex.Cw(i + 1);
                }
            }
        }

        List<long> getPositions()
        {
            List<long> b = new List<long>();
            long i = 0;
            while (i < n)
            {
                if (s[i])
                {
                    b.Add(i);
                    i += c + 1;
                }
                else
                {
                    i++;
                }
            }
            return b;
        }

        void Input()
        {
            var l1 = Ex.ReadLongArray();
            n = l1[0];
            k = l1[1];
            c = l1[2];
            s = Ex.Read.ToCharArray().Select(c => c == 'o').ToArray();
        }
    }
    public class ABC_F
    {
        public ABC_F()
        {
            long n = Ex.ReadLong;

            // Nが1になるようなKの決め方は何通り
            long cnt = 0;

            // NがK未満になるまで
            // 操作：NがKで割り切れるとき、NをN/Kに置き換える。そうでないとき、NをN−Kに置き換える。
            // 1 == n % k;

            var arr0 = div(n);

            cnt += div(n - 1).Where(v => v >= 2).Count();

            // 2以上N以下の整数K
            foreach (var k in arr0)
            {
                if (k < 2) continue;

                // NがK未満になるまで
                long nn = n;
                while (k <= nn)
                {
                    //NがKで割り切れるとき、NをN/Kに置き換える。
                    if (0 == nn % k)
                    {
                        nn /= k;
                    }
                    //そうでないとき、NをN−Kに置き換える。
                    else
                    {
                        nn %= k;
                    }
                }
                if (1 == nn) cnt++;
            }

            Ex.Cw(cnt);
        }

        long[] div(long n)
        {
            var arr = new HashSet<long>();
            for (long i = 1; i * i <= n; i++)
            {
                if (n % i == 0)
                {
                    arr.Add(i);
                    arr.Add(n / i);
                }
            }
            return arr.ToArray();
        }
    }
    public static class Ex
    {
        public static void Cw(object s)
        {
            Console.WriteLine(s);
        }
        public static void Cw(bool b)
        {
            if (b) Ex.Cw("Yes");
            else Ex.Cw("No");
        }

        public static string Read { get { return Console.ReadLine().Trim(); } }
        public static int ReadInt { get { return int.Parse(Read); } }
        public static long ReadLong { get { return long.Parse(Read); } }
        public static double ReadDouble { get { return double.Parse(Read); } }
        public static string[] ReadArray() { return Read.Split(' '); }
        public static int[] ReadIntArray() { return Read.Split(' ').Select(s => int.Parse(s)).ToArray(); }
        public static long[] ReadLongArray() { return Read.Split(' ').Select(s => long.Parse(s)).ToArray(); }
        public static string[] ReadArray(long N) { var ret = new string[N]; for (long i = 0; i < N; ++i) ret[i] = Read; return ret; }
        public static int[] ReadIntArray(long N) { var ret = new int[N]; for (long i = 0; i < N; ++i) ret[i] = ReadInt; return ret; }
        public static long[] ReadLongArray(long N) { var ret = new long[N]; for (long i = 0; i < N; ++i) ret[i] = ReadLong; return ret; }
    }
}