#include <bits/stdc++.h>
using namespace std;
const int maxv = 2e5;
int n, k, br, ind[maxv + 10], niz[maxv + 10], p[maxv + 10], cnt[maxv + 10],
    pm[maxv + 10], pniz[maxv + 10], rnk[maxv + 10], lcp[maxv + 10],
    ss[maxv + 10], uk, brojac[maxv + 10], lseg[2 * maxv + 10],
    rseg[2 * maxv + 10], brs;
int dp[20][maxv + 10], len[maxv + 10], lr[maxv + 10], rl[maxv + 10],
    rez[maxv + 10];
long long sol[maxv + 10];
vector<int> vect[maxv + 10], vect2[maxv + 10];
int get(int x) { return x - 'a' + 1 + n; }
bool srt(int x, int y) { return niz[x] < niz[y]; }
void prek() {
  for (int i = 0; i < br; i++) dp[0][i] = lcp[i];
  int h = log2(br);
  for (int i = 1; i <= h; i++)
    for (int j = 0; j < br; j++) {
      if (j + (1 << i) - 1 >= br) break;
      dp[i][j] = min(dp[i - 1][j], dp[i - 1][j + (1 << (i - 1))]);
    }
}
int query(int l, int r) {
  if (l == r) {
    int id = p[l];
    return len[id];
  }
  r--;
  int h = log2(r - l + 1);
  return min(dp[h][l], dp[h][r - (1 << h) + 1]);
}
struct op {
  bool operator()(int x, int y) { return x > y; }
};
int main() {
  scanf("%d %d", &n, &k);
  int curr = 0;
  for (int i = 1; i <= n; i++) {
    string a;
    cin >> a;
    curr++;
    for (int j = br; j <= br + a.size(); j++) {
      niz[j] = get(a[j - br]);
      ind[j] = i;
      ss[j] = niz[j];
      len[j] = br + a.size() - j;
    }
    br += a.size();
    niz[br++] = curr;
    ss[br - 1] = niz[br - 1];
    ind[br - 1] = i;
  }
  for (int i = 0; i < br; i++) p[i] = i;
  sort(p, p + br, srt);
  for (int i = 1; (1 << (i - 1)) < br; i++) {
    for (int j = 0; j < br; j++) p[j] = (p[j] - (1 << (i - 1)) + br) % br;
    memset(cnt, 0, sizeof(cnt));
    for (int j = 0; j < br; j++) cnt[niz[j]]++;
    for (int j = 1; j <= maxv; j++) cnt[j] += cnt[j - 1];
    for (int j = br - 1; j >= 0; j--) pm[--cnt[niz[p[j]]]] = p[j];
    for (int j = 0; j < br; j++) p[j] = pm[j];
    pniz[p[0]] = 1;
    for (int j = 1; j < br; j++) {
      int id = p[j];
      int id2 = p[j - 1];
      if (niz[id] == niz[id2] &&
          niz[(id + (1 << (i - 1))) % br] == niz[(id2 + (1 << (i - 1))) % br])
        pniz[p[j]] = pniz[p[j - 1]];
      else
        pniz[p[j]] = pniz[p[j - 1]] + 1;
    }
    for (int j = 0; j < br; j++) niz[j] = pniz[j];
  }
  for (int i = 0; i < br; i++) rnk[p[i]] = i;
  int clcp = 0;
  for (int i = 0; i < br; i++) {
    if (rnk[i] == br - 1) {
      lcp[rnk[i]] = 0;
      clcp = 0;
      continue;
    }
    int j = p[rnk[i] + 1];
    while (j + clcp < br && i + clcp < br && ss[i + clcp] == ss[j + clcp])
      clcp++;
    lcp[rnk[i]] = clcp;
    if (clcp) clcp--;
  }
  int l = n;
  int r = l;
  uk = 0;
  while (r < br) {
    while (r < br && uk < k) {
      if (brojac[ind[p[r]]] == 0) uk++;
      brojac[ind[p[r]]]++;
      r++;
    }
    if (uk < k) break;
    while (uk >= k) {
      lseg[++brs] = l;
      rseg[brs] = r - 1;
      brojac[ind[p[l]]]--;
      if (brojac[ind[p[l]]] == 0) uk--;
      l++;
    }
  }
  prek();
  for (int i = 1; i <= brs; i++) {
    vect[lseg[i]].push_back(query(lseg[i], rseg[i]));
    vect2[rseg[i] + 1].push_back(query(lseg[i], rseg[i]));
    lr[rseg[i]] = max(lr[rseg[i]], lseg[i]);
    rl[lseg[i]] = min(rl[lseg[i]], rseg[i]);
  }
  curr = 0;
  for (int i = n; i < br; i++) {
    if (lr[i] != 0) curr = max(curr, lr[i]);
    rez[i] = max(rez[i], query(curr, i));
  }
  curr = 0;
  for (int i = br - 1; i >= n; i--) {
    if (rl[i] != 0) curr = min(curr, rl[i]);
    if (curr != 0) rez[i] = max(rez[i], query(i, curr));
  }
  multiset<int, op> kek;
  for (int i = n; i < br; i++) {
    for (int j = 0; j < vect2[i].size(); j++) kek.erase(vect2[i][j]);
    for (int j = 0; j < vect[i].size(); j++) kek.insert(vect[i][j]);
    rez[i] = max(rez[i], *(kek.begin()));
  }
  for (int j = n; j < br; j++) {
    sol[ind[p[j]]] += (long long)rez[j];
  }
  for (int j = 1; j <= n; j++) printf("%lld ", sol[j]);
  return 0;
}
