unittest
{
	assert( [ "3 2" ].parse.expand.solve == 9 );
	assert( [ "3 200" ].parse.expand.solve == 10813692 );
	assert( [ "100000 100000" ].parse.expand.solve == 742202979 );
}



import std.conv;
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 nk = input.front.split.to!( long[] );
	return tuple( nk[ 0 ], nk[ 1 ] );
}

auto solve( long n, long k )
{
	const M = 10L ^^ 9 + 7;
	
	// 最大公約数がdになるパターン数を計算
	auto ans = ModWorld!M( 0 );
	auto ps = new ModWorld!M[ k ];
	foreach_reverse( i, ref p; ps )
	{
		// 最大公約数がdになるには全要素がdの倍数であることが必要
		auto d = i + 1;
		p = ModWorld!M( k / d ) ^^ n;
		
		// 倍数パターンのうち、最大公約数がdの2倍以上になるものは除外
		for( auto j = i + d; j < k; j += d )
		{
			p -= ps[ j ];
		}
		ans += d * p;
	}
	return ans;
}

// モジュラ整数型（n mod M）
struct ModWorld( long M )
{
	long n;
	
	// 演算子オーバーロード
	void opUnary( string OP )() if( OP == "++" ){ this.n = ( this.n + 1 ) % M; }
	void opUnary( string OP )() if( OP == "--" ){ this.n = ( this.n + M - 1 ) % M; }
	void opOpAssign( string OP )( ModWorld r ) if( OP == "+"  ){ this.n = ( this.n + r.n ) % M; }
	void opOpAssign( string OP )( ModWorld r ) if( OP == "-"  ){ this.n = ( this.n + M - r.n ) % M; }
	void opOpAssign( string OP )( ModWorld r ) if( OP == "*"  ){ this.n = ( this.n * r.n ) % M; }
	void opOpAssign( string OP )( ModWorld r ) if( OP == "/"  ){ this *= r ^^ ModWorld( M - 2 ); }
	void opOpAssign( string OP )( ModWorld r ) if( OP == "^^" )
	{
		auto a = this.n;
		this.n = 1L;
		for( auto i = r.n; 0 < i; i >>= 1 )
		{
			if( i & 1 ) this.n = this.n * a % M;
			a = a ^^ 2 % M;
		}
	}
	auto opBinary( string OP )( ModWorld r )
	{
		auto t = this;
		t.opOpAssign!OP( r );
		return t;
	}
	
	// long型対応
	void opAssign( long r ){ this.n = r; }
	void opOpAssign( string OP )( long r ){ this.opOpAssign!OP( ModWorld( r ) ); }
	auto opBinary( string OP )( long r ){ return this.opBinary!OP( ModWorld( r ) ); }
	auto opBinaryRight( string OP )( long l ){ return ModWorld( l ).opBinary!OP( this ); }
	auto opEquals( long r ){ return this.n == r; }
	
	// format用出力
	string toString()
	{
		return this.n.to!string;
	}
}
