Madoka wants to enter to "Novosibirsk State University", but in the entrance exam she came across a very difficult task:Given an integer $$$n$$$, it is required to calculate $$$\sum{\operatorname{lcm}(c, \gcd(a, b))}$$$, for all triples of positive integers $$$(a, b, c)$$$, where $$$a + b + c = n$$$.In this problem $$$\gcd(x, y)$$$ denotes the greatest common divisor of $$$x$$$ and $$$y$$$, and $$$\operatorname{lcm}(x, y)$$$ denotes the least common multiple of $$$x$$$ and $$$y$$$.Solve this problem for Madoka and help her to enter to the best university!

The first and the only line contains a single integer $$$n$$$ ($$$3 \le n \le 10^5$$$).

Print exactly one interger — $$$\sum{\operatorname{lcm}(c, \gcd(a, b))}$$$. Since the answer can be very large, then output it modulo $$$10^9 + 7$$$.

NoteIn the first example, there is only one suitable triple $$$(1, 1, 1)$$$. So the answer is $$$\operatorname{lcm}(1, \gcd(1, 1)) = \operatorname{lcm}(1, 1) = 1$$$.In the second example, $$$\operatorname{lcm}(1, \gcd(3, 1)) + \operatorname{lcm}(1, \gcd(2, 2)) + \operatorname{lcm}(1, \gcd(1, 3)) + \operatorname{lcm}(2, \gcd(2, 1)) + \operatorname{lcm}(2, \gcd(1, 2)) + \operatorname{lcm}(3, \gcd(1, 1)) = \operatorname{lcm}(1, 1) + \operatorname{lcm}(1, 2) + \operatorname{lcm}(1, 1) + \operatorname{lcm}(2, 1) + \operatorname{lcm}(2, 1) + \operatorname{lcm}(3, 1) = 1 + 2 + 1 + 2 + 2 + 3 = 11$$$

from math import gcd

n = int(input())
MOD = 10**9 + 7

A = [0, 0]
phi = list(range(n+1))

for i in range(2, n+1):
	if phi[i] == i:
		for j in range(i, n+1, i):
			phi[j] = phi[j]*(i-1)//i

P = [0, 0]
Q = [0, 0]

for i in range(2, n+1):
	P.append( (P[-1] + phi[i]) % MOD )
	Q.append( (Q[-1] + phi[i]*i) % MOD )

tot = 0
for g in range(1, n):
	c = n // g
	tot += n*g*P[c]//gcd(n, g) % MOD
	tot -= g*g*Q[c]//gcd(n, g) % MOD

print(tot % MOD)

from math import gcd
n=int(input())
MOD=10**9+7
A = [0, 0]
lst = list(range(n+1))
for i in range(2, n+1):
	if lst[i] == i:
		for j in range(i, n+1, i):
			lst[j] = lst[j]*(i-1)//i
P = [0, 0]
Q = [0, 0]
for i in range(2, n+1):
	P.append( (P[-1] + lst[i]) % MOD )
	Q.append( (Q[-1] + lst[i]*i) % MOD )
tot = 0
for g in range(1, n):
	c = n // g
	tot += n*g*P[c]//gcd(n, g) % MOD
	tot -= g*g*Q[c]//gcd(n, g) % MOD
print(tot % MOD)

from __future__ import division, print_function

import os,sys
from io import BytesIO, IOBase

if sys.version_info[0] < 3:
    from __builtin__ import xrange as range
    from future_builtins import ascii, filter, hex, map, oct, zip

from bisect import bisect_left as lower_bound, bisect_right as upper_bound
def so():  return int(input())
def st():  return input()
def mj():  return map(int,input().strip().split(" "))
def msj(): return list(map(str,input().strip().split(" ")))
def le():  return list(map(int,input().split()))
def rc():  return map(float,input().split())
def lebe():return list(map(int, input()))

def dmain():
    sys.setrecursionlimit(1000000)
    threading.stack_size(1024000)
    thread = threading.Thread(target=main)
    thread.start()
def joro(L):
    return(''.join(map(str, L)))
def joron(L):
    return('\n'.join(map(str, L)))

def decimalToBinary(n): return bin(n).replace("0b","")

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True
def npr(n, r):
    return factorial(n) // factorial(n - r) if n >= r else 0

def ncr(n, r):
    return factorial(n) // (factorial(r) * factorial(n - r)) if n >= r else 0

def lower_bound(li, num):
    answer = -1
    start = 0
    end = len(li) - 1

    while (start <= end):
        middle = (end + start) // 2
        if li[middle] >= num:
            answer = middle
            end = middle - 1
        else:
            start = middle + 1
    return answer  # min index where x is not less than num

def upper_bound(li, num):
    answer = -1
    start = 0
    end = len(li) - 1

    while (start <= end):
        middle = (end + start) // 2

        if li[middle] <= num:
            answer = middle
            start = middle + 1

        else:
            end = middle - 1
    return answer  # max index where x is not greater than num
def tir(a,b,c):
    if(0==c):
        return 1
    if(len(a)<=b):
        return 0

    if(c!=-1):
        return (tir(a,1+b,c+a[b]) or tir(a,b+1,c-a[b]) or tir(a,1+b,c))

    else:
        return (tir(a,1+b,a[b]) or tir(a,b+1,-a[b]) or tir(a,1+b,-1))

def abs(x):
    return x if x >= 0 else -x

def binary_search(li, val, lb, ub):
    # print(lb, ub, li)
    ans = -1
    while (lb <= ub):
        mid = (lb + ub) // 2
        # print('mid is',mid, li[mid])
        if li[mid] > val:
            ub = mid - 1
        elif val > li[mid]:
            lb = mid + 1
        else:
            ans = mid  # return index
            break
    return ans

def kadane(x):  # maximum sum contiguous subarray
    sum_so_far = 0
    current_sum = 0
    for i in x:
        current_sum += i
        if current_sum < 0:
            current_sum = 0
        else:
            sum_so_far = max(sum_so_far, current_sum)
    return sum_so_far

def pref(li):
    pref_sum = [0]
    for i in li:
        pref_sum.append(pref_sum[-1] + i)
    return pref_sum

def SieveOfEratosthenes(n):
    prime = [True for i in range(n + 1)]
    p = 2
    li = []
    while (p * p <= n):
        if (prime[p] == True):
            for i in range(p * p, n + 1, p):
                prime[i] = False
        p += 1

    for p in range(2, len(prime)):
        if prime[p]:
            li.append(p)
    return li

def primefactors(n):
    factors = []
    while (n % 2 == 0):
        factors.append(2)
        n //= 2
    for i in range(3, int(sqrt(n)) + 1, 2):  # only odd factors left
        while n % i == 0:
            factors.append(i)
            n //= i
    if n > 2:  # incase of prime
        factors.append(n)
    return factors

def read():
    sys.stdin  = open('input.txt', 'r')
    sys.stdout = open('output.txt', 'w')
def tr(n):
    return n*(n+1)//2
boi=int(1e9+7)
doi=int(1e9+7)
hoi=int(6e5+5)

poi=int(1e5+5)

y="YES"
n="NO"

def bulli(x):
    return bin(x).count('1')

import sys

f=[0]*(hoi)
r=[0]*(hoi)
d=[]
for i in range(poi):
    d.append([])
L=[0]*poi
M=[0]*poi

def ty(a,b):
    rr=1
    while(b):
        if(b%2):
            rr=(rr*a)%boi
        b=b//2
        a=a*a%boi
    return rr
def inv(a):
    re=1
    for i in range(1,1+a):
        re=(re*i)%boi
    re=ty(re,boi-2)
    return re
def ncr(m,k):
    if(m<0 or k<0 or k>m):
        return 0
    return f[m]*r[k]%boi*r[m-k]%boi
def gosa(a,b):
    if(0!=b):
        return gosa(b,a%b)
    return a

def iu():
    import sys
    import math as my
    import functools
    import bisect as bs
    input=sys.stdin.readline
    from collections import deque, defaultdict
    '''f[0]=1
    for i in range(1,hoi):
        f[i]=(f[i-1]*i)%boi
    r[hoi-1]=ty(f[hoi-1],boi-2)
    for i in range(hoi-2,-1,-1):
        r[i]=r[i+1]*(i+1)%boi'''
    z=0
    m=so()
    for i in range(poi-1,0,-1):
        for j in range(i,poi,i):
            d[j].append(i)
    for i in range(1,1+m):
        r=m-i
        s=len(d[r])
        for j in range(s):
            M[j]=r//(d[r][j])-1
            for k in range(j):
                if(not d[r][k]%d[r][j]):
                    M[j]=M[j]-M[k]
            z=z+M[j]*i*d[r][j]//gosa(d[r][j],i)%boi
    print(z%boi)

def main():
    for i in range(1):
        #print("Case #"+str(i+1)+": ",end="")
        iu()

# region fastio
# template taken from https://github.com/cheran-senthil/PyRival/blob/master/templates/template.py

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

def print(*args, **kwargs):
    """Prints the values to a stream, or to sys.stdout by default."""
    sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
    at_start = True
    for x in args:
        if not at_start:
            file.write(sep)
        file.write(str(x))
        at_start = False
    file.write(kwargs.pop("end", "\n"))
    if kwargs.pop("flush", False):
        file.flush()

if sys.version_info[0] < 3:
    sys.stdin, sys.stdout = FastIO(sys.stdin), FastIO(sys.stdout)
else:
    sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)

input = lambda: sys.stdin.readline().rstrip("\r\n")

# endregion

if __name__ == "__main__":
    #read()
    main()
    #dmain()

# Comment Read()

#from math import ceil, floor #, gcd, log, factorial, comb, perm,
#log10, log2, log, sin, asin, tan, atan,
#from heapq import heappop,heappush,heapify #heappop(hq), heapify(list)
#from collections import defaultdict as dd
#mydd=dd(list) for .append
#from collections import deque as dq #deque  e.g. myqueue=dq(list)
#append/appendleft/appendright/pop/popleft
#from bisect import bisect as bis #a=[1,3,4,6,7,8] #bis(a,5) --> 3
#import statistics as stat  # stat.median(a), mode, mean
from math import gcd
import sys
input = sys.stdin.readline
#print = sys.stdout.write
#sys.setrecursionlimit(100000) #default is 1000
############ ---- Input Functions ---- ############
def inp():
    return(int(input()))
def inlt():
    return(list(map(int,input().split())))   #.split(','), default is space
#list([0,*map(int,input().split(" "))]) # pad a zero to avoid zero indexing
def insr():
    s = input()
    return(list(s[:len(s) - 1]))
####################################################
##def phi(n): #Euler's totient function from Euler's product formula
##    result = n;
##    if (n%2 == 0):
##        while (n % 2 == 0):n//=2;
##        result //=2;
##    p=3
##    while(p*p <= n):
##        if (n % p == 0):
##            while (n % p == 0):n//=p;
##            result -= result//p;
##        p += 2;
##    if (n > 1):
##        result -= result//n;
##    return result;
#t=1
n = int(input())
phi = list(range(n+1))
for i in range(2, n+1):
    if phi[i] == i:
        for j in range(i, n+1, i):
            phi[j] -= phi[j]//i
##phis=[0]
##for i in range(1,n):
##    phis.append(phi(i))
ans=0;mod=10**9+7

for d in range(1,n//2+1):
    g=gcd(n,d)
    tmp=0
    for ncd in range(2,(n-1)//d+1):
        c=n-ncd*d
        tmp+=c*phi[ncd]
    ans+=tmp*d//g
    ans%=mod
print(ans)

#print(*ans,sep=' ')##print("{:.3f}".format(ans)+"%")
#:b binary :% eg print("{:6.2%}".format(ans))
#print(" ".join(str(i) for i in ans))
#print(" ".join(map(str,ans))) #seems faster
#print(a[0] if a else 0)
#prefixsum a=[a1...an] #psa=[0]*(n+1)
#for i in range(n): psa[i+1]=psa[i]+a[i]
#sum[:ax]=psa[x+1] e.g. sum 1st 5 items in psa[5]
#ASCII<->number ord('f')=102 chr(102)='f'
#def binary_search(li, val, lb, ub):
#    while ((ub-lb)>1):
#        mid = (lb + ub) // 2
#        if li[mid] >= val:
#            ub = mid
#        else:
#            lb = mid
#    return lb+1 #return index of elements <val in li
#def binary_search(li, val, lb, ub):
#    ans = -1
#    while (lb <= ub):
#        mid = (lb + ub) // 2
#        if li[mid] > val:
#            ub = mid - 1
#        elif val > li[mid]:
#            lb = mid + 1
#        else:
#            ans = mid  # return index
#            break
#    return ans
##########
#def pref(li):
#    pref_sum = [0]
#    for i in li:
#        pref_sum.append(pref_sum[-1] + i)
#    return pref_sum
##########
#def suff(li):
#    suff_sum = [0]
#    for i in range(len(li)-1,-1,-1):
#        suff_sum.insert(0,suff_sum[0] + li[i])
#    return suff_sum
#############
#def maxSubArraySumI(arr): #Kadane's algorithm with index
#    max_till_now=arr[0];max_ending=0;size=len(arr)
#    start=0;end=0;s=0
#    for i in range(0, size):
#        max_ending = max_ending + arr[i]
#        if max_till_now < max_ending:
#            max_till_now=max_ending
#            start=s;end=i
#        if max_ending<0:
#            max_ending=0
#            s=i+1
#    return max_till_now,start,end
############# avoid max for 2 elements - slower than direct if
#def maxSubArraySum(arr): #Kadane's algorithm
#    max_till_now=arr[0];max_ending=0;size=len(arr)
#    for i in range(0, size):
#        max_ending = max_ending + arr[i]
#        if max_till_now < max_ending:max_till_now=max_ending
#        if max_ending<0:max_ending=0
#    return max_till_now
#############
#def findbits(x):
#    tmp=[]
#    while x>0:tmp.append(x%2);x//=2
#    tmp.reverse()
#    return tmp
##############Dijkstra algorithm example
#dg=[999999]*(n+1);dg[n]=0;todo=[(0,n)];chkd=[0]*(n+1)
#while todo:#### find x with min dg in todo
#    _,x=hq.heappop(todo)
#    if chkd[x]:continue
#    for i in coming[x]:going[i]-=1
#    for i in coming[x]:
#        tmp=1+dg[x]+going[i]
#        if tmp<dg[i]:dg[i]=tmp;hq.heappush(todo,(dg[i],i))
#    chkd[x]=1
################
# adj swaps to match 2 binary strings: sum_{i=1}^n(abs(diff in i-th prefix sums))
###############
##s=[2, 3, 1, 4, 5, 3]
##sorted(range(len(s)), key=lambda k: s[k])
##gives sorted indices [2, 0, 1, 5, 3, 4]
##m= [[3, 4, 6], [2, 4, 8], [2, 3, 4], [1, 2, 3], [7, 6, 7], [1, 8, 2]]
##m.sort(reverse=True,key=lambda k:k[2]) #sorts m according to 3rd elements

#from math import ceil, floor #, gcd, log, factorial, comb, perm,
#log10, log2, log, sin, asin, tan, atan,
#from heapq import heappop,heappush,heapify #heappop(hq), heapify(list)
#from collections import defaultdict as dd
#mydd=dd(list) for .append
#from collections import deque as dq #deque  e.g. myqueue=dq(list)
#append/appendleft/appendright/pop/popleft
#from bisect import bisect as bis #a=[1,3,4,6,7,8] #bis(a,5) --> 3
#import statistics as stat  # stat.median(a), mode, mean
from math import gcd
import sys
input = sys.stdin.readline
#print = sys.stdout.write
#sys.setrecursionlimit(100000) #default is 1000
############ ---- Input Functions ---- ############
def inp():
    return(int(input()))
def inlt():
    return(list(map(int,input().split())))   #.split(','), default is space
#list([0,*map(int,input().split(" "))]) # pad a zero to avoid zero indexing
def insr():
    s = input()
    return(list(s[:len(s) - 1]))
####################################################
def phi(n): #Euler's totient function from Euler's product formula
    result = n;
    if (n%2 == 0):
        while (n % 2 == 0):n//=2;
        result //=2;
    p=3
    while(p*p <= n):
        if (n % p == 0):
            while (n % p == 0):n//=p;
            result -= result//p;
        p += 2;
    if (n > 1):
        result -= result//n;
    return result;
#t=1
n = int(input())
phis=[0]
for i in range(1,n):
    phis.append(phi(i))
ans=0;mod=10**9+7

for d in range(1,n//2+1):
    g=gcd(n,d)
    tmp=0
    for ncd in range(2,(n-1)//d+1):
        c=n-ncd*d
        tmp+=c*phis[ncd]
    ans+=tmp*d//g
    ans%=mod
print(ans)

#print(*ans,sep=' ')##print("{:.3f}".format(ans)+"%")
#:b binary :% eg print("{:6.2%}".format(ans))
#print(" ".join(str(i) for i in ans))
#print(" ".join(map(str,ans))) #seems faster
#print(a[0] if a else 0)
#prefixsum a=[a1...an] #psa=[0]*(n+1)
#for i in range(n): psa[i+1]=psa[i]+a[i]
#sum[:ax]=psa[x+1] e.g. sum 1st 5 items in psa[5]
#ASCII<->number ord('f')=102 chr(102)='f'
#def binary_search(li, val, lb, ub):
#    while ((ub-lb)>1):
#        mid = (lb + ub) // 2
#        if li[mid] >= val:
#            ub = mid
#        else:
#            lb = mid
#    return lb+1 #return index of elements <val in li
#def binary_search(li, val, lb, ub):
#    ans = -1
#    while (lb <= ub):
#        mid = (lb + ub) // 2
#        if li[mid] > val:
#            ub = mid - 1
#        elif val > li[mid]:
#            lb = mid + 1
#        else:
#            ans = mid  # return index
#            break
#    return ans
##########
#def pref(li):
#    pref_sum = [0]
#    for i in li:
#        pref_sum.append(pref_sum[-1] + i)
#    return pref_sum
##########
#def suff(li):
#    suff_sum = [0]
#    for i in range(len(li)-1,-1,-1):
#        suff_sum.insert(0,suff_sum[0] + li[i])
#    return suff_sum
#############
#def maxSubArraySumI(arr): #Kadane's algorithm with index
#    max_till_now=arr[0];max_ending=0;size=len(arr)
#    start=0;end=0;s=0
#    for i in range(0, size):
#        max_ending = max_ending + arr[i]
#        if max_till_now < max_ending:
#            max_till_now=max_ending
#            start=s;end=i
#        if max_ending<0:
#            max_ending=0
#            s=i+1
#    return max_till_now,start,end
############# avoid max for 2 elements - slower than direct if
#def maxSubArraySum(arr): #Kadane's algorithm
#    max_till_now=arr[0];max_ending=0;size=len(arr)
#    for i in range(0, size):
#        max_ending = max_ending + arr[i]
#        if max_till_now < max_ending:max_till_now=max_ending
#        if max_ending<0:max_ending=0
#    return max_till_now
#############
#def findbits(x):
#    tmp=[]
#    while x>0:tmp.append(x%2);x//=2
#    tmp.reverse()
#    return tmp
##############Dijkstra algorithm example
#dg=[999999]*(n+1);dg[n]=0;todo=[(0,n)];chkd=[0]*(n+1)
#while todo:#### find x with min dg in todo
#    _,x=hq.heappop(todo)
#    if chkd[x]:continue
#    for i in coming[x]:going[i]-=1
#    for i in coming[x]:
#        tmp=1+dg[x]+going[i]
#        if tmp<dg[i]:dg[i]=tmp;hq.heappush(todo,(dg[i],i))
#    chkd[x]=1
################
# adj swaps to match 2 binary strings: sum_{i=1}^n(abs(diff in i-th prefix sums))
###############
##s=[2, 3, 1, 4, 5, 3]
##sorted(range(len(s)), key=lambda k: s[k])
##gives sorted indices [2, 0, 1, 5, 3, 4]
##m= [[3, 4, 6], [2, 4, 8], [2, 3, 4], [1, 2, 3], [7, 6, 7], [1, 8, 2]]
##m.sort(reverse=True,key=lambda k:k[2]) #sorts m according to 3rd elements

#from math import ceil, floor #, gcd, log, factorial, comb, perm,
#log10, log2, log, sin, asin, tan, atan,
#from heapq import heappop,heappush,heapify #heappop(hq), heapify(list)
#from collections import defaultdict as dd
#mydd=dd(list) for .append
#from collections import deque as dq #deque  e.g. myqueue=dq(list)
#append/appendleft/appendright/pop/popleft
#from bisect import bisect as bis #a=[1,3,4,6,7,8] #bis(a,5) --> 3
#import statistics as stat  # stat.median(a), mode, mean
from math import gcd
import sys
input = sys.stdin.readline
#print = sys.stdout.write
#sys.setrecursionlimit(100000) #default is 1000
############ ---- Input Functions ---- ############
def inp():
    return(int(input()))
def inlt():
    return(list(map(int,input().split())))   #.split(','), default is space
#list([0,*map(int,input().split(" "))]) # pad a zero to avoid zero indexing
def insr():
    s = input()
    return(list(s[:len(s) - 1]))
####################################################
def phi(n): #Euler's totient function from Euler's product formula
    result = n;
    if (n%2 == 0):
        while (n % 2 == 0):n//=2;
        result //=2;
    p=3
    while(p*p <= n):
        if (n % p == 0):
            while (n % p == 0):n//=p;
            result -= result//p;
        p += 2;
    if (n > 1):
        result -= result//n;
    return result;
#t=1
n = int(input())
phis=[0]
for i in range(1,n):
    phis.append(phi(i))
ans=0;mod=10**9+7

for d in range(1,n//2+1):
    for ncd in range(2,(n-1)//d+1):
        c=n-ncd*d
        ans+=c*d//gcd(c,d)*phis[ncd]
        ans%=mod
print(ans)

#print(*ans,sep=' ')##print("{:.3f}".format(ans)+"%")
#:b binary :% eg print("{:6.2%}".format(ans))
#print(" ".join(str(i) for i in ans))
#print(" ".join(map(str,ans))) #seems faster
#print(a[0] if a else 0)
#prefixsum a=[a1...an] #psa=[0]*(n+1)
#for i in range(n): psa[i+1]=psa[i]+a[i]
#sum[:ax]=psa[x+1] e.g. sum 1st 5 items in psa[5]
#ASCII<->number ord('f')=102 chr(102)='f'
#def binary_search(li, val, lb, ub):
#    while ((ub-lb)>1):
#        mid = (lb + ub) // 2
#        if li[mid] >= val:
#            ub = mid
#        else:
#            lb = mid
#    return lb+1 #return index of elements <val in li
#def binary_search(li, val, lb, ub):
#    ans = -1
#    while (lb <= ub):
#        mid = (lb + ub) // 2
#        if li[mid] > val:
#            ub = mid - 1
#        elif val > li[mid]:
#            lb = mid + 1
#        else:
#            ans = mid  # return index
#            break
#    return ans
##########
#def pref(li):
#    pref_sum = [0]
#    for i in li:
#        pref_sum.append(pref_sum[-1] + i)
#    return pref_sum
##########
#def suff(li):
#    suff_sum = [0]
#    for i in range(len(li)-1,-1,-1):
#        suff_sum.insert(0,suff_sum[0] + li[i])
#    return suff_sum
#############
#def maxSubArraySumI(arr): #Kadane's algorithm with index
#    max_till_now=arr[0];max_ending=0;size=len(arr)
#    start=0;end=0;s=0
#    for i in range(0, size):
#        max_ending = max_ending + arr[i]
#        if max_till_now < max_ending:
#            max_till_now=max_ending
#            start=s;end=i
#        if max_ending<0:
#            max_ending=0
#            s=i+1
#    return max_till_now,start,end
############# avoid max for 2 elements - slower than direct if
#def maxSubArraySum(arr): #Kadane's algorithm
#    max_till_now=arr[0];max_ending=0;size=len(arr)
#    for i in range(0, size):
#        max_ending = max_ending + arr[i]
#        if max_till_now < max_ending:max_till_now=max_ending
#        if max_ending<0:max_ending=0
#    return max_till_now
#############
#def findbits(x):
#    tmp=[]
#    while x>0:tmp.append(x%2);x//=2
#    tmp.reverse()
#    return tmp
##############Dijkstra algorithm example
#dg=[999999]*(n+1);dg[n]=0;todo=[(0,n)];chkd=[0]*(n+1)
#while todo:#### find x with min dg in todo
#    _,x=hq.heappop(todo)
#    if chkd[x]:continue
#    for i in coming[x]:going[i]-=1
#    for i in coming[x]:
#        tmp=1+dg[x]+going[i]
#        if tmp<dg[i]:dg[i]=tmp;hq.heappush(todo,(dg[i],i))
#    chkd[x]=1
################
# adj swaps to match 2 binary strings: sum_{i=1}^n(abs(diff in i-th prefix sums))
###############
##s=[2, 3, 1, 4, 5, 3]
##sorted(range(len(s)), key=lambda k: s[k])
##gives sorted indices [2, 0, 1, 5, 3, 4]
##m= [[3, 4, 6], [2, 4, 8], [2, 3, 4], [1, 2, 3], [7, 6, 7], [1, 8, 2]]
##m.sort(reverse=True,key=lambda k:k[2]) #sorts m according to 3rd elements

from collections import defaultdict
import math

mod=10**9+7
n=int(input())

phi=list(range(n+1))
for x in range(2,n+1):
  if phi[x]==x:
    for y in range(x,n+1,x):
      phi[y]=phi[y]//x*(x-1)

divs=[[] for i in range(n+1)]
for i in range(1,n+1):
  for j in range(2*i,n+1,i):
    divs[j].append(i)

ans=0
for c in range(1,n-1):
  x=n-c
  for d in divs[x]:
    cnt=phi[x//d]
    ans+=c*d//math.gcd(c,d)%mod*cnt%mod
  ans%=mod
  #print(c,cnt)

print(ans)

from collections import defaultdict
import math

mod=10**9+7
n=int(input())

divs=[[] for i in range(n+1)]
for i in range(1,n+1):
  for j in range(i,n+1,i):
    divs[j].append(i)

ans=0
for c in range(1,n-1):
  x=n-c
  cnt=defaultdict(int)
  for d in divs[x][::-1]:
    cnt[d]=x//d-1
    for i in cnt:
      if d<i and i%d==0:
        cnt[d]-=cnt[i]
    ans+=c*d//math.gcd(c,d)%mod*cnt[d]%mod
    ans%=mod
  #print(c,cnt)

print(ans)

def main():
    from sys import stdin, setrecursionlimit
    # setrecursionlimit(1000000)
    input = stdin.readline
    def iinput(): return int(input())
    def sinput(): return input().rstrip()
    def i0input(): return int(input()) - 1
    def linput(): return list(input().split())
    def liinput(): return list(map(int, input().split()))
    def miinput(): return map(int, input().split())
    def li0input(): return list(map(lambda x: int(x) - 1, input().split()))
    def mi0input(): return map(lambda x: int(x) - 1, input().split())
    INF = 1000000000000000000
    MOD = 1000000007

    '''
    c を固定
    a + b = N - c = K は gcd(a, b) で割り切れる -> K の約数のうち K 以外をひとつ k と固定
    k + k + ... + k = K
    l = K / k
    このとき、分け方は phi(l)
    '''

    def make_divisors(n):
        lower_divisors , upper_divisors = [], []
        i = 1
        while i*i <= n:
            if n % i == 0:
                lower_divisors.append(i)
                if i != n // i:
                    upper_divisors.append(n//i)
            i += 1
        return lower_divisors + upper_divisors[::-1]

    class Totient:
        def __init__(self, N:int) -> None:
            self.N = N
            self.enum_tortient = [i for i in range(N+1)]
            self.is_prime = [True] * (N + 1)
            self.is_prime[0] = False
            self.is_prime[1] = False
            for p in range(2, N+1):
                if self.is_prime[p]:
                    self.enum_tortient[p] = p - 1
                    for n in range(2*p, N+1, p):
                        self.is_prime[n] = False
                        self.enum_tortient[n] = self.enum_tortient[n] // p * (p - 1)
        def phi(self, K:int) -> int:
            assert(K <= self.N)
            return self.enum_tortient[K]

    N = iinput()
    ans = 0
    from math import gcd

    tot = Totient(N)
    for c in range(1, N-1):
        K = N - c
        for g in make_divisors(K)[:-1]:
            ans += c * tot.phi(K//g) * g // gcd(g, c)
            ans %= MOD
    print(ans)

main()

''' E. Madoka and The Best University
https://codeforces.com/contest/1717/problem/E
'''

import io, os, sys
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline  # decode().strip() if str
output = sys.stdout.write

def debug(*args):
    if os.environ.get('debug') in [None, '0']: return
    from inspect import currentframe, getframeinfo
    from re import search
    frame = currentframe().f_back
    s = getframeinfo(frame).code_context[0]
    r = search(r"\((.*)\)", s).group(1)
    vnames = r.split(', ')
    var_and_vals = [f'{var}={val}' for var, val in zip(vnames, args)]
    prefix = f'{currentframe().f_back.f_lineno:02d}: '
    print(f'{prefix}{", ".join(var_and_vals)}')

from types import GeneratorType
def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack: return f(*args, **kwargs)
        to = f(*args, **kwargs)
        while True:
            if type(to) is GeneratorType:
                stack.append(to)
                to = next(to)
            else:
                stack.pop()
                if not stack: break
                to = stack[-1].send(to)
        return to
    return wrappedfunc

class IntKeyDict(dict):
    from random import randrange
    rand = randrange(1 << 62)
    def __setitem__(self, k, v): super().__setitem__(k^self.rand, v)
    def __getitem__(self, k): return super().__getitem__(k^self.rand)
    def __contains__(self, k): return super().__contains__(k^self.rand)
    def __repr__(self): return str({k: v for k, v in self.items()})
    def get(self, k, default=None): return super().get(k^self.rand, default)
    def keys(self): return [k^self.rand for k in super().keys()]
    def items(self): return [(k^self.rand, v) for k, v in super().items()]

INF = float('inf')

# -----------------------------------------

MOD = 10**9 + 7

from math import gcd
def lcm(a, b): return a * b // gcd(a, b)

# iterate over c and g = gcd(a, b)
# for each c and g, count num pairs of (a, b) s.t. a + b = N - c and gcd(a, b) = g
# i.e. num pairs of (a', b') s.t. a' + b' == (N - c) // g and gcd(a', b') == 1
# i.e. phi((N - c) // g)

def solve(N):
    phi = list(range(N + 1))
    phi[1] = 0
    for i in range(2, N + 1):
        if phi[i] == i:  # prime
            for j in range(i, N + 1, i):
                phi[j] -= phi[j] // i

    res = 0
    for g in range(1, N):
        for s in range(g, N, g):
            c = N - s
            res = (res + lcm(c, g) * phi[(N - c) // g]) % MOD

    return res

def main():
    N = int(input())
    res = solve(N)
    print(res)

if __name__ == '__main__':
    main()

''' E. Madoka and The Best University
https://codeforces.com/contest/1717/problem/E
'''

import io, os, sys
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline  # decode().strip() if str
output = sys.stdout.write

def debug(*args):
    if os.environ.get('debug') in [None, '0']: return
    from inspect import currentframe, getframeinfo
    from re import search
    frame = currentframe().f_back
    s = getframeinfo(frame).code_context[0]
    r = search(r"\((.*)\)", s).group(1)
    vnames = r.split(', ')
    var_and_vals = [f'{var}={val}' for var, val in zip(vnames, args)]
    prefix = f'{currentframe().f_back.f_lineno:02d}: '
    print(f'{prefix}{", ".join(var_and_vals)}')

from types import GeneratorType
def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack: return f(*args, **kwargs)
        to = f(*args, **kwargs)
        while True:
            if type(to) is GeneratorType:
                stack.append(to)
                to = next(to)
            else:
                stack.pop()
                if not stack: break
                to = stack[-1].send(to)
        return to
    return wrappedfunc

class IntKeyDict(dict):
    from random import randrange
    rand = randrange(1 << 62)
    def __setitem__(self, k, v): super().__setitem__(k^self.rand, v)
    def __getitem__(self, k): return super().__getitem__(k^self.rand)
    def __contains__(self, k): return super().__contains__(k^self.rand)
    def __repr__(self): return str({k: v for k, v in self.items()})
    def get(self, k, default=None): return super().get(k^self.rand, default)
    def keys(self): return [k^self.rand for k in super().keys()]
    def items(self): return [(k^self.rand, v) for k, v in super().items()]

INF = float('inf')

# -----------------------------------------

MOD = 10**9 + 7

from math import gcd
def lcm(a, b): return a * b // gcd(a, b)

# iterate over c and g = gcd(a, b)
# for each c and g, count num pairs of (a, b) s.t. a + b = N - c and gcd(a, b) = g
# i.e. num pairs of (a', b') s.t. a' + b' == (N - c) // g and gcd(a', b') == 1
# i.e. phi((N - c) // g)

def solve(N):
    phi = list(range(N + 1))
    phi[1] = 0
    for i in range(2, N + 1):
        if phi[i] == i:  # prime
            for j in range(i, N + 1, i):
                phi[j] -= phi[j] // i

    lpf = list(range(N + 1))
    for i in range(2, N + 1):
        if lpf[i] == i:
            for j in range(i, N+1, i):
                if lpf[j] == j:
                    lpf[j] = i

    res = 0
    for c in range(1, N):
        s = N - c

        # all factors of s
        facs = [1]
        res = (res + c * phi[N - c]) % MOD
        while s > 1:
            p = lpf[s]
            cnt = 0
            while s % p == 0:
                cnt += 1
                s //= p
            for i in range(len(facs)):
                for j in range(1, cnt + 1):
                    f = facs[i] * p**j
                    facs.append(f)
                    res = (res + lcm(c, f) * phi[(N - c) // f]) % MOD

    return res

def main():
    N = int(input())
    res = solve(N)
    print(res)

if __name__ == '__main__':
    main()

import sys
import math

primes = []
is_prime = [True] * 100001

Q = 0

def get_primes(n):
    global primes
    global Q
    global is_prime

    i=2
    while i*i <= n:
        if is_prime[i]:
            j = i
            while j*i<=n:
                is_prime[i*j] = False
                j += 1
        i += 1

    for i in range(2,n+1):
        if is_prime[i]:
            primes.append(i)
            Q += 1

def gcd(a, b):

    while b > 0:
        c = a % b
        a = b
        b = c

    return a

def fn(n):
    z = n
    f = n
    for p in primes:
        if is_prime[z]:
            break

        if z % p == 0:
            f = f * (p - 1) // p
            while z % p == 0:
                z = z // p

    if z > 1:
        f = f * (z - 1) // z

    #print('fn({}) = {}'.format(n, f))

    return f

def ccc(c, p, nc):
   # print("c={} p={}  => {} * {}".format(c,p, c * p // gcd(c,p), fn(nc // p)));
    return (E[nc // p] * c * p // gcd(c,p)) % M

input = sys.stdin.readline
t = 1#int(input())

M = 1000000007

for _test_ in range(t):

    n = int(input())
    get_primes(n)

    E = [0] * (n+1)
    for i in range(1,n+1):
        E[i] = fn(i)

    S = 0
    for c in range(1, n-1):
        nc = n - c
        i = 1
        while i*i <= nc:

            if nc % i == 0:

                p = i

                a = p
                b = c
                while b > 0:
                    x = a % b
                    a = b
                    b = x
                lcm = c * p // a

                S = (S + E[nc // p] * lcm) % M

                i2 = nc // i

                if (i2 != i) and (i2 < nc):

                    p = i2

                    a = p
                    b = c
                    while b > 0:
                        x = a % b
                        a = b
                        b = x
                    lcm = c * p // a

                    S = (S + E[nc // p] * lcm) % M

            i += 1

    print(S)

import math

def solve():
    n = int(input().strip())

    vis = [False for i in range(n + 1)]
    pri_cnt = [i for i in range(n + 1)]

    pri = [0, 1]
    for i in range(2, n + 1):
        if not vis[i]:
            pri.append(i)
            for j in range(i, n + 1, i):
                vis[j] = True
                pri_cnt[j] -= pri_cnt[j] // i

    # print('pri', pri)
    # print('pri_cnt', pri_cnt)

    ans = 0
    mod: int = 10 ** 9 + 7

    divs = [[] for i in range(n + 1)]

    for i in range(2, n + 1):
        for j in range(i + i, n + 1, i):
            divs[j].append(i)

    for a in range(1, n - 1):
        bc = n - a
        # print(bc, gcd_bc_list)
        temp = 0
        total = bc - 1
        for gcd_bc in divs[bc]:
            cnt = pri_cnt[bc // gcd_bc] % mod
            temp += cnt
            ans += (cnt * math.lcm(a, gcd_bc)) % mod
            ans %= mod
        ans += a * (total - temp) % mod
        ans %= mod
        # print(a, 'temp', temp, 'ans', ans)

    return ans

if __name__ == '__main__':
    # t = int(input().strip())
    # for _ in range(t):
    print(solve())

maxN = 100005
divisors = [[] for _ in range(maxN)]
for d in range(1, maxN):
    d2 = d
    while d2 < maxN:
        divisors[d2].append(d)
        d2 += d
for d in range(1, maxN):
    divisors[d].reverse()

def get_gcd_and_cnts(m):
    # get all gcd and counts for a + b == m
    gcnts = dict()
    for d in divisors[m]:
        gcnts[d] = 0
    for d in divisors[m]:
        c = (m - 2 * d) // d + 1
        gcnts[d] += c
        c2 = gcnts[d]
        for i in range(1, len(divisors[d])):
            gcnts[divisors[d][i]] -= c2
    return gcnts

def lcm(x, y):
    g = gcd(x, y)
    return (x // g) * y

def main():

    MOD = int(1e9 + 7)
    n = int(input())
    ans = 0
    for c in range(1, n - 1):
        gcnts = get_gcd_and_cnts(n - c)
        for g, cnt in gcnts.items():
            ans += lcm(c, g) * cnt
            ans %= MOD
    print(ans)

    return

import sys
input=sys.stdin.buffer.readline #FOR READING PURE INTEGER INPUTS (space separation ok)
# input=lambda: sys.stdin.readline().rstrip("\r\n") #FOR READING STRING/TEXT INPUTS.

def oneLineArrayPrint(arr):
    print(' '.join([str(x) for x in arr]))
def multiLineArrayPrint(arr):
    print('\n'.join([str(x) for x in arr]))
def multiLineArrayOfArraysPrint(arr):
    print('\n'.join([' '.join([str(x) for x in y]) for y in arr]))

def readIntArr():
    return [int(x) for x in input().split()]
# def readFloatArr():
#     return [float(x) for x in input().split()]

def makeArr(defaultValFactory,dimensionArr): # eg. makeArr(lambda:0,[n,m])
    dv=defaultValFactory;da=dimensionArr
    if len(da)==1:return [dv() for _ in range(da[0])]
    else:return [makeArr(dv,da[1:]) for _ in range(da[0])]

def queryInteractive(a, b, c):
    print('? {} {} {}'.format(a, b, c))
    sys.stdout.flush()
    return int(input())

def answerInteractive(x1, x2):
    print('! {} {}'.format(x1, x2))
    sys.stdout.flush()

inf=float('inf')
# MOD=10**9+7
# MOD=998244353

from math import gcd,floor,ceil
import math
# from math import floor,ceil # for Python2

for _abc in range(1):
    main()

import sys
import os
from io import BytesIO, IOBase
BUFSIZE = 8192
class FastIO(IOBase):
    newlines = 0
    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None
    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()
    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()
    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)
class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")
sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

def I():
    return input()
def II():
    return int(input())
def MI():
    return map(int, input().split())
def LI():
    return list(input().split())
def LII():
    return list(map(int, input().split()))
def GMI():
    return map(lambda x: int(x) - 1, input().split())

#------------------------------FastIO---------------------------------

from bisect import *
from heapq import *
from collections import *
from functools import *
from itertools import *
from time import *
from random import *
from math import gcd, lcm
#dfs - stack#
#check top!#

phi = [i for i in range(100010)]
factors = [[1] for _ in range(100010)]
phi[0] = phi[1] = 0
for i in range(2, 100010):
    if phi[i] == i:
        for j in range(i, 100010, i):
            phi[j] -= phi[j] // i
            jj = j
            cnt = 0
            while jj % i == 0:
                cnt += 1
                jj //= i

            k = len(factors[j])
            for kk in range(k):
                for p in range(1, cnt + 1):
                    factors[j].append(factors[j][kk] * i ** p)
#print(factors[:100])

mod = 10 ** 9 + 7

def solve():
    n = II()
    res = 0
    for c in range(1, n - 1):
        for d in factors[n - c]:
            #print(n - c, d, (n - c) // d)
            res += lcm(c, d) * phi[(n - c) // d]
            res %= mod
    print(res)

for _ in range(1):solve()

class primes():
    def __init__(self, n):
        self.prime_num = n
        self.min_prime = [-1] * (self.prime_num + 1)  # 2以上の自然数に対して最小の素因数を表す
        self.min_prime[0] = 0
        self.min_prime[1] = 1
        i = 2
        self.prime = []
        self.memo_prifac = {}
        while i <= self.prime_num:
            if self.min_prime[i] == -1:
                self.min_prime[i] = i
                self.prime.append(i)
            for j in self.prime:
                if i * j > self.prime_num or j > self.min_prime[i]: break
                self.min_prime[j * i] = j
            i += 1

    def prifac(self, n):
        # 素因数分解した結果を返す
        if n in self.memo_prifac:
            return self.memo_prifac[n]
        res = {}
        x = n
        while x > 1:
            p = self.min_prime[x]
            if p in res:
                res[p] += 1
            else:
                res[p] = 1
            x //= p

        # self.memo_prifac[n] = res  #場合によってはこの行を消すと高速化

        return res

    def divisors(self, n):
        # 約数列挙 メモした方がいいかも
        if n== 1: return [1]
        prf = self.prifac(n)
        keys = [key for key in prf]

        def divsearch(i):
            if i == len(keys) - 1:
                return [keys[i] ** j for j in range(prf[keys[i]] + 1)]
            else:
                res = []
                subres = divsearch(i + 1)
                p = keys[i]
                for j in range(prf[p] + 1):
                    for node in subres:
                        res.append(node * p ** j)
                return res

        return divsearch(0)

from math import gcd
def lcm(a,b):
    return a*b//gcd(a,b)
mod=10**9+7
n=int(input())
ans=0
pri=primes(n+3)
dp=[0]*(n+3)
for c in range(1,n-1):
    k=n-c
    yaku=pri.divisors(k)
    yaku.sort(reverse=True)
    for g in yaku:
        m=k//g
        dp[g]=m-1
        for j in yaku:
            if j>g and j%g==0:dp[g]-=dp[j]
        ans+=(c*g//gcd(g,c))*dp[g]
        ans%=mod
    for g in yaku:dp[g]=0
print(ans)

MOD = 10 ** 9 + 7
n = int(input())

def gcd(x, y):
    while y != 0:
        x, y = y, x % y
    return x

def lcm(x, y):
    return x * y // gcd(x, y)

ans = 0

divisors = [[] for _ in range(n)]
for d in range(2, n):
    for m in range(2 * d, n, d):
        divisors[m].append(d)

#print(divisors)

rel_primes_with_sum = [0] * n
for s in range(1, n):
    rel_primes_with_sum[s] = s - 1
    for d in divisors[s]:
        rel_primes_with_sum[s] = (rel_primes_with_sum[s] - rel_primes_with_sum[d]) % MOD

#print(rel_primes_with_sum)

for g in range(1, n):
    for s in range(g, n, g):
        ans = (ans + lcm(n - s, g) * rel_primes_with_sum[s // g]) % MOD

print(ans)

import sys

input = sys.stdin.readline
import functools
import math

def lcm(a, b):
    return int(a * b / math.gcd(a, b))

for _ in range(1):

    n = int(input())

    ## 从因子入手，获取每个数的因数
    factor = [] * n
    for i in range(n + 1):
        factor.append([])
    for i in range(1, n + 1):
        k = 1
        while k * i <= n:
            factor[k * i].append(i)
            k += 1

    ## pairs[i]和为i的两个数a, b
    ## 有多少个a和i互质
    ## 用到欧拉函数
    pairs = [0] * n
    pairs[2] = 1
    for i in range(3, n):
        nums = i
        for small in factor[i]:
            # 保证zhishu
            if len(factor[small]) == 2:
                nums *= (small - 1) / small
        pairs[i] = int(nums)

    ans = 0
    for i in range(1, n - 1):
        # 固定c为i，ab之和为sum
        sums = n - i
        # gcd(a, b) = gcd(a, sum)
        # 遍历sum的因子
        for factors in factor[sums]:
            if factors != sums:
                # 因子为factors的话
                # gcd(a, sum) = factors => gcd(a // factors, sum // factors) = 1
                # 那么这样的a的个数就是pairs[sums // factors]
                ans += lcm(i, factors) * pairs[sums // factors]

        ans %= 1000000007

    # 特判
    if n == 3:
        ans = 1
    print(ans)

import sys
input = sys.stdin.readline
from collections import *
from math import gcd

def lcm(x, y):
    return x*y//gcd(x, y)

n = int(input())
ans = 0
MOD = 10**9+7

for c in range(1, n-1):
    divs = []

    for d in range(1, int((n-c)**0.5)+1):
        if (n-c)%d==0:
            divs.append(d)

            if d!=(n-c)//d:
                divs.append((n-c)//d)

    divs.sort(reverse=True)
    cnts = []

    for i in range(len(divs)):
        cnt = (n-c-1)//divs[i]

        for j in range(i):
            if divs[j]%divs[i]==0:
                cnt -= cnts[j]

        cnts.append(cnt)
        ans += lcm(c, divs[i])*cnt
        ans %= MOD

print(ans)

from sys import stdin
input = stdin.readline

inp = lambda : list(map(int,input().split()))

"""

let g = gcd(a , b)
a + b + c = n

(a + b) is a multiple of g

total = (a + b) // g
gcd(x , x + y) = gcd(x , y)

so phi[total] sub be the pairs which are coprimes

"""

mod = (10 ** 9) + 7
def add(a , b):return ((a % mod) + (b % mod)) % mod
def mul(a , b):return ((a % mod) * (b % mod)) % mod

def Phi(n):

    global phi

    phi = [0 , 1]
    for i in range(2 , n + 1):
        phi.append(i - 1)

    for i in range(2 , n + 1):
        for j in range(2 * i , n + 1 , i):
            phi[j] -= phi[i]

Phi(100001)

def gcd(a , b):
    if(b == 0):return a
    return gcd(b , a % b)

def lcm(a , b):

    return (a * b) // gcd(a , b)

def answer():

    ans = 0
    for g in range(1 , n + 1):
        for j in range(g , n + 1 , g):

            c = n - j
            val = lcm(c , g)

            if(j // g > 1):ans = add(ans , mul(val , phi[j // g]))

    return ans

for T in range(1):

    n = int(input())

    print(answer())

def makediv(n):
	lower_divisors , upper_divisors = [], []
	i = 1
	while i*i <= n:
		if n % i == 0:
			lower_divisors.append(i)
			if i != n // i:
				upper_divisors.append(n//i)
		i += 1
	return lower_divisors + upper_divisors[::-1]

from math import gcd
mod = 10**9 + 7
n = int(input())
ans = 0
for c in range(1, n-1):
	w = makediv(n-c)
	wm = len(w)
	dp = [0] * wm
	for i in range(wm-1,-1,-1):
		dp[i] = (n-c) // w[i] - 1
		for j in range(i+1,wm):
			if w[j] % w[i] == 0:
				dp[i] -= dp[j]
		ans += c * w[i] * dp[i] // gcd(w[i], c)
		ans %= mod

print(ans)

import os,sys
from random import randint, shuffle
from io import BytesIO, IOBase

from collections import defaultdict,deque,Counter
from bisect import bisect_left,bisect_right
from heapq import heappush,heappop
from functools import lru_cache
from itertools import accumulate, permutations
import math

# Fast IO Region
BUFSIZE = 8192
class FastIO(IOBase):
    newlines = 0
    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None
    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()
    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()
    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)
class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")
sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# for _ in range(int(input())):
#     n = int(input())
#     a = list(map(int, input().split()))

# for _ in range(int(input())):
#     n = int(input())
#     ans = n + n // 2 * 2 + n // 3 * 2
#     print(ans)

# for _ in range(int(input())):
#     n, k, r, c = list(map(int, input().split()))
#     ans = [['.'] * n for _ in range(n)]
#     r -= 1
#     c -= 1
#     for i in range(n):
#         for j in range(n):
#             if (i + j) % k == (r + c) % k:
#                 ans[i][j] = 'X'
#     for i in range(n):
#         print(''.join(ans[i]))

# for _ in range(int(input())):
#     def solve():
#         n = int(input())
#         a = list(map(int, input().split()))
#         b = list(map(int, input().split()))
#         for i in range(n):
#             if a[i] > b[i]:
#                 print('NO')
#                 return
#             if b[i] > b[(i + 1) % n] + 1 and a[i] < b[i]:
#                 print('NO')
#                 return
#         print('YES')
#     solve()

# mod = 10 ** 9 + 7
# N = 501000
# fac = [1] * N
# for i in range(2, N):
#     fac[i] = fac[i - 1] * i % mod
# invfac = [1] * N
# invfac[N - 1] = pow(fac[N - 1], mod - 2, mod)
# for i in range(N - 1)[::-1]:
#     invfac[i] = invfac[i + 1] * (i + 1) % mod
# def c(i, j):
#     return fac[i] * invfac[j] * invfac[i - j] % mod
# n, k = list(map(int, input().split()))
# if k >= n:
#     print(pow(2, n, mod))
# else:
#     ans = 0
#     a = [0] * (k + 1)
#     for i in range(k + 1):
#         a[i] = c(n - 1, i)
#     ans = sum(a) * 2 - a[-1]
#     print(ans % mod)

n = 30
s = defaultdict(set)
# s = set()
ans = 0
for i in range(1, n + 1):
    for j in range(1, n + 1):
        if n - i - j > 0:
            ans += 1
            s[math.gcd(i, j)].add(n - i - j)
            # s.add((math.gcd(i, j), n - i - j))
# print(s, ans)

N = int(pow(10 ** 9, 0.5)) + 5
def get_prime_linear(n):
    global cnt
    for i in range(2, n + 1):
        if not st[i]:
            primes[cnt] = i
            cnt += 1
        for j in range(n):
            if primes[j] > n / i: break
            st[primes[j] * i] = True
            if i % primes[j] == 0: break
primes, cnt, st = [0] * (N + 5), 0, [False] * (N + 5)
get_prime_linear(N)
prime1e3 = primes[:cnt]
@lru_cache(None)
def get_factor(n):
    res = []
    for i in prime1e3:
        if i * i > n:
            break
        while n % i == 0:
            n //= i
            res.append(i)
    if n > 1:
        res.append(n)
    return set(res)

@lru_cache(None)
def calc(k):
    cnt = k - 1
    s = list(get_factor(k))
    n = len(s)
    for i in range(1 << n):
        p = 1
        cnt1 = 0
        for j in range(n):
            if i >> j & 1:
                cnt1 += 1
                p *= s[j]
        if p != 1 and p != k:
            if cnt1 % 2:
                cnt -= k // p - 1
            else:
                cnt += k // p - 1
    return cnt

# for i in range(1, 100):
#     cnt = 0
#     for j in range(1, i):
#         if math.gcd(j, i - j) == 1:
#             cnt += 1
#     print(i, calc(i), cnt)

def lcm(x, y):
    return x * y // math.gcd(x, y)
n = int(input())
ans = 0
st = set()
for g in range(1, n + 1):
    mx = n - 2 * g
    if mx > 0:
        for c in range(mx, -10, -g):
            if c <= 0: break
            k = (n - c) // g
            cnt = calc(k)
            ans += cnt * lcm(g, c)
print(ans % (10 ** 9 + 7))

import os, sys
from io import BytesIO, IOBase

from collections import defaultdict, deque, Counter
from bisect import bisect_left, bisect_right
from heapq import heappush, heappop
from functools import lru_cache
from itertools import accumulate
import math

# Fast IO Region
BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")
# sys.setrecursionlimit(800)

mod = 10 ** 9 + 7
from copy import copy

N = 10 ** 5 + 5
pf = [True for _ in range(N)]
P = [[] for _ in range(N)]
for i in range(2, N):
    if not pf[i]:
        continue
    else:
        P[i].append(i)
        for j in range(2 * i, N, i):
            pf[j] = False
            P[j].append(i)

d = [0] * N
for i in range(2, N):
    d[i] = i
    for j in P[i]:
        d[i] *= j - 1
        d[i] //= j

def sp(n):
    res = 0
    for v in range(1, n // 2 + 1):
        c = n - n // v * v
        if c == 0 and v != 1:
            continue
        if math.gcd(c, v) != 1:
            continue
        for k in range(c, n, v):
            t = (n - k) // v
            res += d[t] * v * k
            res %= mod
    return res

def solve():
    # for i in range(10):
    #     print(i, sp(i))
    n = int(input())
    res = 0
    for i in range(1, n):
        if n % i == 0:
            k = n // i
            res += sp(k) * i
    print(res % mod)

for _ in range(1):
    solve()

import itertools as it
import functools as ft
from collections import Counter
import math
from math import gcd

def linear_mul(n, g):
    res = [None for i in range(n+1)]
    res[0] = 0
    res[1] = 1

    sieve = [i for i in range(n+1)] #sieve[i] will store the smallest prime factor of i
    primes = []

    #this is needed to 'remove' coprime factors from the evaluation of f(i)
    #so that we can insert different powers
    count = [0 for i in range(n+1)] #count[i] = power k of p = spf(i); power of smallest prime factor of i

    for i in range(2,n+1):
        if sieve[i]==i:
            primes.append(i)
            res[i] = g(i, 1)
            count[i] = 1 #i is prime => i is the only prime factor of i

        for p in primes:
            u = i*p
            if u>n: break
            sieve[u] = p

            #check comes after we assign current value
            #if i%p==0: #these two are equivalent conditions
            if sieve[i]==p:
                #trickier case, we have to use `count` to remove smaller power of p
                #since p has multiplicity higher than 1
                #res[u] = res[i]//g(p,count[i]) * g(p,count[i]+1) #fails if res[i] is 0
                res[u] = res[i//(p**count[i])] * g(p,count[i]+1)
                count[u] = count[i] + 1
                pass
            else:
                res[u] = res[i] * g(p,1) #p is the smallest prime factor with multiplicity 1
                count[u] = 1
                pass
    return res, primes, sieve

MAXN = 10**5
tot, primes, sieve = linear_mul(MAXN, lambda p, q: (p - 1) * (p ** (q - 1)))

#import sys
#sys.setrecursionlimit(10**5+20)

def readInt():
    return int(input().strip())

def readInts():
    return list(map(int, input().strip().split()))

def read():
    return readInt(),

def f1(n):
    r = 0
    for a in range(1,n):
        r += gcd(a, n - a)
    return r

# print([f1(i) for i in range(1,20+1)])

def f2(n, g):
    if n % g: return 0
    n //= g
    # r = 0
    # for a in range(1,n):
    #     if gcd(a, n) == 1: r += 1
    r2 = tot[n]
    if n <= 1: r2 = 0
    # assert r == r2, (n, r, r2)
    # return r
    return r2

# def solve1(n):
#     # return brute(n)
#     r = 0
#     # for g in range(1, n // 2):
#     #     # gcd(a, b) = g
#     for g2 in range(1, n // 3 + 1):
#         # g2 = gcd(a, b, c)
#         for g in range(g2, n // 2 + 1, g2):
#             # g = gcd(a, b)
#             for c in range(g2, n + 1, g2):
#                 if gcd(g, c) > g2: continue
#                 # assert gcd(g, c) == g2
#                 # a + b = n - c
#                 r += (c * g // g2) * f2(n - c, g)
#     return r

# def solve(n):
#     r = 0
#     for g2 in range(1, n // 3 + 1):  # gcd(a, b, c)
#         if n % g2: continue
#         # for g in range(g2, n // 2 + 1, g2):  # gcd(a, b), could also use n // 2 + 1
#         #     for c in range(g2, n - g + 1, g2):
#         for i in range(1, n // (2 * g2) + 1):
#             # for j in range(1, (n - g2 * i) // g2 + 1):
#             for j in range(1, n // g2 - i + 1):
#                 g, c = i * g2, j * g2
#
#                 if gcd(g, c) != g2: continue
#                 # assert gcd(g, c) == g2
#                 # a + b = n - c
#                 if (n - c) % g != 0: continue
#                 # assert (n - c) % g == 0
#                 r += (c * g // g2) * f2((n - c) // g2, g // g2)
#     return r

BASE = 10**9 + 7

def solve(n):
    r = 0
    for g2 in range(1, n // 3 + 1):  # gcd(a, b, c)
        if n % g2: continue
        m = n // g2
        # for g in range(g2, n // 2 + 1, g2):  # gcd(a, b), could also use n // 2 + 1
        #     for c in range(g2, n - g + 1, g2):
        for i in range(1, m // 2 + 1):
            # for j in range(1, (n - g2 * i) // g2 + 1):
            # for j in range(1, m - i + 1):
            for j in range(m % i, m - i + 1, i):
                if j <= 0: continue
                # g, c = i * g2, j * g2

                if gcd(i, j) != 1: continue
                # assert gcd(g, c) == g2
                # a + b = n - c

                # if (m - j) % i != 0: continue  # j = n // g2 = m (mod i)
                assert (m - j) % i == 0
                # assert (n - c) % g == 0
                r += (j * i * g2) * f2(m - j, i)
    return r % BASE

# print(solve(10**5))
# quit()

def brute(n):
    r = 0
    for a in range(1, n):
        for b in range(1, n - a):
            c = n - a - b
            assert 1 <= c <= n
            assert a + b + c == n
            g = gcd(a, b)
            r += c * g // gcd(c, g)
    return r

def test(*kargs, **kwargs):
    u = solve(*kargs, **kwargs)
    v = brute(*kargs, **kwargs)
    if u == v:
        return u

    if len(kwargs):
        print(kargs, kwargs, "expected", v, "got", u)
    else:
        print(kargs, "expected", v, "got", u)

    raise Exception

# print([brute(i) for i in range(1,20+1)])

# for i in range(1, 20 + 1):
#     # print(i, solve(i), brute(i))
#     print(i, test(i))
#
# quit()

# quit()  # Test if applicable

while True:
    # try:
    if True:
        n, = read()
    # except EOFError: break
    print(solve(n))
    break

import sys
input = lambda: sys.stdin.readline().rstrip()
from math import gcd
n = int(input())
phi = list(range(n+1))
for i in range(2, n+1):
    if phi[i] == i:
        for j in range(i, n+1, i):
            phi[j] -= phi[j]//i
ans = 0
MOD = 10**9+7
def f(m):
    g = gcd(m, n)
    res = 0
    k = 2
    while k*m < n:
        res += phi[k]*(n-k*m)
        res %= MOD
        k += 1
    return res * (m//g) % MOD

for i in range(1, n//2+1):
    ans = (ans+f(i))%MOD
print(ans)

import math

mod = 1000000007

n = int(input())
res = 0
phi = list(range(0,n+1))

for i in range(1,n+1):
    for j in range(i*2,n+1,i):
        phi[j] -= phi[i]

phi[1] = 0

for g in range(1,n+1):
    for sum_ab in range(g,n+1,g):
        c = n - sum_ab
        res += g // math.gcd(g,c) * c * phi[sum_ab//g]
        res %= mod

print(res)

import io,os
from math import gcd
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

dic = [{} for _ in range(100001)]

for i in range(2,100001):

    curr = i - 1
    for key in dic[i]:  curr -= dic[i][key]
    dic[i][1] = curr

    for j in range(2*i,100001,i):
        dic[j][j//i] = curr

#print(dic[:13])

def main(t):

    n = int(input())

    M = 10 ** 9 + 7
    ans = 0
    for i in range(1,n):
        for key in dic[n-i]:
            l = key*i//gcd(key,i)
            ans += l * dic[n-i][key]
            ans %= M

    print(ans)

T = 1 #int(input())
t = 1
while t<=T:
    main(t)
    t += 1

import sys
input = sys.stdin.readline
import functools
import math

a = [1,2,3]
a = a[::-1]
def lcm(a,b):
    return int(a * b / math.gcd(a,b))

for _ in range(1):

    n = int(input())
    factor = [] * n
    for i in range(n+1):
        factor.append([])
    for i in range(1,n+1):
        k = 1
        while k * i <= n:
            factor[k * i].append(i)
            k += 1
    pairs = [0] * n
    pairs[2] = 1
    for i in range(3,n):
        nums = i
        for small in factor[i]:
            if len(factor[small]) == 2:
                nums *= (small-1) / small

        pairs[i] = int(nums)
    ans = 0
    for i  in range(1, n - 1):
        sums= n - i
        for factors in factor[sums]:
            if factors != sums:
                ans += lcm(i, factors) * pairs[ sums // factors]

        ans %= 1000000007

    if n == 3:
        ans = 1
    print(ans)

import sys
input = sys.stdin.readline
import math
import copy
import bisect
import collections
from collections import deque
import heapq
from collections import defaultdict
from collections import OrderedDict
import itertools

def my_lcm(x, y):
    return (x * y) // math.gcd(x, y)

def make_divisors(n):
    lower_divisors , upper_divisors = [], []
    i = 1
    while i*i <= n:
        if n % i == 0:
            lower_divisors.append(i)
            if i != n // i:
                upper_divisors.append(n//i)
        i += 1
    return lower_divisors + upper_divisors[::-1]

n = int(input())
ans = 0
mod = 10**9+7
for i in range(1,n-1):
    check = n-i
    s = make_divisors(check)
    dic = {}
    for j,k in enumerate(s):
        dic[k] = j
    check -= 1
    memo = [0]*(len(s)-1)
    for j in range(len(s)-2,-1,-1):
        memo[j] += check//s[j]
        for k in range(dic[s[j]]):
            if s[j] % s[k] == 0:
                memo[dic[s[k]]] -= memo[j]
    for j in range(len(memo)):
        ans += my_lcm(s[j], i)*memo[j]
        ans %= mod
print(ans)

import math
import sys, os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def divisor(i):
    s = []
    for j in range(1, int(i ** (1 / 2)) + 1):
        if i % j == 0:
            s.append(i // j)
            s.append(j)
    return sorted(set(s))

def lcm(a, b):
    return a * b // math.gcd(a, b)

n = int(input())
mod = pow(10, 9) + 7
ans = 0
for i in range(2, n):
    c = n - i
    d = divisor(i)
    cnt = [(i - 1) // j for j in d]
    l = len(cnt) - 1
    for j in range(l - 1, -1, -1):
        cj, dj = cnt[j], d[j]
        for k in range(j + 1, l):
            if d[k] % dj:
                continue
            cj -= cnt[k]
        if cj:
            ans += lcm(dj, c) % mod * cj % mod
            ans %= mod
            cnt[j] = cj
print(ans)

def main():
    from sys import stdin, setrecursionlimit
    # setrecursionlimit(1000000)
    input = stdin.readline
    def iinput(): return int(input())
    def sinput(): return input().rstrip()
    def i0input(): return int(input()) - 1
    def linput(): return list(input().split())
    def liinput(): return list(map(int, input().split()))
    def miinput(): return map(int, input().split())
    def li0input(): return list(map(lambda x: int(x) - 1, input().split()))
    def mi0input(): return map(lambda x: int(x) - 1, input().split())
    INF = 1000000000000000000
    MOD = 1000000007

    '''
    c を固定
    a + b = N - c = K は gcd(a, b) で割り切れる -> K の約数のうち K 以外をひとつ k と固定
    k + k + ... + k = K
    l = K / k
    このとき、分け方は phi(l)
    '''

    def make_divisors(n):
        lower_divisors , upper_divisors = [], []
        i = 1
        while i*i <= n:
            if n % i == 0:
                lower_divisors.append(i)
                if i != n // i:
                    upper_divisors.append(n//i)
            i += 1
        return lower_divisors + upper_divisors[::-1]

    class Totient:
        def __init__(self, N:int) -> None:
            self.N = N
            self.enum_tortient = [i for i in range(N+1)]
            self.is_prime = [True] * (N + 1)
            self.is_prime[0] = False
            self.is_prime[1] = False
            for p in range(2, N+1):
                if self.is_prime[p]:
                    self.enum_tortient[p] = p - 1
                    for n in range(2*p, N+1, p):
                        self.is_prime[n] = False
                        self.enum_tortient[n] = self.enum_tortient[n] // p * (p - 1)
        def phi(self, K:int) -> int:
            assert(K <= self.N)
            return self.enum_tortient[K]

    N = iinput()
    ans = 0
    from math import gcd

    tot = Totient(N)
    for c in range(1, N-1):
        K = N - c
        for g in make_divisors(K)[:-1]:
            ans += c * tot.phi(K//g) * g // gcd(g, c)
    print(ans)

main()