During a New Year special offer the "Sudislavl Bars" offered n promo codes. Each promo code consists of exactly six digits and gives right to one free cocktail at the bar "Mosquito Shelter". Of course, all the promocodes differ.

As the "Mosquito Shelter" opens only at 9, and partying in Sudislavl usually begins at as early as 6, many problems may arise as to how to type a promotional code without errors. It is necessary to calculate such maximum k, that the promotional code could be uniquely identified if it was typed with no more than k errors. At that, k = 0 means that the promotional codes must be entered exactly.

A mistake in this problem should be considered as entering the wrong numbers. For example, value "123465" contains two errors relative to promocode "123456". Regardless of the number of errors the entered value consists of exactly six digits.


-----Input-----

The first line of the output contains number n (1 ≤ n ≤ 1000) — the number of promocodes.

Each of the next n lines contains a single promocode, consisting of exactly 6 digits. It is guaranteed that all the promocodes are distinct. Promocodes can start from digit "0".


-----Output-----

Print the maximum k (naturally, not exceeding the length of the promocode), such that any promocode can be uniquely identified if it is typed with at most k mistakes.


-----Examples-----
Input
2
000000
999999

Output
2

Input
6
211111
212111
222111
111111
112111
121111

Output
0



-----Note-----

In the first sample k < 3, so if a bar customer types in value "090909", then it will be impossible to define which promocode exactly corresponds to it.

Source: codeforces | Difficulty: MEDIUM
Tags: Complete search

Implementation

Constructive algorithms


Solutions:
def func(a, b):
	t = 0
	for i in range(6):
		if a[i] != b[i]:
			t += 1
	return t
n = int(input())
A = [0] * n
for i in range(n):
	A[i] = input()
per = 10
for i in range(0, n - 1):
	for j in range(i + 1, n):
		per = min(per, func(A[i], A[j]))
if n == 1:
	print(6)
elif per in (5, 6):
	print(2)
elif per in (3, 4):
	print(1)
elif per in (0, 1, 2):
	print(0)


from sys import stdin
n = int(input())
if n == 1:
	print(6)
	exit()
arr = stdin.read().strip().splitlines()
ans = 6
i = 0
while i < n:
	j = i + 1
	while j < n:
		(s, k) = (0, 0)
		while k < 6:
			if arr[i][k] == arr[j][k]:
				s += 1
			k += 1
		if s < 2:
			ans = min(ans, 2)
		elif s < 4:
			ans = 1
		elif s < 6:
			print(0)
			exit()
		j += 1
	i += 1
print(ans)


def main():
	from operator import eq
	(n, l, k) = (int(input()), [], 0)
	if n < 2:
		print(6)
		return
	for _ in range(n):
		a = input()
		for b in l:
			x = sum(map(eq, a, b))
			if k < x:
				k = x
				if k > 4:
					print(0)
					return
		l.append(a)
	print(2 - k // 2)
main()


def checcker(x, y):
	p = 0
	for mkT in range(6):
		if x[mkT] == y[mkT]:
			p = p + 1
		if p >= 4:
			break
	return p

def viewer_finish(x, k):
	if x != 1:
		if k >= 4:
			print('0')
		elif k == 3 or k == 2:
			print('1')
		elif k == 1 or k == 0:
			print('2')
	else:
		print(6)

def checcker_main(kList, x):
	k = 0
	for fmN in range(x - 1):
		for KKT in range(fmN + 1, x):
			p = checcker(kList[fmN], kList[KKT])
			if p > k:
				k = p
			if k >= 4:
				break
		if k >= 4:
			break
	return k

def main():
	kList = []
	x = int(input())
	for i in range(x):
		kList.append(input())
	k = checcker_main(kList, x)
	viewer_finish(x, k)
main()


n = int(input())
codes = []
for i in range(n):
	codes.append(input())

def change(a, b, k):
	x = 0
	for i in range(6):
		if a[i] != b[i]:
			x += 1
		if x == k:
			return 3
	if x % 2 == 0:
		return x // 2 - 1
	return x // 2
if n == 1:
	print(6)
	return
k = 2
for i in range(n):
	for j in range(i + 1, n):
		if change(codes[i], codes[j], 2 * k + 1) < k:
			k = change(codes[i], codes[j], 2 * k + 1)
		if k == 0:
			break
print(k)


l = []
s = 12
for i in range(int(input())):
	y = input()
	s = min({sum((a != b for (a, b) in zip(x, y))) - 1 for x in l} | {s})
	l += [y]
print(s // 2)


n = int(input())
codes = [tuple(input()) for i in range(n)]
mind = 13
for i in range(n - 1):
	for j in range(i + 1, n):
		d = sum((x != y for (x, y) in zip(codes[i], codes[j])))
		if d < mind:
			mind = d
print((mind - 1) // 2)


ans = 12
l = [input() for i in range(int(input()))]
for i in range(len(l)):
	for j in range(i + 1, len(l)):
		d = 0
		for w in range(6):
			d += l[i][w] != l[j][w]
		ans = min(d - 1, ans)
print(ans // 2)


n = int(input())
m = 6
arr = []
for i in range(n):
	arr.append(input())
for i in range(n - 1):
	for j in range(i + 1, n):
		d = 0
		for z in range(6):
			if arr[i][z] != arr[j][z]:
				d += 1
		if d == 6:
			m = min(m, 2)
		elif d == 5:
			m = min(m, 2)
		elif d == 4:
			m = min(m, 1)
		elif d == 3:
			m = min(m, 1)
		else:
			m = 0
print(m)


import sys

def distance(s, t):
	ans = 0
	for (x, y) in zip(s, t):
		ans += x != y
	return ans

def min_distance(n):
	codes = [line.rstrip() for line in sys.stdin]
	m = 6
	for i in range(n):
		for j in range(i + 1, n):
			d = distance(codes[i], codes[j])
			if m > d:
				m = d
				if d < 3:
					return 1
	return m
n = int(input())
if n == 1:
	print(6)
else:
	print((min_distance(n) + 1) // 2 - 1)


3

def dist(str1, str2):
	k = 0
	for i in range(6):
		if str1[i] != str2[i]:
			k += 1
	return k

def solve(promos):
	n = len(promos)
	dist_list = [0, 0, 0, 1, 1, 2, 2]
	min_k = 6
	for i in range(n):
		for j in range(i + 1, n):
			d = dist(promos[i], promos[j])
			k = dist_list[d]
			if k < min_k:
				min_k = k
			if k == 0:
				break
	return min_k

def test():
	import random
	import string
	import time
	while True:
		n = 1000
		promos = []
		for i in range(n):
			promo = ''.join([random.choice(string.digits) for i in range(6)])
			promos.append(promo)
		if len(set(promos)) == n:
			break
	start = time.clock()
	k = solve(promos)
	print(k)
	end = time.clock()
	print('Time: {} sec'.format(end - start))

def main():
	n = int(input())
	promos = [None] * n
	for i in range(n):
		promos[i] = input()
	k = solve(promos)
	print(k)

def __starting_point():
	main()
__starting_point()


def C():
	answer_dict = {6: 2, 5: 2, 4: 1, 3: 1, 2: 0, 1: 0, 0: 0}
	n = int(input())
	if n == 1:
		return 6
	promocodes = [str(input()) for i in range(n)]
	min_diff = 6
	for i in range(len(promocodes) - 1):
		for j in range(i + 1, len(promocodes)):
			count_diff = 0
			for (r, k) in zip(promocodes[i], promocodes[j]):
				if r != k:
					count_diff += 1
			if count_diff < min_diff:
				min_diff = count_diff
	return answer_dict[min_diff]
print(C())


def main():
	(n, l, k) = (int(input()), [], 0)
	if n < 2:
		print(6)
		return
	for _ in range(n):
		a = input()
		for b in l:
			x = sum((u == v for (u, v) in zip(a, b)))
			if k < x:
				k = x
				if k > 4:
					print(0)
					return
		l.append(a)
	print(2 - k // 2)

def __starting_point():
	main()
__starting_point()


(s, r) = ([13], range(int(input())))
t = [input() for i in r]
for i in r:
	s += [sum((x != y for (x, y) in zip(t[i], t[j]))) for j in r[i + 1:]]
print(min(s) - 1 >> 1)


l = []
s = 12
for i in range(int(input())):
	y = input()
	for x in l:
		c = 0
		for j in range(6):
			c += x[j] != y[j]
		s = min(c - 1, s)
	l += [y]
print(s // 2)


n = int(input())
codes = []
max_matches = 0
for i in range(n):
	codes.append(input())
for i in range(n - 1):
	for j in range(i + 1, n):
		matches = 0
		for num in range(6):
			if codes[i][num] == codes[j][num]:
				matches += 1
		max_matches = max(max_matches, matches)
		if max_matches > 3:
			break
if n == 1:
	print(6)
elif max_matches == 0 or max_matches == 1:
	print(2)
elif max_matches == 2 or max_matches == 3:
	print(1)
else:
	print(0)


n = int(input())
arr = []
for i in range(n):
	line = int(input())
	arr.append(line)
m = 6
for i in range(n):
	for j in range(i + 1, n):
		t1 = arr[i]
		t2 = arr[j]
		tm = 0
		for k in range(6):
			if t1 % 10 != t2 % 10:
				tm += 1
			t1 //= 10
			t2 //= 10
		if tm < m:
			m = tm
if m % 2 == 0:
	m -= 1
m //= 2
if m < 0:
	m = 0
if n == 1:
	m = 6
print(m)


def similar_digits(num1, num2):
	result = 0
	for i in range(6):
		if num1[i] == num2[i]:
			result += 1
	return result

def main():
	number_of_codes = eval(input())
	codes = []
	for i in range(number_of_codes):
		codes.append(input())
	max_number_of_similar_digits = 0
	answer = int
	for i in range(number_of_codes - 1):
		for j in range(i + 1, number_of_codes):
			result = similar_digits(codes[i], codes[j])
			if result > max_number_of_similar_digits:
				max_number_of_similar_digits = result
			if result >= 4:
				answer = 0
				break
		if result >= 4:
			answer = 0
			break
	if max_number_of_similar_digits == 0 or max_number_of_similar_digits == 1:
		answer = 2
	if max_number_of_similar_digits == 2 or max_number_of_similar_digits == 3:
		answer = 1
	if number_of_codes == 1:
		answer = 6
	print(answer)
main()


n = int(input())
codes = []
for _ in range(n):
	codes.append(input())
mx = 13
for i in range(1, n):
	for j in range(i):
		c = sum([1 if codes[i][l] != codes[j][l] else 0 for l in range(6)])
		mx = min(c, mx)
print((mx - 1) // 2)


import math

def fnd(a, m, key):
	f1 = [0, 1][key]
	f2 = [lambda m: math.floor(m), lambda m: math.ceil(m)][key]
	if type(m) == int:
		return -1
	if m[0] > a:
		return -1
	if m[-1] < a:
		return -1
	if len(m) == 2:
		return m[f1]
	r = list([m for m in [fnd(a, m[len(m) // 2:], key), fnd(a, m[:len(m) // 2 + 1], key)] if m != -1])
	if len(r) == 0:
		return m[f2(len(m) / 2)]
	return r[0]

def F(a, m, key=True):
	if m[0] > a and key:
		return m[0]
	if m[-1] < a and (not key):
		return m[-1]
	return fnd(a, m, key)

def distance(a, b):
	c = 0
	for i in range(len(a)):
		if a[i] != b[i]:
			c += 1
	return c
n = int(input())
promos = []
for i in range(n):
	promos += [input()]
if len(promos) == 1:
	print(6)
	return
a = min([distance(promos[x], promos[y]) for x in range(len(promos)) for y in range(x + 1, len(promos))])
r = [x for x in range(a + 1) if x != a / 2]
print(F(a / 2, r, False))


def cmp(o1, o2):
	result = 0
	for i in range(6):
		if o1[i] != o2[i]:
			result += 1
	return result
count = int(input())
lst = []
for i in range(count):
	lst += [str(input())]
if count == 1:
	print(6)
	exit()
div = 6
for n in range(1, count):
	for i in range(n - 1, -1, -1):
		div = min(div, cmp(lst[n], lst[i]))
		if div <= 2:
			print(0)
			exit()
if div >= 5:
	print(2)
elif div >= 3:
	print(1)


n = int(input())
s = [''] * n
for i in range(n):
	s[i] = input()
if n == 1:
	print(6)
else:
	diff = 6
	for u in s:
		for v in s:
			kol = 0
			for i in range(6):
				if u[i] != v[i]:
					kol += 1
			if kol > 0:
				diff = min(diff, kol)
	diff = max(0, diff - 1)
	print(diff // 2)


def mp():
	return map(int, input().split())

def lt():
	return list(map(int, input().split()))

def pt(x):
	print(x)

def ip():
	return input()

def it():
	return int(input())

def sl(x):
	return [t for t in x]

def spl(x):
	return x.split()

def aj(liste, item):
	liste.append(item)

def bin(x):
	return '{0:b}'.format(x)

def dist(s, t):
	c = 0
	for i in range(6):
		if s[i] != t[i]:
			c += 1
	return c
n = it()
L = []
for i in range(n):
	L.append(ip())
mindist = 13
for i in range(n - 1):
	for j in range(i + 1, n):
		mindist = min(mindist, dist(L[i], L[j]))
print((mindist + 1) // 2 - 1)


from sys import stdin
n = int(input())
if n == 1:
	print(6)
	exit()
arr = stdin.read().strip().splitlines()
ans = 6
for i in range(n):
	for j in range(i + 1, n):
		s = 0
		for k in [0, 1, 2, 3, 4, 5]:
			if arr[i][k] == arr[j][k]:
				s += 1
		if s < 2:
			ans = min(ans, 2)
		elif s < 4:
			ans = 1
		elif s < 6:
			print(0)
			exit()
print(ans)


n = int(input())
codes = [input() for i in range(n)]
mindist = 6
for i in range(n - 1):
	for j in range(i + 1, n):
		d = sum([x != y for (x, y) in zip(codes[i], codes[j])])
		if mindist > d:
			mindist = d
if n == 1:
	print(6)
else:
	print(max(0, (mindist - 1) // 2))


n = int(input())
p = []
answer = 6
for i in range(n):
	s = input()
	answer = min([(sum((a != b for (a, b) in zip(s, t))) - 1) // 2 for t in p] + [answer])
	p.append(s)
print(answer)


n = int(input())
a = [input() for i in range(n)]
dist = 999999 if len(a) >= 2 else 6
for i in range(n):
	for j in range(i + 1, n):
		h = sum([a[i][k] != a[j][k] for k in range(6)])
		dist = min(dist, (h - 1) // 2)
print(dist)


n = int(input())
a = list(map(lambda i: input(), range(n)))
m = 13
for i in range(n):
	for j in range(i + 1, n):
		m = min(m, sum((a[i][k] != a[j][k] for k in range(6))))
print((m - 1) // 2)


def main():
	minEr = 6
	a = eval(input())
	promocodes = [input() for i in range(a)]
	for i in range(len(promocodes)):
		for j in range(i):
			cnt = 0
			for k in range(6):
				if promocodes[i][k] != promocodes[j][k]:
					cnt += 1
			minEr = min(minEr, (cnt - 1) // 2)
	print(minEr)
main()


n = int(input())
codes = [input() for i in range(n)]

def dist(w1, w2):
	assert len(w1) == len(w2)
	d = 0
	for i in range(len(w1)):
		if w1[i] != w2[i]:
			d += 1
	return max(0, (d - 1) // 2)
d = 6
for i in range(n):
	for j in range(i + 1, n):
		d = min(d, dist(codes[i], codes[j]))
print(d)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from bisect import bisect_left
from collections import Counter
n = int(input())
ls = [input() for i in range(n)]
m = 6
if n == 1:
	print(6)
	exit()
for i in range(n):
	for j in range(i + 1, n):
		cnt = 0
		for k in range(6):
			if ls[i][k] != ls[j][k]:
				cnt += 1
		m = min(m, cnt)
		if m == 1 or m == 2 or m == 0:
			print(0)
			exit()
if m == 3 or m == 4:
	print(1)
if m >= 5:
	print(2)


n = int(input())
a = list(map(lambda i: input(), range(n)))
if n == 1:
	print(6)
	exit()
m = 7
for i in range(n):
	for j in range(i + 1, n):
		m = min(m, sum((a[i][k] != a[j][k] for k in range(6))))
print((m - 1) // 2)


import math
n = int(input())
lst = []
for i in range(n):
	line = input().strip()
	lst.append(line)

def main(lst):
	res = 6
	for word in range(len(lst)):
		if res == 0:
			return res
		for j in range(word + 1, len(lst)):
			mistakes = 0
			for i in range(6):
				if lst[word][i] != lst[j][i]:
					mistakes += 1
			if math.ceil(mistakes / 2 - 1) > 4:
				return 0
			if math.ceil(mistakes / 2 - 1) < res:
				res = math.ceil(mistakes / 2 - 1)
	if int(res) < 0:
		res = 0
	return int(res)
print(main(lst))


count = int(input())
if count == 1:
	print('6')
else:
	hamming = 6
	codes = []
	for _ in range(count):
		new_code = input()
		for code in codes:
			distance = 0
			distance += 0 if new_code[0] == code[0] else 1
			distance += 0 if new_code[1] == code[1] else 1
			distance += 0 if new_code[2] == code[2] else 1
			distance += 0 if new_code[3] == code[3] else 1
			distance += 0 if new_code[4] == code[4] else 1
			distance += 0 if new_code[5] == code[5] else 1
			hamming = min(hamming, distance)
		codes.append(new_code)
	print(int(hamming / 2 - 0.5))


n = int(input())
l = [input() for i in range(n)]

def d(a, b):
	return sum((1 for k in range(6) if l[a][k] != l[b][k])) - 1
print(min({d(i, j) for i in range(n) for j in range(i + 1, n)} | {12}) // 2)


n = int(input())
l = [input() for i in range(n)]
print(min([sum((a != b for (a, b) in zip(l[i], l[j]))) - 1 for i in range(n) for j in range(i + 1, n)] + [12]) // 2)


import operator
import itertools
n = int(input())
strings = [input() for i in range(n)]
if n == 1:
	print(6)
else:
	minDiff = 6
	for (a, b) in itertools.combinations(strings, 2):
		minDiff = min(minDiff, list(map(operator.eq, a, b)).count(False))
	print(int((minDiff - 1) / 2))


n = int(input())
l = [input() for i in range(n)]
print(min([sum((1 for k in range(6) if l[i][k] != l[j][k])) - 1 for i in range(n) for j in range(i + 1, n)] + [12]) // 2)


import math

def main():
	minEr = 6
	a = eval(input())
	promocodes = [input() for i in range(a)]
	for i in range(len(promocodes)):
		for j in range(i):
			cnt = 0
			for k in range(6):
				if promocodes[i][k] != promocodes[j][k]:
					cnt += 1
			if math.ceil(cnt / 2 - 1) > 4:
				print(0)
				return 0
			minEr = min(minEr, (cnt - 1) // 2)
	print(minEr)
main()


from __future__ import division, print_function
import sys
import os
from io import BytesIO, IOBase
from heapq import *
from math import gcd, factorial, floor, ceil, sqrt, log2
from copy import deepcopy
from collections import deque
from bisect import bisect_left as bl
from bisect import bisect_right as br
from bisect import bisect
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
from types import GeneratorType

def iterative(f, stack=[]):

	def wrapped_func(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		to = f(*args, **kwargs)
		while True:
			if type(to) is GeneratorType:
				stack.append(to)
				to = next(to)
				continue
			stack.pop()
			if not stack:
				break
			to = stack[-1].send(to)
		return to
	return wrapped_func

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def testcase(t):
	for pp in range(t):
		solve(pp)

def google(p):
	print('Case #' + str(p) + ': ', end='')

def lcm(a, b):
	return a * b // gcd(a, b)

def power(x, y, p):
	y %= p - 1
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def ncr(n, r):
	return factorial(n) // (factorial(r) * factorial(max(n - r, 1)))

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True
inf = pow(10, 21)
mod = 10 ** 9 + 7

def bucketsort(order, seq):
	buckets = [0] * (max(seq) + 1)
	for x in seq:
		buckets[x] += 1
	for i in range(len(buckets) - 1):
		buckets[i + 1] += buckets[i]
	new_order = [-1] * len(seq)
	for i in reversed(order):
		x = seq[i]
		idx = buckets[x] = buckets[x] - 1
		new_order[idx] = i
	return new_order

def ordersort(order, seq, reverse=False):
	bit = max(seq).bit_length() >> 1
	mask = (1 << bit) - 1
	order = bucketsort(order, [x & mask for x in seq])
	order = bucketsort(order, [x >> bit for x in seq])
	if reverse:
		order.reverse()
	return order

def long_ordersort(order, seq):
	order = ordersort(order, [int(i & 2147483647) for i in seq])
	return ordersort(order, [int(i >> 31) for i in seq])

def multikey_ordersort(order, *seqs, sort=ordersort):
	for i in reversed(range(len(seqs))):
		order = sort(order, seqs[i])
	return order

class DisjointSetUnion:

	def __init__(self, n):
		self.parent = list(range(n))
		self.size = [1] * n
		self.num_sets = n

	def find(self, a):
		acopy = a
		while a != self.parent[a]:
			a = self.parent[a]
		while acopy != a:
			(self.parent[acopy], acopy) = (a, self.parent[acopy])
		return a

	def union(self, a, b):
		(a, b) = (self.find(a), self.find(b))
		if a != b:
			if self.size[a] < self.size[b]:
				(a, b) = (b, a)
			self.num_sets -= 1
			self.parent[b] = a
			self.size[a] += self.size[b]

	def set_size(self, a):
		return self.size[self.find(a)]

	def __len__(self):
		return self.num_sets

def solve(case):
	n = int(inp())
	a = []
	for i in range(n):
		a.append(inp())
	ans = 6
	for i in range(n):
		for j in range(n):
			if i == j:
				continue
			cnt = 0
			for k in range(len(a[i])):
				if a[i][k] != a[j][k]:
					cnt += 1
			ans = min(ans, cnt // 2 - 1 if cnt % 2 == 0 else cnt // 2)
	print(ans)
testcase(1)