#include <bits/stdc++.h>
using namespace std;
const long long N = 3e5 + 500, inf = 0x7fffffff;
long long gti(void) {
  char c = getchar();
  long long ret = 0, st = 1;
  for (; c != '-' && !isdigit(c); c = getchar())
    ;
  if (c == '-') st = -1, c = getchar();
  for (; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
  return ret * st;
}
static unsigned long long M[2] = {97, 47};
struct H {
  unsigned long long a, b;
  H insert(char c) {
    H ret;
    ret.a = a * M[0] + (c - 'a' + 1);
    ret.b = b * M[1] + (c - 'a' + 1);
    return ret;
  }
  bool operator<(const H &y) const {
    if (a == y.a) return b < y.b;
    return a < y.a;
  }
};
map<H, long long> idx;
long long tot;
H geths(char *s, long long len) {
  H ret = {0, 0};
  for (long long i = 0; i < len; i++) ret = ret.insert(s[i]);
  return ret;
}
long long cnt[N], len[N];
long long getid(char *s) {
  long long len = strlen(s);
  for (long long i = 0; i < len; i++) s[i] = tolower(s[i]);
  H hs = geths(s, len);
  if (!idx.count(hs)) {
    idx[hs] = ++tot;
    for (long long i = 0; i < len; i++)
      if (s[i] == 'r') ++cnt[tot];
    ::len[tot] = len;
  }
  return idx[hs];
}
struct Graph {
  struct edge {
    edge *nxt;
    long long to;
  } pool[N << 1], *pt[N], *p = pool;
  void addedge(long long a, long long b) { ++p, *p = {pt[a], b}, pt[a] = p; }
  long long dfn[N], low[N], cnt, col[N], scc = 0, stk[N], ins[N], top;
  void tarjan(long long v) {
    dfn[v] = low[v] = ++cnt;
    stk[++top] = v, ins[v] = true;
    for (edge *i = pt[v]; i; i = i->nxt) {
      if (!dfn[i->to])
        tarjan(i->to), low[v] = min(low[v], low[i->to]);
      else if (ins[i->to])
        low[v] = min(low[v], dfn[i->to]);
    }
    if (low[v] == dfn[v]) {
      for (++scc; stk[top] != v; --top)
        col[stk[top]] = scc, ins[stk[top]] = false;
      col[v] = scc, ins[v] = false, --top;
    }
  }
  void work(long long n, Graph &g) {
    for (long long i = 1; i <= n; i++)
      if (!dfn[i]) tarjan(i);
    for (long long i = 1; i <= scc; i++) g.f[i].x = g.f[i].y = inf;
    for (long long i = 1; i <= n; i++) {
      for (edge *e = pt[i]; e; e = e->nxt)
        if (col[i] != col[e->to]) g.addedge(col[i], col[e->to]);
      g.f[col[i]].x = min(g.f[col[i]].x, ::cnt[i]);
      g.f[col[i]].y = min(g.f[col[i]].y, ::len[i]);
    }
  }
  struct F {
    long long x, y;
    bool operator<(const F &b) const {
      if (x == b.x) return y < b.y;
      return x < b.x;
    }
  } f[N];
  bool vis[N];
  F dfs(long long v) {
    if (vis[v]) return f[v];
    vis[v] = true;
    for (edge *i = pt[v]; i; i = i->nxt) f[v] = min(f[v], dfs(i->to));
    return f[v];
  }
  void solve(long long *a, long long n) {
    long long tot = 0, len = 0;
    for (long long i = 1; i <= n; i++) {
      F ret = dfs(a[i]);
      tot += ret.x, len += ret.y;
    }
    printf("%lld %lld\n", tot, len);
  }
} g, g2;
char s[N];
long long a[N];
signed main(void) {
  long long n = gti();
  for (long long i = 1; i <= n; i++) {
    scanf("%s", s);
    a[i] = getid(s);
  }
  long long m = gti();
  for (long long i = 1; i <= m; i++) {
    scanf("%s", s);
    long long u = getid(s);
    scanf("%s", s);
    long long v = getid(s);
    g.addedge(u, v);
  }
  g.work(tot, g2);
  for (long long i = 1; i <= n; i++) a[i] = g.col[a[i]];
  g2.solve(a, n);
  return 0;
}
