#include <bits/stdc++.h>
using namespace std;
template <class T1>
void deb(T1 e1) {
  cout << e1 << endl;
}
template <class T1, class T2>
void deb(T1 e1, T2 e2) {
  cout << e1 << " " << e2 << endl;
}
template <class T1, class T2, class T3>
void deb(T1 e1, T2 e2, T3 e3) {
  cout << e1 << " " << e2 << " " << e3 << endl;
}
template <class T1, class T2, class T3, class T4>
void deb(T1 e1, T2 e2, T3 e3, T4 e4) {
  cout << e1 << " " << e2 << " " << e3 << " " << e4 << endl;
}
template <class T1, class T2, class T3, class T4, class T5>
void deb(T1 e1, T2 e2, T3 e3, T4 e4, T5 e5) {
  cout << e1 << " " << e2 << " " << e3 << " " << e4 << " " << e5 << endl;
}
template <class T1, class T2, class T3, class T4, class T5, class T6>
void deb(T1 e1, T2 e2, T3 e3, T4 e4, T5 e5, T6 e6) {
  cout << e1 << " " << e2 << " " << e3 << " " << e4 << " " << e5 << " " << e6
       << endl;
}
int dx[] = {0, 0, 1, -1};
int dy[] = {-1, 1, 0, 0};
vector<pair<int, int>> my;
struct state {
  int len, link;
  int nexto[32];
};
const int MAXLEN = 500500;
state st[MAXLEN];
int tree[950000], lazy[950000];
int out[MAXLEN], vis[MAXLEN];
long long cnt[MAXLEN][5];
int sz = 0, last = 0;
void update(int node, int st, int en, int l, int r, int v) {
  if (lazy[node]) {
    tree[node] += lazy[node];
    if (st != en) {
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
      lazy[node * 2] %= 1000000007;
      lazy[node * 2 + 1] %= 1000000007;
    }
    tree[node] %= 1000000007;
    lazy[node] = 0;
  }
  if (st > r or en < l) return;
  if (st >= l and en <= r) {
    tree[node] += v;
    if (st != en) {
      lazy[node * 2] += v;
      lazy[node * 2 + 1] += v;
      lazy[node * 2] %= 1000000007;
      lazy[node * 2 + 1] %= 1000000007;
    }
    tree[node] %= 1000000007;
    return;
  }
  int mid = (st + en) / 2;
  update(node * 2, st, mid, l, r, v);
  update(node * 2 + 1, mid + 1, en, l, r, v);
}
int query(int node, int st, int en, int l) {
  if (st > l or en < l) return 0;
  if (lazy[node]) {
    tree[node] += lazy[node];
    if (lazy[node]) {
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
      lazy[node * 2] %= 1000000007;
      lazy[node * 2 + 1] %= 1000000007;
    }
    tree[node] %= 1000000007;
    lazy[node] = 0;
  }
  if (st == en) return tree[node];
  int mid = (st + en) / 2;
  int p = query(node * 2, st, mid, l);
  p += query(node * 2 + 1, mid + 1, en, l);
  return p;
}
void sa_init() {
  sz = last = 0;
  st[0].len = 0;
  st[0].link = -1;
  for (int i = 0; i < 29; i++) st[sz].nexto[i] = -1;
  ++sz;
}
int nw() {
  for (int i = 0; i < 29; i++) st[sz].nexto[i] = -1;
  sz++;
  return sz - 1;
}
void cp(int clone, int q) {
  for (int i = 0; i < 29; i++) {
    st[clone].nexto[i] = st[q].nexto[i];
  }
}
void sa_extend(int c, int bol) {
  int cur = nw();
  cnt[cur][bol] = 1;
  st[cur].len = st[last].len + 1;
  int p;
  for (p = last; p != -1 && st[p].nexto[c] == -1; p = st[p].link)
    st[p].nexto[c] = cur;
  if (p == -1)
    st[cur].link = 0;
  else {
    int q = st[p].nexto[c];
    if (st[p].len + 1 == st[q].len)
      st[cur].link = q;
    else {
      int clone = nw();
      st[clone].len = st[p].len + 1;
      cp(clone, q);
      st[clone].link = st[q].link;
      for (; p != -1 && st[p].nexto[c] == q; p = st[p].link)
        st[p].nexto[c] = clone;
      st[q].link = st[cur].link = clone;
    }
  }
  last = cur;
}
char str[300000];
char td[] = {'2', '3', '4', '5'};
int main() {
  int i, j, k, l, m, n = 3, ma = 6000000;
  sa_init();
  for (int j = 1; j <= 3; j++) {
    scanf("%s", str);
    m = strlen(str);
    str[m] = td[j];
    ma = min(ma, m);
    str[m + 1] = '\0';
    for (int i = 0; str[i]; i++) {
      int id;
      if (str[i] >= 97 && str[i] <= 122)
        id = str[i] - 97;
      else
        id = str[i] - 48 + 23;
      sa_extend(id, j);
    }
  }
  for (int i = 1; i < sz; i++) {
    my.push_back(make_pair(st[i].len, i));
  }
  sort(my.begin(), my.end());
  for (int j = 1; j <= 3; j++) {
    for (int i = my.size() - 1; i >= 0; i--) {
      l = my[i].second;
      cnt[st[l].link][j] += cnt[l][j];
    }
  }
  for (int i = 1; i < sz; i++) {
    long long p = (cnt[i][1] * cnt[i][2]) % 1000000007;
    p *= cnt[i][3];
    p %= 1000000007;
    int lo = st[st[i].link].len + 1;
    int high = st[i].len;
    update(1, 1, ma, lo, high, p);
  }
  assert(ma < 120000);
  for (int i = 1; i <= ma; i++) {
    l = query(1, 1, ma, i);
    printf("%d ", l);
  }
}
