unittest
{
	assert( [ "10" ].solve == 170 );		// 追加ケース
	
	assert( [ "4" ].solve == 23 );
	assert( [ "100" ].solve == 26879 );
	assert( [ "10000000" ].solve == 838627288460105 );
}



import std.conv;
import std.range;
import std.stdio;

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

auto solve( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto n = input.front.to!( long );
	
	// 素数の組み合わせで2からnまでを列挙
	auto ans = 1L;		// 1の約数の個数
	auto ds = new long[ 1 + n ];
	ds[ 1 ] = 1;
	foreach( p; n.primes )
	{
		foreach_reverse( long x, d; ds[ 0 .. n / p + 1 ] )
		{
			if( d == 0 ) continue;
			for( auto y = 1L; x * p ^^ y <= n; y++ )
			{
				// kの約数の個数は組み合わせた各素数の乗数の掛け算で計算できる
				auto k = x * p ^^ y;
				auto f = d * ( y + 1 );
				ds[ k ] = f;
				ans += k * f;
			}
		}
	}
	return ans;
}

// 素数列
auto primes( long x )
{
	Appender!( long[] ) ps;
	if( x < 2 ) return ps.data;
	
	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.data;
}
