#include <bits/stdc++.h>
const int N = 300010;
const int MOD = 1e9 + 7;
struct xxx {
  int id;
  char c;
} s[N];
std::string a, b, c;
int gap, n;
int sa[N], lcp[N], rank[N], tmp[N], bucket[N], cnt[N][3], ans[N], dp[19][N],
    fw[N];
void update(int i, int v) {
  while (i < N) {
    fw[i] = (fw[i] + v) % MOD;
    i += i & -i;
  }
}
int query(int i) {
  int res = 0;
  while (i) {
    res = (res + fw[i]) % MOD;
    i -= i & -i;
  }
  if (res < 0) res += MOD;
  return res;
}
int rmq(int f, int t) {
  int k = 31 - __builtin_clz(t - f + 1);
  int x = dp[k][f];
  int y = dp[k][t - (1 << k) + 1];
  if (lcp[x] < lcp[y]) return x;
  return y;
}
void solve(int f, int t, int h) {
  if (t - f + 1 < 3) return;
  int m = rmq(f, t - 1);
  int c0 = cnt[t][0] - cnt[f - 1][0];
  int c1 = cnt[t][1] - cnt[f - 1][1];
  int c2 = cnt[t][2] - cnt[f - 1][2];
  int v = lcp[m];
  int num = 1ll * c0 * c1 % MOD * c2 % MOD;
  update(v + 1, -num);
  update(h + 1, num);
  solve(f, m, v);
  solve(m + 1, t, v);
}
bool cmp2(int i, int j) {
  i += gap;
  j += gap;
  if (i < n && j < n) return rank[i] < rank[j];
  return i > j;
}
bool cmp(int i, int j) {
  if (rank[i] != rank[j]) return rank[i] < rank[j];
  i += gap;
  j += gap;
  if (i < n && j < n) return rank[i] < rank[j];
  return i > j;
}
int main() {
  std::cin >> a >> b >> c;
  int an = int(a.size()), bn = int(b.size()), cn = int(c.size());
  for (int i = 0; i < an; ++i) s[i].id = 0, s[i].c = a[i];
  for (int i = 0; i < bn; ++i) s[i + an + 1].id = 1, s[i + an + 1].c = b[i];
  for (int i = 0; i < cn; ++i)
    s[i + an + bn + 2].id = 2, s[i + an + bn + 2].c = c[i];
  s[an].c = 1;
  s[an + bn + 1].c = 2;
  n = an + bn + cn + 2;
  int rn = 255;
  for (int i = 0; i < n; ++i) {
    sa[i] = i;
    rank[i] = s[i].c;
  }
  for (gap = 1;; gap <<= 1) {
    int p = 0;
    for (int i = n - 1; i + gap >= n; --i) tmp[p++] = i;
    std::fill(bucket, bucket + rn, 0);
    for (int i = 0; i + gap < n; ++i) ++bucket[rank[i + gap]];
    for (int i = 1; i < rn; ++i) bucket[i] += bucket[i - 1];
    for (int i = 0; i + gap < n; ++i) tmp[--bucket[rank[i + gap]] + p] = i;
    std::fill(bucket, bucket + rn, 0);
    for (int i = 0; i < n; ++i) ++bucket[rank[i]];
    for (int i = 1; i < rn; ++i) bucket[i] += bucket[i - 1];
    for (int i = n - 1; i >= 0; --i) sa[--bucket[rank[tmp[i]]]] = tmp[i];
    tmp[0] = 0;
    for (int i = 1; i < n; ++i) tmp[i] = tmp[i - 1] + cmp(sa[i - 1], sa[i]);
    for (int i = 0; i < n; ++i) rank[sa[i]] = tmp[i];
    if (tmp[n - 1] == n - 1) break;
    rn = tmp[n - 1] + 1;
  }
  for (int i = 0, k = 0; i < n; ++i) {
    if (rank[i] == n - 1) continue;
    for (int j = sa[rank[i] + 1]; s[i + k].c == s[j + k].c;) ++k;
    lcp[rank[i]] = k;
    if (k) --k;
  }
  for (int i = 0; i < n - 1; ++i) dp[0][i] = i;
  for (int j = 1; 1 << j < n; ++j)
    for (int i = 0; i + (1 << j) - 1 < n - 1; ++i) {
      int x = dp[j - 1][i];
      int y = dp[j - 1][i + (1 << (j - 1))];
      dp[j][i] = lcp[x] < lcp[y] ? x : y;
    }
  assert(s[sa[0]].c == 1);
  assert(s[sa[1]].c == 2);
  for (int i = 2; i < n; ++i) {
    cnt[i][0] = cnt[i - 1][0];
    cnt[i][1] = cnt[i - 1][1];
    cnt[i][2] = cnt[i - 1][2];
    ++cnt[i][s[sa[i]].id];
  }
  int sz = std::min(an, std::min(bn, cn));
  solve(2, n - 1, 0);
  for (int i = 1; i <= sz; ++i) std::cout << query(i) << ' ';
}
