#include #include #include #include #include #include #include using namespace std; const int P1 = 10007; const int P2 = 10009; const int MAXLEN = 100100; char A[ MAXLEN ]; int alen; char B[ MAXLEN ]; int blen; vector< pair< long long, long long > > AH; vector< pair< long long, long long > > BH; struct hasher { int prime, len; long long sum, front_factor; hasher( int _p, int _len ) : prime( _p ), len( _len ) { front_factor = 1; for( int i = 1; i < len; ++i ) front_factor *= prime; sum = 0; } void push_back( char c ) { sum = sum*prime + c; } void pop_front( char c ) { sum -= front_factor*c; } long long output() { return sum; } }; void populate( vector< pair< long long, long long > > &V, char *S, int len, int mid ) { hasher H1( P1, mid ); hasher H2( P2, mid ); for( int i = 0; i < mid-1; ++i ) { H1.push_back( S[i] ); H2.push_back( S[i] ); } V.clear(); V.reserve( len ); for( int i = mid-1; i < len; ++i ) { H1.push_back( S[i] ); H2.push_back( S[i] ); V.push_back( make_pair( H1.output(), H2.output() ) ); H1.pop_front( S[i-mid+1] ); H2.pop_front( S[i-mid+1] ); } } int bs_cmpf( int mid ) { populate( AH, A, alen, mid ); populate( BH, B, blen, mid ); sort( AH.begin(), AH.end() ); sort( BH.begin(), BH.end() ); int b = 0; for( int i = 0; i < ( int )AH.size(); ++i ) { while( b < ( int )BH.size() && BH[b] < AH[i] ) ++b; if( b < ( int )BH.size() && AH[i] == BH[b] ) return true; } return false; } int main( void ) { gets( A ); alen = strlen( A ); gets( B ); blen = strlen( B ); int l = 0, r = min( alen, blen ); while( l < r ) { int mid = ( l + r + 1 ) / 2; if( bs_cmpf( mid ) ) l = mid; else r = mid - 1; } printf( "%d\n", l ); return (0-0); }