#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll MOD = 1000000007;

struct sTree{
    int L, R;
    int pl, pr;
    int ind;
} tree[600009];
int treeSize;

int LCP[300009];

int BuildTree(int L, int R)
{
    int cur = treeSize++;
    tree[cur].L = L;
    tree[cur].R = R;
    tree[cur].ind = -1;
    if (L < R) {
        tree[cur].pl = BuildTree(L, (L+R)/2);
        tree[cur].pr = BuildTree((L+R)/2+1, R);
    }
    return cur;
}

int GetInd(int L, int R, int cur)
{
    if (L <= tree[cur].L && R >= tree[cur].R)
        return tree[cur].ind;

    int ret = -1;
    if (L <= tree[ tree[cur].pl ].R && tree[ tree[cur].pl ].L <= R) {
        int tmp = GetInd(L, R, tree[cur].pl);
        if (ret == -1 || (tmp != -1 && LCP[tmp] < LCP[ret]))
            ret = tmp;
    }
    if (L <= tree[ tree[cur].pr ].R && tree[ tree[cur].pr ].L <= R) {
        int tmp = GetInd(L, R, tree[cur].pr);
        if (ret == -1 || (tmp != -1 && LCP[tmp] < LCP[ret]))
            ret = tmp;
    }

    return ret;
}

void Update(int i, int cur)
{
    if (tree[cur].L == tree[cur].R) {
        tree[cur].ind = i;
        return;
    }

    if (i <= tree[ tree[cur].pl ].R)
        Update(i, tree[cur].pl);
    else
        Update(i, tree[cur].pr);

    int left = tree[ tree[cur].pl ].ind;
    int right = tree[ tree[cur].pr ].ind;

    if (left == -1 || (right != -1 && LCP[right] < LCP[left]))
        tree[cur].ind = right;
    else
        tree[cur].ind = left;
}

int root;
char S[300009];
int sufArr[300009];
bool update[300009];
int next[300009];
int posInSufArr[300009];
int newSufArr[300009];
int bucket[300009];

void BuildSufArr(int N)
{
    memset(LCP, -1, sizeof(int) * N);
    int cnt[256]; memset(cnt, 0, sizeof(int) * 256);
    for (int i = 0; i < N; i++) {
        cnt[ S[i] ]++;
    }
    for (int i = 1; i < 256; i++) {
        cnt[i] += cnt[i-1];
    }
    for (int i = 0; i < N; i++) {
        sufArr[ --cnt[S[i]] ] = i;
    }

    root = BuildTree(0, N-1);

    bucket[0] = 0;
    for (int i = 1; i < N; i++) {
        if (S[sufArr[i-1]] == S[sufArr[i]]) {
            bucket[i] = bucket[i-1];
        }
        else {
            bucket[i] = i;
            LCP[i] = 0;
            Update(i, root);
        }
    }

    for (int step = 1; step < N; step *= 2) {
        memcpy(newSufArr, sufArr, sizeof(int) * N);
        for (int i = 0; i < N; i++) {
            posInSufArr[ sufArr[i] ] = i;
            next[i] = bucket[i];
        }
        for (int i = 0; i < N; i++) {
            if (sufArr[i] >= step) {
                newSufArr[ next [ bucket[ posInSufArr[ sufArr[i]-step ] ] ]++ ] = sufArr[i]-step;
            }
        }

        memcpy(sufArr, newSufArr, sizeof(int) * N);

        for (int i = 1; i < N; i++) {
            if (LCP[i] == -1 && bucket[posInSufArr[sufArr[i] + step]] != bucket[posInSufArr[sufArr[i-1] + step]]) {
                int L = posInSufArr[sufArr[i] + step];
                int R = posInSufArr[sufArr[i-1] + step];
                if (L > R) {
                    swap(L, R);
                }
                LCP[i] = step + LCP[ GetInd(L+1, R, root) ];
                update[i] = true;
            }
        }

        bucket[0] = 0;
        for (int i = 1; i < N; i++) {
            if (LCP[i] != -1) {
                bucket[i] = i;
            }
            else {
                bucket[i] = bucket[i-1];
            }
        }

        for (int i = 0; i < N; i++) {
            if (update[i]) {
                Update(i, root);
                update[i] = false;
            }
        }
    }
}

ll c1[300009], c2[300009], c3[300009];
ll ans[300009];

void Solve(int L, int R, int k)
{
    if (L >= R) return;
    ll sum = (c1[R] - c1[L-1]) * (c2[R] - c2[L-1]) * (c3[R] - c3[L-1]);
    sum %= MOD;

    int i = GetInd(L+1, R, root);

    ans[k] = (ans[k] + sum) % MOD;
    ans[ LCP[i] + 1 ] = (ans[ LCP[i] + 1 ] - sum + MOD) % MOD;

    Solve(L, i-1, LCP[i] + 1);
    Solve(i, R, LCP[i] + 1);
}

int main()
{
    //freopen("input.txt", "r", stdin);

    ios::sync_with_stdio(false);

    int n1 = 0, n2 = 0, n3 = 0;
    int N = 0;

    cin >> S;
    n1 = strlen(S);
    S[n1] = 'a'-1;
    N = n1+1;

    cin >> S+N;
    n2 = strlen(S+N);
    S[N+n2] = 'a'-2;
    N += n2+1;

    cin >> S+N;
    n3 = strlen(S+N);
    S[N+n3] = 'a'-3;
    N += n3+1;

    BuildSufArr(N);

    for (int i = 1; i < N; i++) {
        c1[i] = c1[i-1];
        c2[i] = c2[i-1];
        c3[i] = c3[i-1];

        if (sufArr[i] < n1) {
            c1[i]++;
        }
        if (sufArr[i] >= n1 + 1 && sufArr[i] < n1+n2+1) {
            c2[i]++;
        }
        if (sufArr[i] >= n1+n2+2 && sufArr[i] < N) {
            c3[i]++;
        }
    }

    Solve(3, N-1, 1);

    int m = min(min(n1, n2), n3);
    for (int i = 1; i <= m; i++) {
        ans[i] = (ans[i] + ans[i-1]) % MOD;
        cout << ans[i] << " ";
    }
}


#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <cmath>
#include <cassert>
#include <bitset>
using namespace std;
typedef long long LL;

const int N = 300005;
int n , K; char s[N];
int sa[N] , t1[N] , t2[N] , c[N];
int rank[N] , height[N];
pair<int , int> f[19][N];
void buildsa(int m)
{
    int i , k , *x = t1 , *y = t2;
    for (i = 0 ; i < m ; ++ i) c[i] = 0;
    for (i = 0 ; i < n ; ++ i) ++ c[x[i] = s[i]];
    for (i = 1 ; i < m ; ++ i) c[i] += c[i - 1];
    for (i = n - 1 ; i >= 0 ; -- i) sa[-- c[x[i]]] = i;
    for (k = 1 ; k <= n ; k <<= 1) {
        int p = 0;
        for (i = n - k ; i < n ; ++ i) y[p ++] = i;
        for (i = 0 ; i < n ; ++ i) if (sa[i] >= k) y[p ++] = sa[i] - k;
        for (i = 0 ; i < m ; ++ i) c[i] = 0;
        for (i = 0 ; i < n ; ++ i) ++ c[x[y[i]]];
        for (i = 1 ; i < m ; ++ i) c[i] += c[i - 1];
        for (i = n - 1 ; i >= 0 ; -- i) sa[-- c[x[y[i]]]] = y[i];
        swap(x , y) , p = 1 , x[sa[0]] = 0;
        for (i = 1 ; i < n ; ++ i)
            x[sa[i]] = (y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k]) ? p - 1 : p ++;
        if (p >= n) break;
        m = p;
    }
    k = 0;
    for (i = 0 ; i < n ; ++ i) rank[sa[i]] = i;
    for (i = 0 ; i < n ; ++ i) {
        if (k) -- k; if (!rank[i]) continue;
        int j = sa[rank[i] - 1];
        while (s[i + k] == s[j + k]) ++ k;
        height[rank[i]] = k;
    }
    for (i = 0 ; i < n ; ++ i)
        f[0][i] = make_pair(height[i] , i);
    for (int j = 1 ; 1 << j <= n ; ++ j)
        for (i = 1 ; i + (1 << j) - 1 < n ; ++ i)
            f[j][i] = min(f[j - 1][i] , f[j - 1][i + (1 << j - 1)]);
}
int L1 , L2 , L3;
int sf1[N] , sf2[N] , sf3[N];
LL ans[N]; const int Q = 1e9 + 7;
/*
    L1 [0 , L1)
    L2 [L1 + 1 , L1 + L2 + 1)
    L3 [L1 + L2 + 2 , L1 + L2 + L3 + 2)
*/

pair<int , int> RMQ(int x , int y) {
    int j = log2(y - x + 1);
    return min(f[j][x] , f[j][y - (1 << j) + 1]);
}

void cal(int l , int r) {
    if (l >= r) return;
    pair<int , int> j = RMQ(l + 1 , r);
    int m = j.second;
    // [l , m - 1] , [m , r];
    cal(l , m - 1);
    cal(m , r);
    ans[j.first] += (LL)(sf1[r] - sf1[m - 1]) * (sf2[m - 1] - sf2[l - 1]) * (sf3[m - 1] - sf3[l - 1]) % Q;
    ans[j.first] += (LL)(sf2[r] - sf2[m - 1]) * (sf1[m - 1] - sf1[l - 1]) * (sf3[m - 1] - sf3[l - 1]) % Q;
    ans[j.first] += (LL)(sf3[r] - sf3[m - 1]) * (sf2[m - 1] - sf2[l - 1]) * (sf1[m - 1] - sf1[l - 1]) % Q;
    ans[j.first] += (LL)(sf1[m - 1] - sf1[l - 1]) * (sf2[r] - sf2[m - 1]) * (sf3[r] - sf3[m - 1]) % Q;
    ans[j.first] += (LL)(sf2[m - 1] - sf2[l - 1]) * (sf1[r] - sf1[m - 1]) * (sf3[r] - sf3[m - 1]) % Q;
    ans[j.first] += (LL)(sf3[m - 1] - sf3[l - 1]) * (sf2[r] - sf2[m - 1]) * (sf1[r] - sf1[m - 1]) % Q;
    ans[j.first] %= Q;
}

void work() {
    int i , j , k;
    scanf("%s" , s);
    L1 = n = strlen(s);
    s[n ++] = '@';
    scanf("%s" , s + n);
    n += (L2 = strlen(s + n));
    s[n ++] = '$';
    scanf("%s" , s + n);
    n += (L3 = strlen(s + n));
    s[n ++] = '%';
    buildsa(128);
    for (i = 3 ; i < n ; ++ i) {
        //printf("%s\n" , s + sa[i]);
        sf1[i] = sf1[i - 1];
        sf2[i] = sf2[i - 1];
        sf3[i] = sf3[i - 1];
        if (sa[i] < L1)
            ++ sf1[i];
        else if (sa[i] < L1 + L2 + 1)
            ++ sf2[i];
        else
            ++ sf3[i];
    }
    cal(3 , n - 1);
    for (i = min(L1 , min(L2 , L3)) ; i >= 1 ; -- i) {
        ans[i - 1] += ans[i];
        ans[i - 1] %= Q;
    }
    for (i = 1 ; i <= min(L1 , min(L2 , L3)) ; ++ i)
        printf("%d " , (int)ans[i]);
    puts("");
}

int main()
{
    work();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <cmath>
#include <cassert>
#include <bitset>
using namespace std;
typedef long long LL;

const int N = 300005;
int n , K; char s[N];
int sa[N] , t1[N] , t2[N] , c[N];
int rank[N] , height[N];
pair<int , int> f[19][N];
void buildsa(int m)
{
    int i , k , *x = t1 , *y = t2;
    for (i = 0 ; i < m ; ++ i) c[i] = 0;
    for (i = 0 ; i < n ; ++ i) ++ c[x[i] = s[i]];
    for (i = 1 ; i < m ; ++ i) c[i] += c[i - 1];
    for (i = n - 1 ; i >= 0 ; -- i) sa[-- c[x[i]]] = i;
    for (k = 1 ; k <= n ; k <<= 1) {
        int p = 0;
        for (i = n - k ; i < n ; ++ i) y[p ++] = i;
        for (i = 0 ; i < n ; ++ i) if (sa[i] >= k) y[p ++] = sa[i] - k;
        for (i = 0 ; i < m ; ++ i) c[i] = 0;
        for (i = 0 ; i < n ; ++ i) ++ c[x[y[i]]];
        for (i = 1 ; i < m ; ++ i) c[i] += c[i - 1];
        for (i = n - 1 ; i >= 0 ; -- i) sa[-- c[x[y[i]]]] = y[i];
        swap(x , y) , p = 1 , x[sa[0]] = 0;
        for (i = 1 ; i < n ; ++ i)
            x[sa[i]] = (y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k]) ? p - 1 : p ++;
        if (p >= n) break;
        m = p;
    }
    k = 0;
    for (i = 0 ; i < n ; ++ i) rank[sa[i]] = i;
    for (i = 0 ; i < n ; ++ i) {
        if (k) -- k; if (!rank[i]) continue;
        int j = sa[rank[i] - 1];
        while (s[i + k] == s[j + k]) ++ k;
        height[rank[i]] = k;
    }
    for (i = 0 ; i < n ; ++ i)
        f[0][i] = make_pair(height[i] , i);
    for (int j = 1 ; 1 << j <= n ; ++ j)
        for (i = 1 ; i + (1 << j) - 1 < n ; ++ i)
            f[j][i] = min(f[j - 1][i] , f[j - 1][i + (1 << j - 1)]);
}
int L1 , L2 , L3;
int sf1[N] , sf2[N] , sf3[N];
LL ans[N]; const int Q = 1e9 + 7;
/*
    L1 [0 , L1)
    L2 [L1 + 1 , L1 + L2 + 1)
    L3 [L1 + L2 + 2 , L1 + L2 + L3 + 2)
*/

pair<int , int> RMQ(int x , int y) {
    int j = log2(y - x + 1);
    return min(f[j][x] , f[j][y - (1 << j) + 1]);
}

void cal(int l , int r) {
    if (l >= r) return;
    pair<int , int> j = RMQ(l + 1 , r);
    int m = j.second;
    // [l , m - 1] , [m , r];
    cal(l , m - 1);
    cal(m , r);
    ans[j.first] += (LL)(sf1[r] - sf1[m - 1]) * (sf2[m - 1] - sf2[l - 1]) * (sf3[m - 1] - sf3[l - 1]) % Q;
    ans[j.first] += (LL)(sf2[r] - sf2[m - 1]) * (sf1[m - 1] - sf1[l - 1]) * (sf3[m - 1] - sf3[l - 1]) % Q;
    ans[j.first] += (LL)(sf3[r] - sf3[m - 1]) * (sf2[m - 1] - sf2[l - 1]) * (sf1[m - 1] - sf1[l - 1]) % Q;
    ans[j.first] += (LL)(sf1[m - 1] - sf1[l - 1]) * (sf2[r] - sf2[m - 1]) * (sf3[r] - sf3[m - 1]) % Q;
    ans[j.first] += (LL)(sf2[m - 1] - sf2[l - 1]) * (sf1[r] - sf1[m - 1]) * (sf3[r] - sf3[m - 1]) % Q;
    ans[j.first] += (LL)(sf3[m - 1] - sf3[l - 1]) * (sf2[r] - sf2[m - 1]) * (sf1[r] - sf1[m - 1]) % Q;
    ans[j.first] %= Q;
}

void work() {
    int i , j , k;
    scanf("%s" , s);
    L1 = n = strlen(s);
    s[n ++] = '@';
    scanf("%s" , s + n);
    n += (L2 = strlen(s + n));
    s[n ++] = '$';
    scanf("%s" , s + n);
    n += (L3 = strlen(s + n));
    s[n ++] = '%';
    buildsa(128);
    for (i = 3 ; i < n ; ++ i) {
        //printf("%s\n" , s + sa[i]);
        sf1[i] = sf1[i - 1];
        sf2[i] = sf2[i - 1];
        sf3[i] = sf3[i - 1];
        if (sa[i] < L1)
            ++ sf1[i];
        else if (sa[i] < L1 + L2 + 1)
            ++ sf2[i];
        else
            ++ sf3[i];
    }
    cal(3 , n - 1);
    for (i = min(L1 , min(L2 , L3)) ; i >= 1 ; -- i) {
        ans[i - 1] += ans[i];
        ans[i - 1] %= Q;
    }
    for (i = 1 ; i <= min(L1 , min(L1 , L2)) ; ++ i)
        printf("%d " , (int)ans[i]);
    puts("");
}

int main()
{
    work();
    return 0;
}


#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 600010;
const int Mod = 1e9 + 7;

struct Event {
	int time;
	long long delta;
	Event( int time, long long delta ):time(time),delta(delta){}
};
bool operator<( const Event &r, const Event &s ) {
	return r.time < s.time;
}
vector<Event> events;

void upd( long long &a, long long b ) {
	a += b;
	if( a >= Mod ) a -= Mod;
}
struct SuffixAutomation {
	int son[N][28], maxlen[N], link[N], ntot, last;
	int rcnt[N][3];
	int head[N], dest[N], next[N], etot;
	int lf[3], rg[3];

	void adde( int u, int v ) {
		etot++;
		next[etot] = head[u];
		dest[etot] = v;
		head[u] = etot;
	}
	void init( int len1, int len2, int len3 ) {
		link[0] = -1;
		lf[0] = 1, rg[0] = len1;
		lf[1] = len1+1+1, rg[1] = len1+1+len2;
		lf[2] = len1+len2+2+1, rg[2] = len1+len2+2+len3;
	}
	void append( int c ) {
		int p = last;
		int np = ++ntot;

		memset( son[np], 0, sizeof(son[np]) );
		maxlen[np] = maxlen[p] + 1;
		rcnt[np][0] = rcnt[np][1] = rcnt[np][2] = 0;
		for( int i = 0; i < 3; i++ )
			if( lf[i] <= maxlen[np] && maxlen[np] <= rg[i] ) {
				rcnt[np][i]++;
				break;
			}
		while( p != -1 && !son[p][c] )
			son[p][c] = np, p = link[p];
		if( p == -1 ) {
			link[np] = 0;
		} else {
			int q = son[p][c];
			if( maxlen[p] + 1 == maxlen[q] ) {
				link[np] = q;
			} else {
				int nq = ++ntot;
				memcpy( son[nq], son[q], sizeof(son[nq]) );
				maxlen[nq] = maxlen[p] + 1;
				link[nq] = link[q];
				link[q] = link[np] = nq;
				rcnt[nq][0] = rcnt[nq][1] = rcnt[nq][2] = 0;
				while( p != -1 && son[p][c] == q )
					son[p][c] = nq, p = link[p];
			}
		}
		last = np;
	}
	void dfs( int u ) {
		for( int t = head[u]; t; t = next[t] ) {
			int v = dest[t];
			dfs(v);
			for( int j = 0; j < 3; j++ )
				rcnt[u][j] += rcnt[v][j];
		}
	}
	void right() {
		for( int u = 1; u <= ntot; u++ )
			adde( link[u], u );
		dfs( 0 );
	}
	void add( int lf, int rg, long long delta ) {
		events.push_back( Event(lf,+delta) );
		events.push_back( Event(rg+1,-delta) );
	}
	void solve() {
		for( int u = 1; u <= ntot; u++ ) {
			if( !rcnt[u][0] || !rcnt[u][1] || !rcnt[u][2] ) continue;
			long long cnt = 1LL * rcnt[u][0] * rcnt[u][1] % Mod * rcnt[u][2] % Mod;
			add( maxlen[link[u]]+1, maxlen[u], cnt );
		}
	}
}sam;

int n[3], nmin;
char s[3][N];

int main() {
	for( int i = 0; i < 3; i++ ) {
		scanf( "%s", s[i] + 1 );
		n[i] = (int)strlen(s[i] + 1);
	}
	nmin = min( n[0], min( n[1], n[2] ) );
	sam.init(n[0], n[1], n[2]);
	for( int i = 0; i < 3; i++ ) {
		for( int j = 1; j <= n[i]; j++ )
			sam.append( s[i][j] - 'a' );
		if( i != 2 ) sam.append( 26 + i );
	}
	sam.right();
	sam.solve();
	sort( events.begin(), events.end() );
	long long sum = 0;
	int cur = -1;
	for( int i = 1; i <= nmin; i++ ) {
		while( cur+1<events.size() && events[cur+1].time <= i ) {
			upd( sum, events[cur+1].delta );
			cur++;
		}
		printf( "%d%s", (int)sum, i==nmin ? "\n" : " " );
	}
}


#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 600010;
const int Mod = 1e9 + 7;

struct Event {
	int time;
	long long delta;
	Event( int time, long long delta ):time(time),delta(delta){}
};
bool operator<( const Event &r, const Event &s ) {
	return r.time < s.time;
}
vector<Event> events;

void upd( long long &a, long long b ) {
	a += b;
	if( a < 0 ) a += Mod;
	if( a >= Mod ) a -= Mod;
}
struct SuffixAutomation {
	int son[N][28], maxlen[N], link[N], ntot, last;
	int rcnt[N][3];
	int head[N], dest[N], next[N], etot;
	int lf[3], rg[3];

	void adde( int u, int v ) {
		etot++;
		next[etot] = head[u];
		dest[etot] = v;
		head[u] = etot;
	}
	void init( int len1, int len2, int len3 ) {
		link[0] = -1;
		lf[0] = 1, rg[0] = len1;
		lf[1] = len1+1+1, rg[1] = len1+1+len2;
		lf[2] = len1+len2+2+1, rg[2] = len1+len2+2+len3;
	}
	void append( int c ) {
		int p = last;
		int np = ++ntot;

		memset( son[np], 0, sizeof(son[np]) );
		maxlen[np] = maxlen[p] + 1;
		rcnt[np][0] = rcnt[np][1] = rcnt[np][2] = 0;
		for( int i = 0; i < 3; i++ )
			if( lf[i] <= maxlen[np] && maxlen[np] <= rg[i] ) {
				rcnt[np][i]++;
				break;
			}
		while( p != -1 && !son[p][c] )
			son[p][c] = np, p = link[p];
		if( p == -1 ) {
			link[np] = 0;
		} else {
			int q = son[p][c];
			if( maxlen[p] + 1 == maxlen[q] ) {
				link[np] = q;
			} else {
				int nq = ++ntot;
				memcpy( son[nq], son[q], sizeof(son[nq]) );
				maxlen[nq] = maxlen[p] + 1;
				link[nq] = link[q];
				link[q] = link[np] = nq;
				rcnt[nq][0] = rcnt[nq][1] = rcnt[nq][2] = 0;
				while( p != -1 && son[p][c] == q )
					son[p][c] = nq, p = link[p];
			}
		}
		last = np;
	}
	void dfs( int u ) {
		for( int t = head[u]; t; t = next[t] ) {
			int v = dest[t];
			dfs(v);
			for( int j = 0; j < 3; j++ )
				rcnt[u][j] += rcnt[v][j];
		}
	}
	void right() {
		for( int u = 1; u <= ntot; u++ )
			adde( link[u], u );
		dfs( 0 );
	}
	void add( int lf, int rg, long long delta ) {
		events.push_back( Event(lf,+delta) );
		events.push_back( Event(rg+1,-delta) );
	}
	void solve() {
		for( int u = 1; u <= ntot; u++ ) {
			if( !rcnt[u][0] || !rcnt[u][1] || !rcnt[u][2] ) continue;
			long long cnt = 1LL * rcnt[u][0] * rcnt[u][1] % Mod * rcnt[u][2] % Mod;
			add( maxlen[link[u]]+1, maxlen[u], cnt );
		}
	}
}sam;

int n[3], nmin;
char s[3][N];

int main() {
	for( int i = 0; i < 3; i++ ) {
		scanf( "%s", s[i] + 1 );
		n[i] = (int)strlen(s[i] + 1);
	}
	nmin = min( n[0], min( n[1], n[2] ) );
	sam.init(n[0], n[1], n[2]);
	for( int i = 0; i < 3; i++ ) {
		for( int j = 1; j <= n[i]; j++ )
			sam.append( s[i][j] - 'a' );
		if( i != 2 ) sam.append( 26 + i );
	}
	sam.right();
	sam.solve();
	sort( events.begin(), events.end() );
	long long sum = 0;
	int cur = -1;
	for( int i = 1; i <= nmin; i++ ) {
		while( cur+1<events.size() && events[cur+1].time <= i ) {
			upd( sum, events[cur+1].delta );
			cur++;
		}
		printf( "%d%s", (int)sum, i==nmin ? "\n" : " " );
	}
}


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
#include<map>
#include<set>
#include<cmath>
#include<deque>
//#include<time.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define inf 2000000007
#define mod 1000000007
#define pii pair<int,int>
#define vi vector<int>
#define VS vector<string>
#define all(x) x.begin(),x.end()
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define N 300010
#define pi 3.14159265358979323846
#define DBG(vari) cerr<<#vari<<"="<<(vari)<<endl;
#define FOREACH(i,t) for(__typeof(t.begin()) i=t.begin();i!=t.end();i++)

char s[N],s1[N];
struct node
{
	int ch[28],fail,len;
	void init()
	{
		memset(ch,0,sizeof(ch));
		fail=len=0;
	}
}t[N*6];
int sz,cnt[N*6][3],pos[N*6][3],f[N],n1,n2,n3;
int code(char c)
{
	if(c=='#')return 0;
	if(c=='$')return 1;
	return c-'a'+2;
}
void build(char *s)
{
	int ed=0,i,j,n=strlen(s);t[0].init();t[0].fail=-1;sz=0;
	memset(pos,-1,sizeof(pos));
	for(i=0;s[i];i++)
	{
		j=code(s[i]);
		int p=++sz;t[p].init();t[p].len=t[ed].len+1;
		if(i<n1)pos[p][0]=i,cnt[p][0]=1;
		else if(i<n2)pos[p][1]=i,cnt[p][1]=1;
		else pos[p][2]=i,cnt[p][2]=1;
		while(ed>=0&&t[ed].ch[j]==0)t[ed].ch[j]=p,ed=t[ed].fail;
		if(ed==-1){ed=p;continue;}
		int q=t[ed].ch[j];
		if(t[q].len==t[ed].len+1)t[p].fail=q;
		else
		{
			int r=++sz;t[r]=t[q];t[r].len=t[ed].len+1;
			t[p].fail=t[q].fail=r;
			while(ed>=0&&t[ed].ch[j]==q)t[ed].ch[j]=r,ed=t[ed].fail;
		}
		ed=p;
	}
}
int main()
{
	int i,j,n,m,k;
	scanf("%s",s);n1=strlen(s);strcat(s,"#");n=n1;
	scanf("%s",s1);n=min(n,(int)strlen(s1));
	strcat(s,s1);n2=strlen(s);strcat(s,"$");
	scanf("%s",s1);n=min(n,(int)strlen(s1));
	strcat(s,s1);n3=strlen(s);
	build(s);
	m=strlen(s);
	vi v[m+1];
	for(i=1;i<=sz;i++)v[t[i].len].pb(i);
	for(int len=m;len;len--)
	{
		for(int x=0;x<v[len].size();x++)
		{
			i=v[len][x];
			j=t[i].fail;
			for(k=0;k<3;k++)
			if(pos[i][k]!=-1)
			{
				pos[j][k]=max(pos[j][k],pos[i][k]);
				cnt[j][k]+=cnt[i][k];
			}
			int good=1;
			for(k=0;k<3;k++)
			good&=(pos[i][k]!=-1);
			//cerr<<i<<" "<<t[i].len<<" "<<j<<" "<<good<<"\n";
			if(!good)continue;
			ll cur=(ll)cnt[i][0]*cnt[i][1]%mod*cnt[i][2]%mod;
			int a=t[j].len+1;
			int b=t[i].len;
			(f[a]+=cur)%=mod;(f[b+1]+=mod-cur)%=mod;
		}
	}
	for(i=1;i<=n;i++)
	{
		(f[i]+=f[i-1])%=mod;
		printf("%d ",f[i]);
	}
	puts("");
	return 0;
}


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
#include<map>
#include<set>
#include<cmath>
#include<deque>
//#include<time.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define inf 2000000007
#define mod 1000000007
#define pii pair<int,int>
#define vi vector<int>
#define VS vector<string>
#define all(x) x.begin(),x.end()
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define N 300010
#define pi 3.14159265358979323846
#define DBG(vari) cerr<<#vari<<"="<<(vari)<<endl;
#define FOREACH(i,t) for(__typeof(t.begin()) i=t.begin();i!=t.end();i++)

char s[N],s1[N];
struct node
{
	int ch[28],fail,len;
	void init()
	{
		memset(ch,0,sizeof(ch));
		fail=len=0;
	}
}t[N*6];
int sz,cnt[N*2][3],pos[N*2][3],f[N],n1,n2,n3;
int code(char c)
{
	if(c=='#')return 0;
	if(c=='$')return 1;
	return c-'a'+2;
}
void build(char *s)
{
	int ed=0,i,j,n=strlen(s);t[0].init();t[0].fail=-1;sz=0;
	memset(pos,-1,sizeof(pos));
	for(i=0;s[i];i++)
	{
		j=code(s[i]);
		int p=++sz;t[p].init();t[p].len=t[ed].len+1;
		if(i<n1)pos[p][0]=i,cnt[p][0]=1;
		else if(i<n2)pos[p][1]=i,cnt[p][1]=1;
		else pos[p][2]=i,cnt[p][2]=1;
		while(ed>=0&&t[ed].ch[j]==0)t[ed].ch[j]=p,ed=t[ed].fail;
		if(ed==-1){ed=p;continue;}
		int q=t[ed].ch[j];
		if(t[q].len==t[ed].len+1)t[p].fail=q;
		else
		{
			int r=++sz;t[r]=t[q];t[r].len=t[ed].len+1;
			t[p].fail=t[q].fail=r;
			while(ed>=0&&t[ed].ch[j]==q)t[ed].ch[j]=r,ed=t[ed].fail;
		}
		ed=p;
	}
}
int main()
{
	int i,j,n,m,k;
	scanf("%s",s);n1=strlen(s);strcat(s,"#");n=n1;
	scanf("%s",s1);n=min(n,(int)strlen(s1));
	strcat(s,s1);n2=strlen(s);strcat(s,"$");
	scanf("%s",s1);n=min(n,(int)strlen(s1));
	strcat(s,s1);n3=strlen(s);
	build(s);
	m=strlen(s);
	vi v[m+1];
	for(i=1;i<=sz;i++)v[t[i].len].pb(i);
	for(int len=m;len;len--)
	{
		for(int x=0;x<v[len].size();x++)
		{
			i=v[len][x];
			j=t[i].fail;
			for(k=0;k<3;k++)
			if(pos[i][k]!=-1)
			{
				pos[j][k]=max(pos[j][k],pos[i][k]);
				cnt[j][k]+=cnt[i][k];
			}
			int good=1;
			for(k=0;k<3;k++)
			good&=(pos[i][k]!=-1);
			//cerr<<i<<" "<<t[i].len<<" "<<j<<" "<<good<<"\n";
			if(!good)continue;
			ll cur=(ll)cnt[i][0]*cnt[i][1]%mod*cnt[i][2]%mod;
			int a=t[j].len+1;
			int b=t[i].len;
			(f[a]+=cur)%=mod;(f[b+1]+=mod-cur)%=mod;
		}
	}
	for(i=1;i<=n;i++)
	{
		(f[i]+=f[i-1])%=mod;
		printf("%d ",f[i]);
	}
	puts("");
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<fstream>

using namespace std;

#define maxn 300010
#define P 1000000007
#define cl(a, x) memset(a, x, sizeof(a))
#define rep(i, a, b) for (int i = (a); i < (b); ++i)
#define Rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define rrep(i, b, a) for (int i = (b); i > (a); --i)
#define Rrep(i, b, a) for (int i = (b); i >= (a); --i)
ifstream fin("CF452E.in");
ofstream fout("CF452E.out");
#define fin cin
#define fout cout

string s[3], st;
int n, l[3];
int sa[maxn], rk[maxn], tsa[maxn], trk[maxn << 1], sum[maxn], h[maxn];

void suffix_array()
{
	cl(rk, 255), cl(trk, 255);
	cl(sum, 0);
	rep(i, 0, n) ++sum[(int)st[i]];
	rep(i, 0, 255) sum[i + 1] += sum[i];
	rep(i, 0, n) sa[--sum[(int)st[i]]] = i;
	int m = 0; rk[sa[0]] = 0;
	rep(i, 1, n)
	{
		if (st[sa[i]] != st[sa[i - 1]]) ++m;
		rk[sa[i]] = m;
	}
	int p;
	for (int j = 1; m < n - 1; j <<= 1)
	{
		cl(sum, 0);
		p = 0;
		rep(i, n - j, n) ++sum[rk[tsa[p++] = i]];
		rep(i, 0, n)
			if (sa[i] >= j) ++sum[rk[tsa[p++] = sa[i] - j]];
		rep(i, 0, m) sum[i + 1] += sum[i];
		Rrep(i, n - 1, 0) sa[--sum[rk[tsa[i]]]] = tsa[i];
		memcpy(trk, rk, sizeof(rk));
		m = 0; rk[sa[0]] = 0;
		rep(i, 1, n)
		{
			if (trk[sa[i]] != trk[sa[i - 1]] || trk[sa[i] + j] != trk[sa[i - 1] + j]) ++m;
			rk[sa[i]] = m;
		}
	}
	h[n] = 0;
}

void height_array()
{
	h[0] = 0;
	int p = 0;
	rep(i, 0, n)
		if (rk[i])
		{
			int j = sa[rk[i] - 1];
			while (st[i + p] == st[j + p]) ++p;
			h[rk[i]] = p;
			if (p) --p;
		}
	h[n] = 0;
}

int pre[maxn], next[maxn], top, property[maxn], sump[4][maxn];

void pretreat()
{
	top = trk[0] = 0;
	rep(i, 1, n)
	{
		while (top > 0 && h[i] <= h[trk[top]]) --top;
		pre[i] = trk[top];
		trk[++top] = i;
	}
	top = 0; trk[0] = n;
	rrep(i, n - 1, -1)
	{
		while (top > 0 && h[i] < h[trk[top]]) --top;
		next[i] = trk[top];
		trk[++top] = i;
	}
	rep(i, 0, n)
	{
		if (sa[i] < l[0]) property[i] = 0;
		else if (sa[i] == l[0]) property[i] = 3;
		else if (sa[i] <= l[0] + l[1]) property[i] = 1;
		else if (sa[i] == l[0] + l[1] + 1) property[i] = 3;
		else property[i] = 2;
		rep(j, 0, 4)
			if (i) sump[j][i] = sump[j][i - 1] + (property[i] == j);
			else sump[j][i] = (property[i] == j);
	}
}

long long f[maxn];

void calc_ans()
{
	/*
	rep(i, 0, n)
		cout << st.substr(sa[i], n - sa[i]) << " " << property[i] << endl;
		*/
	cl(f, 0);
	rep(i, 1, n)
	{
		int l1 = pre[i] - 1;
		int r1 = i - 1;
		int l2 = i - 1;
		int r2 = next[i] - 1;
#define sums(t, l, r) ((l == -1) ? (sump[t][r]) : (sump[t][r] - sump[t][l]))
		f[h[i]] += sums(0, l1, r1) * sums(1, l2, r2) * sums(2, l2, r2);
		f[h[i]] += sums(1, l1, r1) * sums(0, l2, r2) * sums(2, l2, r2);
		f[h[i]] += sums(2, l1, r1) * sums(1, l2, r2) * sums(0, l2, r2);
		f[h[i]] += sums(0, l1, r1) * sums(1, l1, r1) * sums(2, l2, r2);
		f[h[i]] += sums(1, l1, r1) * sums(2, l1, r1) * sums(0, l2, r2);
		f[h[i]] += sums(2, l1, r1) * sums(0, l1, r1) * sums(1, l2, r2);
		f[h[i]] %= P;
	}
	int L = P;
	rep(i, 0, 3) if (L > l[i]) L = l[i];
	rrep(i, L, 0)
		f[i - 1] += f[i];
	fout << f[1];
	Rep(i, 2, L)
		fout << " " << f[i];
	fout << endl;
}

int main()
{
	ios::sync_with_stdio(0);
	rep(i, 0, 3) fin >> s[i];
	rep(i, 0, 3) l[i] = s[i].length();
	st = s[0] + '_' + s[1] + '-' + s[2] + '!';
	n = st.length() - 1;
	suffix_array();
	height_array();
	pretreat();
	calc_ans();
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<fstream>

using namespace std;

#define maxn 300010
#define P 1000000007
#define cl(a, x) memset(a, x, sizeof(a))
#define rep(i, a, b) for (int i = (a); i < (b); ++i)
#define Rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define rrep(i, b, a) for (int i = (b); i > (a); --i)
#define Rrep(i, b, a) for (int i = (b); i >= (a); --i)
ifstream fin("CF452E.in");
ofstream fout("CF452E.out");
#define fin cin
#define fout cout

string s[3], st;
int n, l[3];
int sa[maxn], rk[maxn], tsa[maxn], trk[maxn << 1], sum[maxn], h[maxn];

void suffix_array()
{
	cl(rk, 255), cl(trk, 255);
	cl(sum, 0);
	rep(i, 0, n) ++sum[(int)st[i]];
	rep(i, 0, 255) sum[i + 1] += sum[i];
	rep(i, 0, n) sa[--sum[(int)st[i]]] = i;
	int m = 0; rk[sa[0]] = 0;
	rep(i, 1, n)
	{
		if (st[sa[i]] != st[sa[i - 1]]) ++m;
		rk[sa[i]] = m;
	}
	int p;
	for (int j = 1; m < n - 1; j <<= 1)
	{
		cl(sum, 0);
		p = 0;
		rep(i, n - j, n) ++sum[rk[tsa[p++] = i]];
		rep(i, 0, n)
			if (sa[i] >= j) ++sum[rk[tsa[p++] = sa[i] - j]];
		rep(i, 0, m) sum[i + 1] += sum[i];
		Rrep(i, n - 1, 0) sa[--sum[rk[tsa[i]]]] = tsa[i];
		memcpy(trk, rk, sizeof(rk));
		m = 0; rk[sa[0]] = 0;
		rep(i, 1, n)
		{
			if (trk[sa[i]] != trk[sa[i - 1]] || trk[sa[i] + j] != trk[sa[i - 1] + j]) ++m;
			rk[sa[i]] = m;
		}
	}
	h[n] = 0;
}

void height_array()
{
	h[0] = 0;
	int p = 0;
	rep(i, 0, n)
		if (rk[i])
		{
			int j = sa[rk[i] - 1];
			while (st[i + p] == st[j + p]) ++p;
			h[rk[i]] = p;
			if (p) --p;
		}
	h[n] = 0;
}

int pre[maxn], next[maxn], top, property[maxn], sump[4][maxn];

void pretreat()
{
	top = trk[0] = 0;
	rep(i, 1, n)
	{
		while (top > 0 && h[i] <= h[trk[top]]) --top;
		pre[i] = trk[top];
		trk[++top] = i;
	}
	top = 0; trk[0] = n;
	rrep(i, n - 1, -1)
	{
		while (top > 0 && h[i] < h[trk[top]]) --top;
		next[i] = trk[top];
		trk[++top] = i;
	}
	rep(i, 0, n)
	{
		if (sa[i] < l[0]) property[i] = 0;
		else if (sa[i] == l[0]) property[i] = 3;
		else if (sa[i] <= l[0] + l[1]) property[i] = 1;
		else if (sa[i] == l[0] + l[1] + 1) property[i] = 3;
		else property[i] = 2;
		rep(j, 0, 4)
			if (i) sump[j][i] = sump[j][i - 1] + (property[i] == j);
			else sump[j][i] = (property[i] == j);
	}
}

long long f[maxn];

void calc_ans()
{
	/*
	rep(i, 0, n)
		cout << st.substr(sa[i], n - sa[i]) << " " << property[i] << endl;
		*/
	cl(f, 0);
	rep(i, 1, n)
	{
		int l1 = pre[i] - 1;
		int r1 = i - 1;
		int l2 = i - 1;
		int r2 = next[i] - 1;
#define sums(t, l, r) ((l == -1) ? (sump[t][r]) : (sump[t][r] - sump[t][l]))
		f[h[i]] += sums(0, l1, r1) * sums(1, l2, r2) * sums(2, l2, r2);
		f[h[i]] += sums(1, l1, r1) * sums(0, l2, r2) * sums(2, l2, r2);
		f[h[i]] += sums(2, l1, r1) * sums(1, l2, r2) * sums(0, l2, r2);
		f[h[i]] += sums(0, l1, r1) * sums(1, l1, r1) * sums(2, l2, r2);
		f[h[i]] += sums(1, l1, r1) * sums(2, l1, r1) * sums(0, l2, r2);
		f[h[i]] += sums(2, l1, r1) * sums(0, l1, r1) * sums(1, l2, r2);
		f[h[i]] %= P;
	}
	int L = P;
	rep(i, 0, 3) if (L > l[i]) L = l[i];
	rrep(i, L, 0)
		f[i - 1] += f[i];
	fout << f[1] % P;
	Rep(i, 2, L)
		fout << " " << f[i] % P;
	fout << endl;
}

int main()
{
	ios::sync_with_stdio(0);
	rep(i, 0, 3) fin >> s[i];
	rep(i, 0, 3) l[i] = s[i].length();
	st = s[0] + '_' + s[1] + '-' + s[2] + '!';
	n = st.length() - 1;
	suffix_array();
	height_array();
	pretreat();
	calc_ans();
	return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<fstream>

using namespace std;

#define maxn 300010
#define P 1000000007
#define cl(a, x) memset(a, x, sizeof(a))
#define rep(i, a, b) for (int i = (a); i < (b); ++i)
#define Rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define rrep(i, b, a) for (int i = (b); i > (a); --i)
#define Rrep(i, b, a) for (int i = (b); i >= (a); --i)
ifstream fin("CF452E.in");
ofstream fout("CF452E.out");
#define fin cin
#define fout cout

string s[3], st;
int n, l[3];
int sa[maxn], rk[maxn], tsa[maxn], trk[maxn << 1], sum[maxn], h[maxn];

void suffix_array()
{
	cl(rk, 255), cl(trk, 255);
	cl(sum, 0);
	rep(i, 0, n) ++sum[(int)st[i]];
	rep(i, 0, 255) sum[i + 1] += sum[i];
	rep(i, 0, n) sa[--sum[(int)st[i]]] = i;
	int m = 0; rk[sa[0]] = 0;
	rep(i, 1, n)
	{
		if (st[sa[i]] != st[sa[i - 1]]) ++m;
		rk[sa[i]] = m;
	}
	int p;
	for (int j = 1; m < n - 1; j <<= 1)
	{
		cl(sum, 0);
		p = 0;
		rep(i, n - j, n) ++sum[rk[tsa[p++] = i]];
		rep(i, 0, n)
			if (sa[i] >= j) ++sum[rk[tsa[p++] = sa[i] - j]];
		rep(i, 0, m) sum[i + 1] += sum[i];
		Rrep(i, n - 1, 0) sa[--sum[rk[tsa[i]]]] = tsa[i];
		memcpy(trk, rk, sizeof(rk));
		m = 0; rk[sa[0]] = 0;
		rep(i, 1, n)
		{
			if (trk[sa[i]] != trk[sa[i - 1]] || trk[sa[i] + j] != trk[sa[i - 1] + j]) ++m;
			rk[sa[i]] = m;
		}
	}
	h[n] = 0;
}

void height_array()
{
	h[0] = 0;
	int p = 0;
	rep(i, 0, n)
		if (rk[i])
		{
			int j = sa[rk[i] - 1];
			while (st[i + p] == st[j + p]) ++p;
			h[rk[i]] = p;
			if (p) --p;
		}
	h[n] = 0;
}

int pre[maxn], next[maxn], top, property[maxn], sump[4][maxn];

void pretreat()
{
	top = trk[0] = 0;
	rep(i, 1, n)
	{
		while (top > 0 && h[i] <= h[trk[top]]) --top;
		pre[i] = trk[top];
		trk[++top] = i;
	}
	top = 0; trk[0] = n;
	rrep(i, n - 1, -1)
	{
		while (top > 0 && h[i] < h[trk[top]]) --top;
		next[i] = trk[top];
		trk[++top] = i;
	}
	rep(i, 0, n)
	{
		if (sa[i] < l[0]) property[i] = 0;
		else if (sa[i] == l[0]) property[i] = 3;
		else if (sa[i] <= l[0] + l[1]) property[i] = 1;
		else if (sa[i] == l[0] + l[1] + 1) property[i] = 3;
		else property[i] = 2;
		rep(j, 0, 4)
			if (i) sump[j][i] = sump[j][i - 1] + (property[i] == j);
			else sump[j][i] = (property[i] == j);
	}
}

long long f[maxn];

void calc_ans()
{
	/*
	rep(i, 0, n)
		cout << st.substr(sa[i], n - sa[i]) << " " << property[i] << endl;
		*/
	cl(f, 0);
	rep(i, 1, n)
	{
		int l1 = pre[i] - 1;
		int r1 = i - 1;
		int l2 = i - 1;
		int r2 = next[i] - 1;
#define sums(t, l, r) ((l == -1) ? (long long)(sump[t][r]) : (long long)(sump[t][r] - sump[t][l]))
		f[h[i]] += sums(0, l1, r1) * sums(1, l2, r2) * sums(2, l2, r2);
		f[h[i]] += sums(1, l1, r1) * sums(0, l2, r2) * sums(2, l2, r2);
		f[h[i]] += sums(2, l1, r1) * sums(1, l2, r2) * sums(0, l2, r2);
		f[h[i]] += sums(0, l1, r1) * sums(1, l1, r1) * sums(2, l2, r2);
		f[h[i]] += sums(1, l1, r1) * sums(2, l1, r1) * sums(0, l2, r2);
		f[h[i]] += sums(2, l1, r1) * sums(0, l1, r1) * sums(1, l2, r2);
		f[h[i]] %= P;
	}
	int L = P;
	rep(i, 0, 3) if (L > l[i]) L = l[i];
	rrep(i, L, 0)
		f[i - 1] += f[i];
	fout << f[1] % P;
	Rep(i, 2, L)
		fout << " " << f[i] % P;
	fout << endl;
}

int main()
{
	ios::sync_with_stdio(0);
	rep(i, 0, 3) fin >> s[i];
	rep(i, 0, 3) l[i] = s[i].length();
	st = s[0] + '_' + s[1] + '-' + s[2] + '!';
	n = st.length() - 1;
	suffix_array();
	height_array();
	pretreat();
	calc_ans();
	return 0;
}


#include<iostream>
#include<cstdio>
#include<sstream>
#include<fstream>
#include<cctype>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<complex>
#include<bitset>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<queue>
#include<deque>
#include<stack>
#include<iomanip>
#include<utility>

#define pb push_back
#define pp pop_back
#define xx first
#define yy second
#define mp make_pair

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;

const int maxn=300000+10;
const int maxl=20;
const ll base=1e6;
const int inf=-1e9;
const ll mod=1e9+7;
ll F[maxn][maxl][3],ans;
string s[3];
int sz,ps[maxn][3];
vector<pii> suf;
vi adj[maxn];
set<pii> S;
set<pii>::iterator it;
bool cmp(pii a,pii b){
	return F[a.yy][19][a.xx]<F[b.yy][19][b.xx];
}
void suffixArray(){
	for(int id=0;id<3;id++)for(int i=0;i<s[id].size();i++){
		F[i][0][id]=s[id][i]-'a'+1;
		suf.pb(mp(id,i));
	}
	for(int l=1;l<20;l++){
		vector<ll> v;
		for(int id=0;id<3;id++){
			for(int i=0;i<s[id].size();i++){
				if(i+(1<<(l-1))>s[id].size())F[i][l][id]=F[i][l-1][id]*base;
				else F[i][l][id]=F[i][l-1][id]*base+F[i+(1<<(l-1))][l-1][id];
				v.pb(F[i][l][id]);
			}
		}
		sort(v.begin(),v.end());
		v.resize(unique(v.begin(),v.end())-v.begin());
		for(int id=0;id<3;id++)for(int i=0;i<s[id].size();i++)F[i][l][id]=lower_bound(v.begin(),v.end(),F[i][l][id])-v.begin()+1;
	}
	sort(suf.begin(),suf.end(),cmp);
	S.insert(mp(0,sz-1));
	ans=(ll)s[0].size()*(ll)s[1].size()*(ll)s[2].size();
}
int lcp(int p1,int id1,int p2,int id2){
	int ret=0;
	for(int l=19;l>=0;l--){
		if(p1+(1<<l)<=s[id1].size() && p2+(1<<l)<=s[id2].size()){
			if(F[p1][l][id1]==F[p2][l][id2]){
				ret+=(1<<l);
				p1+=(1<<l);
				p2+=(1<<l);
			}
		}
	}
	return ret;
}
ll get(int l,int r){
	ll ret=1;
	for(int id=0;id<3;id++){
		ll cnt=0;
		cnt=ps[r+1][id]-ps[l][id];
		ret*=cnt;
	}
	return ret;
}
void update(int pos){
	it=S.lower_bound(mp(pos+1,inf));
	it--;
	ans-=get(it->xx,it->yy);
	ans+=get(it->xx,pos);
	ans+=get(pos+1,it->yy);
	S.insert(mp(it->xx,pos));
	S.insert(mp(pos+1,it->yy));
	S.erase(it);
}
int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>s[0]>>s[1]>>s[2];
	sz=s[0].size()+s[1].size()+s[2].size();
	suffixArray();
	for(int i=0;i<sz-1;i++)adj[lcp(suf[i].yy,suf[i].xx,suf[i+1].yy,suf[i+1].xx)].pb(i);
	for(int i=0;i<sz;i++){
		for(int j=0;j<3;j++)if(i>0)ps[i+1][j]=ps[i][j];
		for(int j=0;j<3;j++)ps[i+1][j]+=(suf[i].xx==j);
	}
	for(int l=1;l<=min((int)s[0].size(),min((int)s[1].size(),(int)s[2].size()));l++){
		for(int i=0;i<adj[l-1].size();i++){
			int pos=adj[l-1][i];
			update(pos);
		}
		cout<<ans%mod<<" ";
	}
	cout<<endl;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<sstream>
#include<fstream>
#include<cctype>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<complex>
#include<bitset>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<queue>
#include<deque>
#include<stack>
#include<iomanip>
#include<utility>

#define pb push_back
#define pp pop_back
#define xx first
#define yy second
#define mp make_pair

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;

const int maxn=300000+10;
const int maxl=20;
const ll base=1e6;
const int inf=-1e9;
ll F[maxn][maxl][3],ans;
string s[3];
int sz,ps[maxn][3];
vector<pii> suf;
vi adj[maxn];
set<pii> S;
set<pii>::iterator it;
bool cmp(pii a,pii b){
	return F[a.yy][19][a.xx]<F[b.yy][19][b.xx];
}
void suffixArray(){
	for(int id=0;id<3;id++)for(int i=0;i<s[id].size();i++){
		F[i][0][id]=s[id][i]-'a'+1;
		suf.pb(mp(id,i));
	}
	for(int l=1;l<20;l++){
		vi v;
		for(int id=0;id<3;id++){
			for(int i=0;i<s[id].size();i++){
				if(i+(1<<(l-1))>s[id].size())F[i][l][id]=F[i][l-1][id]*base;
				else F[i][l][id]=F[i][l-1][id]*base+F[i+(1<<(l-1))][l-1][id];
				v.pb(F[i][l][id]);
			}
		}
		sort(v.begin(),v.end());
		v.resize(unique(v.begin(),v.end())-v.begin());
		for(int id=0;id<3;id++)for(int i=0;i<s[id].size();i++)F[i][l][id]=lower_bound(v.begin(),v.end(),F[i][l][id])-v.begin()+1;
	}
	sort(suf.begin(),suf.end(),cmp);
	S.insert(mp(0,sz-1));
	ans=(ll)s[0].size()*(ll)s[1].size()*(ll)s[2].size();
}
int lcp(int p1,int id1,int p2,int id2){
	int ret=0;
	for(int l=19;l>=0;l--){
		if(p1+(1<<l)<=s[id1].size() && p2+(1<<l)<=s[id2].size()){
			if(F[p1][l][id1]==F[p2][l][id2]){
				ret+=(1<<l);
				p1+=(1<<l);
				p2+=(1<<l);
			}
		}
	}
	return ret;
}
ll get(int l,int r){
	ll ret=1;
	for(int id=0;id<3;id++){
		ll cnt=0;
		cnt=ps[r+1][id]-ps[l][id];
		ret*=cnt;
	}
	return ret;
}
void update(int pos){
	it=S.lower_bound(mp(pos+1,inf));
	it--;
	ans-=get(it->xx,it->yy);
	ans+=get(it->xx,pos);
	ans+=get(pos+1,it->yy);
	S.insert(mp(it->xx,pos));
	S.insert(mp(pos+1,it->yy));
	S.erase(it);
}
int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>s[0]>>s[1]>>s[2];
	sz=s[0].size()+s[1].size()+s[2].size();
	suffixArray();
	for(int i=0;i<sz-1;i++)adj[lcp(suf[i].yy,suf[i].xx,suf[i+1].yy,suf[i+1].xx)].pb(i);
	for(int i=0;i<sz;i++){
		for(int j=0;j<3;j++)if(i>0)ps[i+1][j]=ps[i][j];
		for(int j=0;j<3;j++)ps[i+1][j]+=(suf[i].xx==j);
	}
	for(int l=1;l<=min((int)s[0].size(),min((int)s[1].size(),(int)s[2].size()));l++){
		for(int i=0;i<adj[l-1].size();i++){
			int pos=adj[l-1][i];
			update(pos);
		}
		cout<<ans<<" ";
	}
	cout<<endl;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<sstream>
#include<fstream>
#include<cctype>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<complex>
#include<bitset>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<queue>
#include<deque>
#include<stack>
#include<iomanip>
#include<utility>

#define pb push_back
#define pp pop_back
#define xx first
#define yy second
#define mp make_pair

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;

const int maxn=300000+10;
const int maxl=20;
const ll base=1e6;
const int inf=-1e9;
ll F[maxn][maxl][3],ans;
string s[3];
int sz,ps[maxn][3];
vector<pii> suf;
vi adj[maxn];
set<pii> S;
set<pii>::iterator it;
bool cmp(pii a,pii b){
	return F[a.yy][19][a.xx]<F[b.yy][19][b.xx];
}
void suffixArray(){
	for(int id=0;id<3;id++)for(int i=0;i<s[id].size();i++){
		F[i][0][id]=s[id][i]-'a'+1;
		suf.pb(mp(id,i));
	}
	for(int l=1;l<20;l++){
		vector<ll> v;
		for(int id=0;id<3;id++){
			for(int i=0;i<s[id].size();i++){
				if(i+(1<<(l-1))>s[id].size())F[i][l][id]=F[i][l-1][id]*base;
				else F[i][l][id]=F[i][l-1][id]*base+F[i+(1<<(l-1))][l-1][id];
				v.pb(F[i][l][id]);
			}
		}
		sort(v.begin(),v.end());
		v.resize(unique(v.begin(),v.end())-v.begin());
		for(int id=0;id<3;id++)for(int i=0;i<s[id].size();i++)F[i][l][id]=lower_bound(v.begin(),v.end(),F[i][l][id])-v.begin()+1;
	}
	sort(suf.begin(),suf.end(),cmp);
	S.insert(mp(0,sz-1));
	ans=(ll)s[0].size()*(ll)s[1].size()*(ll)s[2].size();
}
int lcp(int p1,int id1,int p2,int id2){
	int ret=0;
	for(int l=19;l>=0;l--){
		if(p1+(1<<l)<=s[id1].size() && p2+(1<<l)<=s[id2].size()){
			if(F[p1][l][id1]==F[p2][l][id2]){
				ret+=(1<<l);
				p1+=(1<<l);
				p2+=(1<<l);
			}
		}
	}
	return ret;
}
ll get(int l,int r){
	ll ret=1;
	for(int id=0;id<3;id++){
		ll cnt=0;
		cnt=ps[r+1][id]-ps[l][id];
		ret*=cnt;
	}
	return ret;
}
void update(int pos){
	it=S.lower_bound(mp(pos+1,inf));
	it--;
	ans-=get(it->xx,it->yy);
	ans+=get(it->xx,pos);
	ans+=get(pos+1,it->yy);
	S.insert(mp(it->xx,pos));
	S.insert(mp(pos+1,it->yy));
	S.erase(it);
}
int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>s[0]>>s[1]>>s[2];
	sz=s[0].size()+s[1].size()+s[2].size();
	suffixArray();
	for(int i=0;i<sz-1;i++)adj[lcp(suf[i].yy,suf[i].xx,suf[i+1].yy,suf[i+1].xx)].pb(i);
	for(int i=0;i<sz;i++){
		for(int j=0;j<3;j++)if(i>0)ps[i+1][j]=ps[i][j];
		for(int j=0;j<3;j++)ps[i+1][j]+=(suf[i].xx==j);
	}
	for(int l=1;l<=min((int)s[0].size(),min((int)s[1].size(),(int)s[2].size()));l++){
		for(int i=0;i<adj[l-1].size();i++){
			int pos=adj[l-1][i];
			update(pos);
		}
		cout<<ans<<" ";
	}
	cout<<endl;
	return 0;
}


/*
⣿⣿⣿⣿⣿⣿⡷⣯⢿⣿⣷⣻⢯⣿⡽⣻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠸⣿⣿⣆⠹⣿⣿⢾⣟⣯⣿⣿⣿⣿⣿⣿⣽⣻⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣻⣽⡿⣿⣎⠙⣿⣞⣷⡌⢻⣟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⡄⠹⣿⣿⡆⠻⣿⣟⣯⡿⣽⡿⣿⣿⣿⣿⣽⡷⣯⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣟⣷⣿⣿⣿⡀⠹⣟⣾⣟⣆⠹⣯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢠⡘⣿⣿⡄⠉⢿⣿⣽⡷⣿⣻⣿⣿⣿⣿⡝⣷⣯⢿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣯⢿⣾⢿⣿⡄⢄⠘⢿⣞⡿⣧⡈⢷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⣧⠘⣿⣷⠈⣦⠙⢿⣽⣷⣻⣽⣿⣿⣿⣿⣌⢿⣯⢿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣟⣯⣿⢿⣿⡆⢸⡷⡈⢻⡽⣷⡷⡄⠻⣽⣿⣿⡿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣏⢰⣯⢷⠈⣿⡆⢹⢷⡌⠻⡾⢋⣱⣯⣿⣿⣿⣿⡆⢻⡿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡎⣿⢾⡿⣿⡆⢸⣽⢻⣄⠹⣷⣟⣿⣄⠹⣟⣿⣿⣟⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⡇⢸⣯⣟⣧⠘⣷⠈⡯⠛⢀⡐⢾⣟⣷⣻⣿⣿⣿⡿⡌⢿⣻⣿⣿
⣿⣿⣿⣿⣿⣿⣧⢸⡿⣟⣿⡇⢸⣯⣟⣮⢧⡈⢿⣞⡿⣦⠘⠏⣹⣿⣽⢿⣿⣿⣿⣿⣯⣿⣿⣿⡇⢸⣿⣿⣾⡆⠹⢀⣠⣾⣟⣷⡈⢿⣞⣯⢿⣿⣿⣿⢷⠘⣯⣿⣿
⣿⣿⣿⣿⣿⣿⣿⡈⣿⢿⣽⡇⠘⠛⠛⠛⠓⠓⠈⠛⠛⠟⠇⢀⢿⣻⣿⣯⢿⣿⣿⣿⣷⢿⣿⣿⠁⣾⣿⣿⣿⣧⡄⠇⣹⣿⣾⣯⣿⡄⠻⣽⣯⢿⣻⣿⣿⡇⢹⣾⣿
⣿⣿⣿⣿⣿⣿⣿⡇⢹⣿⡽⡇⢸⣿⣿⣿⣿⣿⣞⣆⠰⣶⣶⡄⢀⢻⡿⣯⣿⡽⣿⣿⣿⢯⣟⡿⢀⣿⣿⣿⣿⣿⣧⠐⣸⣿⣿⣷⣿⣿⣆⠹⣯⣿⣻⣿⣿⣿⢀⣿⢿
⣿⣿⣿⣿⣿⣿⣿⣿⠘⣯⡿⡇⢸⣿⣿⣿⣿⣿⣿⣿⣧⡈⢿⣳⠘⡄⠻⣿⢾⣽⣟⡿⣿⢯⣿⡇⢸⣿⣿⣿⣿⣿⣿⡀⢾⣿⣿⣿⣿⣿⣿⣆⠹⣾⣷⣻⣿⡿⡇⢸⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡇⢹⣿⠇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠻⡇⢹⣆⠹⣟⣾⣽⣻⣟⣿⣽⠁⣾⣿⣿⣿⣿⣿⣿⣇⣿⣿⠿⠛⠛⠉⠙⠋⢀⠁⢘⣯⣿⣿⣧⠘⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⡈⣿⡃⢼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡙⠌⣿⣆⠘⣿⣞⡿⣞⡿⡞⢠⣿⣿⣿⣿⣿⡿⠛⠉⠁⢀⣀⣠⣤⣤⣶⣶⣶⡆⢻⣽⣞⡿⣷⠈⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠘⠁⠉⠉⠉⠉⠉⠉⠉⠉⠉⠙⠛⠛⢿⣄⢻⣿⣧⠘⢯⣟⡿⣽⠁⣾⣿⣿⣿⣿⣿⡃⢀⢀⠘⠛⠿⢿⣻⣟⣯⣽⣻⣵⡀⢿⣯⣟⣿⢀⣿
⣿⣿⣿⣟⣿⣿⣿⣿⣶⣶⡆⢀⣿⣾⣿⣾⣷⣿⣶⠿⠚⠉⢀⢀⣤⣿⣷⣿⣿⣷⡈⢿⣻⢃⣼⣿⣿⣿⣿⣻⣿⣿⣿⡶⣦⣤⣄⣀⡀⠉⠛⠛⠷⣯⣳⠈⣾⡽⣾⢀⣿
⣿⢿⣿⣿⣻⣿⣿⣿⣿⣿⡿⠐⣿⣿⣿⣿⠿⠋⠁⢀⢀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣌⣥⣾⡿⣿⣿⣷⣿⣿⢿⣷⣿⣿⣟⣾⣽⣳⢯⣟⣶⣦⣤⡾⣟⣦⠘⣿⢾⡁⢺
⣿⣻⣿⣿⡷⣿⣿⣿⣿⣿⡗⣦⠸⡿⠋⠁⢀⢀⣠⣴⢿⣿⣽⣻⢽⣾⣟⣷⣿⣟⣿⣿⣿⣳⠿⣵⣧⣼⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣽⣳⣯⣿⣿⣿⣽⢀⢷⣻⠄⠘
⣿⢷⣻⣿⣿⣷⣻⣿⣿⣿⡷⠛⣁⢀⣀⣤⣶⣿⣛⡿⣿⣮⣽⡻⣿⣮⣽⣻⢯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⢀⢸⣿⢀⡆
⠸⣟⣯⣿⣿⣷⢿⣽⣿⣿⣷⣿⣷⣆⠹⣿⣶⣯⠿⣿⣶⣟⣻⢿⣷⣽⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢀⣯⣟⢀⡇
⣇⠹⣟⣾⣻⣿⣿⢾⡽⣿⣿⣿⣿⣿⣆⢹⣶⣿⣻⣷⣯⣟⣿⣿⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢀⡿⡇⢸⡇
⣿⣆⠹⣷⡻⣽⣿⣯⢿⣽⣻⣿⣿⣿⣿⣆⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⢸⣿⠇⣼⡇
⡙⠾⣆⠹⣿⣦⠛⣿⢯⣷⢿⡽⣿⣿⣿⣿⣆⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠎⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⢀⣿⣾⣣⡿⡇
⣿⣷⡌⢦⠙⣿⣿⣌⠻⣽⢯⣿⣽⣻⣿⣿⣿⣧⠩⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⢰⢣⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⢀⢀⢿⣞⣷⢿⡇
⣿⣽⣆⠹⣧⠘⣿⣿⡷⣌⠙⢷⣯⡷⣟⣿⣿⣿⣷⡀⡹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣈⠃⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⢀⣴⡧⢀⠸⣿⡽⣿⢀
⢻⣽⣿⡄⢻⣷⡈⢿⣿⣿⢧⢀⠙⢿⣻⡾⣽⣻⣿⣿⣄⠌⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⢁⣰⣾⣟⡿⢀⡄⢿⣟⣿⢀
⡄⢿⣿⣷⢀⠹⣟⣆⠻⣿⣿⣆⢀⣀⠉⠻⣿⡽⣯⣿⣿⣷⣈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⢀⣠⠘⣯⣷⣿⡟⢀⢆⠸⣿⡟⢸
⣷⡈⢿⣿⣇⢱⡘⢿⣷⣬⣙⠿⣧⠘⣆⢀⠈⠻⣷⣟⣾⢿⣿⣆⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⣠⡞⢡⣿⢀⣿⣿⣿⠇⡄⢸⡄⢻⡇⣼
⣿⣷⡈⢿⣿⡆⢣⡀⠙⢾⣟⣿⣿⣷⡈⠂⠘⣦⡈⠿⣯⣿⢾⣿⣆⠙⠻⠿⠿⠿⠿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⢋⣠⣾⡟⢠⣿⣿⢀⣿⣿⡟⢠⣿⢈⣧⠘⢠⣿
⣿⣿⣿⣄⠻⣿⡄⢳⡄⢆⡙⠾⣽⣿⣿⣆⡀⢹⡷⣄⠙⢿⣿⡾⣿⣆⢀⡀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⣀⣠⣴⡿⣯⠏⣠⣿⣿⡏⢸⣿⡿⢁⣿⣿⢀⣿⠆⢸⣿
⣿⣿⣿⣿⣦⡙⣿⣆⢻⡌⢿⣶⢤⣉⣙⣿⣷⡀⠙⠽⠷⠄⠹⣿⣟⣿⣆⢙⣋⣤⣤⣤⣄⣀⢀⢀⢀⢀⣾⣿⣟⡷⣯⡿⢃⣼⣿⣿⣿⠇⣼⡟⣡⣿⣿⣿⢀⡿⢠⠈⣿
⣿⣿⣿⣿⣿⣷⣮⣿⣿⣿⡌⠁⢤⣤⣤⣤⣬⣭⣴⣶⣶⣶⣆⠈⢻⣿⣿⣆⢻⣿⣿⣿⣿⣿⣿⣷⣶⣤⣌⣉⡘⠛⠻⠶⣿⣿⣿⣿⡟⣰⣫⣴⣿⣿⣿⣿⠄⣷⣿⣿⣿
*/

#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = INF + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 900 * 1000 + 13;
const int AL = 256;
const int LOGN = 20;

int n;
string t1, t2, t3;
string s;

bool read () {
	static char buf[N];
	if (scanf("%s", buf) != 1)
		return false;
	t1 = buf;
	scanf("%s", buf);
	t2 = buf;
	scanf("%s", buf);
	t3 = buf;
	return true;
}

pair<pt, int> p[N];
int c[N];
int lcp[N];

int st[LOGN][N];
int pw[N];

void init(){
	pw[0] = pw[1] = 0;
	fore(i, 2, N)
		pw[i] = pw[i / 2] + 1;
	forn(i, n)
		st[0][i] = lcp[i];
	fore(j, 1, LOGN){
		forn(i, n){
			st[j][i] = st[j - 1][i];
			if (i + (1 << (j - 1)) < n)
				st[j][i] = min(st[j][i], st[j - 1][i + (1 << (j - 1))]);
		}
	}
}

int getMin(int l, int r){
	int len = pw[r - l];
	return min(st[len][l], st[len][r - (1 << len)]);
}

int add(int a, int b){
	a += b;
	if (a >= MOD) a -= MOD;
	return a;
}

int mul(int a, int b){
	return a * li(b) % MOD;
}

int cnt[N][3];
int ans[N];

int get(int l, int r, int k){
	return cnt[r][k] - cnt[l][k];
}

int get(int l, int r){
	int res = 1;
	forn(i, 3) res = mul(res, get(l, r, i));
	return res;
}

pt getLower(int x){
	int l = 0, r = x - 1;
	while (l < r - 1){
		int m = (l + r) / 2;
		if (getMin(m, x) <= lcp[x])
			l = m;
		else
			r = m;
	}
	if (l >= x || getMin(l, x) > lcp[x])
		return mp(0, 0);
	else if (getMin(r, x) <= lcp[x])
		return mp(r + 1, lcp[r]);
	return mp(l + 1, lcp[l]);
}

pt getUpper(int x){
	int l = x + 1, r = n - 1;
	while (l < r - 1){
		int m = (l + r) / 2;
		if (getMin(x + 1, m + 1) < lcp[x])
			r = m;
		else
			l = m;
	}
	if (getMin(x + 1, l + 1) < lcp[x])
		return mp(l + 1, lcp[l]);
	return mp(r + 1, lcp[r]);
}

void build(){
	static int cnt[AL];
	static int cn[N], p[N], pn[N];

	memset (cnt, 0, AL * sizeof(int));
	for (int i=0; i<n; ++i)
		++cnt[s[i]];
	for (int i=1; i<AL; ++i)
		cnt[i] += cnt[i-1];
	for (int i=0; i<n; ++i)
		p[--cnt[s[i]]] = i;
	c[p[0]] = 0;
	int classes = 1;
	for (int i=1; i<n; ++i) {
		if (s[p[i]] != s[p[i-1]])  ++classes;
		c[p[i]] = classes-1;
	}

	for (int h=0; (1<<h)<n; ++h) {
		for (int i=0; i<n; ++i) {
			pn[i] = p[i] - (1<<h);
			if (pn[i] < 0)  pn[i] += n;
		}
		memset (cnt, 0, classes * sizeof(int));
		for (int i=0; i<n; ++i)
			++cnt[c[pn[i]]];
		for (int i=1; i<classes; ++i)
			cnt[i] += cnt[i-1];
		for (int i=n-1; i>=0; --i)
			p[--cnt[c[pn[i]]]] = pn[i];
		classes = 1;
		for (int i=1; i<n; ++i) {
			int mid1 = (p[i] + (1<<h)) % n,  mid2 = (p[i-1] + (1<<h)) % n;
			if (c[p[i]] != c[p[i-1]] || c[mid1] != c[mid2])
				++classes;
			cn[p[i]] = classes-1;
		}
		memcpy (c, cn, n * sizeof(int));
	}

	forn(i, n)
		::p[i].y = p[i];

	int len = 0;
	forn(i, n){
		int pos = c[i];

		if (pos + 1 < n){
			for (int j = p[pos + 1]; s[i + len] == s[j + len]; ++len);
			lcp[pos] = len;
		}
		else{
			lcp[pos] = 0;
		}

		len = max(len - 1, 0);
	}
}

void solve(){
	s = t1 + string(1, 'z' + 1) + t2 + string(1, 'z' + 2) + t3 + string(1, 'z' + 3);
	n = sz(s);
	build();

	//forn(i, n)
	//	cerr << i << " " << p[i].y << " " << s.substr(p[i].y) << " " << lcp[i] << endl;

	memset(cnt, 0, sizeof(cnt));
	forn(i, n){
		forn(j, 3) cnt[i + 1][j] += cnt[i][j];
		if (!isalpha(s[p[i].y])) continue;
		if (p[i].y < sz(t1))
			++cnt[i + 1][0];
		else if (p[i].y < sz(t1) + sz(t2) + 1)
			++cnt[i + 1][1];
		else
			++cnt[i + 1][2];
	}

	//forn(i, 3) cerr << get(0, 5, i) << " ";
	//cerr << endl;

	init();
	memset(ans, 0, sizeof(ans));
	forn(i, n - 1){
		pt l = getLower(i);
		pt r = getUpper(i);
		//cerr << i << " " << l << " " << r << " " << lcp[i] << endl;
		if (l.y == lcp[i])
			continue;
		for (int j = lcp[i]; j > max(l.y, r.y); --j)
			ans[j] = add(ans[j], get(l.x, r.x));
	}

	fore(i, 1, min({sz(t1), sz(t2), sz(t3)}) + 1)
		printf("%d ", ans[i]);
	puts("");
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();

#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

	while(read()) {
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


/*
⣿⣿⣿⣿⣿⣿⡷⣯⢿⣿⣷⣻⢯⣿⡽⣻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠸⣿⣿⣆⠹⣿⣿⢾⣟⣯⣿⣿⣿⣿⣿⣿⣽⣻⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣻⣽⡿⣿⣎⠙⣿⣞⣷⡌⢻⣟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⡄⠹⣿⣿⡆⠻⣿⣟⣯⡿⣽⡿⣿⣿⣿⣿⣽⡷⣯⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣟⣷⣿⣿⣿⡀⠹⣟⣾⣟⣆⠹⣯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢠⡘⣿⣿⡄⠉⢿⣿⣽⡷⣿⣻⣿⣿⣿⣿⡝⣷⣯⢿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣯⢿⣾⢿⣿⡄⢄⠘⢿⣞⡿⣧⡈⢷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⣧⠘⣿⣷⠈⣦⠙⢿⣽⣷⣻⣽⣿⣿⣿⣿⣌⢿⣯⢿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣟⣯⣿⢿⣿⡆⢸⡷⡈⢻⡽⣷⡷⡄⠻⣽⣿⣿⡿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣏⢰⣯⢷⠈⣿⡆⢹⢷⡌⠻⡾⢋⣱⣯⣿⣿⣿⣿⡆⢻⡿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡎⣿⢾⡿⣿⡆⢸⣽⢻⣄⠹⣷⣟⣿⣄⠹⣟⣿⣿⣟⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⡇⢸⣯⣟⣧⠘⣷⠈⡯⠛⢀⡐⢾⣟⣷⣻⣿⣿⣿⡿⡌⢿⣻⣿⣿
⣿⣿⣿⣿⣿⣿⣧⢸⡿⣟⣿⡇⢸⣯⣟⣮⢧⡈⢿⣞⡿⣦⠘⠏⣹⣿⣽⢿⣿⣿⣿⣿⣯⣿⣿⣿⡇⢸⣿⣿⣾⡆⠹⢀⣠⣾⣟⣷⡈⢿⣞⣯⢿⣿⣿⣿⢷⠘⣯⣿⣿
⣿⣿⣿⣿⣿⣿⣿⡈⣿⢿⣽⡇⠘⠛⠛⠛⠓⠓⠈⠛⠛⠟⠇⢀⢿⣻⣿⣯⢿⣿⣿⣿⣷⢿⣿⣿⠁⣾⣿⣿⣿⣧⡄⠇⣹⣿⣾⣯⣿⡄⠻⣽⣯⢿⣻⣿⣿⡇⢹⣾⣿
⣿⣿⣿⣿⣿⣿⣿⡇⢹⣿⡽⡇⢸⣿⣿⣿⣿⣿⣞⣆⠰⣶⣶⡄⢀⢻⡿⣯⣿⡽⣿⣿⣿⢯⣟⡿⢀⣿⣿⣿⣿⣿⣧⠐⣸⣿⣿⣷⣿⣿⣆⠹⣯⣿⣻⣿⣿⣿⢀⣿⢿
⣿⣿⣿⣿⣿⣿⣿⣿⠘⣯⡿⡇⢸⣿⣿⣿⣿⣿⣿⣿⣧⡈⢿⣳⠘⡄⠻⣿⢾⣽⣟⡿⣿⢯⣿⡇⢸⣿⣿⣿⣿⣿⣿⡀⢾⣿⣿⣿⣿⣿⣿⣆⠹⣾⣷⣻⣿⡿⡇⢸⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡇⢹⣿⠇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠻⡇⢹⣆⠹⣟⣾⣽⣻⣟⣿⣽⠁⣾⣿⣿⣿⣿⣿⣿⣇⣿⣿⠿⠛⠛⠉⠙⠋⢀⠁⢘⣯⣿⣿⣧⠘⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⡈⣿⡃⢼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡙⠌⣿⣆⠘⣿⣞⡿⣞⡿⡞⢠⣿⣿⣿⣿⣿⡿⠛⠉⠁⢀⣀⣠⣤⣤⣶⣶⣶⡆⢻⣽⣞⡿⣷⠈⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠘⠁⠉⠉⠉⠉⠉⠉⠉⠉⠉⠙⠛⠛⢿⣄⢻⣿⣧⠘⢯⣟⡿⣽⠁⣾⣿⣿⣿⣿⣿⡃⢀⢀⠘⠛⠿⢿⣻⣟⣯⣽⣻⣵⡀⢿⣯⣟⣿⢀⣿
⣿⣿⣿⣟⣿⣿⣿⣿⣶⣶⡆⢀⣿⣾⣿⣾⣷⣿⣶⠿⠚⠉⢀⢀⣤⣿⣷⣿⣿⣷⡈⢿⣻⢃⣼⣿⣿⣿⣿⣻⣿⣿⣿⡶⣦⣤⣄⣀⡀⠉⠛⠛⠷⣯⣳⠈⣾⡽⣾⢀⣿
⣿⢿⣿⣿⣻⣿⣿⣿⣿⣿⡿⠐⣿⣿⣿⣿⠿⠋⠁⢀⢀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣌⣥⣾⡿⣿⣿⣷⣿⣿⢿⣷⣿⣿⣟⣾⣽⣳⢯⣟⣶⣦⣤⡾⣟⣦⠘⣿⢾⡁⢺
⣿⣻⣿⣿⡷⣿⣿⣿⣿⣿⡗⣦⠸⡿⠋⠁⢀⢀⣠⣴⢿⣿⣽⣻⢽⣾⣟⣷⣿⣟⣿⣿⣿⣳⠿⣵⣧⣼⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣽⣳⣯⣿⣿⣿⣽⢀⢷⣻⠄⠘
⣿⢷⣻⣿⣿⣷⣻⣿⣿⣿⡷⠛⣁⢀⣀⣤⣶⣿⣛⡿⣿⣮⣽⡻⣿⣮⣽⣻⢯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⢀⢸⣿⢀⡆
⠸⣟⣯⣿⣿⣷⢿⣽⣿⣿⣷⣿⣷⣆⠹⣿⣶⣯⠿⣿⣶⣟⣻⢿⣷⣽⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢀⣯⣟⢀⡇
⣇⠹⣟⣾⣻⣿⣿⢾⡽⣿⣿⣿⣿⣿⣆⢹⣶⣿⣻⣷⣯⣟⣿⣿⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢀⡿⡇⢸⡇
⣿⣆⠹⣷⡻⣽⣿⣯⢿⣽⣻⣿⣿⣿⣿⣆⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⢸⣿⠇⣼⡇
⡙⠾⣆⠹⣿⣦⠛⣿⢯⣷⢿⡽⣿⣿⣿⣿⣆⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠎⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⢀⣿⣾⣣⡿⡇
⣿⣷⡌⢦⠙⣿⣿⣌⠻⣽⢯⣿⣽⣻⣿⣿⣿⣧⠩⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⢰⢣⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⢀⢀⢿⣞⣷⢿⡇
⣿⣽⣆⠹⣧⠘⣿⣿⡷⣌⠙⢷⣯⡷⣟⣿⣿⣿⣷⡀⡹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣈⠃⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⢀⣴⡧⢀⠸⣿⡽⣿⢀
⢻⣽⣿⡄⢻⣷⡈⢿⣿⣿⢧⢀⠙⢿⣻⡾⣽⣻⣿⣿⣄⠌⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⢁⣰⣾⣟⡿⢀⡄⢿⣟⣿⢀
⡄⢿⣿⣷⢀⠹⣟⣆⠻⣿⣿⣆⢀⣀⠉⠻⣿⡽⣯⣿⣿⣷⣈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⢀⣠⠘⣯⣷⣿⡟⢀⢆⠸⣿⡟⢸
⣷⡈⢿⣿⣇⢱⡘⢿⣷⣬⣙⠿⣧⠘⣆⢀⠈⠻⣷⣟⣾⢿⣿⣆⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⣠⡞⢡⣿⢀⣿⣿⣿⠇⡄⢸⡄⢻⡇⣼
⣿⣷⡈⢿⣿⡆⢣⡀⠙⢾⣟⣿⣿⣷⡈⠂⠘⣦⡈⠿⣯⣿⢾⣿⣆⠙⠻⠿⠿⠿⠿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⢋⣠⣾⡟⢠⣿⣿⢀⣿⣿⡟⢠⣿⢈⣧⠘⢠⣿
⣿⣿⣿⣄⠻⣿⡄⢳⡄⢆⡙⠾⣽⣿⣿⣆⡀⢹⡷⣄⠙⢿⣿⡾⣿⣆⢀⡀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⣀⣠⣴⡿⣯⠏⣠⣿⣿⡏⢸⣿⡿⢁⣿⣿⢀⣿⠆⢸⣿
⣿⣿⣿⣿⣦⡙⣿⣆⢻⡌⢿⣶⢤⣉⣙⣿⣷⡀⠙⠽⠷⠄⠹⣿⣟⣿⣆⢙⣋⣤⣤⣤⣄⣀⢀⢀⢀⢀⣾⣿⣟⡷⣯⡿⢃⣼⣿⣿⣿⠇⣼⡟⣡⣿⣿⣿⢀⡿⢠⠈⣿
⣿⣿⣿⣿⣿⣷⣮⣿⣿⣿⡌⠁⢤⣤⣤⣤⣬⣭⣴⣶⣶⣶⣆⠈⢻⣿⣿⣆⢻⣿⣿⣿⣿⣿⣿⣷⣶⣤⣌⣉⡘⠛⠻⠶⣿⣿⣿⣿⡟⣰⣫⣴⣿⣿⣿⣿⠄⣷⣿⣿⣿
*/

#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = INF + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 900 * 1000 + 13;
const int AL = 256;
const int LOGN = 20;

int n;
string t1, t2, t3;
string s;

bool read () {
	static char buf[N];
	if (scanf("%s", buf) != 1)
		return false;
	t1 = buf;
	scanf("%s", buf);
	t2 = buf;
	scanf("%s", buf);
	t3 = buf;
	return true;
}

pair<pt, int> p[N];
int c[N];
int lcp[N];

int st[LOGN][N];
int pw[N];

void init(){
	pw[0] = pw[1] = 0;
	fore(i, 2, N)
		pw[i] = pw[i / 2] + 1;
	forn(i, n)
		st[0][i] = lcp[i];
	fore(j, 1, LOGN){
		forn(i, n){
			st[j][i] = st[j - 1][i];
			if (i + (1 << (j - 1)) < n)
				st[j][i] = min(st[j][i], st[j - 1][i + (1 << (j - 1))]);
		}
	}
}

int getMin(int l, int r){
	int len = pw[r - l];
	return min(st[len][l], st[len][r - (1 << len)]);
}

int add(int a, int b){
	a += b;
	if (a >= MOD) a -= MOD;
	if (a < 0) a += MOD;
	return a;
}

int mul(int a, int b){
	return a * li(b) % MOD;
}

int cnt[N][3];
int ans[N];

int get(int l, int r, int k){
	return cnt[r][k] - cnt[l][k];
}

int get(int l, int r){
	int res = 1;
	forn(i, 3) res = mul(res, get(l, r, i));
	return res;
}

pt getLower(int x){
	int l = 0, r = x - 1;
	while (l < r - 1){
		int m = (l + r) / 2;
		if (getMin(m, x) <= lcp[x])
			l = m;
		else
			r = m;
	}
	if (l >= x || getMin(l, x) > lcp[x])
		return mp(0, 0);
	else if (getMin(r, x) <= lcp[x])
		return mp(r + 1, lcp[r]);
	return mp(l + 1, lcp[l]);
}

pt getUpper(int x){
	int l = x + 1, r = n - 1;
	while (l < r - 1){
		int m = (l + r) / 2;
		if (getMin(x + 1, m + 1) < lcp[x])
			r = m;
		else
			l = m;
	}
	if (getMin(x + 1, l + 1) < lcp[x])
		return mp(l + 1, lcp[l]);
	return mp(r + 1, lcp[r]);
}

void build(){
	static int cnt[N];
	static int cn[N], p[N], pn[N];

	memset (cnt, 0, AL * sizeof(int));
	for (int i=0; i<n; ++i)
		++cnt[s[i]];
	for (int i=1; i<AL; ++i)
		cnt[i] += cnt[i-1];
	for (int i=0; i<n; ++i)
		p[--cnt[s[i]]] = i;
	c[p[0]] = 0;
	int classes = 1;
	for (int i=1; i<n; ++i) {
		if (s[p[i]] != s[p[i-1]])  ++classes;
		c[p[i]] = classes-1;
	}

	for (int h=0; (1<<h)<n; ++h) {
		for (int i=0; i<n; ++i) {
			pn[i] = p[i] - (1<<h);
			if (pn[i] < 0)  pn[i] += n;
		}
		memset (cnt, 0, classes * sizeof(int));
		for (int i=0; i<n; ++i)
			++cnt[c[pn[i]]];
		for (int i=1; i<classes; ++i)
			cnt[i] += cnt[i-1];
		for (int i=n-1; i>=0; --i)
			p[--cnt[c[pn[i]]]] = pn[i];
		classes = 1;
		for (int i=1; i<n; ++i) {
			int mid1 = (p[i] + (1<<h)) % n,  mid2 = (p[i-1] + (1<<h)) % n;
			if (c[p[i]] != c[p[i-1]] || c[mid1] != c[mid2])
				++classes;
			cn[p[i]] = classes-1;
		}
		memcpy (c, cn, n * sizeof(int));
	}

	forn(i, n)
		::p[i].y = p[i];

	int len = 0;
	forn(i, n){
		int pos = c[i];

		if (pos + 1 < n){
			for (int j = p[pos + 1]; s[i + len] == s[j + len]; ++len);
			lcp[pos] = len;
		}
		else{
			lcp[pos] = 0;
		}

		len = max(len - 1, 0);
	}
}

void solve(){
	s = t1 + string(1, 'z' + 1) + t2 + string(1, 'z' + 2) + t3 + string(1, 'z' + 3);
	n = sz(s);
	build();

	memset(cnt, 0, sizeof(cnt));
	forn(i, n){
		forn(j, 3) cnt[i + 1][j] += cnt[i][j];
		if (!isalpha(s[p[i].y])) continue;
		if (p[i].y < sz(t1))
			++cnt[i + 1][0];
		else if (p[i].y < sz(t1) + sz(t2) + 1)
			++cnt[i + 1][1];
		else
			++cnt[i + 1][2];
	}

	init();
	memset(ans, 0, sizeof(ans));
	forn(i, n - 1){
		pt l = getLower(i);
		pt r = getUpper(i);
		if (l.y == lcp[i])
			continue;
		ans[lcp[i]] = add(ans[lcp[i]], get(l.x, r.x));
		ans[max(l.y, r.y)] = add(ans[max(l.y, r.y)], -get(l.x, r.x));
	}

	for (int i = n - 1; i > 0; --i)
		ans[i - 1] = add(ans[i - 1], ans[i]);

	fore(i, 1, min({sz(t1), sz(t2), sz(t3)}) + 1)
		printf("%d ", ans[i]);
	puts("");
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();

#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

	while(read()) {
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


/*
⣿⣿⣿⣿⣿⣿⡷⣯⢿⣿⣷⣻⢯⣿⡽⣻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠸⣿⣿⣆⠹⣿⣿⢾⣟⣯⣿⣿⣿⣿⣿⣿⣽⣻⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣻⣽⡿⣿⣎⠙⣿⣞⣷⡌⢻⣟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⡄⠹⣿⣿⡆⠻⣿⣟⣯⡿⣽⡿⣿⣿⣿⣿⣽⡷⣯⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣟⣷⣿⣿⣿⡀⠹⣟⣾⣟⣆⠹⣯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢠⡘⣿⣿⡄⠉⢿⣿⣽⡷⣿⣻⣿⣿⣿⣿⡝⣷⣯⢿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣯⢿⣾⢿⣿⡄⢄⠘⢿⣞⡿⣧⡈⢷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⣧⠘⣿⣷⠈⣦⠙⢿⣽⣷⣻⣽⣿⣿⣿⣿⣌⢿⣯⢿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣟⣯⣿⢿⣿⡆⢸⡷⡈⢻⡽⣷⡷⡄⠻⣽⣿⣿⡿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣏⢰⣯⢷⠈⣿⡆⢹⢷⡌⠻⡾⢋⣱⣯⣿⣿⣿⣿⡆⢻⡿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡎⣿⢾⡿⣿⡆⢸⣽⢻⣄⠹⣷⣟⣿⣄⠹⣟⣿⣿⣟⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⡇⢸⣯⣟⣧⠘⣷⠈⡯⠛⢀⡐⢾⣟⣷⣻⣿⣿⣿⡿⡌⢿⣻⣿⣿
⣿⣿⣿⣿⣿⣿⣧⢸⡿⣟⣿⡇⢸⣯⣟⣮⢧⡈⢿⣞⡿⣦⠘⠏⣹⣿⣽⢿⣿⣿⣿⣿⣯⣿⣿⣿⡇⢸⣿⣿⣾⡆⠹⢀⣠⣾⣟⣷⡈⢿⣞⣯⢿⣿⣿⣿⢷⠘⣯⣿⣿
⣿⣿⣿⣿⣿⣿⣿⡈⣿⢿⣽⡇⠘⠛⠛⠛⠓⠓⠈⠛⠛⠟⠇⢀⢿⣻⣿⣯⢿⣿⣿⣿⣷⢿⣿⣿⠁⣾⣿⣿⣿⣧⡄⠇⣹⣿⣾⣯⣿⡄⠻⣽⣯⢿⣻⣿⣿⡇⢹⣾⣿
⣿⣿⣿⣿⣿⣿⣿⡇⢹⣿⡽⡇⢸⣿⣿⣿⣿⣿⣞⣆⠰⣶⣶⡄⢀⢻⡿⣯⣿⡽⣿⣿⣿⢯⣟⡿⢀⣿⣿⣿⣿⣿⣧⠐⣸⣿⣿⣷⣿⣿⣆⠹⣯⣿⣻⣿⣿⣿⢀⣿⢿
⣿⣿⣿⣿⣿⣿⣿⣿⠘⣯⡿⡇⢸⣿⣿⣿⣿⣿⣿⣿⣧⡈⢿⣳⠘⡄⠻⣿⢾⣽⣟⡿⣿⢯⣿⡇⢸⣿⣿⣿⣿⣿⣿⡀⢾⣿⣿⣿⣿⣿⣿⣆⠹⣾⣷⣻⣿⡿⡇⢸⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡇⢹⣿⠇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠻⡇⢹⣆⠹⣟⣾⣽⣻⣟⣿⣽⠁⣾⣿⣿⣿⣿⣿⣿⣇⣿⣿⠿⠛⠛⠉⠙⠋⢀⠁⢘⣯⣿⣿⣧⠘⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⡈⣿⡃⢼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡙⠌⣿⣆⠘⣿⣞⡿⣞⡿⡞⢠⣿⣿⣿⣿⣿⡿⠛⠉⠁⢀⣀⣠⣤⣤⣶⣶⣶⡆⢻⣽⣞⡿⣷⠈⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠘⠁⠉⠉⠉⠉⠉⠉⠉⠉⠉⠙⠛⠛⢿⣄⢻⣿⣧⠘⢯⣟⡿⣽⠁⣾⣿⣿⣿⣿⣿⡃⢀⢀⠘⠛⠿⢿⣻⣟⣯⣽⣻⣵⡀⢿⣯⣟⣿⢀⣿
⣿⣿⣿⣟⣿⣿⣿⣿⣶⣶⡆⢀⣿⣾⣿⣾⣷⣿⣶⠿⠚⠉⢀⢀⣤⣿⣷⣿⣿⣷⡈⢿⣻⢃⣼⣿⣿⣿⣿⣻⣿⣿⣿⡶⣦⣤⣄⣀⡀⠉⠛⠛⠷⣯⣳⠈⣾⡽⣾⢀⣿
⣿⢿⣿⣿⣻⣿⣿⣿⣿⣿⡿⠐⣿⣿⣿⣿⠿⠋⠁⢀⢀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣌⣥⣾⡿⣿⣿⣷⣿⣿⢿⣷⣿⣿⣟⣾⣽⣳⢯⣟⣶⣦⣤⡾⣟⣦⠘⣿⢾⡁⢺
⣿⣻⣿⣿⡷⣿⣿⣿⣿⣿⡗⣦⠸⡿⠋⠁⢀⢀⣠⣴⢿⣿⣽⣻⢽⣾⣟⣷⣿⣟⣿⣿⣿⣳⠿⣵⣧⣼⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣽⣳⣯⣿⣿⣿⣽⢀⢷⣻⠄⠘
⣿⢷⣻⣿⣿⣷⣻⣿⣿⣿⡷⠛⣁⢀⣀⣤⣶⣿⣛⡿⣿⣮⣽⡻⣿⣮⣽⣻⢯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⢀⢸⣿⢀⡆
⠸⣟⣯⣿⣿⣷⢿⣽⣿⣿⣷⣿⣷⣆⠹⣿⣶⣯⠿⣿⣶⣟⣻⢿⣷⣽⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢀⣯⣟⢀⡇
⣇⠹⣟⣾⣻⣿⣿⢾⡽⣿⣿⣿⣿⣿⣆⢹⣶⣿⣻⣷⣯⣟⣿⣿⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢀⡿⡇⢸⡇
⣿⣆⠹⣷⡻⣽⣿⣯⢿⣽⣻⣿⣿⣿⣿⣆⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⢸⣿⠇⣼⡇
⡙⠾⣆⠹⣿⣦⠛⣿⢯⣷⢿⡽⣿⣿⣿⣿⣆⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠎⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⢀⣿⣾⣣⡿⡇
⣿⣷⡌⢦⠙⣿⣿⣌⠻⣽⢯⣿⣽⣻⣿⣿⣿⣧⠩⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⢰⢣⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⢀⢀⢿⣞⣷⢿⡇
⣿⣽⣆⠹⣧⠘⣿⣿⡷⣌⠙⢷⣯⡷⣟⣿⣿⣿⣷⡀⡹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣈⠃⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⢀⣴⡧⢀⠸⣿⡽⣿⢀
⢻⣽⣿⡄⢻⣷⡈⢿⣿⣿⢧⢀⠙⢿⣻⡾⣽⣻⣿⣿⣄⠌⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⢁⣰⣾⣟⡿⢀⡄⢿⣟⣿⢀
⡄⢿⣿⣷⢀⠹⣟⣆⠻⣿⣿⣆⢀⣀⠉⠻⣿⡽⣯⣿⣿⣷⣈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⢀⣠⠘⣯⣷⣿⡟⢀⢆⠸⣿⡟⢸
⣷⡈⢿⣿⣇⢱⡘⢿⣷⣬⣙⠿⣧⠘⣆⢀⠈⠻⣷⣟⣾⢿⣿⣆⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⣠⡞⢡⣿⢀⣿⣿⣿⠇⡄⢸⡄⢻⡇⣼
⣿⣷⡈⢿⣿⡆⢣⡀⠙⢾⣟⣿⣿⣷⡈⠂⠘⣦⡈⠿⣯⣿⢾⣿⣆⠙⠻⠿⠿⠿⠿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⢋⣠⣾⡟⢠⣿⣿⢀⣿⣿⡟⢠⣿⢈⣧⠘⢠⣿
⣿⣿⣿⣄⠻⣿⡄⢳⡄⢆⡙⠾⣽⣿⣿⣆⡀⢹⡷⣄⠙⢿⣿⡾⣿⣆⢀⡀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⣀⣠⣴⡿⣯⠏⣠⣿⣿⡏⢸⣿⡿⢁⣿⣿⢀⣿⠆⢸⣿
⣿⣿⣿⣿⣦⡙⣿⣆⢻⡌⢿⣶⢤⣉⣙⣿⣷⡀⠙⠽⠷⠄⠹⣿⣟⣿⣆⢙⣋⣤⣤⣤⣄⣀⢀⢀⢀⢀⣾⣿⣟⡷⣯⡿⢃⣼⣿⣿⣿⠇⣼⡟⣡⣿⣿⣿⢀⡿⢠⠈⣿
⣿⣿⣿⣿⣿⣷⣮⣿⣿⣿⡌⠁⢤⣤⣤⣤⣬⣭⣴⣶⣶⣶⣆⠈⢻⣿⣿⣆⢻⣿⣿⣿⣿⣿⣿⣷⣶⣤⣌⣉⡘⠛⠻⠶⣿⣿⣿⣿⡟⣰⣫⣴⣿⣿⣿⣿⠄⣷⣿⣿⣿
*/

#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = INF + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 900 * 1000 + 13;
const int LOGN = 20;

int n;
string t1, t2, t3;
string s;

bool read () {
	static char buf[N];
	if (scanf("%s", buf) != 1)
		return false;
	t1 = buf;
	scanf("%s", buf);
	t2 = buf;
	scanf("%s", buf);
	t3 = buf;
	return true;
}

pair<pt, int> p[N];
int c[N];
int lcp[N];

int st[LOGN][N];
int pw[N];

void init(){
	pw[0] = pw[1] = 0;
	fore(i, 2, N)
		pw[i] = pw[i / 2] + 1;
	forn(i, n)
		st[0][i] = lcp[i];
	fore(j, 1, LOGN){
		forn(i, n){
			st[j][i] = st[j - 1][i];
			if (i + (1 << (j - 1)) < n)
				st[j][i] = min(st[j][i], st[j - 1][i + (1 << (j - 1))]);
		}
	}
}

int getMin(int l, int r){
	int len = pw[r - l];
	return min(st[len][l], st[len][r - (1 << len)]);
}

int add(int a, int b){
	a += b;
	if (a >= MOD) a -= MOD;
	return a;
}

int mul(int a, int b){
	return a * li(b) % MOD;
}

int binpow(int a, int b){
	int res = 1;
	while (b){
		if (b & 1)
			res = mul(res, a);
		a = mul(a, a);
		b >>= 1;
	}
	return res;
}

int fact[N], rfact[N];

int cnk(int n, int k){
	if (k < 0 || k > n) return 0;
	return mul(fact[n], mul(rfact[k], rfact[n - k]));
}

int cnt[N][3];
int ans[N];

int get(int l, int r, int k){
	return cnt[r][k] - cnt[l][k];
}

int get(int l, int r){
	int res = 1;
	forn(i, 3) res = mul(res, get(l, r, i));
	return res;
}

pt getLower(int x){
	int l = 0, r = x - 1;
	while (l < r - 1){
		int m = (l + r) / 2;
		if (getMin(m, x) <= lcp[x])
			l = m;
		else
			r = m;
	}
	if (l >= x || getMin(l, x) > lcp[x])
		return mp(0, 0);
	else if (getMin(r, x) <= lcp[x])
		return mp(r + 1, lcp[r]);
	return mp(l + 1, lcp[l]);
}

pt getUpper(int x){
	int l = x + 1, r = n - 1;
	while (l < r - 1){
		int m = (l + r) / 2;
		if (getMin(x + 1, m + 1) < lcp[x])
			r = m;
		else
			l = m;
	}
	if (getMin(x + 1, l + 1) < lcp[x])
		return mp(l + 1, lcp[l]);
	return mp(r + 1, lcp[r]);
}

void solve(){
	fact[0] = 1;
	fore(i, 1, N) fact[i] = mul(fact[i - 1], i);
	rfact[N - 1] = binpow(fact[N - 1], MOD - 2);
	for (int i = N - 2; i >= 0; --i)
		rfact[i] = mul(rfact[i + 1], i + 1);

	s = t1 + string(1, 'z' + 1) + t2 + string(1, 'z' + 2) + t3 + string(1, 'z' + 3);
	n = sz(s);

	memset(c, 0, sizeof(c));
	memset(p, 0, sizeof(p));

	for (int h = 0; c[p[n - 1].y] != n - 1; h = max(2 * h, 1)){
		forn(i, n)
			p[i] = mp(mp((h ? c[i] : s[i]) , c[(i + h) % n]), i);

		stable_sort(p, p + n);

		fore(i, 1, n)
			c[p[i].y] = c[p[i - 1].y] + (p[i].x != p[i - 1].x);
	}

	int len = 0;
	forn(i, n){
		int pos = c[i];

		if (pos + 1 < n){
			for (int j = p[pos + 1].y; s[i + len] == s[j + len]; ++len);
			lcp[pos] = len;
		}
		else{
			lcp[pos] = 0;
		}

		len = max(len - 1, 0);
	}

	//forn(i, n)
	//	cerr << i << " " << p[i].y << " " << s.substr(p[i].y) << " " << lcp[i] << endl;

	memset(cnt, 0, sizeof(cnt));
	forn(i, n){
		forn(j, 3) cnt[i + 1][j] += cnt[i][j];
		if (!isalpha(s[p[i].y])) continue;
		if (p[i].y < sz(t1))
			++cnt[i + 1][0];
		else if (p[i].y < sz(t1) + sz(t2) + 1)
			++cnt[i + 1][1];
		else
			++cnt[i + 1][2];
	}

	//forn(i, 3) cerr << get(0, 5, i) << " ";
	//cerr << endl;

	init();
	memset(ans, 0, sizeof(ans));
	forn(i, n - 1){
		pt l = getLower(i);
		pt r = getUpper(i);
		//cerr << i << " " << l << " " << r << " " << lcp[i] << endl;
		if (l.y == lcp[i])
			continue;
		for (int j = lcp[i]; j > max(l.y, r.y); --j)
			ans[j] = add(ans[j], get(l.x, r.x));
	}

	fore(i, 1, min({sz(t1), sz(t2), sz(t3)}) + 1)
		printf("%d ", ans[i]);
	puts("");
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();

#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

	while(read()) {
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


/*
⣿⣿⣿⣿⣿⣿⡷⣯⢿⣿⣷⣻⢯⣿⡽⣻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠸⣿⣿⣆⠹⣿⣿⢾⣟⣯⣿⣿⣿⣿⣿⣿⣽⣻⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣻⣽⡿⣿⣎⠙⣿⣞⣷⡌⢻⣟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⡄⠹⣿⣿⡆⠻⣿⣟⣯⡿⣽⡿⣿⣿⣿⣿⣽⡷⣯⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣟⣷⣿⣿⣿⡀⠹⣟⣾⣟⣆⠹⣯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢠⡘⣿⣿⡄⠉⢿⣿⣽⡷⣿⣻⣿⣿⣿⣿⡝⣷⣯⢿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣯⢿⣾⢿⣿⡄⢄⠘⢿⣞⡿⣧⡈⢷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⣧⠘⣿⣷⠈⣦⠙⢿⣽⣷⣻⣽⣿⣿⣿⣿⣌⢿⣯⢿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣟⣯⣿⢿⣿⡆⢸⡷⡈⢻⡽⣷⡷⡄⠻⣽⣿⣿⡿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣏⢰⣯⢷⠈⣿⡆⢹⢷⡌⠻⡾⢋⣱⣯⣿⣿⣿⣿⡆⢻⡿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡎⣿⢾⡿⣿⡆⢸⣽⢻⣄⠹⣷⣟⣿⣄⠹⣟⣿⣿⣟⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⡇⢸⣯⣟⣧⠘⣷⠈⡯⠛⢀⡐⢾⣟⣷⣻⣿⣿⣿⡿⡌⢿⣻⣿⣿
⣿⣿⣿⣿⣿⣿⣧⢸⡿⣟⣿⡇⢸⣯⣟⣮⢧⡈⢿⣞⡿⣦⠘⠏⣹⣿⣽⢿⣿⣿⣿⣿⣯⣿⣿⣿⡇⢸⣿⣿⣾⡆⠹⢀⣠⣾⣟⣷⡈⢿⣞⣯⢿⣿⣿⣿⢷⠘⣯⣿⣿
⣿⣿⣿⣿⣿⣿⣿⡈⣿⢿⣽⡇⠘⠛⠛⠛⠓⠓⠈⠛⠛⠟⠇⢀⢿⣻⣿⣯⢿⣿⣿⣿⣷⢿⣿⣿⠁⣾⣿⣿⣿⣧⡄⠇⣹⣿⣾⣯⣿⡄⠻⣽⣯⢿⣻⣿⣿⡇⢹⣾⣿
⣿⣿⣿⣿⣿⣿⣿⡇⢹⣿⡽⡇⢸⣿⣿⣿⣿⣿⣞⣆⠰⣶⣶⡄⢀⢻⡿⣯⣿⡽⣿⣿⣿⢯⣟⡿⢀⣿⣿⣿⣿⣿⣧⠐⣸⣿⣿⣷⣿⣿⣆⠹⣯⣿⣻⣿⣿⣿⢀⣿⢿
⣿⣿⣿⣿⣿⣿⣿⣿⠘⣯⡿⡇⢸⣿⣿⣿⣿⣿⣿⣿⣧⡈⢿⣳⠘⡄⠻⣿⢾⣽⣟⡿⣿⢯⣿⡇⢸⣿⣿⣿⣿⣿⣿⡀⢾⣿⣿⣿⣿⣿⣿⣆⠹⣾⣷⣻⣿⡿⡇⢸⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡇⢹⣿⠇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠻⡇⢹⣆⠹⣟⣾⣽⣻⣟⣿⣽⠁⣾⣿⣿⣿⣿⣿⣿⣇⣿⣿⠿⠛⠛⠉⠙⠋⢀⠁⢘⣯⣿⣿⣧⠘⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⡈⣿⡃⢼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡙⠌⣿⣆⠘⣿⣞⡿⣞⡿⡞⢠⣿⣿⣿⣿⣿⡿⠛⠉⠁⢀⣀⣠⣤⣤⣶⣶⣶⡆⢻⣽⣞⡿⣷⠈⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠘⠁⠉⠉⠉⠉⠉⠉⠉⠉⠉⠙⠛⠛⢿⣄⢻⣿⣧⠘⢯⣟⡿⣽⠁⣾⣿⣿⣿⣿⣿⡃⢀⢀⠘⠛⠿⢿⣻⣟⣯⣽⣻⣵⡀⢿⣯⣟⣿⢀⣿
⣿⣿⣿⣟⣿⣿⣿⣿⣶⣶⡆⢀⣿⣾⣿⣾⣷⣿⣶⠿⠚⠉⢀⢀⣤⣿⣷⣿⣿⣷⡈⢿⣻⢃⣼⣿⣿⣿⣿⣻⣿⣿⣿⡶⣦⣤⣄⣀⡀⠉⠛⠛⠷⣯⣳⠈⣾⡽⣾⢀⣿
⣿⢿⣿⣿⣻⣿⣿⣿⣿⣿⡿⠐⣿⣿⣿⣿⠿⠋⠁⢀⢀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣌⣥⣾⡿⣿⣿⣷⣿⣿⢿⣷⣿⣿⣟⣾⣽⣳⢯⣟⣶⣦⣤⡾⣟⣦⠘⣿⢾⡁⢺
⣿⣻⣿⣿⡷⣿⣿⣿⣿⣿⡗⣦⠸⡿⠋⠁⢀⢀⣠⣴⢿⣿⣽⣻⢽⣾⣟⣷⣿⣟⣿⣿⣿⣳⠿⣵⣧⣼⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣽⣳⣯⣿⣿⣿⣽⢀⢷⣻⠄⠘
⣿⢷⣻⣿⣿⣷⣻⣿⣿⣿⡷⠛⣁⢀⣀⣤⣶⣿⣛⡿⣿⣮⣽⡻⣿⣮⣽⣻⢯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⢀⢸⣿⢀⡆
⠸⣟⣯⣿⣿⣷⢿⣽⣿⣿⣷⣿⣷⣆⠹⣿⣶⣯⠿⣿⣶⣟⣻⢿⣷⣽⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢀⣯⣟⢀⡇
⣇⠹⣟⣾⣻⣿⣿⢾⡽⣿⣿⣿⣿⣿⣆⢹⣶⣿⣻⣷⣯⣟⣿⣿⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢀⡿⡇⢸⡇
⣿⣆⠹⣷⡻⣽⣿⣯⢿⣽⣻⣿⣿⣿⣿⣆⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⢸⣿⠇⣼⡇
⡙⠾⣆⠹⣿⣦⠛⣿⢯⣷⢿⡽⣿⣿⣿⣿⣆⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠎⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⢀⣿⣾⣣⡿⡇
⣿⣷⡌⢦⠙⣿⣿⣌⠻⣽⢯⣿⣽⣻⣿⣿⣿⣧⠩⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⢰⢣⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⢀⢀⢿⣞⣷⢿⡇
⣿⣽⣆⠹⣧⠘⣿⣿⡷⣌⠙⢷⣯⡷⣟⣿⣿⣿⣷⡀⡹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣈⠃⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⢀⣴⡧⢀⠸⣿⡽⣿⢀
⢻⣽⣿⡄⢻⣷⡈⢿⣿⣿⢧⢀⠙⢿⣻⡾⣽⣻⣿⣿⣄⠌⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⢁⣰⣾⣟⡿⢀⡄⢿⣟⣿⢀
⡄⢿⣿⣷⢀⠹⣟⣆⠻⣿⣿⣆⢀⣀⠉⠻⣿⡽⣯⣿⣿⣷⣈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⢀⣠⠘⣯⣷⣿⡟⢀⢆⠸⣿⡟⢸
⣷⡈⢿⣿⣇⢱⡘⢿⣷⣬⣙⠿⣧⠘⣆⢀⠈⠻⣷⣟⣾⢿⣿⣆⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⣠⡞⢡⣿⢀⣿⣿⣿⠇⡄⢸⡄⢻⡇⣼
⣿⣷⡈⢿⣿⡆⢣⡀⠙⢾⣟⣿⣿⣷⡈⠂⠘⣦⡈⠿⣯⣿⢾⣿⣆⠙⠻⠿⠿⠿⠿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⢋⣠⣾⡟⢠⣿⣿⢀⣿⣿⡟⢠⣿⢈⣧⠘⢠⣿
⣿⣿⣿⣄⠻⣿⡄⢳⡄⢆⡙⠾⣽⣿⣿⣆⡀⢹⡷⣄⠙⢿⣿⡾⣿⣆⢀⡀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⣀⣠⣴⡿⣯⠏⣠⣿⣿⡏⢸⣿⡿⢁⣿⣿⢀⣿⠆⢸⣿
⣿⣿⣿⣿⣦⡙⣿⣆⢻⡌⢿⣶⢤⣉⣙⣿⣷⡀⠙⠽⠷⠄⠹⣿⣟⣿⣆⢙⣋⣤⣤⣤⣄⣀⢀⢀⢀⢀⣾⣿⣟⡷⣯⡿⢃⣼⣿⣿⣿⠇⣼⡟⣡⣿⣿⣿⢀⡿⢠⠈⣿
⣿⣿⣿⣿⣿⣷⣮⣿⣿⣿⡌⠁⢤⣤⣤⣤⣬⣭⣴⣶⣶⣶⣆⠈⢻⣿⣿⣆⢻⣿⣿⣿⣿⣿⣿⣷⣶⣤⣌⣉⡘⠛⠻⠶⣿⣿⣿⣿⡟⣰⣫⣴⣿⣿⣿⣿⠄⣷⣿⣿⣿
*/

#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = INF + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 900 * 1000 + 13;
const int AL = 256;
const int LOGN = 20;

int n;
string t1, t2, t3;
string s;

bool read () {
	static char buf[N];
	if (scanf("%s", buf) != 1)
		return false;
	t1 = buf;
	scanf("%s", buf);
	t2 = buf;
	scanf("%s", buf);
	t3 = buf;
	return true;
}

pair<pt, int> p[N];
int c[N];
int lcp[N];

int st[LOGN][N];
int pw[N];

void init(){
	pw[0] = pw[1] = 0;
	fore(i, 2, N)
		pw[i] = pw[i / 2] + 1;
	forn(i, n)
		st[0][i] = lcp[i];
	fore(j, 1, LOGN){
		forn(i, n){
			st[j][i] = st[j - 1][i];
			if (i + (1 << (j - 1)) < n)
				st[j][i] = min(st[j][i], st[j - 1][i + (1 << (j - 1))]);
		}
	}
}

int getMin(int l, int r){
	int len = pw[r - l];
	return min(st[len][l], st[len][r - (1 << len)]);
}

int add(int a, int b){
	a += b;
	if (a >= MOD) a -= MOD;
	return a;
}

int mul(int a, int b){
	return a * li(b) % MOD;
}

int cnt[N][3];
int ans[N];

int get(int l, int r, int k){
	return cnt[r][k] - cnt[l][k];
}

int get(int l, int r){
	int res = 1;
	forn(i, 3) res = mul(res, get(l, r, i));
	return res;
}

pt getLower(int x){
	int l = 0, r = x - 1;
	while (l < r - 1){
		int m = (l + r) / 2;
		if (getMin(m, x) <= lcp[x])
			l = m;
		else
			r = m;
	}
	if (l >= x || getMin(l, x) > lcp[x])
		return mp(0, 0);
	else if (getMin(r, x) <= lcp[x])
		return mp(r + 1, lcp[r]);
	return mp(l + 1, lcp[l]);
}

pt getUpper(int x){
	int l = x + 1, r = n - 1;
	while (l < r - 1){
		int m = (l + r) / 2;
		if (getMin(x + 1, m + 1) < lcp[x])
			r = m;
		else
			l = m;
	}
	if (getMin(x + 1, l + 1) < lcp[x])
		return mp(l + 1, lcp[l]);
	return mp(r + 1, lcp[r]);
}

void build(){
	static int cnt[N];
	static int cn[N], p[N], pn[N];

	memset (cnt, 0, AL * sizeof(int));
	for (int i=0; i<n; ++i)
		++cnt[s[i]];
	for (int i=1; i<AL; ++i)
		cnt[i] += cnt[i-1];
	for (int i=0; i<n; ++i)
		p[--cnt[s[i]]] = i;
	c[p[0]] = 0;
	int classes = 1;
	for (int i=1; i<n; ++i) {
		if (s[p[i]] != s[p[i-1]])  ++classes;
		c[p[i]] = classes-1;
	}

	for (int h=0; (1<<h)<n; ++h) {
		for (int i=0; i<n; ++i) {
			pn[i] = p[i] - (1<<h);
			if (pn[i] < 0)  pn[i] += n;
		}
		memset (cnt, 0, classes * sizeof(int));
		for (int i=0; i<n; ++i)
			++cnt[c[pn[i]]];
		for (int i=1; i<classes; ++i)
			cnt[i] += cnt[i-1];
		for (int i=n-1; i>=0; --i)
			p[--cnt[c[pn[i]]]] = pn[i];
		classes = 1;
		for (int i=1; i<n; ++i) {
			int mid1 = (p[i] + (1<<h)) % n,  mid2 = (p[i-1] + (1<<h)) % n;
			if (c[p[i]] != c[p[i-1]] || c[mid1] != c[mid2])
				++classes;
			cn[p[i]] = classes-1;
		}
		memcpy (c, cn, n * sizeof(int));
	}

	forn(i, n)
		::p[i].y = p[i];

	int len = 0;
	forn(i, n){
		int pos = c[i];

		if (pos + 1 < n){
			for (int j = p[pos + 1]; s[i + len] == s[j + len]; ++len);
			lcp[pos] = len;
		}
		else{
			lcp[pos] = 0;
		}

		len = max(len - 1, 0);
	}
}

void solve(){
	s = t1 + string(1, 'z' + 1) + t2 + string(1, 'z' + 2) + t3 + string(1, 'z' + 3);
	n = sz(s);
	build();

	memset(cnt, 0, sizeof(cnt));
	forn(i, n){
		forn(j, 3) cnt[i + 1][j] += cnt[i][j];
		if (!isalpha(s[p[i].y])) continue;
		if (p[i].y < sz(t1))
			++cnt[i + 1][0];
		else if (p[i].y < sz(t1) + sz(t2) + 1)
			++cnt[i + 1][1];
		else
			++cnt[i + 1][2];
	}

	init();
	memset(ans, 0, sizeof(ans));
	forn(i, n - 1){
		pt l = getLower(i);
		pt r = getUpper(i);
		if (l.y == lcp[i])
			continue;
		ans[lcp[i]] = add(ans[lcp[i]], get(l.x, r.x));
		ans[max(l.y, r.y)] = add(ans[max(l.y, r.y)], -get(l.x, r.x));
	}

	for (int i = n - 1; i > 0; --i)
		ans[i - 1] = add(ans[i - 1], ans[i]);

	fore(i, 1, min({sz(t1), sz(t2), sz(t3)}) + 1)
		printf("%d ", ans[i]);
	puts("");
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();

#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

	while(read()) {
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


/*
⣿⣿⣿⣿⣿⣿⡷⣯⢿⣿⣷⣻⢯⣿⡽⣻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠸⣿⣿⣆⠹⣿⣿⢾⣟⣯⣿⣿⣿⣿⣿⣿⣽⣻⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣻⣽⡿⣿⣎⠙⣿⣞⣷⡌⢻⣟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⡄⠹⣿⣿⡆⠻⣿⣟⣯⡿⣽⡿⣿⣿⣿⣿⣽⡷⣯⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣟⣷⣿⣿⣿⡀⠹⣟⣾⣟⣆⠹⣯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢠⡘⣿⣿⡄⠉⢿⣿⣽⡷⣿⣻⣿⣿⣿⣿⡝⣷⣯⢿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣯⢿⣾⢿⣿⡄⢄⠘⢿⣞⡿⣧⡈⢷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⣧⠘⣿⣷⠈⣦⠙⢿⣽⣷⣻⣽⣿⣿⣿⣿⣌⢿⣯⢿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣟⣯⣿⢿⣿⡆⢸⡷⡈⢻⡽⣷⡷⡄⠻⣽⣿⣿⡿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣏⢰⣯⢷⠈⣿⡆⢹⢷⡌⠻⡾⢋⣱⣯⣿⣿⣿⣿⡆⢻⡿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡎⣿⢾⡿⣿⡆⢸⣽⢻⣄⠹⣷⣟⣿⣄⠹⣟⣿⣿⣟⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⡇⢸⣯⣟⣧⠘⣷⠈⡯⠛⢀⡐⢾⣟⣷⣻⣿⣿⣿⡿⡌⢿⣻⣿⣿
⣿⣿⣿⣿⣿⣿⣧⢸⡿⣟⣿⡇⢸⣯⣟⣮⢧⡈⢿⣞⡿⣦⠘⠏⣹⣿⣽⢿⣿⣿⣿⣿⣯⣿⣿⣿⡇⢸⣿⣿⣾⡆⠹⢀⣠⣾⣟⣷⡈⢿⣞⣯⢿⣿⣿⣿⢷⠘⣯⣿⣿
⣿⣿⣿⣿⣿⣿⣿⡈⣿⢿⣽⡇⠘⠛⠛⠛⠓⠓⠈⠛⠛⠟⠇⢀⢿⣻⣿⣯⢿⣿⣿⣿⣷⢿⣿⣿⠁⣾⣿⣿⣿⣧⡄⠇⣹⣿⣾⣯⣿⡄⠻⣽⣯⢿⣻⣿⣿⡇⢹⣾⣿
⣿⣿⣿⣿⣿⣿⣿⡇⢹⣿⡽⡇⢸⣿⣿⣿⣿⣿⣞⣆⠰⣶⣶⡄⢀⢻⡿⣯⣿⡽⣿⣿⣿⢯⣟⡿⢀⣿⣿⣿⣿⣿⣧⠐⣸⣿⣿⣷⣿⣿⣆⠹⣯⣿⣻⣿⣿⣿⢀⣿⢿
⣿⣿⣿⣿⣿⣿⣿⣿⠘⣯⡿⡇⢸⣿⣿⣿⣿⣿⣿⣿⣧⡈⢿⣳⠘⡄⠻⣿⢾⣽⣟⡿⣿⢯⣿⡇⢸⣿⣿⣿⣿⣿⣿⡀⢾⣿⣿⣿⣿⣿⣿⣆⠹⣾⣷⣻⣿⡿⡇⢸⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡇⢹⣿⠇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠻⡇⢹⣆⠹⣟⣾⣽⣻⣟⣿⣽⠁⣾⣿⣿⣿⣿⣿⣿⣇⣿⣿⠿⠛⠛⠉⠙⠋⢀⠁⢘⣯⣿⣿⣧⠘⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⡈⣿⡃⢼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡙⠌⣿⣆⠘⣿⣞⡿⣞⡿⡞⢠⣿⣿⣿⣿⣿⡿⠛⠉⠁⢀⣀⣠⣤⣤⣶⣶⣶⡆⢻⣽⣞⡿⣷⠈⣿
⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠘⠁⠉⠉⠉⠉⠉⠉⠉⠉⠉⠙⠛⠛⢿⣄⢻⣿⣧⠘⢯⣟⡿⣽⠁⣾⣿⣿⣿⣿⣿⡃⢀⢀⠘⠛⠿⢿⣻⣟⣯⣽⣻⣵⡀⢿⣯⣟⣿⢀⣿
⣿⣿⣿⣟⣿⣿⣿⣿⣶⣶⡆⢀⣿⣾⣿⣾⣷⣿⣶⠿⠚⠉⢀⢀⣤⣿⣷⣿⣿⣷⡈⢿⣻⢃⣼⣿⣿⣿⣿⣻⣿⣿⣿⡶⣦⣤⣄⣀⡀⠉⠛⠛⠷⣯⣳⠈⣾⡽⣾⢀⣿
⣿⢿⣿⣿⣻⣿⣿⣿⣿⣿⡿⠐⣿⣿⣿⣿⠿⠋⠁⢀⢀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣌⣥⣾⡿⣿⣿⣷⣿⣿⢿⣷⣿⣿⣟⣾⣽⣳⢯⣟⣶⣦⣤⡾⣟⣦⠘⣿⢾⡁⢺
⣿⣻⣿⣿⡷⣿⣿⣿⣿⣿⡗⣦⠸⡿⠋⠁⢀⢀⣠⣴⢿⣿⣽⣻⢽⣾⣟⣷⣿⣟⣿⣿⣿⣳⠿⣵⣧⣼⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣽⣳⣯⣿⣿⣿⣽⢀⢷⣻⠄⠘
⣿⢷⣻⣿⣿⣷⣻⣿⣿⣿⡷⠛⣁⢀⣀⣤⣶⣿⣛⡿⣿⣮⣽⡻⣿⣮⣽⣻⢯⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⢀⢸⣿⢀⡆
⠸⣟⣯⣿⣿⣷⢿⣽⣿⣿⣷⣿⣷⣆⠹⣿⣶⣯⠿⣿⣶⣟⣻⢿⣷⣽⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢀⣯⣟⢀⡇
⣇⠹⣟⣾⣻⣿⣿⢾⡽⣿⣿⣿⣿⣿⣆⢹⣶⣿⣻⣷⣯⣟⣿⣿⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢀⡿⡇⢸⡇
⣿⣆⠹⣷⡻⣽⣿⣯⢿⣽⣻⣿⣿⣿⣿⣆⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⢸⣿⠇⣼⡇
⡙⠾⣆⠹⣿⣦⠛⣿⢯⣷⢿⡽⣿⣿⣿⣿⣆⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠎⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⢀⣿⣾⣣⡿⡇
⣿⣷⡌⢦⠙⣿⣿⣌⠻⣽⢯⣿⣽⣻⣿⣿⣿⣧⠩⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⢰⢣⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⢀⢀⢿⣞⣷⢿⡇
⣿⣽⣆⠹⣧⠘⣿⣿⡷⣌⠙⢷⣯⡷⣟⣿⣿⣿⣷⡀⡹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣈⠃⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⢀⣴⡧⢀⠸⣿⡽⣿⢀
⢻⣽⣿⡄⢻⣷⡈⢿⣿⣿⢧⢀⠙⢿⣻⡾⣽⣻⣿⣿⣄⠌⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⢁⣰⣾⣟⡿⢀⡄⢿⣟⣿⢀
⡄⢿⣿⣷⢀⠹⣟⣆⠻⣿⣿⣆⢀⣀⠉⠻⣿⡽⣯⣿⣿⣷⣈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⢀⣠⠘⣯⣷⣿⡟⢀⢆⠸⣿⡟⢸
⣷⡈⢿⣿⣇⢱⡘⢿⣷⣬⣙⠿⣧⠘⣆⢀⠈⠻⣷⣟⣾⢿⣿⣆⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⣠⡞⢡⣿⢀⣿⣿⣿⠇⡄⢸⡄⢻⡇⣼
⣿⣷⡈⢿⣿⡆⢣⡀⠙⢾⣟⣿⣿⣷⡈⠂⠘⣦⡈⠿⣯⣿⢾⣿⣆⠙⠻⠿⠿⠿⠿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⢋⣠⣾⡟⢠⣿⣿⢀⣿⣿⡟⢠⣿⢈⣧⠘⢠⣿
⣿⣿⣿⣄⠻⣿⡄⢳⡄⢆⡙⠾⣽⣿⣿⣆⡀⢹⡷⣄⠙⢿⣿⡾⣿⣆⢀⡀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⢀⣀⣠⣴⡿⣯⠏⣠⣿⣿⡏⢸⣿⡿⢁⣿⣿⢀⣿⠆⢸⣿
⣿⣿⣿⣿⣦⡙⣿⣆⢻⡌⢿⣶⢤⣉⣙⣿⣷⡀⠙⠽⠷⠄⠹⣿⣟⣿⣆⢙⣋⣤⣤⣤⣄⣀⢀⢀⢀⢀⣾⣿⣟⡷⣯⡿⢃⣼⣿⣿⣿⠇⣼⡟⣡⣿⣿⣿⢀⡿⢠⠈⣿
⣿⣿⣿⣿⣿⣷⣮⣿⣿⣿⡌⠁⢤⣤⣤⣤⣬⣭⣴⣶⣶⣶⣆⠈⢻⣿⣿⣆⢻⣿⣿⣿⣿⣿⣿⣷⣶⣤⣌⣉⡘⠛⠻⠶⣿⣿⣿⣿⡟⣰⣫⣴⣿⣿⣿⣿⠄⣷⣿⣿⣿
*/

#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = INF + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int N = 900 * 1000 + 13;
const int AL = 256;
const int LOGN = 20;

int n;
string t1, t2, t3;
string s;

bool read () {
	static char buf[N];
	if (scanf("%s", buf) != 1)
		return false;
	t1 = buf;
	scanf("%s", buf);
	t2 = buf;
	scanf("%s", buf);
	t3 = buf;
	return true;
}

pair<pt, int> p[N];
int c[N];
int lcp[N];

int st[LOGN][N];
int pw[N];

void init(){
	pw[0] = pw[1] = 0;
	fore(i, 2, N)
		pw[i] = pw[i / 2] + 1;
	forn(i, n)
		st[0][i] = lcp[i];
	fore(j, 1, LOGN){
		forn(i, n){
			st[j][i] = st[j - 1][i];
			if (i + (1 << (j - 1)) < n)
				st[j][i] = min(st[j][i], st[j - 1][i + (1 << (j - 1))]);
		}
	}
}

int getMin(int l, int r){
	int len = pw[r - l];
	return min(st[len][l], st[len][r - (1 << len)]);
}

int add(int a, int b){
	a += b;
	if (a >= MOD) a -= MOD;
	return a;
}

int mul(int a, int b){
	return a * li(b) % MOD;
}

int cnt[N][3];
int ans[N];

int get(int l, int r, int k){
	return cnt[r][k] - cnt[l][k];
}

int get(int l, int r){
	int res = 1;
	forn(i, 3) res = mul(res, get(l, r, i));
	return res;
}

pt getLower(int x){
	int l = 0, r = x - 1;
	while (l < r - 1){
		int m = (l + r) / 2;
		if (getMin(m, x) <= lcp[x])
			l = m;
		else
			r = m;
	}
	if (l >= x || getMin(l, x) > lcp[x])
		return mp(0, 0);
	else if (getMin(r, x) <= lcp[x])
		return mp(r + 1, lcp[r]);
	return mp(l + 1, lcp[l]);
}

pt getUpper(int x){
	int l = x + 1, r = n - 1;
	while (l < r - 1){
		int m = (l + r) / 2;
		if (getMin(x + 1, m + 1) < lcp[x])
			r = m;
		else
			l = m;
	}
	if (getMin(x + 1, l + 1) < lcp[x])
		return mp(l + 1, lcp[l]);
	return mp(r + 1, lcp[r]);
}

void build(){
	static int cnt[N];
	static int cn[N], p[N], pn[N];

	memset (cnt, 0, AL * sizeof(int));
	for (int i=0; i<n; ++i)
		++cnt[s[i]];
	for (int i=1; i<AL; ++i)
		cnt[i] += cnt[i-1];
	for (int i=0; i<n; ++i)
		p[--cnt[s[i]]] = i;
	c[p[0]] = 0;
	int classes = 1;
	for (int i=1; i<n; ++i) {
		if (s[p[i]] != s[p[i-1]])  ++classes;
		c[p[i]] = classes-1;
	}

	for (int h=0; (1<<h)<n; ++h) {
		for (int i=0; i<n; ++i) {
			pn[i] = p[i] - (1<<h);
			if (pn[i] < 0)  pn[i] += n;
		}
		memset (cnt, 0, classes * sizeof(int));
		for (int i=0; i<n; ++i)
			++cnt[c[pn[i]]];
		for (int i=1; i<classes; ++i)
			cnt[i] += cnt[i-1];
		for (int i=n-1; i>=0; --i)
			p[--cnt[c[pn[i]]]] = pn[i];
		classes = 1;
		for (int i=1; i<n; ++i) {
			int mid1 = (p[i] + (1<<h)) % n,  mid2 = (p[i-1] + (1<<h)) % n;
			if (c[p[i]] != c[p[i-1]] || c[mid1] != c[mid2])
				++classes;
			cn[p[i]] = classes-1;
		}
		memcpy (c, cn, n * sizeof(int));
	}

	forn(i, n)
		::p[i].y = p[i];

	int len = 0;
	forn(i, n){
		int pos = c[i];

		if (pos + 1 < n){
			for (int j = p[pos + 1]; s[i + len] == s[j + len]; ++len);
			lcp[pos] = len;
		}
		else{
			lcp[pos] = 0;
		}

		len = max(len - 1, 0);
	}
}

void solve(){
	s = t1 + string(1, 'z' + 1) + t2 + string(1, 'z' + 2) + t3 + string(1, 'z' + 3);
	n = sz(s);
	build();

	//forn(i, n)
	//	cerr << i << " " << p[i].y << " " << s.substr(p[i].y) << " " << lcp[i] << endl;

	memset(cnt, 0, sizeof(cnt));
	forn(i, n){
		forn(j, 3) cnt[i + 1][j] += cnt[i][j];
		if (!isalpha(s[p[i].y])) continue;
		if (p[i].y < sz(t1))
			++cnt[i + 1][0];
		else if (p[i].y < sz(t1) + sz(t2) + 1)
			++cnt[i + 1][1];
		else
			++cnt[i + 1][2];
	}

	//forn(i, 3) cerr << get(0, 5, i) << " ";
	//cerr << endl;

	init();
	memset(ans, 0, sizeof(ans));
	forn(i, n - 1){
		pt l = getLower(i);
		pt r = getUpper(i);
		//cerr << i << " " << l << " " << r << " " << lcp[i] << endl;
		if (l.y == lcp[i])
			continue;
		for (int j = lcp[i]; j > max(l.y, r.y); --j)
			ans[j] = add(ans[j], get(l.x, r.x));
	}

	fore(i, 1, min({sz(t1), sz(t2), sz(t3)}) + 1)
		printf("%d ", ans[i]);
	puts("");
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();

#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

	while(read()) {
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


#include<stack>
#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(),i##_end=(c).end();i!=i##_end;++i)
#define eprintf(...) fprintf(stderr, __VA_ARGS__)

template<class T> inline void amin(T &x, const T &y) { if (y<x) x=y; }
template<class T> inline void amax(T &x, const T &y) { if (x<y) x=y; }
template<class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
    for (bool sp=0; begin!=end; ++begin) { if (sp) putchar(' '); else sp = true; printf(fmt, *begin); }
    putchar('\n');
}
class SAIS {
public:
    vector<int> sa, lcp, rank;
    SAIS(){}
    SAIS(const string &str_) : str(str_) {
	N = str.size()+1;
	S = vector<int>(N, 0);
	for (int i=0; i<N; i++) S[i] = str[i];
	*this = SAIS(S, 256);
    }
    SAIS(const vector<int> &S_, int A_SIZE_, bool lcp=true) : S(S_), A_SIZE(A_SIZE_) {
	buildSA();
	if (lcp) buildLCP();
    }
private:
    string str;
    vector<int> S;
    int A_SIZE;
    int N;
    vector<int> t, B;
    enum { STYPE, LTYPE };

    inline bool is_lms(int i) {
	return i>0 && t[i] == STYPE && t[i-1] == LTYPE;
    }
    void bucket() {
	B = vector<int>(A_SIZE);
	for (int i=0; i<N; i++) B[S[i]]++;
	for (int i=0; i<A_SIZE-1; i++) B[i+1] += B[i];
    }
    void induced_sort() {
	bucket();
	for (int i=0; i<N; i++) {
	    int j = sa[i]-1;
	    if (j >= 0 && S[j] >= S[j+1]) sa[B[S[j]-1]++] = j;
	}
	bucket();
	for (int i=N; i--; ) {
	    int j = sa[i]-1;
	    if (j >= 0 && S[j] <= S[j+1]) sa[--B[S[j]]] = j;
	}
    }
    void buildSA() {
	N = S.size();
	sa.assign(N, -1);
	if (N == 1) {
	    sa[0] = 0;
	    return;
	}
	t.assign(N, STYPE);
	for (int i=N-1; i--;)
	    if (S[i] > S[i+1] || (S[i] == S[i+1] && t[i+1] == LTYPE))
		t[i] = LTYPE;
	bucket();
	for (int i=N; i--;)
	    if (is_lms(i)) sa[--B[S[i]]] = i;
	induced_sort();

	int N1 = 0;
	for (int i=0; i<N; i++) if (is_lms(sa[i])) sa[N1++] = sa[i];

	fill(sa.begin()+N1, sa.end(), -1);
	int name = 0, prev = -1;
	for (int i=0; i<N1; i++) {
	    int cur = sa[i];
	    bool diff = (prev == -1);
	    for (int j=0; !diff; j++) {
		if (j>0 && is_lms(cur+j)) break;
		if (S[cur+j] != S[prev+j]) diff = true;
	    }
	    if (diff) name++;
	    sa[N1+cur/2] = name-1;
	    prev = cur;
	}
	vector<int> S1, sa1(N1);
	for (int i=N1; i<N; i++) if (sa[i]>=0) S1.push_back(sa[i]);
	if (name == N1) for (int i=0; i<N1; i++) sa1[S1[i]] = i;
	else sa1 = SAIS(S1, name, false).sa;

	N1 = 0;
	for (int i=0; i<N; i++) if (is_lms(i)) S1[N1++] = i;
	for (int i=0; i<N1; i++) sa1[i] = S1[sa1[i]];

	fill(sa.begin(), sa.end(), -1);
	bucket();
	for (int i=N1; i--;) {
	    int j = sa1[i];
	    sa[--B[S[j]]] = j;
	}
	induced_sort();
    }
    void buildLCP() {
	rank.resize(N);
	lcp.resize(N-1);
	for (int i=0; i<N; i++) rank[sa[i]] = i;
	int h = 0;
	for (int i=0; i<N-1; i++) {
	    int j = sa[rank[i]-1];
	    if (h>0) h--;
	    for (; j+h<N && i+h<N && S[j+h] == S[i+h]; h++) ;
	    lcp[rank[i]-1] = h;
	}
    }

public:
//    IRMQ<int> rmq;
//    void buildRMQ() {
//	rmq = IRMQ<int>(lcp);
//    }
//    int common_prefix(int x, int y) {
//	if (x == y) return N-1-x;
//	if (y >= N-1) return 0;
//	if (rank[x] > rank[y]) swap(x, y);
//	return rmq.min_v(rank[x], rank[y]);
//    }
//    int compare(int x, int xn, int y, int yn) {
//	int l = common_prefix(x, y);
//	if (l >= xn || l >= yn) return xn < yn ? -1 : xn == yn ? 0 : 1;
//	return rank[x] < rank[y] ? -1 : x == y ? 0 : 1;
//    }
};

template<unsigned MOD> struct ModInt {
    static const unsigned static_MOD = MOD;
    unsigned x;
    void undef() { x = (unsigned)-1; }
    bool isnan() const { return x == (unsigned)-1; }
    inline int getInt() const { return (int)x; }
    ModInt() { x = 0; }
    ModInt(const ModInt &y) { x = y.x; }
    ModInt(int y) { if (y<0 || (int)MOD<=y) y %= (int)MOD; if (y<0) y += MOD; x=y; }
    ModInt(unsigned y) { if (MOD<=y) x = y % MOD; else x = y; }
    ModInt(long long y) { if (y<0 || MOD<=y) y %= MOD; if (y<0) y += MOD; x=y; }
    ModInt(unsigned long long y) { if (MOD<=y) x = y % MOD; else x = y; }
    ModInt &operator+=(const ModInt y) { if ((x += y.x) >= MOD) x -= MOD; return *this; }
    ModInt &operator-=(const ModInt y) { if ((x -= y.x) & (1u<<31)) x += MOD; return *this; }
    ModInt &operator*=(const ModInt y) { x = (unsigned long long)x * y.x % MOD; return *this; }
    ModInt &operator/=(const ModInt y) { x = (unsigned long long)x * y.inv().x % MOD; return *this; }
    ModInt operator-() const { return (x ? MOD-x: 0); }

    ModInt inv() const {
	unsigned a = MOD, b = x; int u = 0, v = 1;
	while (b) {
	    int t = a / b;
	    a -= t * b; swap(a, b);
	    u -= t * v; swap(u, v);
	}
	if (u < 0) u += MOD;
	return ModInt(u);
    }
    ModInt pow(long long y) const {
	ModInt b = *this, r = 1;
	if (y < 0) { b = b.inv(); y = -y; }
	for (; y; y>>=1) {
	    if (y&1) r *= b;
	    b *= b;
	}
	return r;
    }
    friend ModInt operator+(ModInt x, const ModInt y) { return x += y; }
    friend ModInt operator-(ModInt x, const ModInt y) { return x -= y; }
    friend ModInt operator*(ModInt x, const ModInt y) { return x *= y; }
    friend ModInt operator/(ModInt x, const ModInt y) { return x *= y.inv(); }
    friend bool operator<(const ModInt x, const ModInt y) { return x.x < y.x; }
    friend bool operator==(const ModInt x, const ModInt y) { return x.x == y.x; }
    friend bool operator!=(const ModInt x, const ModInt y) { return x.x != y.x; }

    static ModInt buffered_inv(const ModInt y) {
	static ModInt *inv_tbl = NULL;
	if (inv_tbl == NULL) {
	    const int n = 2000001;
	    inv_tbl = new ModInt[n];
	    inv_tbl[0] = 0; inv_tbl[1] = 1;
	    for (int i=2; i<n; i++) inv_tbl[i] = ModInt((unsigned long long)inv_tbl[MOD%i].x * (MOD-MOD/i));
	}
	return inv_tbl[y.x];
    }
};

const LL MOD = 1000000007;
typedef ModInt<MOD> Mint;

int M;
string S[3];
char buf[300111];
Mint ans[300111];

int my_type(int i) {
    REP (k, 3) {
	if (i < (int)S[k].size()) return k;
	if (i == (int)S[k].size()) return -1;
	i -= S[k].size() + 1;
    }
    return -1;
}

int main() {
    M = 300011;
    REP (i, 3) {
	scanf("%s", buf);
	S[i] = buf;
	amin(M, (int)S[i].size());
    }

    string Z = S[0] + "$" + S[1] + "#" + S[2];
    SAIS sa(Z);

    stack<int> st;
    stack<Mint> t[3];
    REP (i, 3) t[i].push(0);
    sa.lcp.push_back(0);
    REP (i, sa.lcp.size()) {
	int my = my_type(sa.sa[i]);
	Mint o[3] = {};
	if (my != -1) o[my] = 1;
	while (!st.empty() && sa.lcp[st.top()] > sa.lcp[i]) {
	    Mint tmp = 1;
	    REP (k, 3) {
		Mint z = t[k].top(); t[k].pop();
		o[k] += z;
		tmp *= o[k];
	    }
	    ans[sa.lcp[st.top()]] += tmp;
	    st.pop();
	    int z = sa.lcp[i];
	    if (!st.empty()) amax(z, sa.lcp[st.top()]);
	    ans[z] -= tmp;
	}

	if (!st.empty() && sa.lcp[st.top()] == sa.lcp[i]) {
	    REP (k, 3) t[k].top() += o[k];
	} else {
	    st.push(i);
	    REP (k, 3) t[k].push(o[k]);
	}
//	eprintf("%d %s\n", sa.lcp[i], Z.substr(sa.sa[i]).c_str());
//	REP (k, 3) eprintf("%d ", t[k].top().getInt()); eprintf("\n");
    }

    for (int i=M; i>0; i--) ans[i-1] += ans[i];

    for (int i=1; i<=M; i++) printf("%d%c", ans[i].getInt(), " \n"[i==M]);
    return 0;
}


#include <bits/stdc++.h>
#include <ext/algorithm>
#include <ext/numeric>

using namespace std;
using namespace __gnu_cxx;

//#define endl '\n'

typedef long long ll;

const ll mod = 1e9 + 7;

ll Madd(ll a, ll b){
	return (a + b) % mod;
}

ll Msub(ll a, ll b){
	return (a - b + mod) % mod;
}

template<size_t maxlen, size_t alpha>
struct SuffixAutomaton
{
	int go[2 * maxlen][alpha], slink[2 * maxlen], length[2 * maxlen], size, last;
	int endpos[2 * maxlen][3];

	int new_node()
	{
		memset(go[size], 0, sizeof go[size]);
		slink[size] = length[size] = 0;
		for (int i = 0; i < 3; ++i) endpos[size][i] = 0;
		return size++;
	}

	SuffixAutomaton() { reset(); }

	void reset()
	{
		size = last = 0;
		new_node();
		slink[0] = -1;
	}

	void add(int c, int id)
	{
		int e = last, nlast = new_node();
		for (; e >= 0 && !go[e][c]; e = slink[e])
			go[e][c] = nlast;

		length[nlast] = 1 + length[last];
		last = nlast;
		endpos[last][id] = 1;

		if (e == -1) slink[last] = 0;
		else
		{
			int q = go[e][c];

			if (length[q] == 1 + length[e]) slink[last] = q;
			else
			{
				int clone = new_node();
				memcpy(go[clone], go[q], sizeof go[q]);
				length[clone] = 1 + length[e];
				slink[clone] = slink[q];
				for (; e != -1 && go[e][c] == q; e = slink[e])
					go[e][c] = clone;
				slink[last] = slink[q] = clone;
			}
		}
	}

	int bucket[maxlen + 1], order[2 * maxlen];

	void top_sort()
	{
		for (int l = 0; l <= length[last]; ++l)
			bucket[l] = 0;

		for (int e = 0; e < size; ++e)
			++bucket[length[e]];

		for (int l = 1; l <= length[last]; ++l)
			bucket[l] += bucket[l - 1];

		for (int e = 0; e < size; ++e)
			order[--bucket[length[e]]] = e;
	}

	void calc_endpos()
	{
		top_sort();
		for (int i = size - 1; i > 0; --i)
		{
			int e = order[i];
			for (int j = 0; j < 3; ++j)
				endpos[slink[e]][j] += endpos[e][j];
		}
	}

	ll ans[maxlen];

	void solve(int N)
	{
		calc_endpos();

		for (int i = 0; i <= N; ++i) ans[i] = 0;

		for (int e = 1; e < size; ++e){
			ll a = endpos[e][0], b = endpos[e][1], c = endpos[e][2];

			if (a == 0 || b == 0 || c == 0) continue;

			ll m = a * b % mod * c % mod;

			ans[ length[e] ] = Madd(ans[ length[e] ], m);
			ans[ length[ slink[e] ] ] = Msub(ans[ length[ slink[e] ]], m);
		}

		for (int i = N - 1; i; --i)
			ans[i] = Madd(ans[i], ans[i + 1]);

		for (int i = 1; i <= N; ++i)
			cout << ans[i] << " ";
		cout << endl;
	}
};

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	static SuffixAutomaton<300003, 29> sa;
	sa.reset();

	int N = 300000;

	for (int i = 0; i < 3; ++i){
		string s; cin >> s;

		N = min(N, (int)s.length());

		for (auto c : s)
			sa.add(c - 'a', i);

		sa.add(26 + i, i);
	}

	sa.solve(N);

	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
const int N=3e5+10;
struct Sam{
	struct gg{
		int nxt[28],fa,mx,mn;
	}node[2*N];
	int wh,las,cnt,tax[2*N],rnk[2*N],m;ll dp[3][2*N],ans[N];
	void init()
	{
		memset(node,0,sizeof node);
		memset(dp,0,sizeof dp);
		memset(tax,0,sizeof tax);
		memset(ans,0,sizeof ans);
		cnt=las=1,m=N;
	}
	void add(int x)
	{
		static int p,np,t,nt;
		p=las,np=++cnt,las=np;
		node[np].mx=node[p].mx+1;
		dp[wh][np]++;
		while(p&&!node[p].nxt[x])
		{
			node[p].nxt[x]=np;
			p=node[p].fa;
		}
		if(!p)node[np].fa=node[np].mn=1;
		else
		{
			t=node[p].nxt[x];
			if(node[p].mx+1==node[t].mx)
				node[np].fa=t,node[np].mn=node[t].mx+1;
			else
			{
				nt=++cnt,node[nt].mx=node[p].mx+1;
				memcpy(node[nt].nxt,node[t].nxt,sizeof node[t].nxt);
				node[nt].fa=node[t].fa;
				node[t].fa=node[np].fa=nt;
				node[nt].mn=node[node[nt].fa].mx+1;
				node[t].mn=node[np].mn=node[nt].mx+1;
				for(;node[p].nxt[x]==t;p=node[p].fa)node[p].nxt[x]=nt;
			}
		}
	}
	void sss()
	{
		for(int i=1;i<=cnt;i++)tax[node[i].mx]++;
		for(int i=1;i<=N;i++)tax[i]+=tax[i-1];
		for(int i=1;i<=cnt;i++)rnk[tax[node[i].mx]--]=i;
	}
	void dfs()
	{
		int nw;
		for(int i=cnt;i>=1;i--)
		{
			nw=rnk[i];
			dp[0][node[nw].fa]+=dp[0][nw];
			dp[1][node[nw].fa]+=dp[1][nw];
			dp[2][node[nw].fa]+=dp[2][nw];
		}
	}
	void solve()
	{
		int l,r;ll nw;
		for(int i=2;i<=cnt;i++)
		{
			l=node[i].mn,r=node[i].mx;
			nw=1;
			nw=nw*dp[0][i]%mod;
			nw=nw*dp[1][i]%mod;
			nw=nw*dp[2][i]%mod;//if(nw)cout<<nw<<" "<<i<<" "<<node[i].mx<<" "<<node[i].mn<<endl;
			ans[l]=(ans[l]+nw)%mod;
			ans[r+1]=(ans[r+1]-nw+mod)%mod;
		}
		for(int i=1;i<=m;i++)
			ans[i]=(ans[i]+ans[i-1])%mod,printf("%lld ",ans[i]);
	}
}sam;
char s[N];int len;
int main()
{
	sam.init();
	for(int i=0;i<3;i++)
	{
		sam.wh=i;
		scanf("%s",s+1);
		len=strlen(s+1),sam.m=min(sam.m,len);
		for(int j=1;j<=len;j++)
			sam.add(s[j]-'a');
		if(i!=2)sam.add(i+1+25);
	}
	sam.sss(),sam.dfs();
	sam.solve();
}


#include<bits/stdc++.h>
#define N 1000000
#define mod 1000000007
#define int long long
using namespace std;
struct state
{
    int link,len;
    int nxt[29];
}node[N];
int sz=0,last=0;
bool vis[N]={
    false
};
int cnt[4][N],ans[N];
void extend(int x)
{
    sz++;
    int cur=sz;
    node[cur].len=(node[last].len + 1);
    int p=last;
    last=cur;
    while(node[p].nxt[x]==0 && p!=-1)
    {
        node[p].nxt[x]=cur;
        p=node[p].link;
    }
    if(p==-1)
    {
        node[cur].link=0;
    }
    else
    {
        int q=node[p].nxt[x];
        if(node[q].len == node[p].len + 1)
        {
            node[cur].link=q;
        }
        else
        {
            sz++;
            int clone=sz;
            for(int i=0;i<29;i++)
            node[clone].nxt[i]=node[q].nxt[i];
            node[clone].link=node[q].link;
            node[q].link=node[cur].link=clone;
            node[clone].len=node[p].len+1;
            while(p!=-1 && node[p].nxt[x]==q)
            {
                node[p].nxt[x]=clone;
                p=node[p].link;
            }
        }
    }
}
void dfs(int x)
{
    if(vis[x])
    return;
    vis[x]=1;
    for(int i=0;i<29;i++)
    {
        if(node[x].nxt[i])
        {
            cout<<"from:"<<x<<" to:"<<node[x].nxt[i]<<endl;
            if(i>25)
            {
                cnt[i-25][x]++;
                cnt[i-25][x]=(cnt[i-25][x])%mod;
                continue;
            }
            dfs(node[x].nxt[i]);
            for(int j=1;j<=3;j++)
            {
                cnt[j][x] = (cnt[j][x] + cnt[j][node[x].nxt[i]])%mod;
            }
        }
    }
}
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    node[0].len =0 ;
    node[0].link=-1;
    string t="";
    int mini=N;
    for(int i=1;i<=3;i++)
    {
        string s;
        cin>>s;
        t+=s;
        t=(t+char('z'+i));
        mini=min(mini,(int)s.size());
    }
    for(auto x:t)
    {
        extend(x-'a');
    }
    dfs(0);
    for(int i=1;i<=sz;i++)
    {
        int prod=((cnt[1][i]*cnt[2][i])%mod * 1LL*cnt[2][i])%mod;
        ans[node[node[i].link].len+1] = (ans[node[node[i].link].len+1]+prod)%mod;
        ans[node[i].len+1] = (ans[node[i].len+1]-prod+mod)%mod;
    }
    for(int i=1;i<=mini;i++)
    {
        ans[i]=(ans[i]+ans[i-1])%mod;
        cout<<ans[i]<<" ";
    }
    cout<<"\n";
    return 0;
}


#include<bits/stdc++.h>
#define N 1000000
#define mod 1000000007
#define int long long
using namespace std;
struct state
{
    int link,len;
    int nxt[29];
}node[N];
int sz=0,last=0;
bool vis[N]={
    false
};
int cnt[4][N],ans[N];
void extend(int x)
{
    sz++;
    int cur=sz;
    node[cur].len=(node[last].len + 1);
    int p=last;
    last=cur;
    while(node[p].nxt[x]==0 && p!=-1)
    {
        node[p].nxt[x]=cur;
        p=node[p].link;
    }
    if(p==-1)
    {
        node[cur].link=0;
    }
    else
    {
        int q=node[p].nxt[x];
        if(node[q].len == node[p].len + 1)
        {
            node[cur].link=q;
        }
        else
        {
            sz++;
            int clone=sz;
            for(int i=0;i<29;i++)
            node[clone].nxt[i]=node[q].nxt[i];
            node[clone].link=node[q].link;
            node[q].link=node[cur].link=clone;
            node[clone].len=node[p].len+1;
            while(p!=-1 && node[p].nxt[x]==q)
            {
                node[p].nxt[x]=clone;
                p=node[p].link;
            }
        }
    }
}
void dfs(int x)
{
    if(vis[x])
    return;
    vis[x]=1;
    for(int i=0;i<29;i++)
    {
        if(node[x].nxt[i])
        {
            //cout<<"from:"<<x<<" to:"<<node[x].nxt[i]<<endl;
            if(i>25)
            {
                cnt[i-25][x]++;
                cnt[i-25][x]=(cnt[i-25][x])%mod;
                continue;
            }
            dfs(node[x].nxt[i]);
            for(int j=1;j<=3;j++)
            {
                cnt[j][x] = (cnt[j][x] + cnt[j][node[x].nxt[i]])%mod;
            }
        }
    }
}
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    node[0].len =0 ;
    node[0].link=-1;
    string t="";
    int mini=N;
    for(int i=1;i<=3;i++)
    {
        string s;
        cin>>s;
        t+=s;
        t=(t+char('z'+i));
        mini=min(mini,(int)s.size());
    }
    for(auto x:t)
    {
        extend(x-'a');
    }
    dfs(0);
    for(int i=1;i<=sz;i++)
    {
        int prod=((cnt[1][i]*cnt[2][i])%mod * 1LL*cnt[3][i])%mod;
        ans[node[node[i].link].len+1] = (ans[node[node[i].link].len+1]+prod)%mod;
        ans[node[i].len+1] = (ans[node[i].len+1]-prod+mod)%mod;
    }
    for(int i=1;i<=mini;i++)
    {
        ans[i]=(ans[i]+ans[i-1])%mod;
        cout<<ans[i]<<" ";
    }
    cout<<"\n";
    return 0;
}


#include<bits/stdc++.h>
#define N 1000000
#define mod 1000000007
//#define int long long
using namespace std;
struct state
{
    int link,len;
    int nxt[29];
}node[N];
int sz=0,last=0;
bool vis[N]={
    false
};
int cnt[4][N],ans[N];
void extend(int x)
{
    sz++;
    int cur=sz;
    node[cur].len=(node[last].len + 1);
    int p=last;
    last=cur;
    while(node[p].nxt[x]==0 && p!=-1)
    {
        node[p].nxt[x]=cur;
        p=node[p].link;
    }
    if(p==-1)
    {
        node[cur].link=0;
    }
    else
    {
        int q=node[p].nxt[x];
        if(node[q].len == node[p].len + 1)
        {
            node[cur].link=q;
        }
        else
        {
            sz++;
            int clone=sz;
            for(int i=0;i<29;i++)
            node[clone].nxt[i]=node[q].nxt[i];
            node[clone].link=node[q].link;
            node[q].link=node[cur].link=clone;
            node[clone].len=node[p].len+1;
            while(p!=-1 && node[p].nxt[x]==q)
            {
                node[p].nxt[x]=clone;
                p=node[p].link;
            }
        }
    }
}
void dfs(int x)
{
    if(vis[x])
    return;
    vis[x]=1;
    for(int i=0;i<29;i++)
    {
        if(node[x].nxt[i])
        {
            //cout<<"from:"<<x<<" to:"<<node[x].nxt[i]<<endl;
            if(i>25)
            {
                cnt[i-25][x]++;
                cnt[i-25][x]=(cnt[i-25][x])%mod;
                continue;
            }
            dfs(node[x].nxt[i]);
            for(int j=1;j<=3;j++)
            {
                cnt[j][x] = (cnt[j][x] + cnt[j][node[x].nxt[i]])%mod;
            }
        }
    }
}
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    node[0].len =0 ;
    node[0].link=-1;
    string t="";
    int mini=N;
    for(int i=1;i<=3;i++)
    {
        string s;
        cin>>s;
        t+=s;
        t=(t+char('z'+i));
        mini=min(mini,(int)s.size());
    }
    for(auto x:t)
    {
        extend(x-'a');
    }
    dfs(0);
    for(int i=1;i<=sz;i++)
    {
        int prod=((cnt[1][i]*cnt[2][i])%mod * 1LL*cnt[3][i])%mod;
        ans[node[node[i].link].len+1] = (ans[node[node[i].link].len+1]+prod)%mod;
        ans[node[i].len+1] = (ans[node[i].len+1]-prod+mod)%mod;
    }
    for(int i=1;i<=mini;i++)
    {
        ans[i]=(ans[i]+ans[i-1])%mod;
        cout<<ans[i]<<" ";
    }
    cout<<"\n";
    return 0;
}


#include<bits/stdc++.h>
#define N 1000000
#define mod 1000000007
//#define int long long
using namespace std;
struct state
{
    int link,len;
    int nxt[29];
}node[N];
int sz=0,last=0;
bool vis[N]={
    false
};
long long cnt[4][N],ans[N];
void extend(int x)
{
    sz++;
    int cur=sz;
    node[cur].len=(node[last].len + 1);
    int p=last;
    last=cur;
    while(node[p].nxt[x]==0 && p!=-1)
    {
        node[p].nxt[x]=cur;
        p=node[p].link;
    }
    if(p==-1)
    {
        node[cur].link=0;
    }
    else
    {
        int q=node[p].nxt[x];
        if(node[q].len == node[p].len + 1)
        {
            node[cur].link=q;
        }
        else
        {
            sz++;
            int clone=sz;
            for(int i=0;i<29;i++)
            node[clone].nxt[i]=node[q].nxt[i];
            node[clone].link=node[q].link;
            node[q].link=node[cur].link=clone;
            node[clone].len=node[p].len+1;
            while(p!=-1 && node[p].nxt[x]==q)
            {
                node[p].nxt[x]=clone;
                p=node[p].link;
            }
        }
    }
}
void dfs(int x)
{
    if(vis[x])
    return;
    vis[x]=1;
    for(int i=0;i<29;i++)
    {
        if(node[x].nxt[i])
        {
            //cout<<"from:"<<x<<" to:"<<node[x].nxt[i]<<endl;
            if(i>25)
            {
                cnt[i-25][x]++;
                cnt[i-25][x]=(cnt[i-25][x])%mod;
                continue;
            }
            dfs(node[x].nxt[i]);
            for(int j=1;j<=3;j++)
            {
                cnt[j][x] = (cnt[j][x] + cnt[j][node[x].nxt[i]])%mod;
            }
        }
    }
}
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    node[0].len =0 ;
    node[0].link=-1;
    string t="";
    int mini=N;
    for(int i=1;i<=3;i++)
    {
        string s;
        cin>>s;
        t+=s;
        t=(t+char('z'+i));
        mini=min(mini,(int)s.size());
    }
    for(auto x:t)
    {
        extend(x-'a');
    }
    dfs(0);
    for(int i=1;i<=sz;i++)
    {
        long long prod=((cnt[1][i]*cnt[2][i])%mod * 1LL*cnt[3][i])%mod;
        ans[node[node[i].link].len+1] = (ans[node[node[i].link].len+1]+prod)%mod;
        ans[node[i].len+1] = (ans[node[i].len+1]-prod+mod)%mod;
    }
    for(int i=1;i<=mini;i++)
    {
        ans[i]=(ans[i]+ans[i-1])%mod;
        cout<<ans[i]<<" ";
    }
    cout<<"\n";
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
#define maxn 300010
#define rank rk
int wa[maxn], wb[maxn], wv[maxn], Ws[maxn];

int cmp(int *r, int a, int b, int l)
{
    return r[a] == r[b] && r[a + l] == r[b + l];
}

void da(int *r, int *sa, int n, int m)
{
    int *x = wa, *y = wb, *t, i, j, p;
    for(i = 0; i < m; i++) Ws[i] = 0;
    for(i = 0; i < n; i++) Ws[x[i] = r[i]]++;
    for(i = 1; i < m; i++) Ws[i] += Ws[i - 1];
    for(i = n - 1; i >= 0; i--) sa[--Ws[x[i]]] = i;
    for(j = 1, p = 1; p < n; j *= 2, m = p)
    {
        for(p = 0, i = n - j; i < n; i++) y[p++] = i;
        for(i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i] - j;
        for(i = 0; i < n; i++) wv[i] = x[y[i]];
        for(i = 0; i < m; i++) Ws[i] = 0;
        for(i = 0; i < n; i++) Ws[wv[i]]++;
        for(i = 1; i < m; i++) Ws[i] += Ws[i - 1];
        for(i = n - 1; i >= 0; i--) sa[--Ws[wv[i]]] = y[i];
        for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i++)
            x[sa[i]] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p++;
    }
    return;
}

int rank[maxn], height[maxn];
void calheight(int *r, int *sa, int n)
{
    int i, j, k = 0;
    for(i = 1; i <= n; i++) rank[sa[i]] = i;
    for(i = 0; i < n; height[rank[i++]] = k)
        for(k ? k-- : 0, j = sa[rank[i] - 1]; r[i + k] == r[j + k]; k++);
    return;
}

int f[maxn];
int find(int x)
{
    return x == f[x] ? x : f[x] = find(f[x]);
}

bool cmp2(int a, int b)
{
    return height[a] > height[b];
}

char str[maxn];
int s[maxn], sa[maxn], p[maxn], belong[maxn], N;
ll cnt[maxn][3], ans[maxn];
const ll mod = 1e9 + 7;

int main()
{
    int mlen=1e9;
    N=0;
	int i,j;
    for (i=0;i<3;i++)
    {
        scanf("%s",str);
        int len=strlen(str);
        mlen=min(len,mlen);
        for(j=0;j<len;j++)
        {
            belong[N]=i;
            s[N++]=str[j]-'a'+1;
        }
        belong[N]=-1;
        s[N++]=27+i;
    }
    N--;
    s[N]=0;
    da(s,sa,N+1,30);
    calheight(s,sa,N);
    for(i=0;i<=N;i++) p[i]=f[i]=i;
    for(i=0;i<=N;i++)
        if(belong[i]!=-1) cnt[i][belong[i]]++;
    sort(p+1,p+N+1,cmp2);
    ll result=0;
    for (i=1;i<=N;i++)
    {
        if (i>1&&height[p[i]]!=height[p[i-1]])
            for (j=height[p[i]]+1;j<=height[p[i-1]];j++)
                ans[j]=result;
        int bl=find(sa[p[i]]), br=find(sa[p[i]-1]);
        result=(result-cnt[bl][0]*cnt[bl][1]*cnt[bl][2]%mod+mod)%mod;
        result=(result-cnt[br][0]*cnt[br][1]*cnt[br][2]%mod+mod)%mod;
        for (j=0;j<3;j++)
            cnt[bl][j]=(cnt[bl][j]+cnt[br][j])%mod;
        f[br]=bl;
        result=(result+cnt[bl][0]*cnt[bl][1]*cnt[bl][2])%mod;
    }
    for (i =1;i<=mlen;i++)
        printf("%lld ",ans[i]);
    return 0;
}