#include <bits/stdc++.h>
using namespace std;
int n, sfeefw, len, able;
int rnk[20][300005], pre[4][300005], ata[300005];
pair<pair<int, int>, int> suf[300005];
int ans[300005];
string s1, s2, s3, all;
pair<int, int> sz[300005];
vector<pair<int, int> > tut[300005];
void print() {
  for (int i = 1; i <= able; i++) {
    cout << ans[i] << ' ';
  }
}
void merge(int n1, int n2, int &cev) {
  int c1 = 1;
  int c2 = 1;
  int c3 = 1;
  for (int i = 1; i <= 3; i++) {
    c1 = 1ll * c1 * (pre[i][sz[n1].second] - pre[i][sz[n1].first - 1]) %
         1000000007;
    c2 = 1ll * c2 * (pre[i][sz[n2].second] - pre[i][sz[n2].first - 1]) %
         1000000007;
    c3 = 1ll * c3 * (pre[i][sz[n2].second] - pre[i][sz[n1].first - 1]) %
         1000000007;
  }
  cev = ((1ll * cev + c3 - c1 + 1000000007) % 1000000007 - c2 + 1000000007) %
        1000000007;
  sz[n2].first = sz[n1].first;
  ata[n1] = n2;
}
int bul(int node) {
  if (node == ata[node]) return node;
  return ata[node] = bul(ata[node]);
}
int get_lcp(int x, int y) {
  int res = 0;
  for (int i = sfeefw; i >= 0; i--) {
    int tut = (1 << (i));
    if (y + tut - 1 > n) continue;
    if (rnk[i][x] == rnk[i][y]) {
      res += tut;
      x += tut;
      y += tut;
    }
  }
  return res;
}
void solve() {
  int cev = 0;
  able = min(min((int)s1.size(), (int)s2.size()), (int)s3.size());
  for (int i = 1; i < n; i++) {
    int lcp = get_lcp(suf[i].second, suf[i + 1].second);
    tut[lcp].push_back({i, i + 1});
  }
  for (int i = 1; i <= n; i++) {
    ata[i] = i;
    sz[i] = {i, i};
  }
  for (int lcp = n; lcp >= 1; lcp--) {
    for (pair<int, int> i : tut[lcp]) {
      int n1 = i.first;
      int n2 = i.second;
      if (bul(n1) != bul(n2)) {
        merge(ata[n1], ata[n2], cev);
      }
    }
    ans[lcp] = cev;
  }
}
void cs() {
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= 3; j++) {
      pre[j][i] += pre[j][i - 1];
    }
    if (all[suf[i].second] > 'z' || all[suf[i].second] < 'a') continue;
    if (suf[i].second <= (int)s1.size()) {
      pre[1][i]++;
    } else if (suf[i].second <= (int)s1.size() + (int)s2.size() + 1) {
      pre[2][i]++;
    } else {
      pre[3][i]++;
    }
  }
}
void suffix_array() {
  sfeefw = 0;
  len = 1;
  for (int i = 1; i <= n; i++) {
    suf[i] = {{all[i] - 'a' + 1, all[i] - 'a' + 1}, i};
  }
  while (1) {
    sort(suf + 1, suf + 1 + n);
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
      cnt++;
      while (i + 1 <= n && suf[i].first == suf[i + 1].first) {
        rnk[sfeefw][suf[i].second] = cnt;
        i++;
      }
      rnk[sfeefw][suf[i].second] = cnt;
    }
    if (len >= n) break;
    for (int i = 1; i <= n; i++) {
      suf[i] = {{rnk[sfeefw][i], i + len <= n ? rnk[sfeefw][i + len] : 0}, i};
    }
    len *= 2;
    sfeefw++;
  }
}
void init() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> s1 >> s2 >> s3;
  n = (int)s1.size() + (int)s2.size() + (int)s3.size() + 2;
  all = "$" + s1 + "#" + s2 + "!" + s3;
}
int main() {
  init();
  suffix_array();
  cs();
  solve();
  print();
}
