Problem:
Problem A:
Membership Management
Peter is a senior manager of Agile Change Management (ACM) Inc., where each employee is a member of one or more task groups. Since ACM is agile, task groups are often reorganized and their members frequently change, so membership management is his constant headache.
Peter updates the membership information whenever any changes occur: for instance, the following line written by him means that Carol and Alice are the members of the Design Group.
design:carol,alice.
The name preceding the colon is the group name and the names following it specify its members.
A smaller task group may be included in a larger one. So, a group name can appear as a member of another group, for instance, as follows.
development:alice,bob,design,eve.
Simply unfolding the design above gives the following membership specification, which is equivalent to the original.
development:alice,bob,carol,alice,eve.
In this case, however, alice occurs twice. After removing one of the duplicates, we have the following more concise specification.
development:alice,bob,carol,eve.
Your mission in this problem is to write a program that, given group specifications, identifies group members.
Note that Peter's specifications can include deeply nested groups. In the following, for instance, the group one contains a single member dave.
one:another.
another:yetanother.
yetanother:dave.
Input
The input is a sequence of datasets, each being in the following format.
n
group
1
:
member
1,1
,...,
member
1,
m
1
.
.
.
.
group
i
:
member
i
,1
,...,
member
i
,
m
i
.
.
.
.
group
n
:
member
n
,1
,...,
member
n
,
m
n
.
The first line contains n, which represents the number of groups and is a positive integer no more than 100. Each of the following n lines contains the membership information of a group:
group
i
(1 ≤
i
≤
n
) is the name of the
i
-th task group and is followed by a colon (
:
) and then the list of its
m
i
member s that are delimited by a comma (
,
) and terminated by a period (
.
).
Those group names are mutually different. Each
m
i
(1 ≤
i
≤
n
) is between 1 and 10, inclusive. A
member
is another group name if it is one of
group
1
,
group
2
,..., or groupn. Otherwise it is an employee name.
There are no circular (or recursive) definitions of group(s). You may assume that
m
i
member names of a group are mutually different.
Each group or employee name is a non-empty character string of length between 1 and 15, inclusive, and consists of lowercase letters.
The end of the input is indicated by a line containing a zero.
Output
For each dataset, output the number of employees included in the first group of the dataset, that is
group
1
, in a line. No extra characters should occur in the output.
Sample Input
2
development:alice,bob,design,eve.
design:carol,alice.
3
one:another.
another:yetanother.
yetanother:dave.
3
friends:alice,bob,bestfriends,carol,fran,badcompany.
bestfriends:eve,alice.
badcompany:dave,carol.
5
a:b,c,d,e.
b:c,d,e,f.
c:d,e,f,g.
d:e,f,g,h.
e:f,g,h,
...(truncated)

Submitted solutions:

code_snippet: #include<stdio.h>
#include<string.h>
#include<string>
#include<vector>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
using namespace std;

vector<string> q[111];
int n;
char s[300];

int main()
{
         //freopen("x.in","r",stdin);
         while(scanf("%d",&n)&&n)
         {
                  int i,j,k;
                  scanf("%s",s);
                  string t;
                  q[0].clear();
                  for(i=0;s[i]!=':';i++);
                  for(i+=1;s[i];i++)
                  {
                           if(s[i]==','||s[i]=='.')
                           {
                                    //cout<<t<<endl;
                                    q[0].push_back(t);
                                    t="";
                           }
                           else t+=s[i];
                  }
                  //if(t!="") q[0].push_back(t);
                  //cout<<endl;
                  for(i=1;i<n;i++)
                  {
                           scanf("%s",s);t="";q[i].clear();
                           for(j=0;s[j]!=':';j++) t+=s[j];
                           //cout<<t<<endl;
                           q[i].push_back(t);t="";
                           for(j+=1;s[j];j++)
                           {
                                    if(s[j]==','||s[j]=='.')
                                    {
                                             //cout<<t<<endl;
                                             q[i].push_back(t);t="";
                                    }
                                    else t+=s[j];
                           }
                           //if(t!="") q[i].push_back(t);
                           //cout<<t<<endl<<endl;
                  }
                  sort(q[0].begin(),q[0].end());
                  for(i=1;i<q[0].size();)
                  {
                           if(q[0][i]==q[0][i-1])
                           {
                                    swap(q[0][i],q[0][q[0].size()-1]);
                                    q[0].pop_back();
                           }
                           else i++;
                  }
                  //vector<string>::iterator it;
                  bool ok=true;
                  while(ok)
                  {
                           ok=false;
                           for(i=0;i<q[0].size();i++)
                           {
                                    for(j=1;j<n;j++)
                                    {
                                             if(q[0][i]==q[j][0])
                                             {
                                                      for(k=1;k<q[j].size();k++)
                                                      {
                                                               q[0].push_back(q[j][k]);
                                                      }
                                                      ok=true;
                                                      swap(q[0][i],q[0][q[0].size()-1]);
                                                      q[0].pop_back();
                                                      sort(q[0].begin(),q[0].end());
                                                      for(j=1;j<q[0].size();)
                                                      {
                                                               if(q[0][j]==q[0][j-1])
                                                               {
                                                                        q[0].erase(q[0].begin()+j);
                                                               }
                                                               else j++;
                                                      }
                                             }
                                    }
                           }
                  }
                  printf("%d\n",q[0].size());
         }
         return 0;
}
accuracy: 1
time_ms: 360
memory_kb: 3456
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) a.begin(),a.end()
#define reps(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)
#define rreps(i, a, n) for (int i = (a); i > (int)(n); i--)
const long long mod = 1000000007;
const long long INF = 1e18;
ll myceil(ll a, ll b) {return (a+b-1)/b;}


int n;
map<string,set<string>> group;
vector<string> qwe(150);
set<string> opened;


void open(string key) {
    for (auto s : group[key]) {
        if (group[s].size() != 0) {
            if (opened.count(s) == 0) {
                open(s);
            }
            opened.insert(s);
            for (auto nm : group[s]) {
                group[key].insert(nm);
            }
        }
    }
    return;
}

void solve() {
    group.clear();
    opened.clear();
    string s;
    rep(i,n) {
        cin >> s;
        int si = 0;
        int ei = 0;
        string gn;
        while (true) {
            ei++;
            if (s[ei] == ':') {
                gn = s.substr(si,ei-si);
                qwe[i] = gn;
                si = ei+1;
            }
            if (s[ei] == ',') {
                group[gn].insert(s.substr(si,ei-si));
                si = ei+1;
            }
            if (s[ei] == '.') {
                group[gn].insert(s.substr(si,ei-si));
                break;
            }
        }
    }


    open(qwe[0]);
    reps(i,1,n) {
        if (group[qwe[0]].count(qwe[i])) {
            group[qwe[0]].erase(qwe[i]);
        }
    }
    cout << group[qwe[0]].size() << endl;
    return;
}

int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    while (cin >> n && n != 0) {
        solve();
    }
}
accuracy: 1
time_ms: 130
memory_kb: 3964
final_rank: 2

code_snippet: #include <iostream>
#include <unordered_map>
#include <set>
#include <string>
#include <vector>
using namespace std;

vector<vector<int>> involve;

void dfs2(int now, vector<bool> &used, set<int> &ans) {
  if (used[now]) return;
  used[now] = true;
  
  for (auto i : involve[now]) {
    if (involve[i].size()) {
      dfs2(i, used, ans);
    } else {
      ans.insert(i);
    }
  }
}

int main() {
  std::ios::sync_with_stdio(false);
  cin.tie(0);

  while (1) {
    int num = 0;
    unordered_map<string, int> mp;
    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]]);
      }
    }
    vector<bool> used(100001, false);
    set<int> allnames;
    dfs2(0, used, allnames);
    cout << allnames.size() << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5728
final_rank: 19

code_snippet: #include <algorithm>
#include <array>
#include <cassert>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

vector<vector<int>> involve;

void dfs2(int now, vector<bool> &used, vector<int> &ans) {
  if (used[now]) return;
  used[now] = true;
  for (auto i : involve[now]) {
    if (involve[i].size()) {
      dfs2(i, used, ans);
    } else {
      ans.push_back(i);
    }
  }
}

int main() {
  while (1) {
    int num = 0;
    unordered_map<string, int> mp;
    unordered_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, allnames);
    sort(allnames.begin(), allnames.end());
    const int ans(unique(allnames.begin(), allnames.end()) - allnames.begin());
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5328
final_rank: 6

code_snippet: #include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <unordered_map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
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 += (i > 2 ? 2 : 1)) {
    if (a % i == 0)
      return false;
  }
  return true;
}

long long int powint(long long int a, long long int b) {
  assert(b >= 0);
  long long int res = 1;
  while (b > 0) {
    if (b & 1)
      res = res * a;
    a = a * a;
    b >>= 1;
  }
  return res;
}

vector<vector<int>> involve;
void dfs2(const int now, vector<bool> &used, vector<int> &ans) {
  if (used[now])
    return;
  used[now] = true;
  for (auto i : involve[now]) {
    if (involve[i].size())
      dfs2(i, used, ans);
    else
      ans.push_back(i);
  }
}

int main() {
  while (1) {
    int num = 0;
    unordered_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, allnames);
    sort(allnames.begin(), allnames.end());
    const int ans(unique(allnames.begin(), allnames.end()) - allnames.begin());
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5324
final_rank: 5

code_snippet: #include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;

vector<bool> primeSieve(int n) {
    vector<bool> isPrime(n + 1, true);
    isPrime[0] = isPrime[1] = false;

    for (int i = 2; i * i <= n; ++i) {
        if (isPrime[i]) {
            for (int j = i * i; j <= n; j += i) {
                isPrime[j] = false;
            }
        }
    }

    return isPrime;
}

struct edge {
    int from;
    int to;
    int cost;
};

struct aa {
    int now;
    int fuel;
    int cost;
};

class Compare {
public:
    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;
        unordered_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;
}
accuracy: 1
time_ms: 10
memory_kb: 5512
final_rank: 9

code_snippet: #include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <cmath>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;

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 = pow(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:
  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;
  stack<int> stk;
  stk.push(now);
  while (!stk.empty()) {
    int curr = stk.top();
    stk.pop();
    for (auto i : involve[curr]) {
      if (!used[i]) {
        used[i] = true;
        stk.push(i);
        if (involve[i].empty()) {
          ans.push_back(i);
        }
      }
    }
  }
  return ans;
}

int main() {
  while (1) {
    int num = 0;
    unordered_map<string, int> mp;
    vector<bool> ed(100000, false);
    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[mp[membername[i]]] = true;
      }
    }
    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;
}
accuracy: 1
time_ms: 10
memory_kb: 5544
final_rank: 10

code_snippet: #include <algorithm>
#include <array>
#include <assert.h>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
using namespace std;

vector<vector<int>> involve;

vector<int> dfs2(const int now, vector<bool> &used) {
  if (used[now]) return vector<int>(0);
  
  used[now] = true;
  vector<int> ans;
  ans.reserve(involve[now].size());

  for (auto i : involve[now]) {
    if (involve[i].size()) {
      vector<int> a(dfs2(i, used));
      ans.insert(ans.end(), make_move_iterator(a.begin()), make_move_iterator(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) {
        auto it = mp.find(membername[i]);
        if (it == mp.end()) {
          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;
}
accuracy: 1
time_ms: 10
memory_kb: 5544
final_rank: 10

code_snippet: #include <algorithm>
#include <map>
#include <set>
#include <iostream>
#include <vector>
using namespace std;

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() {
  std::ios::sync_with_stdio(false);
  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;
      membername.reserve(st.size()); // preallocate memory
      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]].emplace_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;
}
accuracy: 1
time_ms: 10
memory_kb: 5612
final_rank: 14

code_snippet: #include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
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:
  bool operator()(const aa &l, const aa &r) { return l.cost > r.cost; }
};
vector<vector<int>> involve;
void dfs2(const int now, vector<bool> &used, vector<int> &ans) {
  if (used[now])
    return;
  else {
    used[now] = true;
  }
  for (auto i : involve[now]) {
    if (involve[i].size()) {
      dfs2(i, used, ans);
    } else {
      ans.push_back(i);
    }
  }
}
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, allnames);
    sort(allnames.begin(), allnames.end());
    const int ans(unique(allnames.begin(), allnames.end()) - allnames.begin());
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5580
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>

using namespace std;

vector<vector<int>> involve;
vector<int> dfs2(const int now, vector<bool> &used) {
    if (used[now])
        return {};
    used[now] = true;
    vector<int> ans;
    for (const auto &i : involve[now]) {
        if (!involve[i].empty()) {
            vector<int> a = dfs2(i, used);
            ans.insert(ans.end(), make_move_iterator(a.begin()), make_move_iterator(a.end()));
        } else {
            ans.push_back(i);
        }
    }
    return ans;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    while (1) {
        int num = 0;
        unordered_map<string, int> mp;
        unordered_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 (const auto &name : membername) {
                if (!mp.count(name)) {
                    mp[name] = num++;
                }
            }
            for (const auto &name : membername) {
                involve[mp[groupname]].push_back(mp[name]);
                ed.emplace(mp[name]);
            }
        }
        vector<bool> used(100001, false);
        vector<int> allnames = dfs2(0, used);
        sort(allnames.begin(), allnames.end());
        const int ans = distance(allnames.begin(), unique(allnames.begin(), allnames.end()));
        cout << ans << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5504
final_rank: 7

code_snippet: #include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
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:
  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(1100);
    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(1100, 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;
}
accuracy: 1
time_ms: 10
memory_kb: 3324
final_rank: 1

code_snippet: #include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
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:
  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;
}
accuracy: 1
time_ms: 10
memory_kb: 5680
final_rank: 18

code_snippet: #include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;

bool is_prime(long long n) {
    if (n <= 1) {
        return false;
    }
    for (long long i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

long long pow_int(long long a, long long b) {
    assert(b >= 0);
    if (b == 0) {
        return 1;
    }
    if (b == 1) {
        return a;
    }
    long long ans = 1;
    long long aa = pow_int(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:
    bool operator()(const AA& l, const AA& r) {
        return l.cost > r.cost;
    }
};

vector<vector<int>> involve;

vector<int> dfs(int now, vector<bool>& used) {
    if (used[now]) {
        return vector<int>();
    }
    used[now] = true;
    vector<int> ans;
    for (auto i : involve[now]) {
        if (involve[i].size()) {
            vector<int> a(dfs(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 = -1;
            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(dfs(0, used));
        sort(allnames.begin(), allnames.end());
        const int ans(unique(allnames.begin(), allnames.end()) - allnames.begin());
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5508
final_rank: 8

code_snippet: #include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;

bool is_prime(long long int a) {
  if (a == 1 || a == 0)
    return false;
  for (long long int i = 2; i * i <= a; ++i) {
    if (a % i == 0) {
      return false;
    }
  }
  return true;
}

long long int pow_int(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 = pow_int(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:
  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() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  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;
}
accuracy: 1
time_ms: 10
memory_kb: 5632
final_rank: 16

code_snippet: #include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;
bool is_prime(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 pow_int(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 = pow_int(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:
  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(num + 1, 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;
}
accuracy: 1
time_ms: 10
memory_kb: 5288
final_rank: 4

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

bool is_prime(long long int a) {
  if (a < 2) {
    return false;
  }
  for (long long int i = 2; i * i <= a; ++i) {
    if (a % i == 0) {
      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:
  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() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);

  while (true) {
    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 = -1;
      int idx = 0;
      while (idx < st.size()) {
        if (st[idx] == ':') {
          groupname = st.substr(0, idx);
          pre = idx;
        } else if (st[idx] == ',' || st[idx] == '.') {
          membername.push_back(st.substr(pre + 1, idx - pre - 1));
          pre = idx;
        }
        ++idx;
      }
      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;
}
accuracy: 1
time_ms: 10
memory_kb: 5676
final_rank: 17

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;

bool is_prime(long long int a) {
  if (a == 1 || a == 0)
    return false;
  for (long long int i = 2; i * i <= a; ++i) {
    if ((a % i) == 0) {
      return false;
    }
  }
  return true;
}

long long int powint(long long int a, long long int b) {
  if (b == 0)
    return 1;
  if (b == 1)
    return a;
  long long int ans = powint(a * a, b / 2);
  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:
  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() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);

  while (true) {
    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 = -1;
      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(num, false);
    vector<int> allnames(dfs2(0, used));
    sort(allnames.begin(), allnames.end());
    cout << unique(allnames.begin(), allnames.end()) - allnames.begin() << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5576
final_rank: 12

code_snippet: #include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;
bool isprime(int a) {
  if (a == 1 || a == 0)
    return false;
  for (int i = 2; i * i <= a; ++i) {
    if (a % i == 0) {
      return false;
    }
  }
  return true;
}
int powint(int a, int b) {
  assert(b >= 0);
  if (b == 0)
    return 1;
  if (b == 1)
    return a;
  int ans = 1;
  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:
  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(num, 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;
}
accuracy: 1
time_ms: 10
memory_kb: 5624
final_rank: 15

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <complex>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>

using namespace std;

bool is_prime(long long int a) {
  if (a <= 1)
    return false;
  for (long long int i = 2; i * i <= a; ++i) {
    if (a % i == 0) {
      return false;
    }
  }
  return true;
}

long long int pow_int(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 = pow_int(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:
  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(num, 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;
}
accuracy: 1
time_ms: 10
memory_kb: 5260
final_rank: 3