module Graphical
	require 'set'

	def reachable_from(s, max_depth = nil)
		reached = Set[s]
		queue = [s]
		depth = 0
		loop {
			break if max_depth && depth >= max_depth
			next_queue = []
			until queue.empty?
				u = queue.shift
				each_out_connection_of(u){|v, _|
					next if reached.include?(v)
					reached << v
					next_queue << v
				}
			end
			break if next_queue.empty?
			queue = next_queue
			depth += 1
		}
		return reached
	end

	def bfs(start)
		raise "start must be Enumerable" if !start.kind_of?(Enumerable)
		reached = Set[*start.to_a]
		queue = []
		start.each{|s| queue << s}
		dist = {}
		loop.with_index {|_, depth|
			next_queue = []
			until queue.empty?
				u = queue.shift
				dist[u] = depth
				each_out_connection_of(u){|v, _|
					next if reached.include?(v)
					reached << v
					next_queue << v
				}
			end
			break if next_queue.empty?
			queue = next_queue
		}
		return dist
	end

	def dijkstra(start)
		raise "start must be Enumerable" if !start.kind_of?(Enumerable)
		h = Heap.new
		reached = Set[*start.to_a]
		start.each{|s| h.add(s, 0)}

		dist = {}
		until h.empty?
			u, key = h.del_min
			return key if block_given? && yield(u, key)
			dist[u] = key
			each_out_connection_of(u){|v, l|
				d = dist[u] + l
				if reached.include?(v)
					h.update_key(v, d)
				else
					h.add(v, d)
					reached << v
				end
			}
		end
		block_given? ? nil : dist
	end

	def bidir_dijkstra(s, t)
		f_dist = {}
		b_dist = {}

		f_heap = Heap.new
		b_heap = Heap.new

		f_heap.add(s, 0)
		b_heap.add(t, 0)

		f_reached = Set[s]
		b_reached = Set[t]

		f_current_dist = b_current_dist = 0
		best = Float::INFINITY

		loop {
			if !f_heap.empty?
				u, key = f_heap.del_min
				f_dist[u] = key
				f_current_dist = key
				each_out_connection_of(u){|v, l|
					d = f_dist[u] + l
					if b_dist[v]
						path_len = d + b_dist[v]
						best = path_len if path_len < best
					end
					if f_reached.include?(v)
						f_heap.update_key(v, d)
					else
						f_heap.add(v, d)
						f_reached << v
					end
				}
			end

			if !b_heap.empty?
				u, key = b_heap.del_min
				b_dist[u] = key
				b_current_dist = key
				each_in_connection_of(u){|v, l|
					d = b_dist[u] + l
					if f_dist[v]
						path_len = d + f_dist[v]
						best = path_len if path_len < best
					end
					if b_reached.include?(v)
						b_heap.update_key(v, d)
					else
						b_heap.add(v, d)
						b_reached << v
					end
				}
			end

			return best if f_current_dist + b_current_dist >= best
			return nil if f_heap.empty? && b_heap.empty?
		}
	end

	def a_star(start)
		raise "a_star need termination condition" unless block_given?
		h = Heap.new
		reached = Set[start]
		h.add(start, [a_star_heuristic(start), 0])

		dist = {}
		until h.empty?
			u, (e, d) = h.del_min
			return d if yield(u, dist)
			dist[u] = d
			each_out_connection_of(u){|v, l|
				d = dist[u] + l
				e = d + a_star_heuristic(v)
				if reached.include?(v)
					h.update_key(v, [e, d])
				else
					h.add(v, [e, d])
					reached << v
				end
			}
		end
		block_given? ? nil : dist
	end

	#make_variations :bidir_dijkstra

	def prim(start)
		h = Heap.new
		h.add(start, 0)
		reached = Set[start]
		tree_len = 0

		until h.empty?
			u, key = h.del_min
			tree_len += key

			each_connection_of(u){|v, d|
				if reached.include?(v)
					h.update_key(v, d)
				else
					h.add(v, d)
					reached << v
				end
			}
		end
		tree_len
	end
end

class Graph
	include Graphical

	def initialize(*options)
		@options = Set[*options]
	end

	def add_node(property = {})
		Node.new(property)
	end

	def add_edge(u, v, property = {})
		e = Edge.new(u, v, property)
		u.add_edge(e)
		v.add_edge(e)
		e
	end
	
	def del_edge(e)
		u, v = e.from, e.to
		u.del_edge(e)
		v.del_edge(e)
		e
	end

	class Node
		def initialize(property)
			@property = property
			@edges = Set.new
		end

		def add_edge(e)
			@edges << e
		end

		def del_edge(e)
			@edges.delete(e)
		end

		def to_s
			@property[:name] || super
		end

		def each_edge
			@edges.each{|e| 
				yield e
			}
		end

		attr_reader :property
	end

	class Edge
		def initialize(u, v, property)
			@opposite = {u => v, v => u}
			@property = property
		end
		attr_reader :opposite, :property

		def to_s
			@property[:name] || super
		end

		def length
			@property[:length] || 1
		end
	end

	def each_out_connection_of(u)
		u.each_edge{|e|
			yield(e.opposite[u], e.length)
		}
	end

	alias :each_in_connection_of :each_out_connection_of
end

class Digraph < Graph
	def add_node(property = {})
		Node.new(property)
	end

	def add_edge(u, v, property = {})
		e = Edge.new(u, v, property)
		u.out_edges << e
		v.in_edges << e
		e
	end
	
	def del_edge(e)
		u, v = e.from, e.to
		u.out_edges.delete(e)
		v.in_edges.delete(e)
		e
	end

	class Node < Graph::Node
		def initialize(property)
			@property = property
			@out_edges = Set.new
			@in_edges = Set.new
		end

		def add_out_edge(e)
			@out_edges << e
		end

		def del_out_edge(e)
			@out_edges.delete(e)
		end

		def add_in_edge(e)
			@in_edges << e
		end

		def del_in_edge(e)
			@in_edges.delete(e)
		end

		attr_reader :in_edges, :out_edges
	end

	class Edge < Graph::Edge
		def initialize(u, v, property)
			@from = u	
			@to = v
			@property = property
		end

		attr_reader :from, :to
	end

	def each_out_connection_of(u)
		u.out_edges.each{|e|
			yield [e.to, e.length]
		}
	end

	def each_in_connection_of(v)
		v.in_edges.each{|e|
			yield [e.from, e.length]
		}
	end

#----------------------------------------------------------

	def get_path_bfs(s, t)
		path_edge = {}
		reached = Set[s]
		queue = [s]
		while !queue.empty? 
			u = queue.shift
			u.outgoings.each{|e|
				v = e.to
				next if reached.include?(v)	
				reached << v
				queue << v
				path_edge[v] = e

				if v == t
					path = []
					while e = path_edge[v]
						path.unshift e
						v = e.from
					end
					return path
				end
			}
		end	
		return nil
	end

	def get_path_dfs(s, t, reached = Set.new)
		reached << s	
		s.outgoings.each{|e|
			v = e.to
			next if reached.include?(v)
			return [e] if v == t
			
			path = get_path_dfs(v, t, reached) 
			return [e] + path if path
		}
		nil
	end

	def layers_from(start)
		reached = Set[*start]
		layers = [start]

		loop {
			layers << []
			layers[-2].each{|u|
				u.to_nodes.each{|v|
					next if reached.include?(v)
					reached << v
					layers[-1] << v
				}
			}	

			if layers[-1].empty?
				layers.pop
				return layers
			end
		}
	end
end

loop {
	n = gets.to_i
	break if n == 0
	
	g = Digraph.new

	nodes = {}
	g_names = []
	n.times {
		name, *members = gets.chomp.split(/[:,.]/)
		g_names << name
		u = (nodes[name] ||= g.add_node)
		members.each{|m|
			v = (nodes[m] ||= g.add_node)
			g.add_edge(u, v)
		}
	}

	g_names.each{|name| nodes[name].property[:group] = true}

	def count(s, reached)
		return 0 if reached.include?(s)
		reached << s
		if s.out_edges.empty?
			s.property[:group] ? 0 : 1
		else
			s.out_edges.map{|e|
				count(e.to, reached)
			}.inject(0, :+)
		end
	end

	p count(nodes.to_a[0][1], Set.new)
}

Measured memory_bytes: 8400