unittest
{
	assert( [ "atcoder" ].parse.expand.solve == "atcoderb" );
	assert( [ "abc" ].parse.expand.solve == "abcd" );
	assert( [ "zyxwvutsrqponmlkjihgfedcba" ].parse.expand.solve == "-1" );
	assert( [ "abcdefghijklmnopqrstuvwzyx" ].parse.expand.solve == "abcdefghijklmnopqrstuvx" );
}



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 s = input.front.to!( dchar[] );
	return tuple( s );
}

auto solve( dchar[] s )
{
writefln( "\nsolve( %s )", s );
	// 辞書順最後のやつなので次は無い
	if( s == "zyxwvutsrqponmlkjihgfedcba" ) return "-1";
	
	auto us = new bool[]( 'z' + 1 );
	if( s.length < 26 )
	{
		// 26文字未満なら使われている文字の中で一番小さいやつをくっつける
		foreach( c; s ) us[ c ] = true;
		for( auto c = 'a'; c < us.length; c++ )
		{
			if( !us[ c ] ) return ( s ~ c ).to!string;
		}
	}
	else
	{
		// 26文字なら末尾から切り取っていって、末尾より切り取った文字のどれかのほうが大きくなったときに文字を入れ替える
		us[] = true;
		foreach_reverse( i, cf; s )
		{
			for( auto ct = cf + 1; ct < us.length; ct++ )
			{
				if( !us[ ct ] ) return ( s[ 0 .. i ] ~ ct ).to!string;
			}
			us[ cf ] = false;
		}
	}
	return s.to!string;
}
