Buggy python submission (verdict: Runtime Error):
from collections import Counter

while True:
    m, n = (int(s) for s in input().split())
    if not m:
        break

    objs = [int(input(), 2) for i in range(n)]
    f = [[0 for i in range(1 << m)] for i in range(1 << m)]

    for mask in reversed(range(1<<m)):
        s = Counter(obj & mask for obj in objs)
        for mask0 in range(mask + 1):
            if s[mask0] > 1:
                f[mask][mask0] = n + 1
                for b in [1<<k for k in range(m)]:
                    if not (b & mask):
                        f[mask][mask0] = min(f[mask][mask0],
                                             max(f[mask + b][mask0],
                                                 f[mask + b][mask0 + b]) + 1
                                             )
    print(f[0][0])

Fixed submission:
from collections import Counter

while True:
    m, n = (int(s) for s in input().split())
    if not m:
        break

    objects = [int(input(), 2) for i in range(n)]
    dp = [bytearray(1 << m) for i in range(1 << m)]
    bits = [1 << i for i in range(m)]

    for asked in reversed(range((1 << m) - 1)):
        for masked, count in Counter(obj & asked for obj in objects).items():
            if count > 1:
                dp[asked][masked] = min(max(dp[asked + b][masked],
                                            dp[asked + b][masked + b])
                                        for b in bits if not b & asked) + 1
    print(dp[0][0])

Buggy python submission (verdict: Runtime Error):
while True:
    m, n = (int(s) for s in input().split())
    if not m:
        break

    objs = [int(input(), 2) for i in range(n)]
    dp = [[0] * (1<<m) for i in range(1 << m)]
    bits = [1 << i for i in range(m)]

    for mask in reversed(range(1 << m)):
        s = Counter(obj & mask for obj in objs)
        for mask0, value in s.items():
            if value > 1:
                dp[mask][mask0] = min(max(dp[mask | b][mask0],
                                          dp[mask | b][mask0 | b]) + 1
                                      for b in bits if not b & mask)
    print(dp[0][0])

Fixed submission:
from collections import Counter

while True:
    m, n = (int(s) for s in input().split())
    if not m:
        break

    objects = [int(input(), 2) for i in range(n)]
    dp = [bytearray(1 << m) for i in range(1 << m)]
    bits = [1 << i for i in range(m)]

    for asked in reversed(range((1 << m) - 1)):
        for masked, count in Counter(obj & asked for obj in objects).items():
            if count > 1:
                dp[asked][masked] = min(max(dp[asked + b][masked],
                                            dp[asked + b][masked + b])
                                        for b in bits if not b & asked) + 1
    print(dp[0][0])

Buggy python submission (verdict: Runtime Error):
while True:
    m, n = (int(s) for s in raw_input().split())
    if not m:
        break

    objs = [int(raw_input(), 2) for i in range(n)]
    dp = [[0] * (1<<m) for i in range(1 << m)]
    bits = [1 << i for i in range(m)]

    for mask in reversed(range(1 << m)):
        s = Counter(obj & mask for obj in objs)
        for mask0, value in s.items():
            if value > 1:
                dp[mask][mask0] = min(max(dp[mask | b][mask0],
                                          dp[mask | b][mask0 | b]) + 1
                                      for b in bits if not b & mask)
    print dp[0][0]

Fixed submission:
from collections import Counter

while True:
    m, n = (int(s) for s in input().split())
    if not m:
        break

    objects = [int(input(), 2) for i in range(n)]
    dp = [bytearray(1 << m) for i in range(1 << m)]
    bits = [1 << i for i in range(m)]

    for asked in reversed(range((1 << m) - 1)):
        for masked, count in Counter(obj & asked for obj in objects).items():
            if count > 1:
                dp[asked][masked] = min(max(dp[asked + b][masked],
                                            dp[asked + b][masked + b])
                                        for b in bits if not b & asked) + 1
    print(dp[0][0])