#include <bits/stdc++.h>
using namespace std;
enum { f = 0, m, s, d, w, h };
enum {
  father = 0,
  mother,
  son,
  daughter,
  husband,
  wife,
  brother,
  sister,
  grandfather,
  grandmother,
  grandson,
  granddaughter,
  uncle,
  aunt,
  nephew,
  niece
};
const string name[] = {
    "father",      "mother",      "son",      "daughter",
    "husband",     "wife",        "brother",  "sister",
    "grandfather", "grandmother", "grandson", "granddaughter",
    "uncle",       "aunt",        "nephew",   "niece"};
const int inf = 10000;
vector<int> path[16];
void makepath() {
  path[father].push_back((1 << (f)));
  path[mother].push_back((1 << (m)));
  path[son].push_back((1 << (son)));
  path[daughter].push_back((1 << (d)));
  path[husband].push_back((1 << (h)));
  path[wife].push_back((1 << (w)));
  path[brother].push_back((1 << (f)));
  path[brother].push_back((1 << (s)));
  path[sister].push_back((1 << (f)));
  path[sister].push_back((1 << (d)));
  path[grandfather].push_back((1 << (f)) | (1 << (m)));
  path[grandfather].push_back((1 << (f)));
  path[grandmother].push_back((1 << (f)) | (1 << (m)));
  path[grandmother].push_back((1 << (m)));
  path[uncle].push_back((1 << (f)) | (1 << (m)));
  path[uncle].push_back((1 << (f)));
  path[uncle].push_back((1 << (s)));
  path[aunt].push_back((1 << (f)) | (1 << (m)));
  path[aunt].push_back((1 << (f)));
  path[aunt].push_back((1 << (d)));
  path[nephew].push_back((1 << (f)));
  path[nephew].push_back((1 << (s)) | (1 << (d)));
  path[nephew].push_back((1 << (s)));
  path[niece].push_back((1 << (f)));
  path[niece].push_back((1 << (s)) | (1 << (d)));
  path[niece].push_back((1 << (d)));
  path[grandson].push_back((1 << (s)) | (1 << (d)));
  path[grandson].push_back((1 << (s)));
  path[granddaughter].push_back((1 << (s)) | (1 << (d)));
  path[granddaughter].push_back((1 << (d)));
}
class Node {
 public:
  Node(){};
  Node(int tnode, int tpnum, bool tmale)
      : nodenum(tnode), pnum(tpnum), ismale(tmale) {
    f = m = w = h = -1;
    s.clear();
    d.clear();
  }
  bool ismale;
  int f, m, w, h;
  vector<int> s, d;
  int nodenum;
  int pnum;
};
class st {
 public:
  int now, cost;
  bool operator<(const st &a) const { return cost > a.cost; }
};
const int N = 10000;
int total = 0;
bool isgoal[N];
Node all[N];
bool haschild(int val, int val2, int now, bool isson) {
  if (isson) {
    if (all[now].s.size() >= 2) return true;
  } else {
    if (all[now].d.size() >= 2) return true;
  }
  return false;
}
int cnt = 0;
void search(int n, int now, int *in, vector<int> &p, int pp, int cur,
            int prev) {
  cnt++;
  if (pp != p.size()) {
    int np = p[pp];
    if (np & (1 << (f))) {
      if (all[cur].f == -1) {
        if (all[cur].m != -1 && all[all[cur].m].h != -1) {
          all[cur].f = all[all[cur].m].h;
          if (all[cur].ismale)
            all[all[cur].f].s.push_back(cur);
          else
            all[all[cur].f].d.push_back(cur);
        } else {
          all[cur].f = total;
          all[total] = Node(now, pp, true);
          if (all[cur].ismale)
            all[total].s.push_back(cur);
          else
            all[total].d.push_back(cur);
          if (all[cur].m != -1) {
            all[total].w = all[cur].m;
            all[all[cur].m].h = total;
            all[total].d = all[all[cur].m].d;
            all[total].s = all[all[cur].m].s;
          }
          total++;
        }
      }
      search(n, now, in, p, pp + 1, all[cur].f, cur);
    }
    if (np & (1 << (m))) {
      if (all[cur].m == -1) {
        if (all[cur].f != -1 && all[all[cur].f].w != -1) {
          all[cur].m = all[all[cur].f].w;
          if (all[cur].ismale)
            all[all[cur].m].s.push_back(cur);
          else
            all[all[cur].m].d.push_back(cur);
        } else {
          all[cur].m = total;
          all[total] = Node(now, pp, false);
          if (all[cur].ismale)
            all[total].s.push_back(cur);
          else
            all[total].d.push_back(cur);
          if (all[cur].f != -1) {
            all[all[cur].f].w = total;
            all[total].h = all[cur].f;
            all[total].s = all[all[cur].f].s;
            all[total].d = all[all[cur].f].d;
          }
          total++;
        }
      }
      search(n, now, in, p, pp + 1, all[cur].m, cur);
    }
    if (np & (1 << (s))) {
      if (!haschild(now, pp, cur, true)) {
        all[cur].s.push_back(total);
        all[total] = Node(now, pp, true);
        if (all[cur].ismale) {
          all[total].f = cur;
          if (all[cur].w != -1) all[total].m = all[cur].w;
        } else {
          all[total].m = cur;
          if (all[cur].h != -1) all[total].f = all[cur].h;
        }
        total++;
      }
      for (int i = 0; i < all[cur].s.size(); i++) {
        if (all[cur].s[i] != prev) {
          search(n, now, in, p, pp + 1, all[cur].s[i], cur);
          break;
        }
      }
    }
    if (np & (1 << (d))) {
      if (!haschild(now, pp, cur, false)) {
        all[cur].d.push_back(total);
        all[total] = Node(now, pp, false);
        if (all[cur].ismale) {
          all[total].f = cur;
          if (all[cur].w != -1) all[total].m = all[cur].w;
        } else {
          all[total].m = cur;
          if (all[cur].h != -1) all[total].f = all[cur].h;
        }
        total++;
      }
      for (int i = 0; i < all[cur].d.size(); i++) {
        if (all[cur].d[i] != prev)
          search(n, now, in, p, pp + 1, all[cur].d[i], cur);
      }
    }
    if (np & (1 << (w)) && all[cur].ismale) {
      if (all[cur].w == -1) {
        all[cur].w = total;
        all[total] = Node(now, pp, false);
        all[total].h = cur;
        all[total].d = all[cur].d;
        all[total].s = all[cur].s;
        total++;
      }
      search(n, now, in, p, pp + 1, all[cur].w, cur);
    }
    if (np & (1 << (h)) && !all[cur].ismale) {
      if (all[cur].h == -1) {
        all[cur].h = total;
        all[total] = Node(now, pp, true);
        all[total].w = cur;
        all[total].d = all[cur].d;
        all[total].s = all[cur].s;
        total++;
      }
      search(n, now, in, p, pp + 1, all[cur].h, cur);
    }
    return;
  }
  if (now == n) {
    isgoal[cur] = true;
    return;
  } else {
    search(n, now + 1, in, path[in[now]], 0, cur, -1);
  }
}
vector<pair<int, int> > edge[N];
void makegraph() {
  for (int i = 0; i < total; i++) {
    if (all[i].m != -1) edge[i].push_back(make_pair(all[i].m, 1));
    if (all[i].f != -1) edge[i].push_back(make_pair(all[i].f, 1));
    if (all[i].w != -1) edge[i].push_back(make_pair(all[i].w, 0));
    if (all[i].h != -1) edge[i].push_back(make_pair(all[i].h, 0));
    for (int j = 0; j < all[i].s.size(); j++)
      edge[i].push_back(make_pair(all[i].s[j], 1));
    for (int j = 0; j < all[i].d.size(); j++)
      edge[i].push_back(make_pair(all[i].d[j], 1));
  }
}
short cost[N];
pair<int, int> dijkstra(int n) {
  makegraph();
  for (int i = 0; i < n; i++) cost[i] = inf;
  cost[0] = 0;
  priority_queue<st> Q;
  Q.push((st){0, 0});
  while (!Q.empty()) {
    st now = Q.top();
    Q.pop();
    if (now.cost != cost[now.now]) continue;
    for (int i = 0; i < edge[now.now].size(); i++) {
      int nex = edge[now.now][i].first;
      int nec = now.cost + edge[now.now][i].second;
      if (nec < cost[nex]) cost[nex] = nec, Q.push((st){nex, nec});
    }
  }
  pair<int, int> ret(inf, -inf);
  for (int i = 0; i < n; i++) {
    if (isgoal[i] && cost[i] != inf) {
      ret.first = min(ret.first, (int)cost[i]);
      ret.second = max(ret.second, (int)cost[i]);
    }
  }
  return ret;
}
void parse(int &p, int *in, string &a, map<string, int> &M) {
  p = 0;
  for (int i = 0; i < a.size() - 1; i++) {
    if (a[i] == '\'' && a[i + 1] == 's') a[i] = ' ', a[i + 1] = ' ';
  }
  stringstream sin(a);
  string tmp;
  for (int i = 0; i < 3; i++) sin >> tmp;
  while (sin >> tmp) in[p++] = M[tmp];
}
int main() {
  makepath();
  map<string, int> M;
  for (int i = 0; i < 16; i++) M[name[i]] = i;
  vector<int> dummy;
  int te;
  string tmp;
  cin >> te;
  getline(cin, tmp);
  while (te--) {
    getline(cin, tmp);
    int p = 0, in[10];
    pair<int, int> ans1(inf, -inf), ans2(inf, -inf);
    parse(p, in, tmp, M);
    total = 1;
    all[0] = Node(0, -1, true);
    search(p, 0, in, dummy, 0, 0, -1);
    ans1 = dijkstra(total);
    for (int i = 0; i < total; i++)
      edge[i].clear(), isgoal[i] = false, all[i] = Node(0, -1, true);
    total = 1;
    all[0] = Node(0, -1, false);
    search(p, 0, in, dummy, 0, 0, -1);
    ans2 = dijkstra(total);
    for (int i = 0; i < total; i++)
      edge[i].clear(), isgoal[i] = false, all[i] = Node(0, -1, true);
    cout << max(ans1.second, ans2.second) << " " << min(ans1.first, ans2.first)
         << " " << cnt << endl;
    cnt = 0;
  }
  return false;
}
