#include <cstdio>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <string>
#include <queue>

struct edge {
  size_t dst;
  int cap;
  size_t rev;
  edge(size_t dst, int cap, size_t rev): dst(dst), cap(cap), rev(rev) {}
};

struct graph: public std::vector<std::vector<edge>> {
  std::vector<int> level, iter;

  graph(size_t n): std::vector<std::vector<edge>>(n), level(n), iter(n) {}

  void connect_to(size_t src, size_t dst, int cap) {
    (*this)[src].emplace_back(dst, cap, (*this)[dst].size());
    (*this)[dst].emplace_back(src, 0, (*this)[src].size()-1);
  }

  void bfs(size_t s) {
    level.assign(size(), -1);
    level[s] = 0;
    std::queue<size_t> q;
    q.push(s);
    while (!q.empty()) {
      size_t tmp = q.front();
      q.pop();
      for (edge& e: (*this)[tmp]) {
        if (e.cap > 0 && level[e.dst] < 0) {
          level[e.dst] = level[tmp] + 1;
          q.push(e.dst);
        }
      }
    }
  }

  int dfs(size_t v, size_t t, int f) {
    if (v == t) return f;
    for (edge& e: (*this)[v]) {
      if (e.cap > 0 && level[v] < level[e.dst]) {
        int d = dfs(e.dst, t, std::min(f, e.cap));
        if (d > 0) {
          e.cap -= d;
          (*this)[e.dst][e.rev].cap += d;
          return d;
        }
      }
    }
    return 0;
  }

  int max_flow(size_t s, size_t t) {
    int flow = 0;
    int f;
    while (true) {
      bfs(s);
      if (level[t] < 0) return flow;
      iter.assign(size(), 0);
      while ((f = dfs(s, t, 1<<29)) > 0) flow += f;
    }
  }
};

int testcase_ends() {
  size_t n;
  scanf("%zu", &n);

  if (n == 0) return 1;

  std::map<std::string, size_t> name;
  std::vector<std::string> source(n);
  std::set<std::string> ss;
  std::vector<std::vector<std::string>> sink(n);
  for (size_t i=0; i<n; ++i) {
    char buf[1024];
    scanf("%s", buf);
    std::string s = buf;

    size_t j = 0;
    while (s[++j] != ':') {}
    source[i] = s.substr(0, j);
    name.emplace(source[i], 0);
    ss.insert(source[i]);

    while (s[j] != '.') {
      size_t k = ++j;
      while (islower(s[++j])) {}

      std::string tmp = std::string(s.begin()+k, s.begin()+j);
      sink[i].push_back(tmp);
      name.emplace(tmp, 0);
    }

    // fprintf(stderr, "%zu: \"%s\"\n", i, source[i].c_str());
    // for (size_t k=0; k<sink[i].size(); ++k)
    //   fprintf(stderr, "  \"%s\"\n", sink[i][k].c_str());
  }

  {
    size_t tmp = 0;
    for (auto& p: name) p.second = tmp++;
  }

  size_t v = name.size();
  graph g(v+1);
  for (size_t i=0; i<n; ++i) {
    size_t src = name.at(source[i]);
    for (size_t j=0; j<sink[i].size(); ++j) {
      size_t dst = name.at(sink[i][j]);
      // fprintf(stderr, "%s (%zu) -> %s (%zu)\n",
      //         source[i].c_str(), src,
      //         sink[i][j].c_str(), dst);
      g.connect_to(src, dst, 100000);
    }
  }

  // for (size_t i=0; i<v; ++i)
  //   if (g[i].empty()) g.connect_to(i, v);

  for (const auto& p: name) {
    if (ss.count(p.first)) continue;
    // fprintf(stderr, "+ %s (%zu) -> %zu\n",
    //         p.first.c_str(), p.second, v);
    g.connect_to(p.second, v, 1);
  }

  // fprintf(stderr, "%s (%zu) -> %zu\n",
  //         source[0].c_str(), name.at(source[0]), v);
  printf("%d\n", g.max_flow(name.at(source[0]), v));
  return 0;
}

int main() {
  while (!testcase_ends()) {}
}



Measured memory_bytes: 2976