#include <bits/stdc++.h>
using namespace std;
struct SuffixArrayBase {
  vector<int> sa, rank, height;
  template <typename T>
  void init(int n, const T a[]) {
    height.resize(n);
    for (int i = 0, z = 0; i < n; ++i) {
      if (rank[i] == 0) {
        height[0] = z = 0;
      } else {
        int x = i, y = sa[rank[i] - 1];
        z = max(0, z - 1);
        while (x + z < n && y + z < n && a[x + z] == a[y + z]) {
          ++z;
        }
        height[rank[i]] = z;
      }
    }
  }
};
struct SuffixArrayYoung : SuffixArrayBase {
  template <typename T>
  void init(int n, const T a[]) {
    sa.resize(n);
    rank.resize(n);
    vector<pair<T, int> > assoc(n);
    for (int i = 0; i < n; ++i) {
      assoc[i] = make_pair(a[i], i);
    }
    sort(assoc.begin(), assoc.end());
    for (int i = 0; i < n; ++i) {
      sa[i] = assoc[i].second;
      if (i == 0 || assoc[i].first != assoc[i - 1].first) {
        rank[sa[i]] = i;
      } else {
        rank[sa[i]] = rank[sa[i - 1]];
      }
    }
    vector<int> tmp(n), cnt(n);
    vector<pair<int, int> > suffix(n);
    for (int m = 1; m < n; m <<= 1) {
      for (int i = 0; i < m; ++i) {
        tmp[i] = n - m + i;
      }
      for (int i = 0, j = m; i < n; ++i) {
        if (sa[i] >= m) {
          tmp[j++] = sa[i] - m;
        }
      }
      fill(cnt.begin(), cnt.end(), 0);
      for (int i = 0; i < n; ++i) {
        ++cnt[rank[i]];
      }
      partial_sum(cnt.begin(), cnt.end(), cnt.begin());
      for (int i = n - 1; i >= 0; --i) {
        sa[--cnt[rank[tmp[i]]]] = tmp[i];
      }
      for (int i = 0; i < n; ++i) {
        suffix[i] = make_pair(
            rank[i], i + m < n ? rank[i + m] : numeric_limits<int>::min());
      }
      for (int i = 0; i < n; ++i) {
        if (i == 0 || suffix[sa[i]] != suffix[sa[i - 1]]) {
          rank[sa[i]] = i;
        } else {
          rank[sa[i]] = rank[sa[i - 1]];
        }
      }
    }
    SuffixArrayBase::init(n, a);
  }
};
SuffixArrayYoung SA;
const int MAX_L = (int)(1e6);
const int MOD = (int)(1e9 + 7);
int a[MAX_L], belongs[MAX_L];
struct Node {
  int x, lcp;
  Node() {}
  Node(int _x, int _lcp) : x(_x), lcp(_lcp) {}
  bool operator<(const Node& o) const { return lcp > o.lcp; }
};
Node e[MAX_L];
int p[MAX_L], cnt[MAX_L][3];
int find(int x) { return x == p[x] ? x : (p[x] = find(p[x])); }
int add(int a, int b) { return (a + b) % MOD; }
int mul(int a, int b) { return (a * 1LL * b) % MOD; }
int main() {
  ios_base::sync_with_stdio(false);
  string s[3];
  int st[3], ed[3];
  int l = MAX_L, n = 0;
  for (int i = 0; i < 3; ++i) {
    cin >> s[i];
    l = min(l, (int)s[i].size());
    st[i] = n;
    for (int j = 0; j < s[i].size(); ++j) {
      a[n++] = s[i][j] - 'a';
    }
    ed[i] = n - 1;
    if (i != 2) {
      a[n++] = 26;
    }
  }
  SA.init(n, a);
  for (int i = 0; i < n - 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      if (st[j] <= SA.sa[i] && SA.sa[i] <= ed[j]) {
        belongs[i] = j;
        break;
      }
    }
  }
  int m = 0;
  for (int i = 1; i < n - 2; ++i) {
    int lcp = SA.height[i];
    lcp = min(lcp, ed[belongs[i - 1]] - SA.sa[i - 1] + 1);
    lcp = min(lcp, ed[belongs[i]] - SA.sa[i] + 1);
    e[m++] = Node(i, lcp);
  }
  sort(e, e + m);
  for (int i = 0; i < n - 2; ++i) {
    p[i] = i;
    fill(cnt[i], cnt[i] + 3, 0);
    cnt[i][belongs[i]] = 1;
  }
  vector<int> result(l + 1, 0);
  int current = 0;
  for (int i = l, j = 0; i >= 1; --i) {
    for (; j < m && e[j].lcp >= i; ++j) {
      int x = find(e[j].x - 1), y = find(e[j].x);
      if (x != y) {
        current = add(current, MOD - mul(cnt[x][0], mul(cnt[x][1], cnt[x][2])));
        current = add(current, MOD - mul(cnt[y][0], mul(cnt[y][1], cnt[y][2])));
        p[y] = x;
        for (int k = 0; k < 3; ++k) {
          cnt[x][k] += cnt[y][k];
        }
        current = add(current, mul(cnt[x][0], mul(cnt[x][1], cnt[x][2])));
      }
    }
    result[i] = current;
  }
  for (int i = 1; i <= l; ++i) {
    cout << result[i] << (i == l ? "\n" : " ");
  }
  return 0;
}
