#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool gmin(T &a, T b) {
  if (a > b) return a = b, true;
  return false;
}
template <class T>
inline bool gmax(T &a, T b) {
  if (a < b) return a = b, true;
  return false;
}
template <class T>
T exgcd(T a, T b, T &first, T &second) {
  if (!b)
    return first = (T)1, second = (T)0, a;
  else {
    T d = exgcd(b, a % b, second, first);
    return second -= a / b * first, d;
  }
}
const int INF = 0x3f3f3f3f;
const long long LINF = 0x3f3f3f3f3f3f3f3fll;
const double DINF = 1e10;
const double EPS = 1e-9;
const double PI = 3.14159265358979323846264338327950288;
const double TAU = 2.0 * PI;
inline int sgn(const double &a) { return a > EPS ? 1 : (a < -EPS ? -1 : 0); }
inline int lowbit(int i) { return i & (-i); }
struct Initializer {
  Initializer() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
  }
} initializer;
const int MAXN = 300005;
const long long Mod = 1000000007ll;
struct SuffixArray {
  struct Data {
    int id, key1, key2;
    Data() {}
    Data(int _id, int _key1, int _key2) : id(_id), key1(_key1), key2(_key2) {}
  } d[MAXN], t[MAXN];
  int n;
  int s[MAXN], sa[MAXN], rnk[MAXN], height[MAXN], bucket[MAXN], h[MAXN];
  void rsort() {
    memset(bucket, 0, sizeof(bucket));
    for (int i = 0; i <= n - 1; i++) bucket[d[i].key2]++;
    for (int i = 0; i <= MAXN - 1; i++) bucket[i] += bucket[i - 1];
    for (int i = n - 1; i >= 0; i--) t[--bucket[d[i].key2]] = d[i];
    memset(bucket, 0, sizeof(bucket));
    for (int i = 0; i <= n - 1; i++) bucket[t[i].key1]++;
    for (int i = 0; i <= MAXN - 1; i++) bucket[i] += bucket[i - 1];
    for (int i = n - 1; i >= 0; i--) d[--bucket[t[i].key1]] = t[i];
    for (int i = 0; i <= n - 1; i++) {
      if (!i)
        rnk[d[i].id] = 0;
      else
        rnk[d[i].id] = rnk[d[i - 1].id] + (d[i - 1].key1 != d[i].key1 ||
                                           d[i - 1].key2 != d[i].key2);
    }
  }
  void calc_sa() {
    s[n++] = -1;
    for (int i = 0; i <= n - 1; i++) d[i] = Data(i, s[i], 0);
    rsort();
    for (int j = 1; j <= n; j <<= 1) {
      for (int i = 0; i <= n - 1; i++)
        d[i] = Data(i, rnk[i], i + j < n ? rnk[i + j] : 0);
      rsort();
    }
    for (int i = 0; i <= n - 1; i++) sa[rnk[i]] = i;
  }
  void calc_height() {
    for (int i = 0; i <= n - 1; i++) {
      if (!rnk[i])
        height[rnk[i]] = 0;
      else {
        int j = sa[rnk[i] - 1];
        h[i] = height[rnk[i - 1]];
        if (h[i]) h[i]--;
        for (; s[j + h[i]] == s[i + h[i]]; h[i]++)
          ;
        height[rnk[i]] = h[i];
      }
    }
  }
  void clear() {
    n = 0;
    memset(s, 0, sizeof(s));
    memset(sa, 0, sizeof(sa));
    memset(height, 0, sizeof(height));
    memset(rnk, 0, sizeof(rnk));
    memset(h, 0, sizeof(h));
  }
  void print() {
    printf("rnk:\n");
    for (int i = 0; i <= n - 1; i++) printf("%d ", rnk[i]);
    printf("\n");
    printf("sa:\n");
    for (int i = 0; i <= n - 1; i++) printf("%d ", sa[i]);
    printf("\n");
    printf("height:\n");
    for (int i = 0; i <= n - 1; i++) printf("%d ", height[i]);
    printf("\n");
  }
};
SuffixArray sa;
int l1, l2, l3;
char st1[MAXN], st2[MAXN], st3[MAXN];
int f[MAXN], val[MAXN];
long long sum[4][MAXN];
long long c[MAXN], ans[MAXN];
int Find(int i) { return i == f[i] ? i : f[i] = Find(f[i]); }
void add(int first, long long k) {
  for (int i = first; i <= sa.n; i += lowbit(i)) c[i] = (c[i] + k + Mod) % Mod;
}
long long get(int first) {
  long long ret = 0;
  for (int i = first; i; i -= lowbit(i)) ret = (ret + c[i] + Mod) % Mod;
  return ret;
}
int main() {
  scanf("%s", st1);
  scanf("%s", st2);
  scanf("%s", st3);
  l1 = strlen(st1), l2 = strlen(st2), l3 = strlen(st3);
  sa.n = l1 + l2 + l3 + 2;
  for (int i = 0; i <= l1 - 1; i++) sa.s[i] = st1[i] - 'a' + 1;
  sa.s[l1] = 0;
  for (int i = 0; i <= l2 - 1; i++) sa.s[l1 + 1 + i] = st2[i] - 'a' + 1;
  sa.s[l1 + 1 + l2] = 0;
  for (int i = 0; i <= l3 - 1; i++)
    sa.s[l1 + 1 + l2 + 1 + i] = st3[i] - 'a' + 1;
  sa.s[l1 + 1 + l2 + 1 + l3] = 0;
  sa.calc_sa();
  sa.calc_height();
  priority_queue<pair<int, int> > heap;
  for (int i = 0; i <= sa.n - 1; i++) {
    val[i] = 0;
    if (0 <= sa.sa[i] && sa.sa[i] <= l1 - 1) val[i] = 1;
    if (l1 + 1 <= sa.sa[i] && sa.sa[i] <= l1 + l2) val[i] = 2;
    if (l1 + 1 + l2 + 1 <= sa.sa[i] && sa.sa[i] <= l1 + 1 + l2 + l3) val[i] = 3;
    heap.push(make_pair(sa.height[i], i));
  }
  for (int i = 0; i <= sa.n - 1; i++) {
    f[i] = i;
    sum[val[i]][i]++;
  }
  while (!heap.empty()) {
    pair<int, int> t = heap.top();
    heap.pop();
    int k = t.first, i = t.second;
    if (i == 0) continue;
    int f1 = Find(i - 1), f2 = Find(i);
    if (f1 == f2) continue;
    long long tot = 0;
    tot = (tot + sum[1][f1] * sum[2][f1] % Mod * sum[3][f2] % Mod) % Mod;
    tot = (tot + sum[1][f1] * sum[3][f1] % Mod * sum[2][f2] % Mod) % Mod;
    tot = (tot + sum[2][f1] * sum[3][f1] % Mod * sum[1][f2] % Mod) % Mod;
    tot = (tot + sum[1][f1] * sum[2][f2] % Mod * sum[3][f2] % Mod) % Mod;
    tot = (tot + sum[2][f1] * sum[1][f2] % Mod * sum[3][f2] % Mod) % Mod;
    tot = (tot + sum[3][f1] * sum[1][f2] % Mod * sum[2][f2] % Mod) % Mod;
    add(1, tot);
    add(k + 1, -tot);
    sum[1][f1] += sum[1][f2];
    sum[2][f1] += sum[2][f2];
    sum[3][f1] += sum[3][f2];
    f[f2] = f1;
  }
  int lim = min(l1, min(l2, l3));
  for (int i = 1; i <= lim; i++) ans[i] = get(i);
  printf("%I64d", ans[1]);
  for (int i = 2; i <= lim; i++) printf(" %I64d", ans[i]);
  printf("\n");
  return 0;
}
