unittest
{
	assert( [ "5", "ababa" ].solve == 2 );
	assert( [ "2", "xy" ].solve == 0 );
	assert( [ "13", "strangeorange" ].solve == 5 );
}



import std.algorithm;
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 );
	input.popFront;
	auto s = input.front.to!( dchar[] );
	
	auto ans = 0L;
	foreach( i; 0L .. n )
	{
		foreach( j, z; z_algorithm( s[ i .. $ ] ) )
		{
			ans = max( ans, min( j, z ) );
		}
	}
	return ans;
}

// 最長共通接頭辞の長さ（s[ 0 .. l ] == s[ b .. b+l ] が成り立つbごとのlの最大値）
auto z_algorithm( dchar[] s )
{
	auto zs = new long[ s.length ];
	zs[ 0 ] = s.length;
	for( auto b = 1L, l = 0L; b < s.length; /* nop */ )
	{
		while( b + l < s.length && s[ l ] == s[ b + l ] ) l++;
		zs[ b ] = l;
		if( l == 0 )
		{
			b++;
			continue;
		}
		
		auto c = 1L;
		while( b + c < s.length && zs[ c ] + c < l )
		{
			zs[ b + c ] = zs[ c ];
			c++;
		}
		b += c;
		l -= c;
	}
	return zs;
}
