#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int _w;
char str[N], s[N];
int n, L[N], R[N], len[N], m, B, trs[N][26], lnk[N], nidx, que[N], he, ta,
    ed[N], val[N], head[N], eidx;
long long ans[N], pre[N];
vector<pair<pair<int, int>, int> > vec[N];
vector<int> id[N];
namespace Bloc {
const int B = 501;
int Bl[N], Br[N], bidx, Bid[N], bloc, Bpre[N], Bsuf[N], Bsum[N];
void init(void) {
  bloc = ceil(sqrt(n));
  for (int i = 1, r; i <= n; i = r + 1) {
    r = min(n, i + bloc - 1);
    Bid[i] = Bid[i - 1] + 1;
    Bl[Bid[i]] = i;
    Br[Bid[i]] = r;
    for (int j = i + 1; j <= r; ++j) Bid[j] = Bid[i];
  }
}
void add(int x, int v) {
  int bid = Bid[x];
  for (int i = 1; i <= bid; ++i) Bsum[i] += v;
  for (int i = Bl[bid]; i <= x; ++i) Bsuf[i] += v;
  for (int i = Br[bid]; i >= x; --i) Bpre[i] += v;
}
int qry(int l, int r) {
  int lid = Bid[l], rid = Bid[r], res = 0;
  if (lid == rid) return Bsuf[l] - (r == Br[lid] ? 0 : Bsuf[r + 1]);
  res = Bsum[lid + 1] - Bsum[rid];
  return res + Bsuf[l] + Bpre[r];
}
}  // namespace Bloc
struct Query {
  int l, r, id, k;
} qry[N];
struct Edge {
  int nxt, to;
} edge[N];
bool mark[N];
void addedge(int u, int v) {
  edge[++eidx] = (Edge){head[u], v};
  head[u] = eidx;
}
void dfs(int u) {
  for (int i = head[u]; i; i = edge[i].nxt) {
    dfs(edge[i].to);
    val[u] += val[edge[i].to];
  }
}
void work(int id) {
  int u = 0;
  memset(val, 0, sizeof(int) * (nidx + 1));
  for (int i = L[id]; i <= R[id]; ++i) val[u = trs[u][str[i] - 'a']] = 1;
  dfs(0);
  for (int i = 1; i <= n; ++i) {
    pre[i] = pre[i - 1] + val[ed[i]];
  }
  for (int i = 1; i <= m; ++i)
    if (qry[i].k == id) ans[i] = pre[qry[i].r] - pre[qry[i].l - 1];
}
void redfs(int u) {
  for (const int& v : id[u]) Bloc::add(v, 1);
  for (const pair<pair<int, int>, int>& v : vec[u])
    ans[v.second] += Bloc::qry(v.first.first, v.first.second);
  for (int i = head[u]; i; i = edge[i].nxt) redfs(edge[i].to);
  for (const int& v : id[u]) Bloc::add(v, -1);
}
int main(void) {
  _w = scanf("%d%d", &n, &m);
  for (int i = 1, u; i <= n; ++i) {
    _w = scanf("%s", s + 1);
    len[i] = strlen(s + 1);
    L[i] = R[i - 1] + 1;
    R[i] = L[i] + len[i] - 1;
    for (int j = L[i], cur = 1; j <= R[i]; ++j) str[j] = s[cur++];
    u = 0;
    for (int j = 1; j <= len[i]; ++j) {
      if (!trs[u][s[j] - 'a']) trs[u][s[j] - 'a'] = ++nidx;
      u = trs[u][s[j] - 'a'];
    }
    ed[i] = u;
    id[u].push_back(i);
  }
  B = ceil(sqrt(R[n]));
  he = 1;
  for (int i = 0; i < 26; ++i)
    if (trs[0][i]) que[++ta] = trs[0][i];
  while (he <= ta) {
    int u = que[he++];
    for (int i = 0; i < 26; ++i)
      if (trs[u][i])
        lnk[que[++ta] = trs[u][i]] = trs[lnk[u]][i];
      else
        trs[u][i] = trs[lnk[u]][i];
  }
  for (int i = 1; i <= nidx; ++i) addedge(lnk[i], i);
  for (int i = 1; i <= m; ++i) {
    _w = scanf("%d%d%d", &qry[i].l, &qry[i].r, &qry[i].k);
    mark[qry[i].k] = 1;
  }
  for (int i = 1; i <= n; ++i)
    if (mark[i] && len[i] >= B) work(i);
  Bloc::init();
  for (int i = 1, u, k; i <= m; ++i)
    if (len[k = qry[i].k] < B) {
      u = 0;
      for (int j = L[k]; j <= R[k]; ++j) {
        u = trs[u][str[j] - 'a'];
        vec[u].push_back(
            pair<pair<int, int>, int>(pair<int, int>(qry[i].l, qry[i].r), i));
      }
    }
  redfs(0);
  for (int i = 1; i <= m; ++i) printf("%lld\n", ans[i]);
  return 0;
}
