#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int maxn = 6e5 + 20, N = 26;
struct Node {
  int mxCnt;
  int miCnt;
  int id;
  int pos;
  bool flag;
  bool R[3];
  struct Node *pNext[N], *fa;
} suffixAutomaton[maxn], *root, *last;
int t;
struct Node *create(int mxCnt = -1, struct Node *node = NULL) {
  if (mxCnt != -1) {
    suffixAutomaton[t].mxCnt = mxCnt, suffixAutomaton[t].fa = NULL;
    for (int i = 0; i < N; ++i) suffixAutomaton[t].pNext[i] = NULL;
  } else {
    suffixAutomaton[t] = *node;
  }
  suffixAutomaton[t].id = t;
  suffixAutomaton[t].flag = false;
  return &suffixAutomaton[t++];
}
void addChar(int x, int pos, int id) {
  struct Node *p = last;
  if (p->pNext[x] != NULL) {
    struct Node *q = p->pNext[x];
    if (p->mxCnt + 1 == q->mxCnt) {
      last = q;
      q->flag = true;
      q->R[id] = true;
      return;
    }
    struct Node *nq = create(-1, q);
    for (int i = 0; i < 3; ++i) nq->R[i] = false;
    nq->mxCnt = p->mxCnt + 1;
    nq->R[id] = true;
    nq->flag = true;
    q->fa = nq;
    q->miCnt = nq->mxCnt + 1;
    for (; p && p->pNext[x] == q; p = p->fa) p->pNext[x] = nq;
    last = nq;
    return;
  }
  struct Node *np = create(p->mxCnt + 1, NULL);
  for (int i = 0; i < 3; ++i) np->R[i] = false;
  np->R[id] = true;
  np->flag = true;
  np->pos = pos, last = np;
  for (; p != NULL && p->pNext[x] == NULL; p = p->fa) p->pNext[x] = np;
  if (p == NULL) {
    np->fa = root;
    np->miCnt = 1;
    return;
  }
  struct Node *q = p->pNext[x];
  if (q->mxCnt == p->mxCnt + 1) {
    np->fa = q;
    np->miCnt = q->mxCnt + 1;
    return;
  }
  struct Node *nq = create(-1, q);
  for (int i = 0; i < 3; ++i) nq->R[i] = false;
  nq->mxCnt = p->mxCnt + 1;
  q->miCnt = nq->mxCnt + 1, np->miCnt = nq->mxCnt + 1;
  q->fa = nq, np->fa = nq;
  for (; p && p->pNext[x] == q; p = p->fa) {
    p->pNext[x] = nq;
  }
}
void init() {
  t = 0;
  root = last = create(0, NULL);
}
char str[maxn];
long long int dp[maxn][3];
queue<int> que;
int in[maxn];
long long int ans[maxn];
void work() {
  init();
  int len = (0x3f3f3f3f);
  for (int i = 0; i < 3; ++i) {
    last = root;
    scanf("%s", str + 1);
    int t = 0;
    for (int j = 1; str[j]; ++j) {
      t++;
      addChar(str[j] - 'a', j, i);
    }
    len = min(len, t);
  }
  for (int i = 1; i < t; ++i) {
    in[suffixAutomaton[i].fa->id]++;
    if (suffixAutomaton[i].flag) {
      for (int j = 0; j < 3; ++j) {
        dp[i][j] = suffixAutomaton[i].R[j];
      }
    }
  }
  for (int i = 1; i < t; ++i) {
    if (in[i] == 0) {
      que.push(i);
    }
  }
  while (!que.empty()) {
    int cur = que.front();
    que.pop();
    if (!cur) break;
    for (int i = 0; i < 3; ++i) {
      dp[suffixAutomaton[cur].fa->id][i] += dp[cur][i];
    }
    in[suffixAutomaton[cur].fa->id]--;
    if (in[suffixAutomaton[cur].fa->id] == 0)
      que.push(suffixAutomaton[cur].fa->id);
  }
  for (int i = 1; i < t; ++i) {
    long long int res = 1;
    for (int j = 0; j < 3; ++j) {
      res = res * dp[i][j] % MOD;
    }
    int en = suffixAutomaton[i].mxCnt;
    int be = suffixAutomaton[i].miCnt;
    ans[en + 1] = (ans[en + 1] - res + MOD) % MOD;
    ans[be] = (ans[be] + res) % MOD;
  }
  for (int i = 1; i <= len; ++i) {
    ans[i] = (ans[i] + ans[i - 1] + MOD) % MOD;
  }
  for (int i = 1; i <= len; ++i) {
    printf("%I64d ", ans[i]);
  }
}
int main() {
  work();
  return 0;
}
