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 C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class Program
{
    static void Main(string[] args)
    {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            // 準備
            // 1兆までの値の素因数分解なので 2 から 999983 までの素数(√1兆 = 1000000なので)が判明していれば素因数分解が出来る
            // 2から999983まので素数取得
            // 2から999983まので素数取得する為には2から997までの素数(√999983 = 999.9915なので)が判明していればOK
            int iRng = 999983;                                                                   // 調査範囲 999983まで
            List<int> lstPrm = new List<int>() { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997 };
            GetPrim(ref lstPrm, iRng);
            //DebugDip2(sw);

            // 入力
            string[] sS = System.Console.ReadLine().Trim().Split(' ');
            long iN = long.Parse(sS[0]);
            long iP = long.Parse(sS[1]);

            // 解析
            int iOut = 1;                                               // 最大公約数
            List<int> lstFct = new List<int>();                         // 素因数分解した結果格納用
            GetFact(lstFct, lstPrm, iP);                                // 素因数分解実行
            //DebugDisp(lstFct);
            if (lstFct.Count == 0) { }                                  // 素因数分解出来なかった→素数なので最大公約数は1
            else
            {
                List<ClsFct> lstRet = new List<ClsFct>();               // 素因数を素数別に分解
                for (int i = 0; i < lstFct.Count; i++)
                {
                    if (lstRet.Count == 0) { lstRet.Add(new ClsFct() { iP = lstFct[i], iC = 1 }); }
                    else
                    {
                        if (lstRet[lstRet.Count - 1].iP == lstFct[i]) { lstRet[lstRet.Count - 1].iC += 1; }
                        else { lstRet.Add(new ClsFct() { iP = lstFct[i], iC = 1 }); }
                    }
                }
                for (int i = 0; i < lstRet.Count; i++)
                {
                    if (lstRet[i].iC >= iN) { iOut *= (int)Math.Pow(lstRet[i].iP, (int)(lstRet[i].iC / iN)); }   // その素数がiNだけあれば最大公約数になりえる
                }
            }

            // 出力
            System.Console.WriteLine("{0}", iOut.ToString().Trim());

            sw.Stop();
#if DEBUG
            Console.WriteLine();
            Console.WriteLine("{0}", sw.Elapsed.ToString());
            Console.WriteLine("続行するには何かキーを押してください．．．");
            Console.ReadKey();
#endif
    }

        // Debug表示
        private static void DebugDip2(System.Diagnostics.Stopwatch sw)
        {
            sw.Stop();
            Console.WriteLine("{0}", sw.Elapsed.ToString());
            sw.Restart();
        }

        // Debug表示
        private static void DebugDisp(List<int> lstFct)
        {
            string sOut = "";
            for (int i = 0; i < lstFct.Count; i++)
            {
                sOut += lstFct[i].ToString() + " ";
            }
            Console.WriteLine("{0}", sOut.ToString());
        }

        // 素数算出
        private static void GetPrim(ref List<int> lstPrm, int iRng)
        {
            // 調査対象定義
            List<Boolean> lstTag = new List<Boolean>();                                         // 配列(true:素数 false:合成)
            for (int i = 0; i <= iRng / 2; i += 1) { lstTag.Add(false); lstTag.Add(true); }     // 予め 2の倍数は false にしておく

            // 調査
            lstTag[1] = false;                                                                  // 1は除外
            lstTag[2] = true;                                                                   // 2は素数
            for (int i = 1; i < lstPrm.Count; i++)                                              // 調査素数 2は除外しているので3から
            {
                int iMtS = 2;                                                                   // 例 3では100000000
                int iMtE = iRng / lstPrm[i];                                                    // 例 3では133333333
                for (int j = iMtS; j <= iMtE; j++)
                {
                    int iTmp = (int)(lstPrm[i] * j);
                    if (iTmp >= 0 && iTmp <= iRng) { lstTag[iTmp] = false; }
                }
            }
            // 結果
            List<int> lstNew = new List<int>();
            for (int i = 0; i < lstTag.Count; i++) { if (lstTag[i]) { lstNew.Add(i); } }
            lstPrm = lstNew;
        }

        // 素因数分解
        private static void GetFact(List<int> lstFct, List<int> lstPrm, long iN)
        {
            for (int i = 0; i < lstPrm.Count; i++)
            {
                if (iN < lstPrm[i]) { break; }
                while (true)
                {
                    if (iN % lstPrm[i] == 0)
                    {
                        lstFct.Add(lstPrm[i]);
                        iN = iN / lstPrm[i];
                    }
                    else { break; }
                }
            }
        }

        // 素因数分解結果
        private class ClsFct
        {
            public int iP { get; set; } = 0;                    // 素数
            public int iC { get; set; } = 0;                    // 数
        }

}