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# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Text;
using System.Collections.Generic;
using static System.Math;
using System.Linq;
using static System.Array;

namespace ConsoleApp2
{
    class Program
    {
        static long N;
        static long[] zurashi;
        static string S;
        static void Main(string[] args)
        {
            //var NK = Console.ReadLine().Split(' ').Select(x => int.Parse(x)).ToArray();
            N = long.Parse(Console.ReadLine());
            S = Console.ReadLine();

            var ans = 0L;
            var r = 0;
            var ln = 0L;


            for (int l = 0; l < N; l++)
            {
                MakeZurashi(l);
                ln = l;
                var a = 0L;
                r = l + 1;
                var r0 = r;
                for (; r < N; r++)
                {
                    
                    if (ln >= r0)
                    {
                        ans = Max(ans, a);
                        a = 0;
                        ln = l;
                        r0 = r+1;
                        r--;
                        continue;
                    }

                    if(S[(int)ln] != S[r])
                    {
                        ans = Max(ans, a);
                        a = zurashi[a];
                        ln = l + a;
                        
                        r0 = r + 1;
                        if (a > 0)
                        {
                            r0 = r;
                            r--;
                        }
                    }
                    else
                    {
                        ln++;
                        a++;
                        ans = Max(ans, a);
                    }
                }
            }
            Console.WriteLine(ans);
        }

        static void MakeZurashi(int i)
        {
            var len = (N-1)-i+1;
            zurashi = new long[len];
            var count = 0;

            for (int j = 1; j < len; j++)
            {
                if (S[count] == S[j])
                {
                    zurashi[j] = count++;
                }
                else
                {
                    zurashi[j] = count;
                    count = 0;
                }
            }
        }
    }

    class Node
    {
        public List<long> adj;
        public long one = 0;
        public long sec = 0;

        public Node()
        {
            adj = new List<long>();
        }

        public void AddAdj(long node)
        {
            adj.Add(node);
        }
    }
}