Buggy python submission (verdict: Runtime Error):
import math
def charToNum(char):
    return ord(char) - 96

def check(string,subLen):
    if subLen == 0: return True
    #長さsubLenの部分文字列すべてについてローリングハッシュを計算して、
    #一致するものがあるかどうかを計算する。
    # setOfRollingHash = set()
    dictOfRollingHash = {}
    totalLen = len(string)
    h = 0
    b = 1
    for i in range(subLen):
        c = string[subLen - 1 - i]
        h += charToNum(c) * b
        b *= 27
    dictOfRollingHash[h] = 0
    maxBase = math.pow(27,subLen - 1)
    for i in range(1,totalLen - subLen + 1):
        h -= maxBase * charToNum(string[i - 1])
        h *= 27
        h += charToNum(string[i + subLen - 1])
        if h in dictOfRollingHash:
            if i - dictOfRollingHash[h] >= subLen:
                return True
        else:
            dictOfRollingHash[h] = i
    return False

N = int(input())
S = input()
ok = 0
ng = N + 1
while abs(ok-ng) > 1:
    mid = (ok+ng)//2
    if check(S,mid):
        ok = mid
    else:
        ng = mid
print(ok)

Fixed submission:
import math
MOD = pow(2,61) - 1
def charToNum(char):
    return ord(char) - 96

def check(string,subLen):
    if subLen == 0: return True
    #長さsubLenの部分文字列すべてについてローリングハッシュを計算して、
    #一致するものがあるかどうかを計算する。
    # setOfRollingHash = set()
    dictOfRollingHash = {}
    totalLen = len(string)
    h = 0
    b = 1
    for i in range(subLen):
        c = string[subLen - 1 - i]
        h += charToNum(c) * b
        b *= 27
        b %= MOD
    h %= MOD
    dictOfRollingHash[h] = 0
    maxBase = pow(27,subLen - 1,MOD) 
    for i in range(1,totalLen - subLen + 1):
        h -= maxBase * charToNum(string[i - 1])
        h *= 27
        h += charToNum(string[i + subLen - 1])
        h %= MOD
        if h in dictOfRollingHash:
            if i - dictOfRollingHash[h] >= subLen:
                return True
        else:
            dictOfRollingHash[h] = i
    return False

N = int(input())
S = input()
ok = 0
ng = N + 1
while abs(ok-ng) > 1:
    mid = (ok+ng)//2
    if check(S,mid):
        ok = mid
    else:
        ng = mid
print(ok)

Buggy python submission (verdict: Time Limit Exceeded):
def maxLengthBeginningFrom(i, string):
    ans = 0
    substring = string[i:]
    zArray = efficientZ(substring)
    for j in range(len(zArray)):
        ans = max(ans, min(j, zArray[j]))
    return ans

def efficientZ(string):
    """
    引数: string
    戻り値: 数値からなる配列。0番目の値は0．空文字列に対しては[]を返す。
    >>> efficientZ("ababa")
    [0,0,3,0,1]
    >>> efficientZ("aaaaa")
    [0,4,3,2,1]
    """
    length = len(string)
    Z = [0 for _ in range(length)]
    left = 0
    right = 0
    for i in range(1, length):
        if i >= right: 
            j = 0
            while i + j < length:
                if (string[j] == string[i + j]):
                    j += 1
                else:
                    break
            Z[i] = j
            left = i
            right = i + j
        else:
            correspondingValue = Z[i - left]
            if i + correspondingValue < right:
                Z[i] = correspondingValue
            else:
                j = right - i
                while i + j < length:
                    if string[i + j] == string[j]:
                        j += 1
                    else:
                        break
                Z[i] = j
                left = i
                right = i + j
    return Z 

N = int(input())
S = input()
ans = 0
for i in range(len(S)):
    ans = max(ans,maxLengthBeginningFrom(i, S))
print(ans)

Fixed submission:
import math
MOD = pow(2,61) - 1
def charToNum(char):
    return ord(char) - 96

def check(string,subLen):
    if subLen == 0: return True
    #長さsubLenの部分文字列すべてについてローリングハッシュを計算して、
    #一致するものがあるかどうかを計算する。
    # setOfRollingHash = set()
    dictOfRollingHash = {}
    totalLen = len(string)
    h = 0
    b = 1
    for i in range(subLen):
        c = string[subLen - 1 - i]
        h += charToNum(c) * b
        b *= 27
        b %= MOD
    h %= MOD
    dictOfRollingHash[h] = 0
    maxBase = pow(27,subLen - 1,MOD) 
    for i in range(1,totalLen - subLen + 1):
        h -= maxBase * charToNum(string[i - 1])
        h *= 27
        h += charToNum(string[i + subLen - 1])
        h %= MOD
        if h in dictOfRollingHash:
            if i - dictOfRollingHash[h] >= subLen:
                return True
        else:
            dictOfRollingHash[h] = i
    return False

N = int(input())
S = input()
ok = 0
ng = N + 1
while abs(ok-ng) > 1:
    mid = (ok+ng)//2
    if check(S,mid):
        ok = mid
    else:
        ng = mid
print(ok)