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 Haskell (GHC 7.10.3) (judge verdict: Time Limit Exceeded)

{-# LANGUAGE BangPatterns #-}
import           Control.Monad
import qualified Control.Monad.ST            as ST
import           Data.Array.IO
import           Data.Bits
import qualified Data.ByteString.Char8       as BS
import           Data.Char
import           Data.Maybe
import qualified Data.Vector.Unboxed         as V
import qualified Data.Vector.Unboxed.Mutable as VM

rollingHash :: BS.ByteString -> Int -> (V.Vector Word, V.Vector Word)
rollingHash s b = ST.runST $ do
  let sz = BS.length s
      b' = fromIntegral b
  h <- VM.new (sz+1)
  VM.write h 0 (0::Word)
  power <- VM.new (sz+1)
  VM.write power 0 (1::Word)
  forM_ [0..(sz-1)] $ \i -> do
    powi <- VM.read power i
    VM.write power (i+1) (powi * b')
    hi <- VM.read h i
    let si = fromIntegral $ ord $ BS.index s i
    VM.write h (i+1) (hi * b' + si)
  h' <- V.freeze h
  power' <- V.freeze power
  return (h', power')

getRH :: (V.Vector Word, V.Vector Word) -> Int -> Int -> Word
getRH (h, power) l r = hr - pr_1 * hl
  where hr = h V.! r
        pr_1 = power V.! (r-l)
        hl = h V.! l

bisectRight :: Ord a => (Int -> a) -> a -> Int -> Int -> Int
bisectRight f x lo hi
  | lo >= hi  = lo
  | x < f mid = bisectRight f x lo mid
  | otherwise = bisectRight f x (mid+1) hi
  where
    mid = lo + (hi - lo) `div` 2

readInt = fst . fromJust . BS.readInt
getInt = readInt <$> BS.getLine

main = do
  n <- getInt
  s <- BS.getLine

  let rh1 = rollingHash s 100000007
      rh2 = rollingHash s 10007
      check k =
        V.or $ V.map (\ !i ->
                     let hi1 = getRH rh1 i (i+k)
                         hi2 = getRH rh2 i (i+k)
                         f = (\ !j -> (hi1 == getRH rh1 j (j+k) &&
                                       hi2 == getRH rh2 j (j+k)))
                     in
                       V.or $ V.map f (V.fromList [(i+k)..(n-k)]))
                  (V.fromList [0..(n-2*k)])
      ans = bisectRight (not . check) False 0 (n `div` 2 + 1) - 1

  print ans