#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
long long prod(vector<long long> &a) { return a[0] * a[1] % mod * a[2] % mod; }
bool all(vector<long long> &a) { return a[0] && a[1] && a[2]; }
template <typename T>
struct suffix_tree {
  vector<T> s;
  vector<map<T, int>> next;
  vector<int> spos, len, link;
  int node, pos, last;
  suffix_tree() { make_node(0), node = pos = 0; }
  int make_node(int p, int l = 2e9) {
    spos.push_back(p);
    len.push_back(l);
    link.push_back(0);
    next.emplace_back();
    return spos.size() - 1;
  }
  void extend(T c) {
    for (s.push_back(c), pos++, last = 0; pos > 0;) {
      int n = s.size();
      while (pos > len[next[node][s[n - pos]]])
        node = next[node][s[n - pos]], pos -= len[node];
      T edge = s[n - pos];
      int &v = next[node][edge];
      T t = s[spos[v] + pos - 1];
      if (v == 0) {
        v = make_node(n - pos);
        link[last] = node;
        last = 0;
      } else if (t == c) {
        link[last] = node;
        return;
      } else {
        int u = make_node(spos[v], pos - 1);
        next[u][c] = make_node(n - 1);
        next[u][t] = v;
        spos[v] += pos - 1;
        len[v] -= pos - 1;
        v = last = link[last] = u;
      }
      if (node == 0)
        pos--;
      else
        node = link[node];
    }
  }
  vector<int> from, dist;
  vector<vector<long long>> dp;
  vector<long long> ans;
  void dfs1(int u, int l) {
    if (next[u].empty()) {
      dp[u][from[l]] = 1;
    }
    for (auto v : next[u]) {
      dfs1(v.second, l + get_len(v.second));
      for (int i = 0; i < 3; ++i) dp[u][i] += dp[v.second][i];
    }
  }
  void update(int a, int b, long long x) {
    if (a > b) return;
    ++b;
    ans[a] += x;
    ans[b] -= x;
    if (ans[a] >= mod) ans[a] -= mod;
    if (ans[b] < 0) ans[b] += mod;
  }
  void dfs2(int u, int l) {
    if (u && all(dp[u]))
      update(l + 1, l + min(get_len(u), dist[spos[u]]), prod(dp[u]));
    if (dist[spos[u]] + 1 > get_len(u))
      for (auto v : next[u]) dfs2(v.second, l + get_len(u));
  }
  int get_len(int p) {
    return p == 0 ? 0 : min(len[p], (int)s.size() - spos[p]);
  }
};
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0);
  vector<string> a(3);
  for (auto &i : a) cin >> i;
  suffix_tree<short> st;
  int sz = 0, mn = 1 << 30;
  for (int i = 0; i < 3; ++i) {
    for (auto j : a[i]) st.extend(j - 'a');
    st.extend(100 + i);
    mn = min(mn, (int)a[i].length());
  }
  sz = st.next.size();
  st.dp.resize(sz + 2, vector<long long>(3));
  st.from.resize(sz + 2);
  st.dist.resize(sz + 2, 1 << 30);
  sz = 0;
  for (int i = 2; i >= 0; --i) {
    for (int j = 1; j <= a[i].length() + 1; ++j) st.from[sz + j] = i;
    sz += a[i].length() + 1;
  }
  for (int i = st.s.size() - 1; i >= 0; --i) {
    if (st.s[i] >= 100) st.dist[i] = 0;
    st.dist[i] = min(st.dist[i], st.dist[i + 1] + 1);
  }
  st.ans.resize(mn + 2);
  st.dfs1(0, 0);
  st.dfs2(0, 0);
  for (int i = 1; i <= mn; ++i) {
    st.ans[i] += st.ans[i - 1];
    if (st.ans[i] >= mod) st.ans[i] -= mod;
    cout << st.ans[i] << " \n"[i == mn];
  }
  return 0;
}
