#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T sqr(T x) {
  return x * x;
}
template <class T>
inline string tostr(const T &x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
inline long long parse(const string &s) {
  stringstream ss(s);
  long long x;
  ss >> x;
  return x;
}
const double EPS = 1e-9;
const int INF = 1000 * 1000 * 1000;
const char CINF = 102;
const long long LINF = INF * 1ll * INF;
const double DINF = 1e200;
const double PI = 3.1415926535897932384626433832795l;
int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
long long powmod(long long a, long long p, long long m) {
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
struct automaton {
  struct state {
    int len = 0;
    int asdlink = -1;
    int asdnext[27];
    bool term = false;
    int M = -1;
    int D[3] = {0, 0, 0};
    state() { memset(asdnext, -1, sizeof(asdnext)); }
  };
  vector<state> st = vector<state>(1);
  int last = 0;
  automaton() {}
  automaton(const string &s) {
    for (int i = 0; i < (((int)(s).size())); ++i) {
      extend(s[i]);
    }
    terms();
  }
  void extend(char c) {
    c -= 'a';
    int cur = ((int)(st).size());
    st.push_back(state());
    st[cur].len = st[last].len + 1;
    int p;
    for (p = last; p != -1 && st[p].asdnext[c] == -1; p = st[p].asdlink)
      st[p].asdnext[c] = cur;
    if (p == -1)
      st[cur].asdlink = 0;
    else {
      int q = st[p].asdnext[c];
      if (st[p].len + 1 == st[q].len)
        st[cur].asdlink = q;
      else {
        int clone = ((int)(st).size());
        st.push_back(state());
        st[clone].len = st[p].len + 1;
        memcpy(st[clone].asdnext, st[q].asdnext, sizeof(st[clone].asdnext));
        st[clone].asdlink = st[q].asdlink;
        for (; p != -1 && st[p].asdnext[c] == q; p = st[p].asdlink)
          st[p].asdnext[c] = clone;
        st[q].asdlink = st[cur].asdlink = clone;
      }
    }
    last = cur;
  }
  void terms() {
    for (int v = last; v != -1; v = st[v].asdlink) st[v].term = true;
  }
  void dfs(int v) {
    if (st[v].M != -1) return;
    if (st[v].term) {
      st[v].M = 0;
      st[v].D[0] = 1;
    }
    for (int i = 0; i < (27); ++i) {
      int t = st[v].asdnext[i];
      if (t == -1) continue;
      dfs(t);
      st[v].M = max(st[v].M, st[t].M + 1);
      if (i == 26) {
        for (int j = 1; j < 3; ++j) {
          st[v].D[j] += st[t].D[j - 1];
        }
      } else {
        for (int j = 0; j < (3); ++j) {
          st[v].D[j] += st[t].D[j];
        }
      }
    }
  }
  void MD() {
    for (int i = 0; i < (((int)(st).size())); ++i) {
      dfs(i);
    }
  }
};
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  string S[3];
  for (int i = 0; i < (3); ++i) {
    cin >> S[i];
  }
  string s = S[0] + '{' + S[1] + '{' + S[2];
  automaton A(s);
  A.MD();
  const long long mod = INF + 7;
  int L = min(min(((int)(S[0]).size()), ((int)(S[1]).size())),
              ((int)(S[2]).size()));
  vector<long long> add(L + 2);
  for (int i = 1; i < ((int)(A.st).size()); ++i) {
    const auto &st = A.st[i];
    long long x = 1ll * st.D[0] * st.D[1] % mod * st.D[2] % mod;
    if (!x) continue;
    int b = st.len;
    int a = A.st[st.asdlink].len + 1;
    int p = ((int)(s).size()) - st.M;
    int ps = -1;
    if (((int)(S[0]).size()) < p) ps = ((int)(S[0]).size());
    if (((int)(S[0]).size()) + 1 + ((int)(S[1]).size()) < p)
      ps = ((int)(S[0]).size()) + 1 + ((int)(S[1]).size());
    b = min(b, p - ps - 1);
    b = min(b, L);
    if (b < a) continue;
    ++b;
    (add[a] += x) %= mod;
    (add[b] += mod - x) %= mod;
  }
  long long r = 0;
  for (int i = 0; i < (((int)(add).size())); ++i) {
    (r += add[i]) %= mod;
    if (i >= 1 && i <= L) cout << r << ' ';
  }
  return 0;
}
