Problem:
Score : 300 points

Problem Statement

There are N integers a_1, a_2, ..., a_N not less than 1.
The values of a_1, a_2, ..., a_N are not known, but it is known that a_1 \times a_2 \times ... \times a_N = P.

Find the maximum possible greatest common divisor of a_1, a_2, ..., a_N.

Constraints

1 \leq N \leq 10^{12}

1 \leq P \leq 10^{12}

Input

Input is given from Standard Input in the following format:

N P

Output

Print the answer.

Sample Input 1

3 24

Sample Output 1

2

The greatest common divisor would be 2 when, for example, a_1=2, a_2=6 and a_3=2.

Sample Input 2

5 1

Sample Output 2

1

As a_i are positive integers, the only possible case is a_1 = a_2 = a_3 = a_4 = a_5 = 1.

Sample Input 3

1 111

Sample Output 3

111

Sample Input 4

4 972439611840

Sample Output 4

206

Solution in Rust (1.42.0) (judge verdict: Accepted)

use std::convert::TryInto;
use proconio::input;
use num::{pow, One};
use std::ops::{Div, MulAssign, Sub};

fn main() {
    input! {
        n: usize,
        p: usize
    }
    
    let vec = factor(p);

    let ans = {
        let mut ans = 1;
        for &(q,k) in &vec {
            ans *= q.pow(((k/n) as u32).try_into().unwrap());
        }
        ans
    };

    println!("{}",ans)

}

/// Make bool table by using Sieve of Eratosthenes
pub fn sieve(n: usize) -> Vec<bool> {
    let mut tbl = vec![true; n];
    tbl[0] = false;
    tbl[1] = false;
    for i in 2..n {
        if tbl[i] {
            let mut j = i + i;
            while j < n {
                tbl[j] = false;
                j += i;
            }
        }
    }
    tbl
}


/// Returns all primes less than `n`
pub fn primes(n: usize) -> Vec<usize> {
    let mut tbl = vec![true; n];
    let mut ps = vec![];
    tbl[0] = false;
    tbl[1] = false;
    for i in 2..n {
        if tbl[i] {
            ps.push(i);
            let mut j = i + i;
            while j < n {
                tbl[j] = false;
                j += i;
            }
        }
    }
    ps
}


/// Prime factorization
pub fn factor(n: usize) -> Vec<(usize, usize)> {
    let mut n = n;
    let mut ret = vec![];
    let ps = primes((n as f64).sqrt() as usize + 2);
    for p in ps {
        let mut cnt = 0;
        while n % p == 0 {
            n /= p;
            cnt += 1;
        }
        if cnt > 0 {
            ret.push((p, cnt));
        }
    }
    if n > 1 {
        ret.push((n, 1));
    }
    ret
}


/// Number of divisors
pub fn num_of_divisors(factors: &[(usize, usize)]) -> usize {
    factors.iter().map(|r| r.1 + 1).product()
}



/// Sum of divisors
pub fn sum_of_divisors<
    T: From<usize> + Sub<Output = T> + Div<Output = T> + MulAssign + One<Output = T> + Clone,
>(
    factors: &[(usize, usize)],
) -> T {
    let mut ret = T::from(1_usize);
    for &(p, n) in factors {
        ret *= (pow(T::from(p), n + 1) - T::from(1_usize)) / T::from(p - 1);
    }
    ret
}


/// Returns all divisors of `n`
pub fn divisors(n: usize) -> Vec<usize> {
    let fs = factor(n);
    let mut ret = vec![];
    gen_divisors(&fs[..], 1, &mut ret);
    ret
}

fn gen_divisors(s: &[(usize, usize)], cur: usize, ret: &mut Vec<usize>) {
    if s.is_empty() {
        ret.push(cur);
        return;
    }

    let mut cur = cur;
    for _ in 0..=s[0].1 {
        gen_divisors(&s[1..], cur, ret);
        cur = cur.wrapping_mul(s[0].0);
    }
}