#include <bits/stdc++.h>   using namespace std;   class SuffixArrayBuilder {     int n, gap;     string s;     vector<int> pos;       public:     SuffixArrayBuilder(string &s) : s(s) {}     bool operator()(int i, int j) {       if (pos[i] != pos[j]) return pos[i] < pos[j];       i += gap;       j += gap;       return ((i < n && j < n) ? pos[i] < pos[j] : i > j);     }     vector<int> buildSA() {       n = (int)(s).size();       vector<int> sa(n), tmp(n);       pos.resize(n);       for (int i = (0); i <= ((int)(sa).size() - 1); ++i)         sa[i] = i, pos[i] = s[i];       for (gap = 1;; gap *= 2) {         sort(sa.begin(), sa.end(), ref(*this));         for (int i = (0); i <= (n - 2); ++i)           tmp[i + 1] = tmp[i] + (*this)(sa[i], sa[i + 1]);         for (int i = (0); i <= (n - 1); ++i) pos[sa[i]] = tmp[i];         if (tmp.back() == n - 1) return sa;       }     }     vector<int> buildLCP(vector<int> &sa) {       vector<int> lcp(n - 1);       for (int i = 0, k = 0; i < n; ++i)         if (pos[i] != n - 1) {           for (int j = sa[pos[i] + 1]; s[i + k] == s[j + k];) k++;           lcp[pos[i]] = k;           if (k) k--;         }       return lcp;     }   };   vector<long long int> solve(string &p, string &q, string &r) {     string s = p +  #  + q +  $  + r;     SuffixArrayBuilder Builder(s);     vector<int> SA = Builder.buildSA();     vector<int> LCP = Builder.buildLCP(SA);     int n = (int)(s).size();     int cnt[3][n];     int len[] = {0, (int)(p).size() + 1, (int)(q).size() + 1,                  (int)(r).size() + 1};     for (int i = (1); i <= (3); ++i) len[i] += len[i - 1];     for (int i = (0); i <= (2); ++i)       for (int j = (0); j <= (n - 1); ++j) {         cnt[i][j] = ((j) ? cnt[i][j - 1] : 0);         cnt[i][j] += (SA[j] >= len[i] && SA[j] < len[i + 1] - 1);       }     vector<pair<int, int> > ord;     for (int i = (0); i <= ((int)(LCP).size() - 1); ++i)       ord.push_back(make_pair(LCP[i], i));     sort(ord.begin(), ord.end());     set<int> S;     S.insert(-1);     S.insert(n - 1);     int m = min({(int)(p).size(), (int)(q).size(), (int)(r).size()});     vector<long long int> agg(m, 0);     for (int i = (0); i <= ((int)(ord).size() - 1); ++i) {       int pos = ord[i].second, L, R;       auto it = S.lower_bound(pos);       R = *it;       it--;       L = *it;       long long int left[3], right[3], whole[3];       for (int i = (0); i <= (2); ++i) {         left[i] = cnt[i][pos] - ((L >= 0) ? cnt[i][L] : 0);         right[i] = cnt[i][R] - cnt[i][pos];         whole[i] = cnt[i][R] - ((L >= 0) ? cnt[i][L] : 0);       }       long long int ans = whole[0] * whole[1] * whole[2] -                           left[0] * left[1] * left[2] -                           right[0] * right[1] * right[2];       ans %= 1000000007;       ans = (ans + 1000000007) % 1000000007;       int val = ord[i].first;       if (val > 0) {         agg[val - 1] += ans;         agg[val - 1] %= 1000000007;       }       S.insert(pos);     }     for (int i = (m - 2); i >= (0); --i)       agg[i] = (agg[i] + agg[i + 1]) % 1000000007;     return agg;   }   int main() {     ios_base::sync_with_stdio(0);     string p, q, r;     cin >> p >> q >> r;     vector<long long int> ans = solve(p, q, r);     for (int i = (0); i <= ((int)(ans).size() - 1); ++i) cout << ans[i] <<    ;     return 0;   }