Buggy python submission (verdict: Time Limit Exceeded):
import sys

sys.setrecursionlimit(1000000)

div_cache = {}
def primes(N):
    if N in div_cache:
        return div_cache[N]
    ret = set()
    for i in range(1, min(int(pow(N, 0.5) + 1), N)):
        if N % i == 0:
            ret.add(i)
            if i != 1:
                ret.add(N // i)
    div_cache[N] = ret
    return ret


cache = {}
def solve(N, K):
    M = pow(10, 9) + 7
    ans = 0
    for i in range(1, K + 1):
        P = pow(K // i, N, M)
        ans += i * P

        affect = {}
        def past(p, sign):
            nonlocal ans
            prim = primes(p)
            for p in prim:
                affect.setdefault(p, 0)
                affect[p] += p * sign
                if p != 1:
                    for k, v in cache[p].items():
                        affect.setdefault(k, 0)
                        affect[k] -= v

        past(i, -1)
        cache[i] = affect
        for v in affect.values():
            ans += v * P
            ans %= M

        ans %= M
    return ans

if __name__ == "__main__":
    N, K = tuple(map(int, input().split(" ")))
    print(solve(N, K))


Fixed submission:
import sys

sys.setrecursionlimit(1000000)

def slowsolve(N, K):
    import itertools
    import math
    data = {}
    s = 0
    KK = [i for i in range(1, K + 1)]
    for p in itertools.product(KK, repeat=N):
        cdi = p[0]
        for c in p:
            cdi = math.gcd(cdi, c)
        s += cdi
        data.setdefault(cdi, 0)
        data[cdi] += 1
    print(data)
    return s


cache = {}
def solve(N, K):
    M = pow(10, 9) + 7
    ans = 0
    for i in range(K, 0, -1):
        P = pow(K // i, N, M)
        j = i + i
        while j <= K:
            P -= cache[j]
            j += i
        while P < 0:
            P += M

        cache[i] = P
        ans += i * P
        ans %= M
    return ans

if __name__ == "__main__":
    N, K = tuple(map(int, input().split(" ")))
    print(solve(N, K))

Buggy python submission (verdict: Time Limit Exceeded):
import sys

sys.setrecursionlimit(1000000)

div_cache = {}
def primes(N):
    if N in div_cache:
        return div_cache[N]
    ret = set()
    for i in range(1, min(int(pow(N, 0.5) + 1), N)):
        if N % i == 0:
            ret.add(i)
            if i != 1:
                ret.add(N // i)
    div_cache[N] = ret
    return ret



def slowsolve(N, K):
    import itertools
    import math
    data = {}
    s = 0
    KK = [i for i in range(1, K + 1)]
    for p in itertools.product(KK, repeat=N):
        cdi = p[0]
        for c in p:
            cdi = math.gcd(cdi, c)
        s += cdi
        data.setdefault(cdi, 0)
        data[cdi] += 1
    print(data)
    return s


def solve(N, K):
    M = pow(10, 9) + 7
    ans = 0
    for i in range(1, K + 1):
        P = pow(K // i, N, M)
        ans += i * P

        def past(prim, sign):
            nonlocal ans
            ans += sum(prim) * P * sign
            ans %= M
            for p in prim:
                if p != 1:
                    past(primes(p), sign * -1)

        past(primes(i), -1)
        ans %= M
    return ans


if __name__ == "__main__":
    N, K = tuple(map(int, input().split(" ")))
    print(solve(N, K))


Fixed submission:
import sys

sys.setrecursionlimit(1000000)

def slowsolve(N, K):
    import itertools
    import math
    data = {}
    s = 0
    KK = [i for i in range(1, K + 1)]
    for p in itertools.product(KK, repeat=N):
        cdi = p[0]
        for c in p:
            cdi = math.gcd(cdi, c)
        s += cdi
        data.setdefault(cdi, 0)
        data[cdi] += 1
    print(data)
    return s


cache = {}
def solve(N, K):
    M = pow(10, 9) + 7
    ans = 0
    for i in range(K, 0, -1):
        P = pow(K // i, N, M)
        j = i + i
        while j <= K:
            P -= cache[j]
            j += i
        while P < 0:
            P += M

        cache[i] = P
        ans += i * P
        ans %= M
    return ans

if __name__ == "__main__":
    N, K = tuple(map(int, input().split(" ")))
    print(solve(N, K))

Buggy python submission (verdict: Time Limit Exceeded):
import sys

sys.setrecursionlimit(1000000)

div_cache = {}


def primes(N):
    if N in div_cache:
        return div_cache[N]
    ret = set()

    for i in range(1, N):
        if N % i == 0:
            ret.add(i)
            if i != 1:
                ret.add(N // i)
    div_cache[N] = ret
    return ret


# assert(primes(1) == set())
# assert(primes(2) == {1})
# assert(primes(10) == {1, 2, 5})
# assert(primes(20) == {1, 2, 4, 5, 10})

def slowsolve(N, K):
    import itertools
    import math
    data = {}
    s = 0
    KK = [i for i in range(1, K + 1)]
    for p in itertools.product(KK, repeat=N):
        cdi = p[0]
        for c in p:
            cdi = math.gcd(cdi, c)
        s += cdi
        data.setdefault(cdi, 0)
        data[cdi] += 1
    print(data)
    return s


def solve(N, K):
    M = pow(10, 9) + 7
    ans = 0
    data = {}
    for i in range(1, K + 1):
        P = pow(K // i, N, M)
        ans += i * P
        # data[i] = P

        def past(prim, sign):
            nonlocal ans
            for p in prim:
                # data[p] += P * sign
                ans += p * P * sign
                ans %= M
                if p != 1:
                    past(primes(p), sign * -1)

        past(primes(i), -1)
        ans %= M

    # print(data)
    return ans


# assert(solve(3, 2) == 9)
# assert(slowsolve(3, 2) == 9)
# assert(slowsolve(3, 3) == 30)
# assert(solve(3, 3) == slowsolve(3, 3))
# print("collect")
# print(slowsolve(2, 6))
# print("wrong")
# print(solve(2, 6))
# assert(solve(6, 6) == slowsolve(6, 6))
# assert (solve(3, 200) == 10813692)
# print("OK")
# assert (solve(100000, 100000) == 742202979)
# print("OK!!!!")

if __name__ == "__main__":
    N, K = tuple(map(int, input().split(" ")))
    print(solve(N, K))


Fixed submission:
import sys

sys.setrecursionlimit(1000000)

def slowsolve(N, K):
    import itertools
    import math
    data = {}
    s = 0
    KK = [i for i in range(1, K + 1)]
    for p in itertools.product(KK, repeat=N):
        cdi = p[0]
        for c in p:
            cdi = math.gcd(cdi, c)
        s += cdi
        data.setdefault(cdi, 0)
        data[cdi] += 1
    print(data)
    return s


cache = {}
def solve(N, K):
    M = pow(10, 9) + 7
    ans = 0
    for i in range(K, 0, -1):
        P = pow(K // i, N, M)
        j = i + i
        while j <= K:
            P -= cache[j]
            j += i
        while P < 0:
            P += M

        cache[i] = P
        ans += i * P
        ans %= M
    return ans

if __name__ == "__main__":
    N, K = tuple(map(int, input().split(" ")))
    print(solve(N, K))