#include <bits/stdc++.h>
using namespace std;
class SuffixArrayBuilder {
  int n, gap;
  string s;
  vector<int> pos;

 public:
  SuffixArrayBuilder(string &s) : s(s) {}
  bool operator()(int i, int j) {
    if (pos[i] != pos[j]) return pos[i] < pos[j];
    i += gap;
    j += gap;
    return ((i < n && j < n) ? pos[i] < pos[j] : i > j);
  }
  vector<int> buildSA() {
    n = (int)(s).size();
    vector<int> sa(n), tmp(n);
    pos.resize(n);
    for (int i = (0); i <= ((int)(sa).size() - 1); ++i)
      sa[i] = i, pos[i] = s[i];
    for (gap = 1;; gap *= 2) {
      sort(sa.begin(), sa.end(), ref(*this));
      for (int i = (0); i <= (n - 2); ++i)
        tmp[i + 1] = tmp[i] + (*this)(sa[i], sa[i + 1]);
      for (int i = (0); i <= (n - 1); ++i) pos[sa[i]] = tmp[i];
      if (tmp.back() == n - 1) return sa;
    }
  }
  vector<int> buildLCP(vector<int> &sa) {
    vector<int> lcp(n - 1);
    for (int i = 0, k = 0; i < n; ++i)
      if (pos[i] != n - 1) {
        for (int j = sa[pos[i] + 1]; s[i + k] == s[j + k];) k++;
        lcp[pos[i]] = k;
        if (k) k--;
      }
    return lcp;
  }
};
vector<long long int> solve(string &p, string &q, string &r) {
  string s = p + '#' + q + '$' + r;
  SuffixArrayBuilder Builder(s);
  vector<int> SA = Builder.buildSA();
  vector<int> LCP = Builder.buildLCP(SA);
  int n = (int)(s).size();
  int cnt[3][n];
  int len[] = {0, (int)(p).size() + 1, (int)(q).size() + 1,
               (int)(r).size() + 1};
  for (int i = (1); i <= (3); ++i) len[i] += len[i - 1];
  for (int i = (0); i <= (2); ++i)
    for (int j = (0); j <= (n - 1); ++j) {
      cnt[i][j] = ((j) ? cnt[i][j - 1] : 0);
      cnt[i][j] += (SA[j] >= len[i] && SA[j] < len[i + 1] - 1);
    }
  vector<pair<int, int> > ord;
  for (int i = (0); i <= ((int)(LCP).size() - 1); ++i)
    ord.push_back(make_pair(LCP[i], i));
  sort(ord.begin(), ord.end());
  set<int> S;
  S.insert(-1);
  S.insert(n - 1);
  int m = min({(int)(p).size(), (int)(q).size(), (int)(r).size()});
  vector<long long int> agg(m, 0);
  for (int i = (0); i <= ((int)(ord).size() - 1); ++i) {
    int pos = ord[i].second, L, R;
    auto it = S.lower_bound(pos);
    R = *it;
    it--;
    L = *it;
    long long int left[3], right[3], whole[3];
    for (int i = (0); i <= (2); ++i) {
      left[i] = cnt[i][pos] - ((L >= 0) ? cnt[i][L] : 0);
      right[i] = cnt[i][R] - cnt[i][pos];
      whole[i] = cnt[i][R] - ((L >= 0) ? cnt[i][L] : 0);
    }
    long long int ans = whole[0] * whole[1] * whole[2] -
                        left[0] * left[1] * left[2] -
                        right[0] * right[1] * right[2];
    ans %= 1000000007;
    ans = (ans + 1000000007) % 1000000007;
    int val = ord[i].first;
    if (val > 0) {
      agg[val - 1] += ans;
      agg[val - 1] %= 1000000007;
    }
    S.insert(pos);
  }
  for (int i = (m - 2); i >= (0); --i)
    agg[i] = (agg[i] + agg[i + 1]) % 1000000007;
  return agg;
}
int main() {
  ios_base::sync_with_stdio(0);
  string p, q, r;
  cin >> p >> q >> r;
  vector<long long int> ans = solve(p, q, r);
  for (int i = (0); i <= ((int)(ans).size() - 1); ++i) cout << ans[i] << ' ';
  return 0;
}
