#include <bits/stdc++.h>
using namespace std;
struct que {
  int r, k, id, tp;
  que(int _r = 0, int _k = 0, int _id = 0, int _tp = 0) {
    r = _r, k = _k, id = _id, tp = _tp;
  }
  bool operator<(const que &rhs) const { return r < rhs.r; }
} qs[100010 << 1];
struct que2 {
  int l, r, k, id;
  que2(int _l = 0, int _r = 0, int _k = 0, int _id = 0) {
    l = _l, r = _r, k = _k, id = _id;
  }
  bool operator<(const que2 &rhs) const { return k < rhs.k; }
} qs2[100010];
int len[100010], nxt[100010][26], fail[100010], tn, n, q, lim, SZ, rt = 1,
                                                                   cnt = 1;
int nd[100010], pos[100010], epos[100010], T = 0;
int bel[100010], sta[100010], ed[100010], tag[100010], qc = 0, qc2 = 0;
long long SUM[100010], sum[100010];
long long ans[100010], tmpans[100010];
char S[100010], *s[100010];
vector<int> son[100010];
void insert(int id) {
  int tmp = rt;
  for (int i = 1; i <= len[id]; i++) {
    if (!nxt[tmp][s[id][i]]) nxt[tmp][s[id][i]] = ++cnt;
    tmp = nxt[tmp][s[id][i]];
  }
  nd[id] = tmp;
}
void getfail() {
  queue<int> q;
  for (int i = 0; i < 26; i++) {
    if (!nxt[rt][i]) continue;
    fail[nxt[rt][i]] = rt, q.push(nxt[rt][i]);
  }
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = 0; i < 26; i++) {
      if (!nxt[x][i]) continue;
      int tmp = fail[x];
      while (tmp && !nxt[tmp][i]) tmp = fail[tmp];
      fail[nxt[x][i]] = tmp ? nxt[tmp][i] : rt;
      q.push(nxt[x][i]);
    }
  }
}
void dfs(int x) {
  pos[x] = ++T;
  for (int v : son[x]) dfs(v);
  epos[x] = T;
}
void insert(int pos, int val) {
  if (pos > cnt) return;
  for (int i = pos; i <= ed[bel[pos]]; i++) sum[i] += val;
  for (int i = bel[pos]; i <= tn; i++) SUM[i] += val;
}
int query(int pos) { return SUM[bel[pos] - 1] + sum[pos]; }
void Insert(int id) { insert(pos[nd[id]], 1), insert(epos[nd[id]] + 1, -1); }
long long solve(int id) {
  int tmp = rt;
  long long ret = 0;
  for (int i = 1; i <= len[id]; i++)
    tmp = nxt[tmp][s[id][i]], ret += query(pos[tmp]);
  return ret;
}
void solve2(int id) {
  int tmp = rt;
  memset(tag, 0, sizeof(tag));
  memset(tmpans, 0, sizeof(tmpans));
  for (int i = 1; i <= len[id]; i++) tmp = nxt[tmp][s[id][i]], tag[pos[tmp]]++;
  for (int i = 1; i <= cnt; i++) tag[i] += tag[i - 1];
  for (int i = 1; i <= n; i++)
    tmpans[i] = tag[epos[nd[i]]] - tag[pos[nd[i]] - 1];
  for (int i = 1; i <= n; i++) tmpans[i] += tmpans[i - 1];
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n >> q, lim = sqrt(n);
  for (int i = 1, tmp = 0; i <= n; i++)
    s[i] = S + tmp, cin >> s[i] + 1, tmp += len[i] = strlen(s[i] + 1);
  for (int i = 1; S[i]; i++) S[i] -= 'a';
  for (int i = 1; i <= n; i++) insert(i);
  getfail(), SZ = sqrt(cnt);
  for (int i = 1; i <= cnt; i++) {
    bel[i] = (i - 1) / SZ + 1;
    if (!sta[bel[i]]) sta[bel[i]] = i;
    ed[bel[i]] = i;
  }
  tn = bel[cnt];
  for (int i = 1; i <= cnt; i++) son[fail[i]].push_back(i);
  for (int i = 1, l, r, k; i <= q; i++) {
    cin >> l >> r >> k;
    if (len[k] <= lim) {
      if (l > 1) qs[++qc] = que(l - 1, k, i, -1);
      qs[++qc] = que(r, k, i, 1);
    } else
      qs2[++qc2] = que2(l, r, k, i);
  }
  dfs(rt);
  sort(qs + 1, qs + qc + 1), sort(qs2 + 1, qs2 + qc2 + 1);
  for (int i = 1, tmpr = 0; i <= qc; i++) {
    while (tmpr + 1 <= qs[i].r) Insert(++tmpr);
    ans[qs[i].id] += qs[i].tp * solve(qs[i].k);
  }
  for (int i = 1, j; i <= qc2; i = j + 1) {
    solve2(qs2[j = i].k);
    ans[qs2[i].id] = tmpans[qs2[i].r] - tmpans[qs2[i].l - 1];
    while (j < qc2 && qs2[j + 1].k == qs2[i].k)
      j++, ans[qs2[j].id] = tmpans[qs2[j].r] - tmpans[qs2[j].l - 1];
  }
  for (int i = 1; i <= q; i++) cout << ans[i] << endl;
  return 0;
}
