#include <bits/stdc++.h>
using namespace std;
inline int readint() {
  int a = 0;
  char c = getchar(), f = 1;
  for (; c < '0' || c > '9'; c = getchar())
    if (c == '-') f = -f;
  for (; '0' <= c && c <= '9'; c = getchar())
    a = (a << 3) + (a << 1) + (c ^ 48);
  return a * f;
}
const int MaxN = 300010;
int sa[MaxN], rnk[MaxN << 1];
int tmp[MaxN << 1], buck[MaxN];
void prepare(int n, int m) {
  memset(buck, 0, m << 2);
  for (int i = 0; i < n; ++i) ++buck[rnk[i]];
  for (int i = 1; i < m; ++i) buck[i] += buck[i - 1];
}
void getSA(int a[], int n) {
  memset(tmp + n, -1, n << 2);
  memset(rnk + n, -1, n << 2);
  memcpy(tmp, a, n << 2);
  sort(tmp, tmp + n);
  int m = unique(tmp, tmp + n) - tmp;
  for (int i = 0; i < n; ++i) rnk[i] = lower_bound(tmp, tmp + m, a[i]) - tmp;
  prepare(n, m);
  for (int i = 0; i < n; ++i) sa[--buck[rnk[i]]] = i;
  for (int w = 1, p; m != n; w <<= 1, m = p + 1) {
    for (int i = n - w + (p = 0); i < n; ++i) tmp[p++] = i;
    for (int i = 0; i < n; ++i)
      if (sa[i] >= w) tmp[p++] = sa[i] - w;
    prepare(n, m);
    for (int i = n - 1; ~i; --i) sa[--buck[rnk[tmp[i]]]] = tmp[i];
    memcpy(tmp, rnk, n << 2);
    rnk[sa[0]] = p = 0;
    for (int i = 1; i < n; ++i) {
      if (tmp[sa[i]] != tmp[sa[i - 1]] || tmp[sa[i] + w] != tmp[sa[i - 1] + w])
        ++p;
      rnk[sa[i]] = p;
    }
  }
}
int heit[MaxN];
void getHei(int a[], int n) {
  for (int i = 0, j, k = 0; i < n; ++i)
    if (rnk[i] == 0)
      heit[0] = k = 0;
    else {
      if (k) --k;
      j = sa[rnk[i] - 1];
      while (max(i, j) + k <= n && a[j + k] == a[i + k]) ++k;
      heit[rnk[i]] = k;
    }
}
namespace RMQ {
int st[20][MaxN], *item;
void prepare(int a[], int n) {
  for (int i = 0; i < n; ++i) st[0][i] = i;
  item = a;
  for (int j = 0; (2 << j) <= n; ++j)
    for (int i = 0; i + (2 << j) <= n; ++i) {
      st[j + 1][i] = st[j][i + (1 << j)];
      if (a[st[j + 1][i]] > a[st[j][i]]) st[j + 1][i] = st[j][i];
    }
}
int query(int l, int r) {
  int k = 0;
  while ((2 << k) <= r - l + 1) ++k;
  r = st[k][r - (1 << k) + 1];
  if (item[r] < item[st[k][l]]) return r;
  return st[k][l];
}
}  // namespace RMQ
const int Mod = 1e9 + 7;
int ans[MaxN], cnt[MaxN][3], lenA, lenB;
inline int toInt(int x) {
  if (x == lenA || x == lenB) return 3;
  return (x > lenA) + (x > lenB);
}
void solve(int l, int r) {
  if (l >= r) return;
  int o = RMQ::query(l, r);
  int sy = 1;
  for (int i = 0; i < 3; ++i)
    sy = 1ll * sy * (cnt[r + 1][i] - cnt[l - 1][i]) % Mod;
  int bad = 1;
  for (int i = 0; i < 3; ++i)
    bad = 1ll * bad * (cnt[o][i] - cnt[l - 1][i]) % Mod;
  sy = (sy + Mod - bad) % Mod;
  for (int i = (bad = 1) - 1; i < 3; ++i)
    bad = 1ll * bad * (cnt[r + 1][i] - cnt[o][i]) % Mod;
  sy = (sy + Mod - bad) % Mod;
  ans[heit[o]] = (ans[heit[o]] + sy) % Mod;
  solve(l, o - 1), solve(o + 1, r);
}
char A[MaxN], B[MaxN], C[MaxN];
int xyx[MaxN];
int main() {
  scanf("%s %s %s", A, B, C);
  lenA = strlen(A), lenB = strlen(B);
  int lenC = strlen(C);
  for (int i = 0; i < lenA; ++i) xyx[i] = A[i];
  xyx[lenA] = -1;
  for (int i = 0; i < lenB; ++i) xyx[i + lenA + 1] = B[i];
  lenB += lenA + 1;
  xyx[lenB] = -2;
  for (int i = 0; i < lenC; ++i) xyx[i + lenB + 1] = C[i];
  lenC += lenB + 1;
  getSA(xyx, lenC);
  getHei(xyx, lenC);
  RMQ::prepare(heit, lenC);
  for (int i = 0; i < lenC; ++i) {
    for (int j = 0; j < 3; ++j) cnt[i + 1][j] = cnt[i][j];
    if (toInt(sa[i]) != 3) ++cnt[i + 1][toInt(sa[i])];
  }
  solve(1, lenC - 1);
  for (int i = lenC - 1; i; --i) ans[i] = (ans[i] + ans[i + 1]) % Mod;
  lenC -= (lenB + 1);
  lenB -= (lenA + 1);
  lenC = min(lenC, min(lenA, lenB));
  for (int i = 1; i <= lenC; ++i) printf("%d ", ans[i]);
  return 0;
}
