#include <bits/stdc++.h>
using namespace std;
int getint() {
  unsigned int c;
  int x = 0;
  while (((c = getchar()) - '0') >= 10) {
    if (c == '-') return -getint();
    if (!~c) exit(0);
  }
  do {
    x = (x << 3) + (x << 1) + (c - '0');
  } while (((c = getchar()) - '0') < 10);
  return x;
}
int getstr(char* s) {
  int c, n = 0;
  while ((c = getchar()) <= ' ') {
    if (!~c) exit(0);
  }
  do {
    s[n++] = c;
  } while ((c = getchar()) > ' ');
  s[n] = 0;
  return n;
}
template <class T>
inline bool chmin(T& a, T b) {
  return a > b ? a = b, 1 : 0;
}
template <class T>
inline bool chmax(T& a, T b) {
  return a < b ? a = b, 1 : 0;
}
template <typename C = char>
struct SA {
  static const int N = 1 << 20;
  int n, m, sa[N], as[N], cp[N], is[N];
  vector<int> ds;
  struct Compare {
    int h, *p;
    Compare(int h, int* p) : h(h), p(p) {}
    bool operator()(int a, int b) {
      return a == b           ? 0
             : (p[a] != p[b]) ? (p[a] < p[b])
                              : (p[a + h] < p[b + h]);
    }
  };
  void clear() {
    for (int i = 0; i < N; i++) cp[i] = is[i] = 0;
  }
  void gen_sa(C* in, int len) {
    int i, hh;
    n = len;
    for (i = 0; i <= n; ++i) as[sa[i] = i] = in[i];
    is[0] = is[n] = hh = 0;
    sort(sa, sa + n + 1, Compare(0, as));
    for (hh = 1; is[n] != n; hh <<= 1) {
      Compare cmp(hh, as);
      sort(sa, sa + n + 1, cmp);
      for (i = 0; i < n; ++i) is[i + 1] = is[i] + cmp(sa[i], sa[i + 1]);
      for (i = 0; i <= n; ++i) as[sa[i]] = is[i];
    }
  }
  void gen_cp(C* in, int len) {
    int i, j, h = 0;
    for (i = 0; i < n; i++) {
      for (j = sa[as[i] - 1]; in[j + h] == in[i + h]; ++h) continue;
      cp[as[i] - 1] = h;
      if (h) --h;
    }
  }
  int range_cp(int s, int e) {
    if (s > e) swap(s, e);
    return (s == e) ? (n - sa[s]) : (s + 1 == e) ? cp[s] : range_min(s, e - 1);
  }
  void gen_rm() {
    int i, k, ln, p;
    for (k = ln = 1, m = n + 1; k < m; k <<= 1) ++ln;
    ds.assign(m * ln, 0);
    vector<int>::iterator it = ds.begin();
    copy(cp, cp + m, it);
    for (k = 1; k < m; k <<= 1) {
      copy(it, it + m, it + m), it += m;
      for (i = 0; i < m - k; i++) {
        *(it + i) = min(*(it + i), *(it + i + k));
      }
    }
  }
  int range_min(int a, int b) {
    int p = b - a, k = 0, e = 1, s;
    s = ((p & 0xffff0000) != 0) << 4;
    p >>= s;
    e <<= s;
    k |= s;
    s = ((p & 0x0000ff00) != 0) << 3;
    p >>= s;
    e <<= s;
    k |= s;
    s = ((p & 0x000000f0) != 0) << 2;
    p >>= s;
    e <<= s;
    k |= s;
    s = ((p & 0x0000000c) != 0) << 1;
    p >>= s;
    e <<= s;
    k |= s;
    s = ((p & 0x00000002) != 0) << 0;
    p >>= s;
    e <<= s;
    k |= s;
    return min(ds[a + m * k], ds[b + m * k - e + 1]);
  }
};
int n, len[3];
char in[3 * 100000 * 3 + 111111];
SA<char> sa;
int which_str(int idx) {
  if (in[idx] == '#') return -1;
  if (in[idx] == '$') return -1;
  if (idx < len[0]) return 0;
  if (idx < len[0] + 1 + len[1]) return 1;
  return 2;
}
const int MOD = 1000000007;
struct modint {
  int v;
  modint() : v(0) {}
  modint(int a) : v(a) {
    if (v < 0) v += MOD;
    if (v >= MOD) v -= MOD;
  }
  modint(long long a) {
    if (a < 0) a = a % MOD + MOD;
    if (a >= MOD) a = a % MOD;
    v = a;
  }
  void clear() { v = ~0; }
  bool is() { return ~v; }
  int to_int() { return v; }
  modint& operator+=(modint x) { return *this = v + x.v; }
  modint& operator-=(modint x) { return *this = MOD + v - x.v; }
  modint& operator*=(modint x) { return *this = (long long)v * x.v; }
  modint operator+(modint x) const { return modint(v) += x; }
  modint operator-(modint x) const { return modint(v) -= x; }
  modint operator*(modint x) const { return modint(v) *= x; }
  modint operator-() { return modint(0) - *this; }
};
ostream& operator<<(ostream& os, modint x) {
  os << x.v;
  return os;
}
modint mod_pow(modint x, long long n) {
  modint y = 1;
  for (; n; x *= x, n >>= 1)
    if (n & 1) y *= x;
  return y;
}
modint mod_inv(modint x) {
  modint y = 1;
  for (int n = MOD - 2; n; x *= x, n >>= 1)
    if (n & 1) y *= x;
  return y;
}
modint& operator/=(modint& x, modint y) { return x *= mod_inv(y); }
modint operator/(modint x, modint y) { return x /= y; }
vector<int> cp_idx[1 << 20];
modint cnt[3][1 << 20];
modint res[1 << 20];
int par[1 << 20];
int root(int p) {
  if (par[p] < 0) return p;
  par[p] = root(par[p]);
}
int main() {
  int i, j, tcc, tc = 1 << 28;
  memset(par, ~0, sizeof(par));
  for (tcc = 0; tcc < tc; tcc++) {
    len[0] = getstr(in);
    in[len[0]] = '#';
    len[1] = getstr(in + len[0] + 1);
    in[len[0] + 1 + len[1]] = '$';
    len[2] = getstr(in + len[0] + 1 + len[1] + 1);
    n = len[0] + 1 + len[1] + 1 + len[2];
    sa.gen_sa(in, n);
    sa.gen_cp(in, n);
    int min_len = min(min(len[0], len[1]), len[2]);
    int maxCp = 0;
    for (i = 0; i <= n; i++) {
      cp_idx[min(min_len, sa.cp[i])].push_back(i);
    }
    for (i = 0; i <= n; i++) {
      int type = which_str(sa.sa[i]);
      if (type == -1) continue;
      cnt[type][i] += 1;
    }
    modint prod = 0;
    for (int k = min_len; k; --k) {
      for (i = cp_idx[k].size() - 1; ~i; --i) {
        int p = cp_idx[k][i];
        int a = root(p);
        int b = root(p + 1);
        if (a == b) continue;
        par[a] = b;
        prod -= cnt[0][a] * cnt[1][a] * cnt[2][a];
        prod -= cnt[0][b] * cnt[1][b] * cnt[2][b];
        cnt[0][b] += cnt[0][a];
        cnt[1][b] += cnt[1][a];
        cnt[2][b] += cnt[2][a];
        prod += cnt[0][b] * cnt[1][b] * cnt[2][b];
      }
      res[k] = prod;
    }
    for (int k = 1; k <= min(min(len[0], len[1]), len[2]); k++) {
      if (k > 1) putchar(' ');
      printf("%d", res[k]);
    }
    puts("");
  }
  return 0;
}
