#include <bits/stdc++.h>
inline unsigned int getuint() {
  char w = getchar();
  while (w < '0' || '9' < w) w = getchar();
  unsigned int ans = 0;
  for (; '0' <= w && w <= '9'; w = getchar()) ans = ans * 10 + w - '0';
  return ans;
}
const int mod = 1000000007;
int n;
char str[300005];
int sum[300005];
inline void add(int l, int r, long long x) {
  if (l <= r)
    sum[l] = (sum[l] + x) % mod, sum[r + 1] = (sum[r + 1] + mod - x) % mod;
}
struct Suffix_AutoMaton {
  struct node {
    node *s[26], *p;
    int maxlen, cnt[3];
    std::vector<std::pair<int, int> > vec;
  } pool[300005 << 1], *poolnow, *root, *topo[300005 << 1];
  node *insert(node *p, int f) {
    node *np = poolnow++;
    np->maxlen = p->maxlen + 1;
    for (; p && !p->s[f]; p = p->p) p->s[f] = np;
    if (p)
      if (p->s[f]->maxlen != p->maxlen + 1) {
        node *q = p->s[f], *nq = poolnow++;
        memcpy(nq->s, q->s, sizeof(q->s)),
            nq->p = q->p, nq->maxlen = p->maxlen + 1, q->p = np->p = nq;
        for (; p && p->s[f] == q; p = p->p) p->s[f] = nq;
      } else
        np->p = p->s[f];
    else
      np->p = root;
    return np;
  }
  void init(int n, char str[]) {
    root = (poolnow = pool)++;
    node *last = root;
    for (int i = 1; i <= n; i++)
      (last = insert(last, str[i] - 'a'))->cnt[0] = 1;
    static int c[300005];
    for (node *p = pool; p != poolnow; p++) c[p->maxlen]++;
    for (int i = 1; i <= n; i++) c[i] += c[i - 1];
    for (node *p = pool; p != poolnow; p++) topo[c[p->maxlen]--] = p;
    root->cnt[0] = 0;
  }
  void solve(int n) {
    int m, l;
    static char str[2][300005];
    scanf("%s%s", str[0] + 1, str[1] + 1), m = strlen(str[0] + 1),
                                           l = strlen(str[1] + 1);
    node *p = root;
    int now = 0;
    for (int i = 1; i <= m; i++) {
      int f = str[0][i] - 'a';
      for (; p && !p->s[f]; p = p->p)
        ;
      if (p)
        now = std::min(now, p->maxlen) + 1, p = p->s[f];
      else
        now = 0, p = root;
      if (now) p->p->cnt[1]++, p->vec.push_back(std::make_pair(now, 1));
    }
    p = root, now = 0;
    for (int i = 1; i <= l; i++) {
      int f = str[1][i] - 'a';
      for (; p && !p->s[f]; p = p->p)
        ;
      if (p)
        now = std::min(now, p->maxlen) + 1, p = p->s[f];
      else
        now = 0, p = root;
      if (now) p->p->cnt[2]++, p->vec.push_back(std::make_pair(now, 2));
    }
    for (int i = poolnow - pool; i > 1; i--)
      for (int f = 0; f < 3; f++) topo[i]->p->cnt[f] += topo[i]->cnt[f];
    for (node *p = pool + 1; p != poolnow; p++) {
      static int cnt[3];
      for (int f = 0; f < 3; f++) cnt[f] = p->cnt[f];
      std::sort(p->vec.begin(), p->vec.end());
      if (!p->vec.empty())
        add(p->vec[(int)p->vec.size() - 1].first + 1, p->maxlen,
            1ll * cnt[0] * cnt[1] % mod * cnt[2] % mod);
      else
        add(p->p->maxlen + 1, p->maxlen,
            1ll * cnt[0] * cnt[1] % mod * cnt[2] % mod);
      for (int l = (int)p->vec.size() - 1, r; ~l; l = r - 1) {
        for (r = l; r && p->vec[l].first == p->vec[r - 1].first; r--)
          ;
        for (int i = l; i >= r; i--) cnt[p->vec[i].second]++;
        if (r)
          add(p->vec[r - 1].first + 1, p->vec[l].first,
              1ll * cnt[0] * cnt[1] % mod * cnt[2] % mod);
        else
          add(p->p->maxlen + 1, p->vec[l].first,
              1ll * cnt[0] * cnt[1] % mod * cnt[2] % mod);
      }
    }
    for (int i = 1; i <= n; i++) (sum[i] += sum[i - 1]) %= mod;
    if (n > m) n = m;
    if (n > l) n = l;
    for (int i = 1; i <= n; i++) printf("%d%c", sum[i], " \n"[i == n]);
  }
} SAM;
int main() {
  scanf("%s", str + 1), n = strlen(str + 1), SAM.init(n, str), SAM.solve(n);
  return 0;
}
