#include <bits/stdc++.h>
#pragma GCC diagnostic ignored "-Wchar-subscripts"
using namespace std;
const int maxn = 3e+5 + 5;
int n, la, lb, lc;
char str[maxn], a[maxn], b[maxn], c[maxn];
struct SuffixArray {
  int ht[maxn], sa[maxn], rk[maxn];
  int tmp[maxn], bkt1[maxn], bkt2[maxn], fir[maxn], sec[maxn];
  void build() {
    for (int i = 1; i <= n; ++i) bkt1[str[i]]++;
    for (int i = 1; i <= 128; ++i) bkt1[i] += bkt1[i - 1];
    for (int i = 1; i <= n; ++i) sa[bkt1[str[i]]--] = i;
    rk[sa[1]] = 1;
    for (int i = 2; i <= n; ++i)
      rk[sa[i]] = rk[sa[i - 1]] + (str[sa[i]] != str[sa[i - 1]]);
    for (int l = 1; rk[sa[n]] < n; l <<= 1) {
      memset(bkt1, 0, sizeof bkt1);
      memset(bkt2, 0, sizeof bkt2);
      for (int i = 1; i <= n; ++i) {
        fir[i] = rk[i];
        bkt1[fir[i]]++;
        sec[i] = (i + l <= n) ? rk[i + l] : 0;
        bkt2[sec[i]]++;
      }
      for (int i = 1; i <= n; ++i)
        bkt1[i] += bkt1[i - 1], bkt2[i] += bkt2[i - 1];
      for (int i = n; i; --i) tmp[bkt2[sec[i]]--] = i;
      for (int i = n; i; --i) sa[bkt1[fir[tmp[i]]]--] = tmp[i];
      rk[sa[1]] = 1;
      for (int i = 2; i <= n; ++i)
        rk[sa[i]] = rk[sa[i - 1]] + (fir[sa[i]] != fir[sa[i - 1]] ||
                                     sec[sa[i]] != sec[sa[i - 1]]);
    }
    for (int i = 1, j = 0; i <= n; ++i) {
      j = j ? j - 1 : 0;
      while (str[i + j] == str[sa[rk[i] - 1] + j]) j++;
      ht[rk[i]] = j;
    }
  }
} SA;
int f[maxn], num[maxn][4], P[maxn];
long long curans, ans[maxn];
struct node {
  int pos, len;
  node(int p_ = 0, int l_ = 0) : pos(p_), len(l_) {}
  inline bool operator<(const node &rhs) const { return len > rhs.len; }
};
int find(int x) { return (f[x] == x) ? x : f[x] = find(f[x]); }
int calc(int x) {
  return 1ll * num[x][1] * num[x][2] % 1000000007 * num[x][3] % 1000000007;
}
void link(int x, int y) {
  int fx = find(x), fy = find(y);
  if (fx == fy) return;
  curans -= calc(fx);
  curans -= calc(fy);
  f[fx] = fy;
  for (int i = 1; i <= 3; ++i) num[fy][i] += num[fx][i];
  curans += calc(fy);
  curans %= 1000000007;
  if (curans < 0) curans += 1000000007;
}
vector<node> vec;
void init() {
  scanf("%s", a + 1);
  la = strlen(a + 1);
  scanf("%s", b + 1);
  lb = strlen(b + 1);
  scanf("%s", c + 1);
  lc = strlen(c + 1);
  for (int i = 1; i <= la; ++i) str[++n] = a[i], P[n] = 1;
  str[++n] = '#', P[n] = 0;
  for (int i = 1; i <= lb; ++i) str[++n] = b[i], P[n] = 2;
  str[++n] = '*', P[n] = 0;
  for (int i = 1; i <= lc; ++i) str[++n] = c[i], P[n] = 3;
  str[++n] = '%', P[n] = 0;
}
void solve() {
  SA.build();
  for (int i = 1; i <= n; ++i) f[i] = i, num[i][P[i]] = 1;
  for (int i = 1; i <= n; ++i) vec.push_back(node(i, SA.ht[i]));
  sort(vec.begin(), vec.end());
  int ptr = 0, L = min(la, min(lb, lc));
  for (int i = L; i; --i) {
    while (ptr < (int)vec.size() - 1 && vec[ptr].len >= i) {
      int tmp = vec[ptr].pos;
      link(SA.sa[tmp], SA.sa[tmp - 1]);
      ptr++;
    }
    ans[i] = curans;
  }
  for (int i = 1; i <= L; ++i) printf("%lld ", ans[i]);
}
int main() {
  init();
  solve();
  return 0;
}
