#include <bits/stdc++.h>   using namespace std;   namespace Elaina {   template <class T>   inline T Max(const T x, const T y) {     return x < y ? y : x;   }   template <class T>   inline T Min(const T x, const T y) {     return x < y ? x : y;   }   template <class T>   inline T fab(const T x) {     return x < 0 ? -x : x;   }   template <class T>   inline void getMax(T& x, const T y) {     x = Max(x, y);   }   template <class T>   inline void getMin(T& x, const T y) {     x = Min(x, y);   }   template <class T>   T gcd(const T x, const T y) {     return y ? gcd(y, x % y) : x;   }   template <class T>   inline T readin(T x) {     x = 0;     int f = 0;     char c;     while ((c = getchar()) <  0  ||  9  < c)       if (c ==  - ) f = 1;     for (x = (c ^ 48);  0  <= (c = getchar()) && c <=  9 ;          x = (x << 1) + (x << 3) + (c ^ 48))       ;     return f ? -x : x;   }   template <class T>   void fwrit(const T x) {     if (x < 0) return putchar( - ), fwrit(-x);     if (x > 9) fwrit(x / 10);     putchar(x % 10 ^ 48);   }   }  // namespace Elaina   using namespace Elaina;   const int maxn = 3e5;   const int jzm = 1000000007;   char fuck[maxn + 5];   int min_len;   char s[maxn + 5];   int n;   int tot[maxn + 5][4];   int sy = 0;   int ans[maxn + 5];   inline void addchar(const char c, const int i) {     ++n;     s[n] = c, ++tot[n][i];   }   inline void init() {     min_len = (1 << 30);     for (int id = 1, id_end_ = 3; id <= id_end_; ++id) {       scanf( %s , fuck + 1);       int len = strlen(fuck + 1);       for (int i = 1, i_end_ = len; i <= i_end_; ++i) addchar(fuck[i], id);       addchar( z  + id, 0);       min_len = Min(min_len, len);     }     --n;   }   int sa[maxn + 5], x[maxn * 2 + 5], y[maxn * 2 + 5], c[maxn + 5], lev;   inline void getsa() {     lev =  z  + 3;     for (int i = 1, i_end_ = n; i <= i_end_; ++i) ++c[x[i] = s[i]];     for (int i = 2, i_end_ = lev; i <= i_end_; ++i) c[i] += c[i - 1];     for (int i = n, i_end_ = 1; i >= i_end_; --i) sa[c[x[i]]--] = i;     for (int k = 1; k <= n; k <<= 1) {       int sz = 0;       for (int i = n - k + 1, i_end_ = n; i <= i_end_; ++i) y[++sz] = i;       for (int i = 1, i_end_ = n; i <= i_end_; ++i)         if (sa[i] > k) y[++sz] = sa[i] - k;       for (int i = 1, i_end_ = lev; i <= i_end_; ++i) c[i] = 0;       for (int i = 1, i_end_ = n; i <= i_end_; ++i) ++c[x[i]];       for (int i = 2, i_end_ = lev; i <= i_end_; ++i) c[i] += c[i - 1];       for (int i = n, i_end_ = 1; i >= i_end_; --i)         sa[c[x[y[i]]]--] = y[i], y[i] = 0;       swap(x, y);       x[sa[1]] = 1;       int level = 1;       for (int i = 2, i_end_ = n; i <= i_end_; ++i)         x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k])                        ? level                        : ++level;       if (level == n) break;       lev = level;     }   }   int heit[maxn + 5], rk[maxn + 5];   inline void getheit() {     int h = 0;     for (int i = 1, i_end_ = n; i <= i_end_; ++i) rk[sa[i]] = i;     for (int i = 1, i_end_ = n; i <= i_end_; ++i) {       if (rk[i] == 1) continue;       if (h) --h;       int j = sa[rk[i] - 1];       while (i + h <= n && j + h <= n && s[i + h] == s[j + h]) ++h;       heit[rk[i]] = h;     }   }   struct node {     int x, v;     inline int operator<(const node rhs) const { return v > rhs.v; }   } v[maxn + 5 + 5];   int fa[maxn + 5];   int find(const int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }   int cock(const int x) {     return 1ll * tot[x][1] * tot[x][2] % jzm * tot[x][3] % jzm;   }   inline void merge(int x, int y) {     x = find(x), y = find(y);     if (x == y) return;     sy -= cock(x);     if (sy < 0) sy += jzm;     sy -= cock(y);     if (sy < 0) sy += jzm;     fa[x] = y;     for (int j = 1, j_end_ = 3; j <= j_end_; ++j) tot[y][j] += tot[x][j];     sy += cock(y);     if (sy >= jzm) sy -= jzm;   }   inline void solve() {     for (int i = 1, i_end_ = n; i <= i_end_; ++i) v[i] = node{sa[i], heit[i]};     for (int i = 1, i_end_ = n; i <= i_end_; ++i) fa[i] = i;     sort(v + 1, v + n + 1);     int now = 1;     for (int i = min_len, i_end_ = 1; i >= i_end_; --i) {       while (now <= n && v[now].v >= i) {         int pre = sa[rk[v[now].x] - 1];         merge(pre, v[now].x);         ++now;       }       ans[i] = sy;     }     for (int i = 1, i_end_ = min_len; i <= i_end_; ++i) printf( %d  , ans[i]);   }   signed main() {     init();     getsa();     getheit();     solve();     return 0;   }