#include <bits/stdc++.h>
namespace OPT {
char buf[120];
}
template <typename T>
inline void qw(T x, const char aft, const bool pt) {
  if (x < 0) {
    x = -x, putchar('-');
  }
  int top = 0;
  do {
    OPT::buf[++top] = static_cast<char>(x % 10 + '0');
  } while (x /= 10);
  while (top) putchar(OPT::buf[top--]);
  if (pt) putchar(aft);
}
const int maxn = 600010;
const int MOD = 1000000007;
int n, m;
long long int ans;
long long int Ans[maxn];
char S[maxn], T[maxn];
int len[maxn], L[maxn], R[maxn], sa[maxn], rnk[maxn], tp[maxn], tax[maxn],
    height[maxn], ufs[maxn], sz[maxn], sum[maxn][4];
std::vector<int> MU[maxn];
void SA();
void Init();
void Calc();
void Beginning();
void RadixSort();
void CalcHeight();
int find(const int x);
int merge(int u, int v);
void update(const int v, const int p);
int main() {
  ;
  Init();
  SA();
  CalcHeight();
  Beginning();
  Calc();
  return 0;
}
int find(const int x) { return ufs[x] == x ? x : ufs[x] = find(ufs[x]); }
void update(const int v, const int p) {
  long long int _tmp = 1;
  for (int i = 0; i < 3; ++i) {
    (_tmp *= sum[p][i]) %= MOD;
  }
  (ans += v * _tmp) %= MOD;
}
int merge(int u, int v) {
  if (sz[u] > sz[v]) std::swap(u, v);
  for (int i = 0; i < 3; ++i) {
    sum[u][i] += sum[v][i];
  }
  if (sz[u] == sz[v]) {
    ++sz[u];
  }
  return ufs[v] = u;
}
void Calc() {
  int L = std::min(len[0], std::min(len[1], len[2]));
  for (int i = n; i; --i) {
    for (auto v : MU[i]) {
      int x = find(v), y = find(v - 1);
      update(-1, x);
      update(-1, y);
      update(1, merge(x, y));
    }
    Ans[i] = ans;
  }
  for (int i = 1; i <= L; ++i) {
    qw((Ans[i] + MOD) % MOD, ' ', true);
  }
  putchar('\n');
}
void Init() {
  for (int i = 2; ~i; --i) {
    scanf("%s", T + 1);
    memcpy(S + (L[i] = n + 1), T + 1, (len[i] = strlen(T + 1)) * sizeof(char));
    R[i] = L[i] + len[i];
    S[n += len[i] + 1] = i;
  }
}
void SA() {
  --n;
  for (int i = 1; i <= n; ++i) {
    tp[i] = i;
    m = std::max(m, rnk[i] = S[i]);
  }
  RadixSort();
  for (int w = 1, p = 0; p != n; w <<= 1) {
    p = 0;
    for (int i = n - w + 1; i <= n; ++i) tp[++p] = i;
    for (int i = 1; i <= n; ++i)
      if (sa[i] > w) tp[++p] = sa[i] - w;
    RadixSort();
    std::swap(tp, rnk);
    rnk[sa[1]] = p = 1;
    for (int i = 2; i <= n; ++i) {
      int ds = sa[i - 1];
      rnk[sa[i]] =
          ((tp[sa[i]] == tp[ds]) && (tp[sa[i] + w] == tp[ds + w])) ? p : ++p;
    }
    m = p;
  }
}
void RadixSort() {
  for (int i = 0; i <= m; ++i) tax[i] = 0;
  for (int i = 1; i <= n; ++i) ++tax[rnk[i]];
  for (int i = 1; i <= m; ++i) tax[i] += tax[i - 1];
  for (int i = n; i; --i) sa[tax[rnk[tp[i]]]--] = tp[i];
}
void CalcHeight() {
  for (int i = 1, p = 0; i <= n; ++i) {
    if (p) --p;
    int pre = sa[rnk[i] - 1];
    while (S[i + p] == S[pre + p]) ++p;
    MU[height[rnk[i]] = p].push_back(rnk[i]);
  }
}
void Beginning() {
  for (int i = 1; i <= n; ++i) {
    sz[ufs[i] = i] = 1;
    int k = 3;
    for (int j = 0; j < 3; ++j)
      if ((sa[i] >= L[j]) && (sa[i] <= R[j])) {
        k = j;
        break;
      }
    sum[i][k] = 1;
  }
}
