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 Common Lisp (SBCL 1.1.14) (judge verdict: Time Limit Exceeded)

;; -*- coding: utf-8 -*-
(eval-when (:compile-toplevel :load-toplevel :execute)
  (sb-int:defconstant-eqx OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0))
    #'equal)
  #+swank (ql:quickload '(:cl-debug-print :fiveam) :silent t)
  #-swank (set-dispatch-macro-character
           #\# #\> (lambda (s c p) (declare (ignore c p)) (read s nil nil t))))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(declaim (inline read-line-into))
(defun read-line-into (buffer-string &key (in *standard-input*) (term-char #\Space))
  "Receives ASCII inputs and returns multiple values: the string and the end
position.

This function calls READ-BYTE to read characters though it calls READ-CHAR
instead on SLIME because SLIME's IO is not bivalent."
  (declare (inline read-byte)
           #-swank (sb-kernel:ansi-stream in)) ; declaring (sb-kernel:ansi-stream in) will be faster
  (loop for c of-type base-char =
           #-swank (code-char (read-byte in nil #.(char-code #\Newline)))
           #+swank (read-char in nil #\Newline)
        for idx from 0
        until (char= c #\Newline)
        do (setf (char buffer-string idx) c)
        finally (when (< idx (length buffer-string))
                  (setf (char buffer-string idx) term-char))
                (return (values buffer-string idx))))

;;;
;;; Rolling hash (32-bit)
;;; NOTE: 32-bit doesn't suffice especially when the strong collision resistance
;;; is required. Better to use 62-bit version instead.
;;;

(defconstant +modulus+ 4294967291)
(defconstant +base+ 2095716802)

(defstruct (rhash (:constructor %make-rhash (cumul powers)))
  (cumul nil :type (simple-array (unsigned-byte 32) (*)))
  (powers nil :type (simple-array (unsigned-byte 32) (*))))

(defun make-rhash (vector)
  (declare #.OPT
           (simple-base-string vector))
  (let* ((size (length vector))
         (cumul (make-array (+ 1 size) :element-type '(unsigned-byte 32)))
         (powers (make-array (+ 1 size) :element-type '(unsigned-byte 32))))
    (setf (aref powers 0) 1)
    (dotimes (i size)
      (setf (aref powers (+ i 1))
            (mod (* (aref powers i) +base+) +modulus+))
      (let ((sum (+ (mod (* (aref cumul i) +base+) +modulus+)
                    (the (unsigned-byte 32) (char-code (aref vector i))))))
        (setf (aref cumul (+ i 1))
              (if (> sum +modulus+)
                  (- sum +modulus+)
                  sum))))
    (%make-rhash cumul powers)))

(declaim (ftype (function * (values (unsigned-byte 32) &optional)) rhash-get-lcp))
(defun rhash-get-lcp (rhash start1 start2)
  (declare #.OPT
           ((mod #.most-positive-fixnum) start1 start2))
  (let* ((cumul (rhash-cumul rhash))
         (powers (rhash-powers rhash))
         (max-length (min (- (length cumul) start1 1)
                          (- (length cumul) start2 1))))
    (labels ((bisect (ok ng)
               (declare ((integer 0 #.most-positive-fixnum) ok ng))
               (if (<= (- ng ok) 1)
                   ok
                   (let ((mid (ash (+ ng ok) -1)))
                     (if (= (let ((res (+ (aref cumul (+ start1 mid))
                                          (- +modulus+ (mod (* (aref cumul start1) (aref powers mid)) +modulus+)))))
                              (if (> res +modulus+)
                                  (- res +modulus+)
                                  res))
                            (let ((res (+ (aref cumul (+ start2 mid))
                                          (- +modulus+ (mod (* (aref cumul start2) (aref powers mid)) +modulus+)))))
                              (if (> res +modulus+)
                                  (- res +modulus+)
                                  res)))
                         (bisect mid ng)
                         (bisect ok mid))))))
      (bisect 0 (+ 1 max-length)))))


(defmacro dbg (&rest forms)
  #+swank
  (if (= (length forms) 1)
      `(format *error-output* "~A => ~A~%" ',(car forms) ,(car forms))
      `(format *error-output* "~A => ~A~%" ',forms `(,,@forms)))
  #-swank (declare (ignore forms)))

(defmacro define-int-types (&rest bits)
  `(progn
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "UINT~A" b)) () '(unsigned-byte ,b))) bits)
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "INT~A" b)) () '(signed-byte ,b))) bits)))
(define-int-types 2 4 7 8 15 16 31 32 62 63 64)

(declaim (inline println))
(defun println (obj &optional (stream *standard-output*))
  (let ((*read-default-float-format* 'double-float))
    (prog1 (princ obj stream) (terpri stream))))

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;

(defun main ()
  (declare #.OPT)
  (let* ((n (read))
         (s (make-string n :element-type 'base-char))
         (res 0))
    (declare (uint62 res)
             (uint31 n))
    (read-line-into s)
    (let ((rhash (make-rhash s)))
      (dotimes (i1 n)
        (loop for i2 from (+ i1 1) below n
              for len = (min (- i2 i1) (rhash-get-lcp rhash i1 i2))
              do (setq res (max res len))))
      (println res))))

#-swank (main)