Buggy python submission (verdict: Time Limit Exceeded):
# coding: utf-8
import sys
#from operator import itemgetter
sysread = sys.stdin.buffer.readline
read = sys.stdin.buffer.read
#from heapq import heappop, heappush
#from collections import defaultdict
sys.setrecursionlimit(10**7)
import math
#from itertools import product, accumulate, combinations, product
#import bisect
import numpy as np
#from copy import deepcopy
#from collections import deque
#from decimal import Decimal
from numba import jit

INF = 1 << 50
EPS = 1e-8

@jit
def solve(S):
    N = S.shape[0]
    ans = 0
    for k in range(N):
        #print(k, '-------------------')
        seen = set()
        seen.add(k)
        merged = np.ones(N, dtype=np.int32) * (-1)
        merged[0] = k
        count = 0
        while merged[0] > -1:
            #print(merged)
            count += 1
            nexts = np.ones(N, dtype=np.int32) * (-1)
            p = 0
            for i in merged:
                if i == -1:break
                for j, e in enumerate(S[i]):
                    if e and not j in seen:
                        #print(j)
                        nexts[p] = j
                        p += 1
                        seen.add(j)
            # merge check
            for i in range(N):
                if nexts[i] == -1:break
            checks = S[nexts[:i],:][:, nexts[:i]]
            #print(checks)
            if checks.sum() != 0:
                seen = set()
                break
            merged = nexts
        if len(seen) == N:
            ans = max(ans, count)
    if ans:
        print(ans)
    else:
        print(-1)


def run():
    N = int(sysread())
    S = []
    for i in range(N):
        S.append(list(map(int, list(input()))))
    S = np.array(S, dtype = np.int8)

    solve(S)


if __name__ == "__main__":
    run()


Fixed submission:
# coding: utf-8
import sys
#from operator import itemgetter
sysread = sys.stdin.buffer.readline
read = sys.stdin.buffer.read
#from heapq import heappop, heappush
#from collections import defaultdict
sys.setrecursionlimit(10**7)
import math
#from itertools import product, accumulate, combinations, product
#import bisect
#import numpy as np
#from copy import deepcopy
#from collections import deque
#from decimal import Decimal
#from numba import jit

INF = 1 << 50
EPS = 1e-8

def check_merge(merged,S):
    merged = set(merged)
    for i in merged:
        for j, e in enumerate(S[i]):
            if int(e) and j in merged:
                return False
    return True

def run():
    N = int(sysread())
    S = []
    for i in range(N):
        S.append(input())

    ans = 0

    #for s in S:
    #    print(s)
    for k in range(N):
        #print(k, '-------------------')
        seen = set()
        seen.add(k)
        merged = [k]
        count = 0
        while merged:
            #print(merged)
            count += 1
            nexts = []
            for i in merged:
                for j, e in enumerate(S[i]):
                    if int(e) and not j in seen:
                        nexts.append(j)
                        seen.add(j)
            if not check_merge(merged, S):
                seen = set()
                break
            merged = nexts
        if len(seen) == N:
            ans = max(ans, count)
    if ans:
        print(ans)
    else:
        print(-1)


if __name__ == "__main__":
    run()

Buggy python submission (verdict: Time Limit Exceeded):
# coding: utf-8
import sys
#from operator import itemgetter
sysread = sys.stdin.buffer.readline
read = sys.stdin.buffer.read
#from heapq import heappop, heappush
#from collections import defaultdict
sys.setrecursionlimit(10**7)
import math
#from itertools import product, accumulate, combinations, product
#import bisect
#import numpy as np
#from copy import deepcopy
#from collections import deque
#from decimal import Decimal
#from numba import jit

INF = 1 << 50
EPS = 1e-8

def check_merge(merged,S):
    merged = set(merged)
    for i in merged:
        for j, e in enumerate(S[i]):
            if int(e) and j in merged:
                return False
    return True

def run():
    N = int(sysread())
    S = []
    for i in range(N):
        S.append(input())

    ans = 0

    #for s in S:
    #    print(s)
    for k in range(N):
        #print(k, '-------------------')
        seen = set()
        seen.add(k)
        merged = [k]
        count = 0
        while merged:
            #print(merged)
            count += 1
            nexts = []
            for i in merged:
                for j, e in enumerate(S[i]):
                    if int(e) and not j in seen:
                        nexts.append(j)
                        seen.add(j)
            if not check_merge(merged, S):
                seen = set()
                break
            merged = nexts
        if len(seen) == N:
            ans = max(ans, count)
    if ans:
        print(ans)
    else:
        print(-1)


if __name__ == "__main__":
    run()


Fixed submission:
# coding: utf-8
import sys
#from operator import itemgetter
sysread = sys.stdin.buffer.readline
read = sys.stdin.buffer.read
#from heapq import heappop, heappush
#from collections import defaultdict
sys.setrecursionlimit(10**7)
import math
#from itertools import product, accumulate, combinations, product
#import bisect
#import numpy as np
#from copy import deepcopy
#from collections import deque
#from decimal import Decimal
#from numba import jit

INF = 1 << 50
EPS = 1e-8

def check_merge(merged,S):
    merged = set(merged)
    for i in merged:
        for j, e in enumerate(S[i]):
            if int(e) and j in merged:
                return False
    return True

def run():
    N = int(sysread())
    S = []
    for i in range(N):
        S.append(input())

    ans = 0

    #for s in S:
    #    print(s)
    for k in range(N):
        #print(k, '-------------------')
        seen = set()
        seen.add(k)
        merged = [k]
        count = 0
        while merged:
            #print(merged)
            count += 1
            nexts = []
            for i in merged:
                for j, e in enumerate(S[i]):
                    if int(e) and not j in seen:
                        nexts.append(j)
                        seen.add(j)
            if not check_merge(merged, S):
                seen = set()
                break
            merged = nexts
        if len(seen) == N:
            ans = max(ans, count)
    if ans:
        print(ans)
    else:
        print(-1)


if __name__ == "__main__":
    run()