#include <bits/stdc++.h>
#pragma GCC optimize("O2")
#pragma GCC optimize("unroll-loops")
using namespace std;
long long power(long long a, long long b, long long md) {
  return (!b ? 1
             : (b & 1 ? a * power(a * a % md, b / 2, md) % md
                      : power(a * a % md, b / 2, md) % md));
}
const int xn = 1e5 + 10;
const int xm = -20 + 10;
const int sq = 200;
const int inf = 1e9 + 10;
const long long INF = 1e18 + 10;
const int mod = 1e9 + 7;
const int base = 257;
const int SIG = 26;
int n, q, col[xn], F[xn], nxt[SIG][xn], TM;
int stm[xn], ftm[xn], ptr, Q[xn], fen[xn];
long long ps[2][xn], ans[xn];
string S[xn];
vector<int> adj[xn], vec[xn], vrt[xn];
vector<pair<int, int> > query[2][xn];
vector<pair<pair<int, int>, int> > que[xn];
void build_aho() {
  int L = 0, R = 0;
  for (int i = 0; i < SIG; ++i)
    if (nxt[i][0]) Q[R++] = nxt[i][0];
  while (L < R) {
    int v = Q[L++];
    adj[F[v]].push_back(v);
    for (int i = 0; i < SIG; ++i) {
      if (nxt[i][v])
        F[nxt[i][v]] = nxt[i][F[v]], Q[R++] = nxt[i][v];
      else
        nxt[i][v] = nxt[i][F[v]];
    }
  }
}
void preDFS(int v) {
  stm[v] = TM++;
  for (int u : adj[v]) preDFS(u);
  ftm[v] = TM;
}
void mofen(int pos, int val) {
  for (pos += 5; pos < xn; pos += pos & -pos) fen[pos] += val;
}
int gefen(int pos) {
  int res = 0;
  for (pos += 5; pos > 0; pos -= pos & -pos) res += fen[pos];
  return res;
}
void DFS(int v) {
  for (int u : adj[v]) DFS(u), ps[0][v] += ps[0][u];
  for (int id : vrt[v]) ps[1][id] += ps[0][v];
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  cin >> n >> q;
  for (int i = 1; i <= n; ++i) {
    cin >> S[i];
    int v = 0;
    for (int j = 0; j < int(S[i].size()); ++j) {
      int c = S[i][j] - 'a';
      if (!nxt[c][v]) nxt[c][v] = ++ptr;
      v = nxt[c][v];
      vec[i].push_back(v);
    }
    vrt[v].push_back(i);
    col[i] = v;
  }
  build_aho(), preDFS(0);
  for (int i = 0; i < q; ++i) {
    int l, r, k;
    cin >> l >> r >> k;
    if (int(S[k].size()) <= sq) {
      query[0][r].push_back({k, i});
      query[1][l - 1].push_back({k, i});
    } else
      que[k].push_back({{l, r}, i});
  }
  for (int i = 0; i <= n; ++i) {
    mofen(stm[col[i]], 1);
    mofen(ftm[col[i]], -1);
    for (pair<int, int> id : query[0][i])
      for (int v : vec[id.first]) ans[id.second] += gefen(stm[v]);
    for (pair<int, int> id : query[1][i])
      for (int v : vec[id.first]) ans[id.second] -= gefen(stm[v]);
  }
  for (int i = 1; i <= n; ++i) {
    if (int(S[i].size()) <= sq) continue;
    for (int v : vec[i]) ++ps[0][v];
    DFS(0);
    for (int j = 1; j <= n; ++j) ps[1][j] += ps[1][j - 1];
    for (pair<pair<int, int>, int> x : que[i])
      ans[x.second] = ps[1][x.first.second] - ps[1][x.first.first - 1];
    memset(ps, 0, sizeof ps);
  }
  for (int i = 0; i < q; ++i) cout << ans[i] << '\n';
  return 0;
}
