Problem:
Score : 500 points

Problem Statement

Given is a string S of length N.

Find the maximum length of a non-empty string that occurs twice or more in S as contiguous substrings without overlapping.

More formally, find the maximum positive integer len such that there exist integers l_1 and l_2 ( 1 \leq l_1, l_2 \leq N - len + 1 ) that satisfy the following:

l_1 + len \leq l_2

S[l_1+i] = S[l_2+i] (i = 0, 1, ..., len - 1)

If there is no such integer len, print 0.

Constraints

2 \leq N \leq 5 \times 10^3

|S| = N

S consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

N
S

Output

Print the maximum length of a non-empty string that occurs twice or more in S as contiguous substrings without overlapping. If there is no such non-empty string, print 0 instead.

Sample Input 1

5
ababa

Sample Output 1

2

The strings satisfying the conditions are: a, b, ab, and ba. The maximum length among them is 2, which is the answer.
Note that aba occurs twice in S as contiguous substrings, but there is no pair of integers l_1 and l_2 mentioned in the statement such that l_1 + len \leq l_2.

Sample Input 2

2
xy

Sample Output 2

0

No non-empty string satisfies the conditions.

Sample Input 3

13
strangeorange

Sample Output 3

5

Solution in C (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define ll long long
#define rep(i,l,r)for(ll i=(l);i<(r);i++)
#define repp(i,l,r,k)for(ll i=(l);i<(r);i+=(k))
#define INF ((1LL<<62)-(1LL<<31))
#define max(p,q)((p)>(q)?(p):(q))
#define min(p,q)((p)<(q)?(p):(q))
#define bit(n,m)(((n)>>(m))&1)
int upll(const void*a, const void*b){return*(ll*)a<*(ll*)b?-1:*(ll*)a>*(ll*)b?1:0;}
int downll(const void*a, const void*b){return*(ll*)a<*(ll*)b?1:*(ll*)a>*(ll*)b?-1:0;}
void sortup(ll*a,int n){qsort(a,n,sizeof(ll),upll);}
void sortdown(ll*a,int n){qsort(a,n,sizeof(ll),downll);}
ll pom(ll a,ll n,int m){ll x=1;for(a%=m;n;n/=2)n&1?x=x*a%m:0,a=a*a%m;return x;}
//#define MOD 998244353
#define invp(a,p)pom(a,p-2,p)


int n;
char s[5010];
ll atai[5010];
int idx[5010];
int c(const void*p,const void*q){
	if(atai[*(int*)p]<atai[*(int*)q])return -1;
	if(atai[*(int*)p]>atai[*(int*)q])return 1;
	if(*(int*)p<*(int*)q)return -1;
	return 1;
}

int f(int m,int g,int MOD){
	ll ue=pom(g,m,MOD);
	ll has=0;
	rep(i,0,m)has=(has*g+s[i])%MOD;
	rep(i,m,n+1){
		atai[i-m]=has;
		has=(has*g+s[i])%MOD;
		has=((has-s[i-m]*ue)%MOD+MOD)%MOD;
	}
	
	rep(i,0,n-m+1)idx[i]=i;
	qsort(idx,n-m+1,sizeof(int),c);
//	printf("%d:",m);
//	rep(i,0,n-m+1)printf("%d ",atai[idx[i]]);puts("");
		
	int flag=0;

	rep(i,0,n-m+1){
		int t=i;
		while(t+1<n-m+1&&atai[idx[i]]==atai[idx[t+1]])t++;
		if(idx[i]+m<=idx[t]){
			flag=1;
			break;
		}
		i=t;
	}
	return flag;
}

int main(){
	scanf("%d %s",&n,s);
	int l=0,r=n;//lはok,rはng
	while(r-l>1){
		int m=(l+r)/2;
		if(f(m,3,1000000007)&&f(m,7,1000000021))l=m;
		else r=m;
	}
	printf("%d",l);
}