Buggy python submission (verdict: Time Limit Exceeded):
n = int(input())
s = input()

dp = [[0]*(n+1) for i in range(n+1)]

ans = 0
for i in range(n-1, -1, -1):
    for j in range(n-1, i, -1):
        if s[i] == s[j]:
            dp[i][j] = dp[i+1][j+1] + 1
        else:
            dp[i][j] = 0
        ans = max(ans, min(dp[i][j], j-i))

print(ans)

Fixed submission:
n = int(input())
s = input()

A = 1234567
MOD = 10000000000000007

def ok(length):
    rolling_hash = 0
    head = pow(A, length, MOD)
    occurence = {}
    for i in range(n):
        rolling_hash = (rolling_hash * A + ord(s[i])) % MOD
        if i - length >= 0:
            rolling_hash = (rolling_hash - head * ord(s[i-length])) % MOD
        if rolling_hash not in occurence:
            occurence[rolling_hash] = []
        occurence[rolling_hash].append(i)

    for key in occurence:
        if occurence[key][-1] - occurence[key][0] >= length:
            return True
    return False

bottom, top = 0, n

while top - bottom > 1:
    mid = (top + bottom) // 2
    if ok(mid):bottom = mid
    else: top = mid

print(bottom)

Buggy python submission (verdict: Time Limit Exceeded):
n = int(input())
s = input()

dp = [[0 if max(i,j) == n else -1 for i in range(n+1)] for j in range(n+1)]

ans = 0
for i in range(n-1, -1, -1):
    for j in range(n-1, i, -1):
        if s[i] == s[j]:dp[i][j] = dp[i+1][j+1] + 1
        else: dp[i][j] = 0
        ans = max(ans, min(dp[i][j], j-i))

print(ans)

Fixed submission:
n = int(input())
s = input()

A = 1234567
MOD = 10000000000000007

def ok(length):
    rolling_hash = 0
    head = pow(A, length, MOD)
    occurence = {}
    for i in range(n):
        rolling_hash = (rolling_hash * A + ord(s[i])) % MOD
        if i - length >= 0:
            rolling_hash = (rolling_hash - head * ord(s[i-length])) % MOD
        if rolling_hash not in occurence:
            occurence[rolling_hash] = []
        occurence[rolling_hash].append(i)

    for key in occurence:
        if occurence[key][-1] - occurence[key][0] >= length:
            return True
    return False

bottom, top = 0, n

while top - bottom > 1:
    mid = (top + bottom) // 2
    if ok(mid):bottom = mid
    else: top = mid

print(bottom)

Buggy python submission (verdict: Runtime Error):
n = int(input())
s = input()

dp = [[-1]*n for _ in range(n)]

def calc(x, y):
    if x >= n or y >= n:return 0
    if dp[x][y] != -1:return dp[x][y]
    if s[x] != s[y]:
        dp[x][y] = 0
        return dp[x][y]
    dp[x][y] = calc(x+1, y+1) + 1
    return dp[x][y]
        
ans = 0
for i in range(n):
    for j in range(i+1, n):
        ans = max(ans, min(calc(i, j), j-i))

print(ans)

Fixed submission:
n = int(input())
s = input()

A = 1234567
MOD = 10000000000000007

def ok(length):
    rolling_hash = 0
    head = pow(A, length, MOD)
    occurence = {}
    for i in range(n):
        rolling_hash = (rolling_hash * A + ord(s[i])) % MOD
        if i - length >= 0:
            rolling_hash = (rolling_hash - head * ord(s[i-length])) % MOD
        if rolling_hash not in occurence:
            occurence[rolling_hash] = []
        occurence[rolling_hash].append(i)

    for key in occurence:
        if occurence[key][-1] - occurence[key][0] >= length:
            return True
    return False

bottom, top = 0, n

while top - bottom > 1:
    mid = (top + bottom) // 2
    if ok(mid):bottom = mid
    else: top = mid

print(bottom)