#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 10, maxnode = 2 * maxn, inf = 1e9 + 10, lg = 19,
          M = 1e9 + 7;
int n, sz[3], iw[maxn], sa[maxn], pos[maxn], dp[maxnode], lcp[maxnode],
    par[maxnode], bu[maxnode], H[maxnode], cnt[3][maxnode];
char s[maxn];
pair<pair<int, int>, int> p[lg][maxn];
vector<int> G[maxnode];
long long ans[maxn];
int per[maxn];
struct SuffixTree {
  int ts = 1, lastv = 0;
  void add(int i) {
    int bef = lastv;
    while (H[lastv] > lcp[i]) {
      bef = lastv;
      lastv = par[lastv];
    }
    if (H[lastv] < lcp[i]) {
      H[ts] = lcp[i];
      bu[ts] = i;
      par[ts] = lastv;
      par[bef] = ts;
      lastv = ts;
      ts++;
    }
    H[ts] = n - sa[i];
    bu[ts] = i;
    par[ts] = lastv;
    lastv = ts;
    if (iw[sa[i]] != -1) {
      cnt[iw[sa[i]]][ts]++;
    }
    ts++;
  }
  void SA() {
    for (int i = 0; i < n; i++) {
      pos[i] = s[i];
      per[i] = i;
    }
    for (int j = 0; j < lg; j++) {
      for (int i = 0; i < n; i++) {
        p[j][i] = make_pair(
            make_pair(pos[i], (i + (1 << j) < n) ? pos[i + (1 << j)] : -1), i);
      }
      sort(per, per + n, [j](int a, int b) { return p[j][a] < p[j][b]; });
      pos[p[j][per[0]].second] = 0;
      for (int i = 1; i < n; i++) {
        pos[p[j][per[i]].second] =
            pos[p[j][per[i - 1]].second] +
            (p[j][per[i - 1]].first < p[j][per[i]].first);
      }
    }
    for (int i = 0; i < n; i++) {
      sa[pos[i]] = i;
    }
    for (int i = 1; i < n; i++) {
      int a = sa[i - 1], b = sa[i];
      for (int j = lg - 1; j >= 0; j--) {
        if (a + (1 << j) <= n && b + (1 << j) <= n &&
            p[j][a].first.first == p[j][b].first.first) {
          lcp[i] += (1 << j);
          a += (1 << j);
          b += (1 << j);
        }
      }
    }
  }
  void Build() {
    SA();
    for (int i = 0; i < n; i++) {
      add(i);
    }
    for (int a = 1; a < ts; a++) {
      G[par[a]].push_back(a);
    }
  }
  void dfs(int a = 0) {
    for (int b : G[a]) {
      dfs(b);
      for (int j = 0; j < 3; j++) {
        cnt[j][a] += cnt[j][b];
      }
    }
    dp[a] = 1ll * cnt[0][a] * cnt[1][a] * cnt[2][a] % M;
    if (a != 0) {
      ans[H[par[a]] + 1] = (ans[H[par[a]] + 1] + dp[a]) % M;
      ans[H[a] + 1] = (ans[H[a] + 1] + M - dp[a]) % M;
    }
  }
} stree;
int32_t main() {
  int n0 = 0;
  for (int j = 0; j < 3; j++) {
    scanf("%s", s + n);
    n = strlen(s);
    sz[j] = n - n0;
    for (int i = n0; i < n; i++) {
      iw[i] = j;
    }
    iw[n] = -1;
    s[n++] = '#' + j;
    n0 = n;
  }
  stree.Build();
  stree.dfs();
  for (int i = 1; i < maxn; i++) {
    ans[i] = (ans[i] + ans[i - 1]) % M;
  }
  int size = sz[0];
  size = min(size, sz[1]);
  size = min(size, sz[2]);
  for (int i = 1; i < size + 1; i++) {
    printf("%lld ", ans[i]);
  }
  printf("\n");
}
