'''
01分数规划,SPFA判断是否有负环,需要一些玄学剪枝
二分枚举可能的平均值mid, 边权修改为mid - w, 验证
图中是否存在负环
'''
from collections import deque
class SPFA:
def __init__(self, start_node, edges, is_directed, max_node_num):
self.edges = edges[::]
self.start_node = start_node
self.is_directed = is_directed
self.max_node_num = max_node_num
def getMinPathLen(self):
return self.getMinInfo()
def getMinInfo(self):
link = {}
dis = [0x7fffffff] * (self.max_node_num+1)
dis[self.start_node] = 0
for a, b, w in self.edges:
if not self.is_directed:
if w < 0:
return None
if a not in link:
link[a] = []
if b not in link:
link[b] = []
link[a].append((b, w))
link[b].append((a, w))
else:
if a not in link:
link[a] = []
link[a].append((b, w))
updated_nodes = deque()
updated_nodes.append(self.start_node)
in_que = [0] * (self.max_node_num + 1)
in_que[self.start_node] = 1
iter_times = 0
update_cnt = 0
while iter_times < self.max_node_num:
update_flag = False
node_num = len(updated_nodes)
for _ in range(node_num):
a = updated_nodes.popleft()
in_que[a] = 0
if a not in link:
continue
for b, w in link[a]:
new_dis = 0x7fffffff if dis[a] == 0x7fffffff else dis[a] + w
if new_dis < dis[b]:
update_cnt += 1
if update_cnt >= self.max_node_num * 5:
return None
dis[b] = new_dis
update_flag = True
if in_que[b] == 0:
in_que[b] = 1
updated_nodes.append(b)
iter_times += 1
if iter_times == self.max_node_num:
if update_flag:
return None
if not update_flag:
break
return [[node, dis[node]] for node in range(1, self.max_node_num+1)]
while True:
n = int(input())
if n == 0:
break
all_nodes = set()
e = {}
for i in range(n):
s = input()
a, b = s[:2], s[-2:]
all_nodes.add(a)
all_nodes.add(b)
if (a, b) not in e:
e[(a, b)] = len(s)
else:
e[(a, b)] = max(e[(a, b)], len(s))
str2idx = {}
for i, val in enumerate(all_nodes):
str2idx[val] = i+1
l, r = 0, 1000
ans = None
while abs(r-l) > 1e-3:
mid = l + (r-l) / 2
edges = []
for (a, b), w in e.items():
a, b = str2idx[a], str2idx[b]
edges.append((a, b, mid-w))
for i in range(1, len(all_nodes)+1):
edges.append((len(all_nodes)+1, i, 0))
algo = SPFA(len(all_nodes)+1, edges, is_directed=True, max_node_num=len(all_nodes)+1)
if algo.getMinPathLen() is None:
ans = mid
l = mid
else:
r = mid
print('{:.2f}'.format(ans) if ans is not None else 'No solution')