#include <bits/stdc++.h>
using namespace std;
const int MOD = (int)1e9 + 7;
const int N = (int)3e5 + 7;
const int alphabet = 256;
string s, s1, s2, s3;
int n, mn, mx, suf[N];
int len1, len2, len3;
inline void calcSuf() {
  vector<int> p(n), cnt(alphabet), c(n);
  for (int i = 0; i < n; ++i) ++cnt[s[i]];
  for (int i = 1; i < alphabet; ++i) cnt[i] += cnt[i - 1];
  for (int i = n - 1; i >= 0; --i) p[--cnt[s[i]]] = i;
  c[p[0]] = 0;
  int classes = 1;
  for (int i = 1; i < n; ++i) {
    if (s[p[i]] != s[p[i - 1]]) ++classes;
    c[p[i]] = classes - 1;
  }
  vector<int> pn(n), cn(n);
  for (int h = 0; (1 << h) < n; ++h) {
    cnt.assign(classes, 0);
    for (int i = 0; i < n; ++i) {
      pn[i] = p[i] - (1 << h);
      if (pn[i] < 0) pn[i] += n;
    }
    for (int i = 0; i < n; ++i) ++cnt[c[pn[i]]];
    for (int i = 1; i < classes; ++i) cnt[i] += cnt[i - 1];
    for (int i = n - 1; i >= 0; --i) p[--cnt[c[pn[i]]]] = pn[i];
    cn[p[0]] = 0;
    classes = 1;
    for (int i = 1; i < n; ++i) {
      int mid1 = (p[i] + (1 << h)) % n, mid2 = (p[i - 1] + (1 << h)) % n;
      if (c[p[i]] != c[p[i - 1]] || c[mid1] != c[mid2]) ++classes;
      cn[p[i]] = classes - 1;
    }
    c = cn;
  }
  for (int i = 0; i < n; ++i) suf[i] = p[i];
}
int lcp[N], rank12351[N];
void kasai() {
  for (int i = 0; i < n; ++i) rank12351[suf[i]] = i;
  int k = 0;
  for (int i = 0; i < n; ++i) {
    if (k > 0) --k;
    if (rank12351[i] == n - 1) {
      lcp[i] = -1;
      k = 0;
    } else {
      int j = suf[rank12351[i] + 1];
      while (max(j + k, i + k) < n && s[j + k] == s[i + k]) ++k;
      lcp[i] = k;
    }
  }
}
bool is_1(int pos) { return pos < len1; }
bool is_2(int pos) { return pos > len1 && pos < len1 + len2 + 1; }
bool is_3(int pos) { return pos > len1 + len2 + 1; }
int cnt1[N], cnt2[N], cnt3[N];
int n1, n2, n3;
int getCnt(int l, int r) {
  if (l == 0) return (1ll * cnt1[r] * cnt2[r] * cnt3[r]) % MOD;
  return (1ll * (cnt1[r] - cnt1[l - 1]) * (cnt2[r] - cnt2[l - 1]) *
          (cnt3[r] - cnt3[l - 1])) %
         MOD;
}
struct Data {
  Data(){};
  Data(int l, int r, int x) : l(l), r(r), x(x){};
  bool operator<(const Data& a) const { return l < a.l; }
  int l, r, x;
};
int main() {
  cin >> s1 >> s2 >> s3;
  len1 = s1.size();
  len2 = s2.size();
  len3 = s3.size();
  mn = min(len1, min(len2, len3));
  mx = max(len1, max(len2, len3));
  s = s1 + "#" + s2 + "$" + s3 + "%";
  n = s.length();
  calcSuf();
  kasai();
  for (int i = 0; i < n; ++i) {
    if (is_1(suf[i])) ++n1;
    if (is_2(suf[i])) ++n2;
    if (is_3(suf[i])) ++n3;
    cnt1[i] = n1;
    cnt2[i] = n2;
    cnt3[i] = n3;
  }
  vector<int> delims[mn];
  for (int i = 0; i < n - 1; ++i)
    if (lcp[suf[i]] < mn) delims[lcp[suf[i]]].push_back(i);
  int ans = getCnt(0, n - 1);
  set<Data> segms;
  segms.insert(Data(0, n - 1, ans));
  for (int len = 1; len <= mn; ++len) {
    for (int j = 0; j < (int)delims[len - 1].size(); ++j) {
      int pos = delims[len - 1][j];
      auto it = segms.upper_bound(Data(pos, 0, 0));
      --it;
      int x = it->x;
      int l = it->l;
      int r = it->r;
      segms.erase(it);
      if (l <= pos) {
        segms.insert(Data(l, pos, getCnt(l, pos)));
        ans += getCnt(l, pos);
        if (ans >= MOD) ans -= MOD;
      }
      if (r >= pos + 1) {
        segms.insert(Data(pos + 1, r, getCnt(pos + 1, r)));
        ans += getCnt(pos + 1, r);
        if (ans >= MOD) ans -= MOD;
      }
      ans -= x;
      if (ans < 0) ans += MOD;
    }
    cout << ans << " ";
  }
  return 0;
}
