// Original C++ solution (slower):
#include<stdio.h>

#include <iostream>

#include <math.h>

#include <numeric>

#include <vector>

#include <map>

#include <functional>

#include <stdio.h>

#include <array>

#include <algorithm>

#include <string>

#include <string.h>

#include <assert.h>

#include <stdio.h>

#include <queue>

#include<iomanip>

#include<bitset>

#include<stack>

#include<set>

#include<limits>

#include <complex>

#include<cstdlib>

using namespace std;



bool isso(long long int a) {

	if (a == 1||a==0)return false;

	for (long long int i = 2; i*i <= a; ++i) {

		if ((a%i)) {

		}

		else {

			return false;

		}

	}

	return true;

}







long long int powint(long long int a, long long int b) {

	assert(b >= 0);

	if (b == 0)return 1;

	if (b == 1)return a;

	long long int ans = 1;

	long long int aa = powint(a, b / 2);

	ans *= aa*aa;

	if (b % 2)ans *= a;

	return ans;

}



struct edge {

	int from;

	int to;

	int cost;

};



struct aa {

	int now;

	int fuel;

	int cost;

};



class Compare {

public:

	//keiroが昇順に並ぶ

	bool operator()(const aa&l, const aa&r) {

		return l.cost> r.cost;

	}

};



vector<vector<int>>involve;





vector<int> dfs2(const int now, vector<bool>&used) {

	if (used[now])return vector<int>(0);

	else {

		used[now] = true;

	}

	vector<int>ans;

	for (auto i : involve[now]) {

		if (involve[i].size()) {

			vector<int>a(dfs2(i,used));

			ans.insert(ans.end(), a.begin(), a.end());

		}

		else {

			ans.push_back(i);

		}

	}

	return ans;

}





int main() {

	while (1) {

		int num = 0;

		map<string,int>mp;

		set<int>ed;

		int N; cin >> N;

		if (!N)break;

		involve.clear();

		involve.resize(100000);

		for (int i = 0; i < N; ++i) {

			string st; cin >> st;

			string groupname;

			vector<string> membername;

			int pre;

			for (int j = 0; j < st.size(); ++j) {

				if (st[j] == ':') {

					groupname = st.substr(0, j);

					pre = j;

				}

				else if (st[j] == ','||st[j]=='.') {

					membername.push_back(st.substr(pre + 1, j - pre - 1));

					pre = j;

				}

			}

			if (!mp.count(groupname)) {

				mp[groupname] = num++;

			}

			for (int i = 0; i < membername.size(); ++i) {

				if (!(mp.count(membername[i]))) {

					mp[membername[i]] = num++;

				}

			}

			for (int i = 0; i < membername.size(); ++i) {

				involve[mp[groupname]].push_back(mp[membername[i]]);

				ed.emplace(mp[membername[i]]);

			}

		}

		vector<bool>used(100001, false);

		vector<int>allnames(dfs2(0,used));

		sort(allnames.begin(), allnames.end());

		const int ans(unique(allnames.begin(), allnames.end()) - allnames.begin());

		cout << ans << endl;



	}

	return 0;

}

// Optimized solution to the same problem (faster):
#include "bits/stdc++.h"

#include<unordered_map>

#include<unordered_set>

#pragma warning(disable:4996)

using namespace std;

using ld = long double;

const ld eps = 1e-9;



//// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"

set<string>memo;

vector<string> dfs(string now, map<string, vector<string>>mp) {

	if (memo.find(now) != memo.end())return vector<string>();

	else memo.emplace(now);

	if (mp.find(now) == mp.end())return vector<string>(1,now);

	else {

		vector<string>ans;

		for (auto child : mp[now]) {

			auto sts=dfs(child,mp);

			ans.insert(ans.end(), sts.begin(), sts.end());

			sort(ans.begin(), ans.end());

			ans.erase(unique(ans.begin(), ans.end()), ans.end());

		}

		return ans;

	}

}



int main() {

	while (1) {

		memo.clear();

		int N; cin >> N;

		if (!N)break;

		map<string, vector<string>>mp;

		string start;

		for (int i = 0; i < N; ++i) {

			string st; cin >> st;

			int a = st.find(':');

			string parent = st.substr(0, a);

			if (!i)start = parent;

			vector<string>children;

			int from = a+1;

			while (1) {

				int r = st.find(',',from);

				if (r == string::npos) {

					children.push_back(st.substr(from,st.find('.')-from));

					break;

				}

				else {

					children.push_back(st.substr(from, r-from));

					from = r + 1;

				}

			}

			mp[parent] = children;

		}

		auto anss = dfs(start, mp);

		cout << anss.size() << endl;

	}

	return 0;

}

// Fastest known solution for this problem: