unittest
{
	assert( [ "3 24" ].parse.expand.solve == 2 );
	assert( [ "5 1" ].parse.expand.solve == 1 );
	assert( [ "1 111" ].parse.expand.solve == 111 );
	assert( [ "4 972439611840" ].parse.expand.solve == 206 );
	
	assert( [ "190000000000 972439611841" ].parse.expand.solve == 1 );		// 追加ケース
}



import std.algorithm;
import std.conv;
import std.math;
import std.range;
import std.stdio;
import std.typecons;

void main()
{
	stdin.byLineCopy.parse.expand.solve.writeln;
}

auto parse( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto np = input.front.split.to!( long[] );
	return tuple( np[ 0 ], np[ 1 ] );
}

auto solve( long n, long p )
{
	// pを素因数分解して素因数ごとの個数をカウント
	auto gs = primefactorize( p ).group;
	
	// as全部に掛けられる個数の素因数があったら最大公約数を大きくできる
	auto ans = 1L;
	foreach( g; gs )
	{
		auto d = g[ 1 ] / n;
		if( 0 < d ) ans *= g[ 0 ] ^^ d;
	}
	return ans;
}

// 素数列
auto primes( long x )
{
	long[] ps;
	if( x < 2 ) return ps;
	
	auto cs = new bool[]( x + 1 );
	ps = [ 2L ];
	for( auto i = 3L; i * i < cs.length; i += 2 )
	{
		if( cs[ i ] ) continue;
		for( auto j = i; i * j < cs.length; j++ )
		{
			cs[ i * j ] = true;
		}
	}
	for( auto i = 3L; i < cs.length; i += 2 )
	{
		if( !cs[ i ] ) ps ~= i;
	}
	return ps;
}

// 素因数分解
long[] primefactorize( long x )
{
	auto s = cast( long ) sqrt( cast( float ) x ) + 1;
	return primefactorize( x, s.primes );
}

// 素因数分解（事前に作った素数列を使う）
auto primefactorize( long x, long[] ps )
{
	long[] fs;
	if( x < 2 ) return fs;
	
	foreach( p; ps )
	{
		while( x % p == 0 )
		{
			x /= p;
			fs ~= p;
		}
	}
	if( 1 < x ) fs ~= x;
	return fs;
}
