unittest
{
	assert( [ "1 3 2" ].parse.expand.solve == 1 );
	assert( [ "1 3 1" ].parse.expand.solve == 2 );
	assert( [ "2 3 3" ].parse.expand.solve == 1 );
	assert( [ "2 3 1" ].parse.expand.solve == 5 );
	assert( [ "7 1 1" ].parse.expand.solve == 1 );
	assert( [ "15 8 5" ].parse.expand.solve == 437760187 );
}



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

auto solve( long h, long w, long k )
{
	// dp[ 上からy段目 ][ 右からx本目 ] = 辿り着くパターン数 を計算
	auto dp = new long[][]( 1 + h, w );
	dp[ 0 ][ 0 ] = 1;
	auto bm = 1L << ( w - 1 );
	for( auto y = 0L; y < h; y++ )
	{
		// 横棒のパターンを全列挙
		for( auto b = 0L; b < bm; b++ )
		{
			if( !b.validate ) continue;
			for( auto x = 0L; x < w; x++ )
			{
				if( b & ( 1L << x ) )
				{
					// 横棒で繋がっている場合
					dp[ y + 1 ][ x     ] = dp[ y + 1 ][ x     ].addMod( dp[ y ][ x + 1 ] );
					dp[ y + 1 ][ x + 1 ] = dp[ y + 1 ][ x + 1 ].addMod( dp[ y ][ x     ] );
					x++;		// 次も計算済なのでスキップする
				}
				else
				{
					// 横棒で繋がっていない場合
					dp[ y + 1 ][ x ] = dp[ y + 1 ][ x ].addMod( dp[ y ][ x ] );
				}
			}
		}
	}
	return dp[ $ - 1 ][ k - 1 ];
}

// 横棒の引き方が正しいか判定
bool validate( long b )
{
	auto memo = [ 0L:true, 1L:true ];
	if( b !in memo ) memo[ b ] = ( ( b & 3 ) != 3 && ( b >> 1 ).validate );
	return memo[ b ];
}

// 足し算
auto addMod( long MOD = 10L ^^ 9 + 7 )( long x, long y )
{
	return ( x + y ) % MOD;
}
