#include<cstdio>
#include<algorithm>
#include <iostream>
using namespace std;
const int maxn = 2000+10;
char map[maxn][10];
int f[maxn];
int n,cnt;
struct edge{
int u,v;
int w;
}e[maxn*maxn/2];
int dist(int st, int en)
{
int distance = 0;
for(int i = 0; i < 7; i++)
if(map[st][i] != map[en][i])
distance++;
return distance;
}
bool cmp(edge a, edge b)
{
return a.w < b.w;
}
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
int Kruskal()
{
int ans = 0;
for(int i = 1; i <= n; i++) f[i] = i;
sort(e,e+cnt,cmp);
for(int i = 0; i < cnt; i++)
{
int u = find(e[i].u);
int v = find(e[i].v);
if(u != v)
{
f[v] = u;
ans += e[i].w;
}
}
return ans;
}
int main()
{
while(scanf("%d", &n) != EOF)
{
if(n == 0) break;
for(int i = 1; i <= n; i++)
scanf("%s", map[i]);
cnt = 0;
for(int i = 1; i < n; i++)
{
for(int j = i+1; j <= n; j++)
{
e[cnt].u = i;
e[cnt].v = j;
e[cnt].w = dist(i,j); //把字符串差值变权值
cnt++;
}
}
int ans = Kruskal();
printf("The highest possible quality is 1/%d.\n", ans);
}
return 0;
}
dist为处理权值的函数,也可以把判断的连通问题写进merge函数,并查集压缩路径,用来提高效率