output_description: 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.
  
  * * *
input_description: Input is given from Standard Input in the following format:
  
      
      
      N
      S
attempt: import sys
  
  sys.setrecursionlimit(10**5 + 10)
  
  
  def input():
      return sys.stdin.readline().strip()
  
  
  def resolve():
  
      class SuffixArray:
          """
          construct:
              suffix array: O(N(logN)^2)
              lcp array: O(N)
              sparse table: O(NlogN)
          query:
              get_lcp: O(1)
          """
  
          def __init__(self, s):
              """
              s: str
              """
              self.__s = s
              self.__n = len(s)
              self.__suffix_array()
              self.__lcp_array()
              self.__sparse_table()
  
          # suffix array
          def __suffix_array(self):
              s = self.__s
              n = self.__n
              # initialize
              sa = list(range(n))
              rank = [ord(s[i]) for i in range(n)]
              tmp = [0] * n
              k = 1
  
              def cmp_key(i):
                  return (rank[i], rank[i + k] if i + k < n else -1)
  
              # iterate
              while k <= n:
                  sa.sort(key=cmp_key)
                  tmp[sa[0]] = 0
                  for i in range(1, n):
                      tmp[sa[i]] = tmp[sa[i - 1]] + (cmp_key(sa[i - 1]) < cmp_key(sa[i]))
                  rank = tmp[:]
                  k <<= 1
              self.__sa = sa
              self.__rank = rank
  
          # LCP array
          def __lcp_array(self):
              n = self.__n
              s = self.__s
              sa = self.__sa
              rank = self.__rank
              lcp = [0] * n
              h = 0
              for i in range(n):
                  j = sa[rank[i] - 1]
                  if h > 0:
                      h -= 1
                  while j + h < n and i + h < n and s[j + h] == s[i + h]:
                      h += 1
                  lcp[rank[i]] = h
              self.__lcp = lcp
  
          # sparse table (LCPのminをとるindexを持つ)
          def __sparse_table(self):
              n = self.__n
              logn = max(0, (n - 1).bit_length())
              table = [[0] * n for _ in range(logn)]
              table[0] = list(range(n))
              # construct
              for i in range(1, logn):
                  for k in range(n):
                      if k + (1 << (i - 1)) >= n:
                          table[i][k] = table[i - 1][k]
                          continue
                      if (
                          self.__lcp[table[i - 1][k]]
                          <= self.__lcp[table[i - 1][k + (1 << (i - 1))]]
                      ):
                          table[i][k] = table[i - 1][k]
                      else:
                          table[i][k] = table[i - 1][k + (1 << (i - 1))]
              self.__table = table
  
          def get_lcp(self, a, b):
              """
              a,b: int 0<=a,b<n
              return LCP length between s[a:] and s[b:]
              """
              if a == b:
                  return self.__n - a
              l, r = self.__rank[a], self.__rank[b]
              l, r = min(l, r) + 1, max(l, r) + 1
              if r - l == 1:
                  return self.__lcp[l]
              i = (r - l - 1).bit_length() - 1
              if (
                  self.__lcp[self.__table[i][l]]
                  <= self.__lcp[self.__table[i][r - (1 << i)]]
              ):
                  return self.__lcp[self.__table[i][l]]
              else:
                  return self.__lcp[self.__table[i][r - (1 << i)]]
  
      n = int(input())
      s = input()
      sa = SuffixArray(s)
      ans = 0
      for i in range(n):
          for j in range(i + 1, n):
              ans = max(ans, min(sa.get_lcp(i, j), j - i))
      print(ans)
  
  
  resolve()
  
problem_description: 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.
samples: [{"input": "5\n    ababa", "output": "2\n    \n\nThe strings satisfying the conditions are: `a`, `b`, `ab`, and `ba`. The\nmaximum length among them is 2, which is the answer. Note that `aba` occurs\ntwice in S as contiguous substrings, but there is no pair of integers l_1 and\nl_2 mentioned in the statement such that l_1 + len \\leq l_2.\n\n* * *"}, {"input": "2\n    xy", "output": "0\n    \n\nNo non-empty string satisfies the conditions.\n\n* * *"}, {"input": "13\n    strangeorange", "output": "5"}]