M = [[1, 0, 0, 0], [0, 0, 1, 1], [0, 1, 1, 1], [0, 1, 0, 1]]

def estCarree(M, x, y, k):
    for i in range(x, x + k):
        for j in range(y, y + k):
            if M[i][j] != 1:
                return False
    return True
assert(estCarree(M, 1, 2, 2) and not estCarree(M, 1, 1, 2))

def contientCarre(M, k):
    n = len(M)
    for i in range(n - k + 1):
        for j in range(n - k + 1):
            if estCarree(M, i, j, k):
                return True
    return False
assert(contientCarre(M, 2) and not contientCarre(M, 3))

def PlusGrandCarre_v1(M):
    n = len(M)
    for k in range(n, 0, -1):
        if contientCarre(M, k):
            return k
    return 0
PlusGrandCarre_v1(M)   # 2

def PlusGrandCarre_v2(M):
    c = M.copy() 
    maxi = 0
    indicesMaxi=[]
    for i in range(1,len(M)):
        for j in range(1,len(M[0])):
            if M[i][j] == 1:
                c[i][j] = 1 + min(c[i - 1][j], c[i][j - 1], c[i - 1][j - 1])
                if c[i][j]>maxi :
                    maxi = c[i][j]
                    indicesMaxi=[i-maxi+1,j-maxi+1]
    return maxi, indicesMaxi
print(PlusGrandCarre_v2(M)) # (2, [2,3])
