#include <bits/stdc++.h>
using namespace std;
string to_string(string s) { return '"' + s + '"'; }
string to_string(const char* s) { return to_string((string)s); }
string to_string(bool b) { return (b ? "true" : "false"); }
template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto& x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}
void debug_out() { cerr << "\n"; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}
struct SuffixArray {
  vector<long long int> sa, lcp;
  SuffixArray(string& s, long long int lim = 256) {
    long long int n = (long long int)(s).size() + 1, k = 0, a, b;
    vector<long long int> x(begin(s), end(s) + 1), y(n), ws(max(n, lim)),
        rank(n);
    sa = lcp = y, iota(begin(sa), end(sa), 0);
    for (long long int j = 0, p = 0; p < n; j = max(1LL, j * 2), lim = p) {
      p = j, iota(begin(y), end(y), n - j);
      for (long long int i = 0; i < (n); ++i)
        if (sa[i] >= j) y[p++] = sa[i] - j;
      fill(begin(ws), end(ws), 0);
      for (long long int i = 0; i < (n); ++i) ws[x[i]]++;
      for (long long int i = 1; i < (lim); ++i) ws[i] += ws[i - 1];
      for (long long int i = n; i--;) sa[--ws[x[y[i]]]] = y[i];
      swap(x, y), p = 1, x[sa[0]] = 0;
      for (long long int i = 1; i < (n); ++i)
        a = sa[i - 1], b = sa[i],
        x[b] = (y[a] == y[b] && y[a + j] == y[b + j]) ? p - 1 : p++;
    }
    for (long long int i = 1; i < (n); ++i) rank[sa[i]] = i;
    for (long long int i = 0, j; i < n - 1; lcp[rank[i++]] = k)
      for (k &&k--, j = sa[rank[i] - 1]; s[i + k] == s[j + k]; k++)
        ;
  }
};
const long long int mod = 1000000007;
struct UF {
  vector<long long int> e;
  vector<vector<long long int>> aa;
  UF(long long int n) : e(n, -1), aa(n, vector<long long int>(3, 0)) {}
  bool sameSet(long long int a, long long int b) { return find(a) == find(b); }
  long long int size(long long int x) { return -e[find(x)]; }
  long long int find(long long int x) {
    return e[x] < 0 ? x : e[x] = find(e[x]);
  }
  long long int get(long long int x) {
    x = find(x);
    return aa[x][1] * aa[x][2] * aa[x][0] % mod;
  }
  bool join(long long int a, long long int b) {
    a = find(a), b = find(b);
    if (a == b) return false;
    if (e[a] > e[b]) swap(a, b);
    e[a] += e[b];
    aa[a][1] += aa[b][1];
    aa[a][2] += aa[b][2];
    aa[a][0] += aa[b][0];
    e[b] = a;
    return true;
  }
};
long long int n, m, k, i, j;
vector<long long int> a;
int32_t main(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  string s1, s2, s3;
  cin >> s1;
  cin >> s2;
  cin >> s3;
  string s = s1 + '#' + s2 + '$' + s3;
  const long long int n = (long long int)(s).size();
  const long long int m =
      min((long long int)(s1).size(),
          min((long long int)(s2).size(), (long long int)(s3).size()));
  UF aa(n);
  long long int c = 0;
  for (long long int i = 0; i < n; ++i) {
    if (s[i] == '#' || s[i] == '$')
      c++;
    else
      aa.aa[i][c]++;
  }
  auto gg = SuffixArray(s);
  vector<pair<long long int, pair<long long int, long long int>>> edges;
  for (long long int i = 2; i <= n; ++i) {
    edges.push_back({gg.lcp[i], {gg.sa[i - 1], gg.sa[i]}});
    42;
  }
  sort(begin(edges), end(edges));
  reverse(begin(edges), end(edges));
  vector<long long int> ans(m);
  long long int cnt = 0;
  long long int j = m;
  for (const auto& vv : edges) {
    while (j > vv.first) {
      ans[j - 1] = cnt;
      j--;
    }
    const long long int u = aa.find(vv.second.first),
                        v = aa.find(vv.second.second);
    cnt -= aa.get(u);
    cnt -= aa.get(v);
    assert(aa.join(u, v));
    cnt += aa.get(v);
  }
  42;
  for (auto x : ans) cout << x % mod << " ";
  cout << "\n";
  return 0;
}
