#include <bits/stdc++.h>
using namespace std;
using namespace placeholders;
template <class T>
void mini(T &l, T r) {
  l = min(l, r);
}
template <class T>
void maxi(T &l, T r) {
  l = max(l, r);
}
template <class TH>
void _dbg(const char *sdbg, TH h) {
  cerr << sdbg << "=" << h << "\n";
}
template <class TH, class... TA>
void _dbg(const char *sdbg, TH h, TA... a) {
  while (*sdbg != ',') cerr << *sdbg++;
  cerr << "=" << h << ",";
  _dbg(sdbg + 1, a...);
}
template <class T>
ostream &operator<<(ostream &os, vector<T> v) {
  os << "[";
  for (auto vv : v) os << vv << ",";
  return os << "]";
}
template <class L, class R>
ostream &operator<<(ostream &os, pair<L, R> p) {
  return os << "(" << p.first << "," << p.second << ")";
}
using llint = long long;
const int N = 3e5 + 10, SIG = 30, B = 1e9 + 7;
vector<int> e[N << 1];
char s[3][N];
llint d[N];
struct Node {
  Node *ch[SIG], *fa;
  int sz[3];
  int len;
  Node() : len(0), fa(NULL) {
    memset(ch, 0, sizeof(ch));
    memset(sz, 0, sizeof(sz));
  }
} pool[(N << 1) + 5], *last, *root;
void add_edge(int x, int y) { e[x].push_back(y); }
namespace SAM {
int cnt;
void init() {
  if (cnt)
    for (int i = 0; i < cnt; ++i) pool[i] = Node();
  cnt = 1;
  root = &pool[0];
  last = root;
}
void add(int c, int j) {
  Node *np = &pool[cnt++];
  np->sz[j] = 1;
  np->len = last->len + 1;
  Node *p = last;
  while (p && !p->ch[c]) {
    p->ch[c] = np;
    p = p->fa;
  }
  if (!p) {
    np->fa = root;
  } else {
    Node *q = p->ch[c];
    if (q->len != p->len + 1) {
      Node *nq = &pool[cnt++];
      nq->len = p->len + 1;
      for (int i = 0; i < SIG; ++i) nq->ch[i] = q->ch[i];
      nq->fa = q->fa;
      q->fa = np->fa = nq;
      while (p && p->ch[c] == q) {
        p->ch[c] = nq;
        p = p->fa;
      }
    } else {
      np->fa = q;
    }
  }
  last = np;
}
void add_fa_tree() {
  for (int i = 1; i < cnt; ++i) {
    assert(pool[i].fa - pool != i);
    add_edge(pool[i].fa - pool, i);
  }
}
void dfs(int v, int f) {
  for (int u : e[v]) {
    if (u == f) continue;
    dfs(u, v);
    for (int j = 0; j < 3; ++j) pool[v].sz[j] += pool[u].sz[j];
  }
}
}  // namespace SAM
void add(llint &a, llint b) {
  a = (a + b) % B;
  if (a < 0) a += B;
}
void add(int l, int r, llint b) {
  ;
  add(d[l], b);
  add(d[r + 1], -b);
}
llint calc(const Node &a) { return 1ll * a.sz[0] * a.sz[1] % B * a.sz[2] % B; }
void run() {
  SAM::init();
  for (int i = 0; i < 3; ++i) scanf("%s", s[i]);
  int mn_len = N;
  for (int i = 0; i < 3; ++i) {
    int m = strlen(s[i]);
    mn_len = min(mn_len, m);
    for (int j = 0; j < m; ++j) {
      SAM::add(s[i][j] - 'a', i);
    }
    SAM::add(26 + i, i);
  }
  SAM::add_fa_tree();
  SAM::dfs(0, 0);
  for (int i = 1; i < SAM::cnt; ++i) {
    int l = pool[i].fa->len + 1, r = pool[i].len;
    add(l, r, calc(pool[i]));
  }
  for (int i = 1; i <= mn_len; ++i) {
    add(d[i], d[i - 1]);
  }
  for (int i = 1; i <= mn_len; ++i) printf("%lld%c", d[i], " \n"[i == mn_len]);
}
int main() {
  run();
  return 0;
}
