unittest
{
	assert( [ "100", "1" ].parse.expand.solve == 19 );
	assert( [ "25", "2" ].parse.expand.solve == 14 );
	assert( [ "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "3" ].parse.expand.solve == 117879300 );
	
	assert( [ "99", "3" ].parse.expand.solve == 0 );		// 追加ケース
}



import std.algorithm;
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 n = input.front.map!( ( a ) => ( a - '0' ).to!( long ) ).array;
	input.popFront;
	auto k = input.front.to!( long );
	return tuple( n, k );
}

auto solve( long[] n, long k )
{
	// dp[ i桁目 ][ 0でない数字の数 ][ n未満フラグ ] = 条件を満たす整数の個数
	auto dp = new long[][][]( 1 + n.length, 1 + k + 1, 2 );
	dp[ 0 ][ 0 ][ 0 ] = 1;
	foreach( i; 0L .. dp.length.signed - 1 )
	{
		foreach( j; 0L .. dp[ i ].length.signed - 1 )
		{
			// n未満じゃないとき
			if( n[ i ] == 0 )
			{
				dp[ i + 1 ][ j     ][ 0 ] += dp[ i ][ j ][ 0 ];						// i桁目を 0 にしたとき
			}
			else
			{
				dp[ i + 1 ][ j + 1 ][ 0 ] += dp[ i ][ j ][ 0 ];						// i桁目を n[i] にしたとき
				dp[ i + 1 ][ j + 1 ][ 1 ] += dp[ i ][ j ][ 0 ] * ( n[ i ] - 1 );	// i桁目を 1 ~ n[i]-1 にしたとき
				dp[ i + 1 ][ j     ][ 1 ] += dp[ i ][ j ][ 0 ];						// i桁目を 0 にしたとき
			}
			
			// n未満のとき
			dp[ i + 1 ][ j + 1 ][ 1 ] += dp[ i ][ j ][ 1 ] * 9;		// i桁目を 1 ~ 9 にしたとき
			dp[ i + 1 ][ j     ][ 1 ] += dp[ i ][ j ][ 1 ];			// i桁目を 0 にしたとき
		}
	}
	return dp[ $ - 1 ][ k ].sum;
}
