#include <bits/stdc++.h>
using namespace std;
int n, q, End[100010], num, Len, lEn[100010], sumlen, limit;
int que[100010], tou, wei;
int size[100010], dfn[100010], dfs_clock, _dfn[100010];
long long ans[100010], sum[100010], sUm[100010], SUM[100010];
int Lpos[100010], Rpos[100010], bel[100010], T;
char str[100010];
vector<int> G[100010];
vector<int> BGC[100010], DCL[100010], DCR[100010];
struct TRIE {
  int son[26], fa, next, val;
} trie[100010];
struct SYZ {
  int l, r, k, id;
} syz[100010];
inline long long read() {
  long long x = 0, w = 0;
  char ch = 0;
  while (!isdigit(ch)) {
    w |= ch == '-';
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = (x << 1) + (x << 3) + (ch ^ 48);
    ch = getchar();
  }
  return w ? -x : x;
}
void insert(int iD) {
  int p = 0;
  for (int i = 1; i <= Len; i++) {
    int ch = str[i] - 'a';
    if (!trie[p].son[ch]) trie[p].son[ch] = ++num;
    trie[trie[p].son[ch]].fa = p;
    p = trie[p].son[ch];
  }
  End[iD] = p;
}
void prepare() {
  tou = 1;
  wei = 0;
  for (int i = 0; i < 26; i++)
    if (trie[0].son[i]) que[++wei] = trie[0].son[i];
  while (tou <= wei) {
    int x = que[tou++];
    for (int i = 0; i < 26; i++)
      if (trie[x].son[i]) {
        trie[trie[x].son[i]].next = trie[trie[x].next].son[i];
        que[++wei] = trie[x].son[i];
      } else
        trie[x].son[i] = trie[trie[x].next].son[i];
  }
}
void dfs1(int x) {
  for (int y : G[x]) dfs1(y), sum[x] += sum[y];
}
void dfs(int x) {
  size[x] = 1;
  _dfn[dfn[x] = ++dfs_clock] = x;
  for (int y : G[x]) dfs(y), size[x] += size[y];
}
void change(int pos, int delta) {
  if (pos > dfs_clock) return;
  for (int i = pos; i <= Rpos[bel[pos]]; i++) sum[i] += delta;
  for (int i = bel[pos] + 1; i <= T; i++) SUM[i] += delta;
}
int ask(int pos) { return sum[pos] + SUM[bel[pos]]; }
int main() {
  n = read();
  q = read();
  for (int i = 1; i <= n; i++) {
    scanf("%s", str + 1);
    lEn[i] = Len = strlen(str + 1);
    sumlen += Len;
    insert(i);
  }
  prepare();
  for (int i = 1; i <= num; i++) G[trie[i].next].emplace_back(i);
  limit = sumlen / sqrt(q);
  for (int i = 1; i <= q; i++) {
    int l = read(), r = read(), k = read();
    syz[i] = (SYZ){l, r, k, i};
    if (lEn[k] > limit)
      BGC[k].emplace_back(i);
    else
      DCL[l].emplace_back(i), DCR[r].emplace_back(i);
  }
  for (int i = 1; i <= n; i++)
    if (BGC[i].size()) {
      int p = End[i];
      memset(sum, 0, sizeof(long long) * (num + 5));
      while (p) sum[p] = 1, p = trie[p].fa;
      dfs1(0);
      for (int j = 1; j <= n; j++) sUm[j] = sUm[j - 1] + sum[End[j]];
      for (int j = 0; j < int(BGC[i].size()); j++)
        ans[syz[BGC[i][j]].id] =
            sUm[syz[BGC[i][j]].r] - sUm[syz[BGC[i][j]].l - 1];
    }
  dfs(0);
  memset(sum, 0, sizeof sum);
  T = sqrt(dfs_clock);
  for (int i = 1; i <= T; i++) Lpos[i] = (i - 1) * T + 1, Rpos[i] = i * T;
  if (Rpos[T] != dfs_clock) {
    Lpos[T + 1] = Rpos[T] + 1;
    Rpos[++T] = dfs_clock;
  }
  Lpos[1] = 0;
  for (int i = 1; i <= T; i++)
    for (int j = Lpos[i]; j <= Rpos[i]; j++) bel[j] = i;
  for (int i = 1; i <= n; i++) {
    for (auto abc : DCL[i]) {
      for (int p = End[syz[abc].k]; p; p = trie[p].fa)
        ans[syz[abc].id] -= ask(dfn[p]);
    }
    change(dfn[End[i]], 1);
    change(dfn[End[i]] + size[End[i]], -1);
    for (auto abc : DCR[i]) {
      for (int p = End[syz[abc].k]; p; p = trie[p].fa)
        ans[syz[abc].id] += ask(dfn[p]);
    }
  }
  for (int i = 1; i <= q; i++) printf("%lld\n", ans[i]);
}
