unittest
{
	assert( [ "2", "tourist", "petr", "e" ].parse.expand.solve == "1" );
	assert( [ "2", "?o?r?s?", "?et?", "e" ].parse.expand.solve == "1 2 3" );
	assert( [ "4", "e", "e", "e", "e", "e" ].parse.expand.solve == "1 2 3 4 5" );
	assert( [ "5", "??", "??", "d?", "?e", "?f", "zzz" ].parse.expand.solve == "6" );
	assert( [ "7", "atcoder", "topcoder", "codeforces", "hackerrank", "csacademy", "codechef", "atcoder", "square" ].parse.expand.solve == "7" );
	assert( [ "7", "??i?", "?o???g????", "??m??x?", "?h?????i", "s????", "?og????", "u??", "square" ].parse.expand.solve == "1 2 3 4 5 6 7" );

	assert( [ "2", "?cc", "??", "aa" ].parse.expand.solve == "1 2" );		// 追加ケース
	assert( [ "3", "??c", "aaa", "aad", "aac" ].parse.expand.solve == "2 3" );		// 追加ケース
}



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.to!( long );
	auto ss = new dchar[][ n ];
	foreach( ref s; ss )
	{
		input.popFront;
		s = input.front.to!( dchar[] );
	}
	input.popFront;
	auto t = input.front.to!( dchar[] );
	return tuple( ss, t );
}

auto solve( dchar[][] ss, dchar[] t )
{
	auto us = ss.sort!( ( a, b ) => b < a ).find!( ( a, b ) => a <= b )( t ).array;
	foreach_reverse( i, u; us )
	{
		if( t < u.replace( "?", "a" ) ) us = us[ 0 .. i ] ~ us[ i + 1 .. $ ];
	}
	
	auto anss = [ us.length.signed + 1 ];
	foreach( u; us )
	{
		if( t <= u.replace( "?", "z" ) ) anss ~= anss[ $ - 1 ] - 1;
	}
	return anss.retro.map!( to!string ).join( " " );
}
