Задача на теорию чисел (python) (есть код на pascal)

Задача звучит следующим образом:

Для того чтобы проверить, как её ученики умеют считать, Мария Ивановна каждый год задаёт им на дом одну и ту же задачу — для заданного натурального A найти минимальное натуральное N такое, что N в степени N (N, умноженное на себя N раз) делится на A. От года к году и от ученика к ученику меняется только число A. Вы решили помочь будущим поколениям. Для этого вам необходимо написать программу, решающую эту задачу.

Требуется решение на Python. Есть работающий код на Pascal, но из меня знаток Паскаля, как из моей кошки бармен.

function GetSmplNums(n: integer; from: integer): List<(integer,integer)>;
begin
  Result := new List<(integer, integer)>;
  var i := from;
  repeat
    if n mod i = 0 then
    begin
      var c := 0;
      
      repeat
        c += 1;
        n := n div i;
      until n mod i <> 0;
      
      Result += (i, c);
    end;
    
    i += 1;
  until i*i > n;
  
  if n <> 1 then
    Result += (n, 1);
end;
 
begin
  var l := GetSmplNums(ReadlnInteger,2);
  var min_exp := l.Max(t->t[1]);
  var n := 1;
  foreach var t in l do
    n *= t[0];
  var res := n;
  while res < min_exp do
    res *= n;
  res.Print;
end.

Вот решение на Питоне, но оно работает слишком долго.

from sys import setrecursionlimit
setrecursionlimit(10**9)

def fast_pow(a, n):
    if n == 0:
        return 1
    elif n == 1:
        return a
    elif n % 2 != 0:
        return a * fast_pow(a, n-1)
    elif n % 2 == 0:
        return fast_pow(a*a, n/2)

def decomp(n):
    ans = []
    d = 2
    while d * d <= n:
        if n % d == 0:
            ans.append(d)
            n //= d
        else:
            d += 1
    if n > 1:
        ans.append(n)
    return ans



x = int(input())
a = list(set(decomp(x)))

y = 1
for i in a:
    y *= i

if x == 1:
    print(1)
elif a[0] != x:
    for i in range(40):
        if fast_pow(((i+1) * y), ((i+1) * y)) % x == 0:
            print((i+1) * y)
            break
else:
    print(a[0])

Ответы (2 шт):

Автор решения: Liquid

Решение нашёл. Привожу код.

def decomp(n): 
    ans = []
    d = 2
    while d * d <= n:
        if n % d == 0:
            ans.append(d)
            n //= d
        else:
            d += 1
    if n > 1:
        ans.append(n)
    return ans
 
 
 
x = int(input())
if x == 1:
    print(1)
else:
    a = list(set(decomp(x)))
    b = decomp(x) 
 
    y = 1
    for i in range(len(a)): 
        y *= a[i]
    k = 1
    n = k*y
 
    if a[0] != x:
        for i in range(40):
            t = (i+1)*y
            if pow(t, t, x) == 0:
                print((i+1) * y)
                break
    else:
        print(a[0])
→ Ссылка
Автор решения: makarus_fel

решал немного по-другому, и пока не могу найти ошибку код:

def fact(n):
   p = {}
   d = 2
   while d*d <= n:
       while n % d == 0:
           if d in p:
               p[d] += 1
           else:
               p[d] = 1
           n //= d
       d += 1
   if n > 1:
       p[n] = 1
   return p
from math import sqrt
n = int(input())
s = fact(n)
k = 1
step = [int(i) for i in s.keys()]
for i in range(len(step)):
    if s[step[i]]%2 != 0:
        s[step[i]] += 1
    k = k*(step[i]**s[step[i]])
print(int(sqrt(k)))
→ Ссылка