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 LuaJIT (2.0.4) (judge verdict: Time Limit Exceeded)

local n = io.read("*n", "*l")
local s = io.read()
local mfl = math.floor
local maxlen = mfl(n / 2)
local found = false
local bt = {}
for i = 1, n do
  bt[i] = s:sub(i, i):byte() - 97
end

local function solve(len)
  local hlen = mfl(len / 2)
  local map = {}
  local hash = {}
  local tmap = {}
  local thash = {}
  for k = 1, n - len + 1 do
    tmap[k] = s:sub(k, k + len - 1)
    if 6 <= len then
      thash[k] = bt[k]
        + bt[k + 1] * 30
        + bt[k + hlen] * 900
        + bt[k + hlen + 1] * 27000
        + bt[k + len - 2] * 810000
        + bt[k + len - 1] * 24300000
    end
  end
  if 6 <= len then
    for pos = n - len, len, -1 do
      map[tmap[pos + 1]] = true
      hash[thash[pos + 1]] = true
      if hash[thash[pos + 1 - len]] and map[tmap[pos + 1 - len]] then
        return true
      end
    end
  else
    for pos = n - len, len, -1 do
      map[tmap[pos + 1]] = true
      if map[tmap[pos + 1 - len]] then
        return true
      end
    end
  end
  return false
end
if not solve(1) then
  print(0)
else
  local lmin, lmax = 1, maxlen + 1
  while 1 < lmax - lmin do
    local len = mfl((lmax + lmin) / 2)
    if solve(len) then
      lmin = len
    else
      lmax = len
    end
  end
  print(lmin)
end