package pro.proclass.chaopengfan;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class VjudgeH {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (br.ready()) {
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
if(n==0)break;
String[] data = new String[n];
int[][] map = new int[n][n]; //所有卡车相互转换所需要的衍生距离
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
data[i] = st.nextToken();
}
// 初始化所有卡车之间的距离
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(i==j)continue; // 卡车自己不需要衍生
int dis = 0;
// 计算卡车i和卡车j之间不同的字母位置个数
for (int k = 0; k < 7; k++) {
if(data[i].charAt(k) != data[j].charAt(k))
dis++;
}
map[i][j] = dis;
}
}
int ans = 0;
// 开始prim算法
int[] distance = new int[n]; // 存储到点i的最短距离的边权值。
//开始随便从一个点开始。我这里从0点走
// 初始化distance
for (int i = 0; i < n; i++) {
distance[i] = map[0][i]; // 0点到其他所有点的距离
}
boolean[] visited = new boolean[n]; //存储哪些点的最短权边已经找到
visited[0] = true; // 从0点开始走,不需要找
for (int i = 0; i < n; i++) { // 最多可能需要找n-1次最短距离边
int node = -1;
int min = Integer.MAX_VALUE;
for (int j = 0; j < n; j++) { // 查找distance最短边点的权值
if(distance[j] < min && !visited[j]) {
min = distance[j];
node = j;
}
}
if(min == Integer.MAX_VALUE) break;
visited[node] = true;
ans += min;
for (int j = 0; j < n; j++) {
// 寻找结束点node对应边的权值,存储较小的权
if(!visited[j] && distance[j] > map[node][j]) {
distance[j] = map[node][j];
}
}
}
System.out.println(String.format("The highest possible quality is 1/%d.", ans));
}
}
}