#include <bits/stdc++.h>
using std::queue;
using std::vector;
const int N = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int LEN = 400;
const int SIZ = ((N / LEN) + 2);
template <class T>
inline void read(T &x) {
  T f = 1;
  x = 0;
  char s = getchar();
  while (s < '0' || s > '9') {
    if (s == '-') f = -1;
    s = getchar();
  }
  while (s >= '0' && s <= '9') {
    x = x * 10 + s - '0';
    s = getchar();
  }
  x *= f;
}
long long idx = 1, val[N];
inline int lo(int x) { return (x & (-x)); }
inline void upd(int x, int ch) {
  while (x <= idx) val[x] += ch, x += lo(x);
}
inline long long qry(int x) {
  int ans = 0;
  while (x) ans += val[x], x -= lo(x);
  return ans;
}
inline long long qry(int l, int r) { return qry(r) - qry(l - 1); }
long long Ans[SIZ][N];
int L[SIZ], R[SIZ], bel[N];
int son[26][N], n, m, q, fail[N], end[N], id, mx, ch[26][N], db[N];
char s[N];
vector<int> p[N];
inline void insert(char *S, int LENN) {
  int ps = 1, nxt;
  for (int i = 1; i <= LENN; i++) {
    p[id].emplace_back(S[i] - 'a');
    nxt = (S[i] - 'a');
    if (!son[nxt][ps]) son[nxt][ps] = (++idx);
    ps = son[nxt][ps];
  }
  end[id] = ps;
  db[ps] = id;
}
queue<int> Q;
vector<int> e[N];
int dfn[N], sz[N], sn[N], tp[N], fa[N];
long long rans[N];
inline void bfs() {
  for (int i = 0; i <= 25; i++)
    if (son[i][1])
      fail[son[i][1]] = 1, Q.push(son[i][1]);
    else
      son[i][1] = 1;
  while (!Q.empty()) {
    int u = Q.front();
    Q.pop();
    e[fail[u]].emplace_back(u);
    for (int i = 0; i <= 25; i++) {
      if (son[i][u])
        fail[son[i][u]] = son[i][fail[u]], Q.push(son[i][u]);
      else
        son[i][u] = son[i][fail[u]];
    }
  }
}
inline void dfs1(int x) {
  sz[x] = 1;
  for (int v : e[x]) {
    fa[v] = x;
    dfs1(v);
    sz[x] += sz[v];
    if (sz[v] > sz[sn[x]]) sn[x] = v;
  }
}
inline void dfs2(int x, int topf) {
  dfn[x] = (++dfn[0]);
  tp[x] = topf;
  if (!sn[x]) return;
  dfs2(sn[x], topf);
  for (int v : e[x]) {
    if (v == sn[x]) continue;
    dfs2(v, v);
  }
}
inline long long query(int x) {
  long long ans = 0;
  while (tp[x] != 1) {
    ans += qry(dfn[tp[x]], dfn[x]);
    x = fa[tp[x]];
  }
  return ans + qry(dfn[1], dfn[x]);
}
vector<int> qy[N];
inline long long query(int l, int r, int k) {
  long long ans = 0;
  if (bel[l] == bel[r]) {
    for (int i = l; i <= r; i++)
      ans += qry(dfn[end[i]], dfn[end[i]] + sz[end[i]] - 1);
    return ans;
  }
  for (int i = bel[l] + 1; i <= bel[r] - 1; i++) ans += Ans[i][db[k]];
  int LL = l, RR = r;
  while (bel[l] == bel[LL])
    ans += qry(dfn[end[l]], dfn[end[l]] + sz[end[l]] - 1), l++;
  while (bel[r] == bel[RR])
    ans += qry(dfn[end[r]], dfn[end[r]] + sz[end[r]] - 1), r--;
  return ans;
}
int l[N], r[N];
inline void dfs(int x) {
  upd(dfn[x], 1);
  for (int v : qy[x]) rans[v] = query(l[v], r[v], x);
  for (int i = 0; i <= 25; i++) {
    if (!ch[i][x]) continue;
    dfs(ch[i][x]);
  }
  upd(dfn[x], -1);
}
int k;
inline void solve() {
  read(n);
  read(q);
  for (int i = 1; i <= n; i++) {
    scanf("%s", s + 1);
    id = i;
    insert(s, strlen(s + 1));
  }
  for (int i = 1; i <= idx; i++)
    for (int j = 0; j <= 25; j++) ch[j][i] = son[j][i];
  bfs();
  dfs1(1);
  dfs2(1, 1);
  for (int i = 1; i <= n; i++) {
    if (i % LEN == 1)
      bel[i] = bel[i - 1] + 1;
    else
      bel[i] = bel[i - 1];
    if (bel[i] != bel[i - 1]) {
      L[bel[i]] = i;
      R[bel[i - 1]] = (i - 1);
    }
  }
  R[bel[n]] = n;
  mx = bel[n];
  for (int ps = 1; ps <= mx; ps++) {
    for (int i = L[ps]; i <= R[ps]; i++) upd(dfn[end[i]], 1);
    int pss = 1, ans = 0;
    for (int i = 1; i <= n; i++) {
      pss = 1;
      ans = 0;
      for (int nxt : p[i]) pss = son[nxt][pss], ans += query(pss);
      Ans[ps][i] = ans;
    }
    for (int i = L[ps]; i <= R[ps]; i++) upd(dfn[end[i]], -1);
  }
  for (int i = 1; i <= q; i++) {
    read(l[i]);
    read(r[i]);
    read(k);
    qy[end[k]].emplace_back(i);
  }
  dfs(1);
  for (int i = 1; i <= q; i++) printf("%lld\n", rans[i]);
}
signed main() { solve(); }
