CodeEff/ECCO huggingface dataset:
# Original solution
# Acceptance of input
import sys

file_input = sys.stdin

V, E = list(map(int, file_input.readline().split()))

adj = [[] for i in range(V)]

for i in range(E):
    s, t = list(map(int, file_input.readline().split()))
    adj[s].append(t)


# dfs path detect
import collections

def isConnected(u, v):
    path = collections.deque()
    path.append(u)

    notVisited = [True] * V
    notVisited[u] = False

    while path:
        e = path[-1]
        for n in adj[e]:
            if n == v:
                return True
            elif notVisited[n]:
                path.append(n)
                notVisited[n] = False
        if e == path[-1]:
            path.pop()

    return False

def isStronglyConnected(u, v):
    if isConnected(u, v) and isConnected(v, u):
        print((1))
    else:
        print((0))


# Output
Q = file_input.readline()

for line in file_input:
    u, v = list(map(int, line.split()))
    isStronglyConnected(u, v)

# Optimized solution
# Acceptance of input
import sys

file_input = sys.stdin

V, E = list(map(int, file_input.readline().split()))

adj = [[] for i in range(V)]

for i in range(E):
    s, t = list(map(int, file_input.readline().split()))
    adj[s].append(t)


# Tarjan's strongly connected components algorithm
import collections

sys.setrecursionlimit(100000)

S = collections.deque()
indices = [None] * V
lowlink = [None] * V
onStack = [False] * V
index = 0
scc_id = [None] * V

def strong_connect(v):
    global index
    indices[v] = index
    lowlink[v] = index
    index += 1
    S.append(v)
    onStack[v] = True

    for w in adj[v]:
        if indices[w] == None:
            strong_connect(w)
            lowlink[v] = min(lowlink[v], lowlink[w])
        elif onStack[w]:
            lowlink[v] = min(lowlink[v], indices[w])

    if lowlink[v] == indices[v]:
        while S:
            w = S.pop()
            onStack[w] = False
            scc_id[w] = v
            if w == v:
                break

for v in range(V):
    if not indices[v]:
        strong_connect(v)


# Output
Q = file_input.readline()

for line in file_input:
    u, v = list(map(int, line.split()))
    if scc_id[u] == scc_id[v]:
        print((1))
    else:
        print((0))
# Original solution
def solve():
    N, M = list(map(int, input().split()))
    edges = [[] for _ in [0]*N]
    r_edges = [[] for _ in [0]*N]

    for _ in [0]*M:
        a, b = list(map(int, input().split()))
        edges[a].append(b)
        r_edges[b].append(a)
        
    c = get_strongly_connected_components(edges, r_edges)
    group = [0]*N
    for i in range(len(c)):
        for v in c[i]:
            group[v] = i

    result = []
    append = result.append
    for _ in [0]*int(eval(input())):
        a, b = list(map(int, input().split()))
        append("1" if group[a] == group[b] else "0")

    print(("\n".join(result)))


def get_strongly_connected_components(edges, r_edges):
    import sys
    sys.setrecursionlimit(10**7)
    v_count = len(edges)
    order = [0]*v_count
    k = 1

    def get_order(v):
        order[v] = 1
        nonlocal k
        for dest in edges[v]:
            if order[dest] == 0:
                get_order(dest)
        order[v] = k
        k += 1

    def get_components(v):
        order[v] = 0
        return [v] + [_v for dest in r_edges[v] if order[dest] > 0 for _v in get_components(dest)]

    [None for v in range(v_count) if order[v] == 0 and get_order(v)]
    return [get_components(v) for v, _ in sorted(enumerate(order), key=lambda x: x[1], reverse=True) if order[v] > 0]

if __name__ == "__main__":
    solve()

# Optimized solution
def solve():
    N, M = list(map(int, input().split()))
    edges = [[] for _ in [0]*N]
    r_edges = [[] for _ in [0]*N]

    for _ in [0]*M:
        a, b = list(map(int, input().split()))
        edges[a].append(b)
        r_edges[b].append(a)

    c = get_strongly_connected_components(edges, r_edges)
    group = [0]*N
    for i in range(len(c)):
        for v in c[i]:
            group[v] = i

    result = []
    append = result.append
    for _ in [0]*int(eval(input())):
        a, b = list(map(int, input().split()))
        append("1" if group[a] == group[b] else "0")

    print(("\n".join(result)))


def get_strongly_connected_components(edges, r_edges):
    import sys
    sys.setrecursionlimit(10**7)
    v_count = len(edges)
    order = [0]*v_count
    k = [1]

    def get_order(v):
        order[v] = 1
        for dest in edges[v]:
            if order[dest] == 0:
                get_order(dest)
        order[v] = k[0]
        k[0] += 1

    def get_components(v):
        order[v] = 0
        return [v] + [_v for dest in r_edges[v] if order[dest] > 0 for _v in get_components(dest)]

    [None for v in range(v_count) if order[v] == 0 and get_order(v)]
    return [get_components(v) for v, _ in sorted(enumerate(order), key=lambda x: x[1], reverse=True) if order[v] > 0]

if __name__ == "__main__":
    solve()
# Original solution
def solve():
    N, M = list(map(int, input().split()))
    edges = [[] for _ in [0]*N]
    r_edges = [[] for _ in [0]*N]

    for _ in [0]*M:
        a, b = list(map(int, input().split()))
        edges[a].append(b)
        r_edges[b].append(a)

    c = kosaraju(edges, r_edges)
    group = [0]*N
    for i in range(len(c)):
        for v in c[i]:
            group[v] = i

    result = []
    append = result.append
    for _ in [0]*int(eval(input())):
        a, b = list(map(int, input().split()))
        append("1" if group[a] == group[b] else "0")

    print(("\n".join(result)))


def kosaraju(edges, reverse_edges):
    import sys
    sys.setrecursionlimit(10**7)
    v_count = len(edges)
    order = [0]*v_count
    k = [1]

    def get_order(v):
        order[v] = 1
        for dest in (_v for _v in edges[v] if order[_v] == 0):
            get_order(dest)
        order[v] = k[0]
        k[0] += 1

    def get_components(v):
        order[v] = 0
        return [v] + [_v for dest in reverse_edges[v] if order[dest] > 0 for _v in get_components(dest)]

    for v in (_v for _v in range(v_count) if order[_v] == 0):
        get_order(v)
    return [get_components(v) for v, _ in sorted(enumerate(order), key=lambda x: x[1], reverse=True) if order[v] > 0]

if __name__ == "__main__":
    solve()

# Optimized solution
def solve():
    N, M = list(map(int, input().split()))
    edges = [[] for _ in [0]*N]
    r_edges = [[] for _ in [0]*N]

    for _ in [0]*M:
        a, b = list(map(int, input().split()))
        edges[a].append(b)
        r_edges[b].append(a)

    c = kosaraju(edges, r_edges)
    group = [0]*N
    for i in range(len(c)):
        for v in c[i]:
            group[v] = i

    result = []
    append = result.append
    for _ in [0]*int(eval(input())):
        a, b = list(map(int, input().split()))
        append("1" if group[a] == group[b] else "0")

    print(("\n".join(result)))


def kosaraju(edges, reverse_edges):
    import sys
    sys.setrecursionlimit(10**7)
    v_count = len(edges)
    order = [0]*v_count
    k = [1]

    def get_order(v):
        order[v] = 1
        [None for dest in edges[v] if order[dest] == 0 and get_order(dest)]
        order[v] = k[0]
        k[0] += 1

    def get_components(v):
        order[v] = 0
        return [v] + [_v for dest in reverse_edges[v] if order[dest] > 0 for _v in get_components(dest)]

    [None for v in range(v_count) if order[v] == 0 and get_order(v)]
    return [get_components(v) for v, _ in sorted(enumerate(order), key=lambda x: x[1], reverse=True) if order[v] > 0]

if __name__ == "__main__":
    solve()
# Original solution
"""
強連結成分分解
"""

import sys

sys.setrecursionlimit(1000000)

def dfs(v, visited, edges, order):
  visited[v] = True
  for to in edges[v]:
    if not visited[to]:
      dfs(to, visited, edges, order)
  order.append(v)

def search_strongly_connection(v, visited, reverse_edges, parent):
  visited[v] = True
  for to in reverse_edges[v]:
    if not visited[to]:
      parent[to] = v
      search_strongly_connection(to, visited, reverse_edges, parent)

def find(parent, x):
  if parent[x] == x:
    return x
  tmp = find(parent, parent[x])
  parent[x] = tmp
  return tmp

v_num , e_num = list(map(int, input().split()))
edges = [[] for _ in range(v_num)]
reverse_edges = [[] for _ in range(v_num)]
for _ in range(e_num):
  s, t = list(map(int, input().split()))
  edges[s].append(t)
  reverse_edges[t].append(s)


order = []
visited = [False] * v_num
for v in range(v_num):
  if not visited[v]:
    dfs(v, visited, edges, order)
order.reverse()


visited = [False] * v_num
parent = [i for i in range(v_num)]
for v in order:
  if not visited[v]:
    search_strongly_connection(v, visited, reverse_edges, parent)

q_num = int(eval(input()))
for _ in range(q_num):
  u, v = list(map(int, input().split()))
  if find(parent, u) == find(parent, v):
    print((1))
  else:
    print((0))


# Optimized solution
"""
強連結成分分解
"""

import sys

sys.setrecursionlimit(1000000)

def dfs(v, visited, edges, order):
  visited[v] = True
  for to in edges[v]:
    if not visited[to]:
      dfs(to, visited, edges, order)
  order.append(v)

def search_strongly_connection(v, visited, reverse_edges, parent, num):
  visited[v] = True
  for to in reverse_edges[v]:
    if not visited[to]:
      parent[to] = num
      search_strongly_connection(to, visited, reverse_edges, parent, num)

v_num , e_num = list(map(int, input().split()))
edges = [[] for _ in range(v_num)]
reverse_edges = [[] for _ in range(v_num)]
for _ in range(e_num):
  s, t = list(map(int, input().split()))
  edges[s].append(t)
  reverse_edges[t].append(s)


order = []
visited = [False] * v_num
for v in range(v_num):
  if not visited[v]:
    dfs(v, visited, edges, order)
order.reverse()


visited = [False] * v_num
parent = [i for i in range(v_num)]
for v in order:
  num = v
  if not visited[v]:
    search_strongly_connection(v, visited, reverse_edges, parent, num)

q_num = int(eval(input()))
for _ in range(q_num):
  u, v = list(map(int, input().split()))
  if parent[u] == parent[v]:
    print((1))
  else:
    print((0))
# Original solution
import sys
sys.setrecursionlimit(10001)

def dfs(u, g, stack):
    visited[u] = True
    for v in g[u]:
        if not visited[v]:
            dfs(v, g, stack)
    stack.append(u)
    return stack

nv, ne = list(map(int, input().split(' ')))
adj, tps = ([[] for _ in range(nv)] for _ in range(2))

for _ in range(ne):
    s, t = list(map(int, input().split(' ')))
    adj[s].append(t)
    tps[t].append(s)

visited = [False] * nv
stack = []
for i in range(nv):
    if not visited[i]:
        stack = dfs(i, adj, stack)

visited = [False] * nv
comps = []
while stack:
    i = stack.pop()
    if not visited[i]:
        comp = dfs(i, tps, [])
        comps.append(comp)

nv = int(eval(input()))
for _ in range(nv):
    u, v = list(map(int, input().split(' ')))
    ans = 0

    for comp in comps:
        if u in comp and v in comp:
            ans = 1

    print(ans)

# Optimized solution
import sys
sys.setrecursionlimit(10001)

def dfs(u, g, stack):
    visited[u] = True
    for v in g[u]:
        if not visited[v]:
            dfs(v, g, stack)
    stack.append(u)
    return stack

nv, ne = list(map(int, input().split(' ')))
adj, tps = ([[] for _ in range(nv)] for _ in range(2))

for _ in range(ne):
    s, t = list(map(int, input().split(' ')))
    adj[s].append(t)
    tps[t].append(s)

visited = [False] * nv
stack = []
for i in range(nv):
    if not visited[i]:
        stack = dfs(i, adj, stack)

visited = [False] * nv
comp_is = {}
while stack:
    i = stack.pop()
    if not visited[i]:
        comp = dfs(i, tps, [])
        for v in comp:
            comp_is[v] = i

nv = int(eval(input()))
for _ in range(nv):
    u, v = list(map(int, input().split(' ')))
    if comp_is[u] == comp_is[v]: print((1))
    else: print((0))
# Original solution
N = int(eval(input()))
from math import sqrt
#N mod K = 0 or 1 となるk をさがす
#K = Nの約数　or N-1 の約数
def divisor(num):
    max_num = int(sqrt(num))
    divisor_list = []
    for i in range(1, max_num + 1):
        if num % i == 0:
            if i != 1:
                divisor_list.append(i)
            divisor_list.append(num//i)
    sorted_divisor_list = sorted(divisor_list)
    return sorted_divisor_list

K_1 = divisor(N-1)
K_2 = divisor(N)
Ks = set(K_1 + K_2)
count = 0
for k in Ks:
    temp = N
    while temp % k == 0:
        temp //= k
    if temp == 1 or temp % k == 1:
        count += 1

ans = count
print(ans)

# Optimized solution
N = int(eval(input()))
from math import sqrt
#N mod K = 0 or 1 となるk をさがす
#K = Nの約数　or N-1 の約数
def divisor(num):
    max_num = int(sqrt(num))
    divisor_list = []
    for i in range(1, max_num + 1):
        if num % i == 0:
            if i != 1:
                divisor_list.append(i)
            if num // i != 1:
                divisor_list.append(num//i)
    #sorted_divisor_list = sorted(divisor_list)
    return divisor_list

K_1 = divisor(N-1)
K_2 = divisor(N)
K_3 = []
count = 0
for k in K_2:
    temp = N
    while temp % k == 0:
        temp //= k
    if temp == 1 or temp % k == 1:
        count += 1
        K_3.append(k)
kk = K_1 + K_3
ans = len(set(kk))
print(ans)
# Original solution
N = int(eval(input()))
from math import sqrt
#N mod K = 0 or 1 となるk をさがす
#K = Nの約数　or N-1 の約数
def divisor(num):
    max_num = int(sqrt(num))
    divisor_list = []
    for i in range(1, max_num + 1):
        if num % i == 0:
            if i != 1:
                divisor_list.append(i)
            if num // i != 1:
                divisor_list.append(num//i)
    #sorted_divisor_list = sorted(divisor_list)
    return divisor_list

K_1 = divisor(N-1)
K_2 = divisor(N)
K_3 = []
count = 0
for k in K_2:
    temp = N
    while temp % k == 0:
        temp //= k
    if temp == 1 or temp % k == 1:
        count += 1
        K_3.append(k)
kk = K_1 + K_3
ans = len(set(kk))
print(ans)

# Optimized solution
N = int(eval(input()))
from math import sqrt

def divisor(num):
    max_num = int(sqrt(num))
    divisor_list = []
    for i in range(1, max_num + 1):
        if num % i == 0:
            divisor_list.append(i)
            divisor_list.append(num//i)
    return divisor_list

K0 = divisor(N)
K1 = divisor(N-1)
S = set(K1)
S.remove(1)
for k in K0:
    tmp = N
    if k == 1:
        continue
    while tmp % k == 0 and tmp >= k:
        tmp //= k
    if tmp % k == 1:
        S.add(k)
print((len(S)))
# Original solution

N = int(eval(input()))


def solve(num):
    ret = set()

    p = 1
    while p * p <= num:
        if num % p == 0:
            ret.add(p)
            ret.add(num // p)
        p += 1

    return ret


s1 = solve(N)
s2 = solve(N-1)



# 1は答えに入らないので抜いた
ans = len(s2) - 1
for n in s1:
    if n == 1:
        continue
    tmp = N
    while tmp % n == 0:
        tmp = tmp // n
    if tmp % n == 1:
        ans += 1


print(ans)

# Optimized solution



N = int(eval(input()))

"""
愚直にやると、Kを2～Nの範囲で全部調べて数え上げる。N <= 10**12 なので間に合わない。


たとえば N=100だと、
[2, 3, 4, 9, 10, 11, 33, 99, 100]
が条件を満たす数字になる。

割り算を行わないとき、明らかに N % K = 1 になる
これは、「NをKで割ったら、１あまる」であるから、「N-1をKでわったら割り切れる」ともいえる。
なので、割り算が起こらないものは、N-1の約数。

割り算が起こるやつは、割れるだけ割った後、余りを調べればよい。
"""



def solve(n):
    i = 1
    ret = set()
    while i * i <= n:
        if n % i == 0:
            ret.add(i)
            ret.add(n // i)
        i += 1

    return ret


div_N_sub_1 = solve(N-1)
div_N = solve(N)

ans = len(div_N_sub_1) - 1

for i in div_N:
    if i == 1:
        continue
    tmp = N
    while tmp % i == 0:
        tmp //= i
    if tmp % i == 1:
        ans += 1


print(ans)
# Original solution
n = int(eval(input()))


def check(n, k):
    while n % k == 0:
        n = n // k
    if n >= k:
        n = n - k * (n // k)
    return n


def count(n):
    total = 0
    cands = set([n, n-1])
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            cands.add(i)
            cands.add(n // i)
    for i in range(2, int(n ** 0.5) + 1):
        if (n-1) % i == 0:
            cands.add(i)
            cands.add((n - 1) // i)
    for k in cands:
        if check(n, k) == 1:
            total += 1
    return total


print((count(n)))

# Optimized solution
n = int(eval(input()))


def check(n, k):
    while n % k == 0:
        n = n // k
    if n >= k:
        n = n - k * (n // k)
    return n


def count(n):
    total = 0
    cands = set([n, n-1])
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            cands.add(i)
            cands.add(n // i)
    for i in range(2, int(n ** 0.5) + 1):
        if (n-1) % i == 0:
            cands.add(i)
            cands.add((n - 1) // i)
    for k in cands:
        if k == 1:
            continue
        if check(n, k) == 1:
            total += 1
    return total


print((count(n)))
# Original solution
N=int(eval(input()))
k=2
ans=1
factors=[]
i=1
while i*i<N-1:
  if (N-1)%i==0:
    ans+=1
  i+=1
while k*k<=N:
  n=0
  while pow(k,n)<=N:
    if (N-pow(k,n))%(pow(k,n+1))==0:
      ans+=1
      break
    n+=1
  k+=1
print(ans)

# Optimized solution
n=int(eval(input()))
ans=set()
ans.add(n)
i=2
x = 1
while x * x <= n-1 :
  if (n-1) % x == 0:          
    ans.add(x)
    ans.add((n-1)//x)
  x += 1
while i*i<=n:
  t=n
  while t%i==0:
    t/=i
  if t%i==1:
    ans.add(i)
  i+=1
print((len(ans)-1))
# Original solution
def make_div(n):
    divs = []
    
    for i in range(1, int(n**0.5)+1):
        if n%i==0:
            divs.append(i)
            
            if i!=n//i:
                divs.append(n//i)
    
    divs.sort()
    
    return divs

N = int(eval(input()))
d = make_div(N)
d = d[1:]
s = set()

for di in d:
    N2 = N
    
    while N2%di==0:
        N2 //= di
    
    if (N2-1)%di==0:
        s.add(di)

d = make_div(N-1)
d = d[1:]

for di in d:
    s.add(di)

print((len(s)))

# Optimized solution
def make_divs(n):
    divs = []
    
    for i in range(1, int(n**0.5)+1):
        if n%i==0:
            divs.append(i)
            
            if i!=n//i:
                divs.append(n//i)
    
    return divs

N = int(eval(input()))
divs = make_divs(N)
ans = 0

for d in divs:
    if d==1:
        continue
    
    N2 = N
    
    while N2%d==0:
        N2 //= d
    
    if (N2-1)%d==0:
        ans += 1

divs = make_divs(N-1)
ans += len(divs)-1

print(ans)
# Original solution
N = int(eval(input()))

divisor = set([N, N - 1])
x = N
for i in range(2, int(x ** 0.5) + 1):
    z = x
    while z % i == 0:
        z //= i
    if z % i == 1:
        divisor.add(i)
        
    if i == x // i:
        continue
        
    z = x
    while z % (x // i) == 0:
        z //= (x // i)
    if z % (x // i) == 1:
        divisor.add((x // i))
        
x = N - 1
for i in range(2, int(x ** 0.5) + 1):
    if x % i == 0:
        divisor.add(i)
        divisor.add(x // i)

print((len(divisor) if N > 2 else 1))


# Optimized solution

N = int(eval(input()))


def calc_divisor(x):
    divisor = []
    for i in range(1, int(x ** 0.5) + 1):
        if x % i == 0:
            if i != 1:
                divisor.append(i)
            if i != x // i:
                divisor.append(x // i)
    return divisor


cand = len(calc_divisor(N - 1))
divisor_n = calc_divisor(N)
for v in divisor_n:
    x = N
    while x % v == 0:
        x //= v

    if x % v == 1:
        cand += 1

print(cand)
# Original solution
N = int(eval(input()))

if N == 2:
    print((1))
    exit()

if N == 3:
    print((2))
    exit()

ans = []
for n in range(1, int(N ** 0.5) + 1):
    if (N - 1) % n == 0:
        ans.append(n)
        ans.append((N - 1) // n)

for k in range(2, int(N ** 0.5) + 1):
    x = N
    while x % k == 0:
        x //= k

    if 1 in (x % k - k, x % k):
        ans.append(k)

print((len(set(ans))))


# Optimized solution
N = int(eval(input()))

ans = []
for n in range(1, int(N ** 0.5) + 1):
    if (N - 1) % n == 0:
        ans.append(n)
        ans.append((N - 1) // n)

for k in range(2, int(N ** 0.5) + 1):
    if N % k != 0:
        continue

    x = N
    while x % k == 0:
        x //= k

    if x % k == 1:
        ans.append(k)

print((len(set(ans))))
# Original solution
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    # divisors.sort()
    return divisors

n = int(eval(input()))
i = 2
cnt = 1
check = 0

# for i in range(2, n + 1):
#     m = n
#     while m % i == 0:
#         m //= i
#     m %= i
#     if m == 1:
#         print(i)
#         cnt += 1
# print(cnt)
# print()
# print()

out = [n]
while i < n: #割ってひく
    m = n
    if i - m / i > 2:
        break
    while m % i == 0:
        check = 1
        m //= i

    if (m % i == 1 and check):
        out.append(i)
        cnt += 1
    i += 1

i = 2
while i * i <= n: #割ってひく
    m = n
    while m % i == 0:
        m //= i
    if m == 1:
        out.append(i)
    i += 1

out += make_divisors(n - 1)
print((len(set(out)) - 1))

# Optimized solution
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    # divisors.sort()
    return divisors

n = int(eval(input()))
out = make_divisors(n)
ans = []
for i in out:
    if i == 1:
        continue
    m = n
    while m % i == 0:
        m //= i
    if m == 1 or m % i == 1:
        ans.append(i)
ans += make_divisors(n - 1)
# print(set(out))
print((len(set(ans)) - 1))
# Original solution
def MI():return list(map(int,input().split()))
def LI():return list(MI())

# n,k,c=MI()
# s=input()

"""nを素因数分解"""
"""2以上の整数n => [[素因数, 指数], ...]の2次元リスト"""

def factorization(n):
    arr = []
    temp = n
    for i in range(2, int(-(-n**0.5//1))+1):
        if temp%i==0:
            cnt=0
            while temp%i==0:
                cnt+=1
                temp //= i
            arr.append([i, cnt])

    if temp!=1:
        arr.append([temp, 1])

    if arr==[]:
        arr.append([n, 1])

    return arr

def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    divisors.sort()
    return divisors[1:]

n=int(eval(input()))
l=[]

yakusuu=(make_divisors(n-1))

for k in range(2,min(10**6,n)+1):
    NN=int(n)
    while NN>=k:
        if NN%k==0:
            NN=NN//k
        else:
            NN=NN%k
    if NN==1:
        l+=k,

ll=(l+yakusuu+[n])

print((len(set(ll))))

# Optimized solution
def MI():return list(map(int,input().split()))
def LI():return list(MI())

def factorization(n):
  arr=[]
  temp=n
  for i in range(2,int(n**0.5)+1):
    if temp%i==0:
      cnt=0
      while temp%i==0:
        cnt+=1
        temp//=i
      arr.append([i,cnt])      
  if temp!=1:arr.append([temp,1])
  if arr==[]:arr.append([n,1])
  return arr

def make_divisors(n):
  divisors=[]
  for i in range(1,int(n**0.5)+1):
    if n%i==0:
      divisors.append(i)
      if i!=n//i:
        divisors.append(n//i)
  divisors.sort()
  return divisors[1:]

n=int(eval(input()))

l=[]
for k in make_divisors(n):
  NN=int(n)
  while NN>=k:
    if NN%k==0:
      NN=NN//k
    else:
      NN=NN%k
  if NN==1:l+=k,

ll=(l+make_divisors(n-1))

print((len(ll)))
# Original solution
N=int(eval(input()))
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)
    divisors.sort()
    return divisors
s=len(make_divisors(N-1))
for i in range(1,len(make_divisors(N))):
  q=N
  p=make_divisors(N)[i]
  while True:
    if q%p==0:
      q/=p
    else:
      break
  if (q-1)%p==0:
    s+=1
print((s-1))

# Optimized solution
N=int(eval(input()))
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)
    divisors.sort()
    return divisors
s=len(make_divisors(N-1))
p=make_divisors(N)
for i in range(1,len(p)):
  q=N
  while True:
    if q%p[i]==0:
      q/=p[i]
    else:
      break
  if (q-1)%p[i]==0:
    s+=1
print((s-1))