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 thash = {}
if 6 <= n then
  thash[1]
    = bt[1]
    + bt[2] * 30
    + bt[3] * 900
    + bt[4] * 27000
    + bt[5] * 810000
    + bt[6] * 24300000
  for k = 2, n - 5 do
    thash[k] = mfl(thash[k - 1] / 30) + bt[k + 5] * 24300000
  end
end

local function solve(len)
  if 6 <= len then
    local hlen = mfl(len / 2)
    local map = {}
    local tmplen = len
    local hash = {}
    local tmap = {}
    for k = 1, n - len + 1 do
      tmap[k] = s:sub(k, k + len - 1)
    end
    local taskpos = n - len + 1
    for pos = n - len, len, -1 do
      hash[thash[pos + len - 5]] = true
      if hash[thash[pos - 5]] then
        for tmp = pos + 1, taskpos do
          map[tmap[tmp]] = true
        end
        taskpos = pos
        if map[tmap[pos + 1 - len]] then
          return true
        end
      end
    end
  else
    local map = {}
    local tmap = {}
    for k = 1, n - len + 1 do
      tmap[k] = s:sub(k, k + len - 1)
    end
    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
  local nextnt = false
  while 1 < lmax - lmin do
    local len = mfl((lmax + lmin) / 2)
    if nextnt and 8 < lmax - lmin then
      len = mfl((lmax + 7 * lmin) / 8)
      nextnt = false
    end
    if solve(len) then
      lmin = len
    else
      lmax = len
      nextnt = true
    end
  end
  print(lmin)
end