#include <bits/stdc++.h>
using namespace std;
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline int qread() {
  register char c =
      (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)
           ? EOF
           : *p1++);
  register int x = 0, f = 1;
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)
             ? EOF
             : *p1++);
  }
  while (c >= '0' && c <= '9') {
    x = (x << 3) + (x << 1) + c - 48;
    c = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2)
             ? EOF
             : *p1++);
  }
  return x * f;
}
inline int Abs(const int& x) { return (x > 0 ? x : -x); }
inline int Max(const int& x, const int& y) { return (x > y ? x : y); }
inline int Min(const int& x, const int& y) { return (x < y ? x : y); }
const long long mod = 1000000007;
const int N = 300005;
char s1[N], s2[N], s3[N], s[N];
int l1, l2, l3, n, suf[N], cnt[N], suftmp[N], rnk[N], a[N], b[N], f[N], cntA[N],
    cntB[N], cntC[N], h[N];
long long tot, ans[N];
vector<int> vc[N];
inline void Init() {
  for (int i = 1; i <= n; i++) {
    f[i] = i;
    if (i <= l1)
      cntA[i] = 1;
    else if (i <= l1 + l2 + 1)
      cntB[i] = 1;
    else
      cntC[i] = 1;
  }
  tot = 0;
}
inline int GetRoot(int v) {
  if (f[v] == v) return v;
  return f[v] = GetRoot(f[v]);
}
inline void Merge(int x, int y) {
  int u = GetRoot(x), v = GetRoot(y);
  if (u != v) {
    tot = (tot - 1ll * cntA[u] * cntB[u] % mod * cntC[u] % mod + mod) % mod;
    tot = (tot - 1ll * cntA[v] * cntB[v] % mod * cntC[v] % mod + mod) % mod;
    f[v] = u;
    cntA[u] += cntA[v];
    cntB[u] += cntB[v];
    cntC[u] += cntC[v];
    tot = (tot + 1ll * cntA[u] * cntB[u] % mod * cntC[u] % mod) % mod;
  }
}
inline void Read() {
  scanf("%s%s%s", s1 + 1, s2 + 1, s3 + 1);
  l1 = strlen(s1 + 1);
  l2 = strlen(s2 + 1);
  l3 = strlen(s3 + 1);
}
inline bool cmp1(int i, int j) { return s[i] < s[j]; }
inline void Prefix() {
  for (int i = 1; i <= l1; i++) s[i] = s1[i];
  s[l1 + 1] = '1';
  for (int i = 1; i <= l2; i++) s[i + l1 + 1] = s2[i];
  s[l1 + l2 + 2] = '2';
  for (int i = 1; i <= l3; i++) s[i + l1 + l2 + 2] = s3[i];
  n = strlen(s + 1);
  for (int i = 1; i <= n; i++) suf[i] = i;
  sort(suf + 1, suf + n + 1, cmp1);
  for (int i = 1; i <= n;) {
    int l = i;
    while (i <= n && s[suf[l]] == s[suf[i]]) rnk[suf[i++]] = l;
  }
  for (int k = 1; k <= 20; k++) {
    for (int i = 1; i <= n; i++)
      b[i] = (i + (1 << k - 1) <= n ? rnk[i + (1 << k - 1)] : 0);
    memset(cnt, 0, sizeof(cnt));
    for (int i = 1; i <= n; i++) cnt[b[i]]++;
    for (int i = 1; i <= n; i++) cnt[i] += cnt[i - 1];
    for (int i = n; i >= 1; i--) suftmp[cnt[b[i]]--] = i;
    for (int i = 1; i <= n; i++) a[i] = rnk[i];
    memset(cnt, 0, sizeof(cnt));
    for (int i = 1; i <= n; i++) cnt[a[i]]++;
    for (int i = 1; i <= n; i++) cnt[i] += cnt[i - 1];
    for (int i = n; i >= 1; i--) suf[cnt[a[suftmp[i]]]--] = suftmp[i];
    for (int i = 1; i <= n;) {
      int l = i;
      while (i <= n && a[suf[l]] == a[suf[i]] && b[suf[l]] == b[suf[i]])
        rnk[suf[i++]] = l;
    }
  }
  for (int i = 1; i <= n; i++) {
    h[rnk[i]] = Max(h[rnk[i - 1]] - 1, 0);
    while (s[i + h[rnk[i]]] == s[suf[rnk[i] - 1] + h[rnk[i]]]) h[rnk[i]]++;
  }
}
inline void Solve() {
  Init();
  for (int i = 1; i <= n; i++) vc[h[i]].push_back(i);
  for (int l = n; l >= 1; l--) {
    int siz = vc[l].size();
    for (int i = 0; i < siz; i++) Merge(suf[vc[l][i]], suf[vc[l][i] - 1]);
    ans[l] = tot;
  }
  for (int i = 1; i <= Min(Min(l1, l2), l3); i++) printf("%d ", ans[i]);
}
int main() {
  Read();
  Prefix();
  Solve();
  return 0;
}
