#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
struct edge {
  int next, to;
  edge() {}
  edge(int x, int y) : next(x), to(y) {}
} e[maxn << 1];
int h[maxn], ent;
void addedge(int x, int y) {
  e[++ent] = edge(h[x], y);
  h[x] = ent;
}
int n, m, q, dfn, blk, cnt = 1;
string s[maxn];
int len[maxn], ys[maxn], in[maxn], out[maxn];
long long ans[maxn], c[maxn];
int lowbit(int x) { return x & (-x); }
void add(int x, int k) {
  for (int i = x; i <= dfn; i += lowbit(i)) c[i] += k;
}
long long sum(int x) {
  long long ans = 0;
  for (int i = x; i; i -= lowbit(i)) ans += c[i];
  return ans;
}
struct trie {
  int c[26], fail;
} t[maxn];
struct node {
  int k, id;
};
bool cmp(node tx, node ty) { return tx.k < ty.k; }
vector<node> v1[maxn], v2[maxn];
void ins(int id) {
  int v = 1;
  for (int i = 0; i < len[id]; i++) {
    if (!t[v].c[s[id][i] - 'a']) t[v].c[s[id][i] - 'a'] = ++cnt;
    v = t[v].c[s[id][i] - 'a'];
  }
  ys[id] = v;
}
void dfs(int x) {
  in[x] = ++dfn;
  for (int i = h[x]; i; i = e[i].next) dfs(e[i].to);
  out[x] = dfn;
}
void getac() {
  queue<int> q;
  int x, y, fail;
  for (int i = 0; i < 26; i++) t[0].c[i] = 1;
  q.push(1);
  t[0].fail = 1;
  while (!q.empty()) {
    x = q.front();
    q.pop();
    fail = t[x].fail;
    for (int i = 0; i < 26; i++) {
      y = t[x].c[i];
      if (y)
        t[y].fail = t[fail].c[i], q.push(y);
      else
        t[x].c[i] = t[fail].c[i];
    }
  }
  for (int i = 2; i <= cnt; i++) addedge(t[i].fail, i);
  dfs(1);
}
void sub1() {
  for (int i = 1; i <= n; i++) {
    if (!v1[i].size()) continue;
    int v = 1, h1 = 0, x;
    long long tmp = 0;
    for (int j = 0; j < len[i]; j++) v = t[v].c[s[i][j] - 'a'], add(in[v], 1);
    sort(v1[i].begin(), v1[i].end(), cmp);
    while (h1 < v1[i].size() && !v1[i][h1].k) h1++;
    for (int j = 1; j <= n; j++) {
      tmp += sum(out[ys[j]]) - sum(in[ys[j]] - 1);
      for (int k = h1; k < v1[i].size(); k++) {
        if (v1[i][k].k == j) {
          h1++;
          x = abs(v1[i][k].id);
          if (v1[i][k].id < 0)
            ans[x] -= tmp;
          else
            ans[x] += tmp;
        } else
          break;
      }
    }
    v = 1;
    for (int j = 0; j < len[i]; j++) v = t[v].c[s[i][j] - 'a'], add(in[v], -1);
  }
}
void sub2() {
  for (int i = 1; i <= n; i++) {
    add(in[ys[i]], 1), add(out[ys[i]] + 1, -1);
    for (int k = 0; k < v2[i].size(); k++) {
      int x = v2[i][k].k, y = abs(v2[i][k].id), v = 1;
      for (int j = 0; j < len[x]; j++) {
        v = t[v].c[s[x][j] - 'a'];
        if (v2[i][k].id < 0)
          ans[y] -= sum(in[v]);
        else
          ans[y] += sum(in[v]);
      }
    }
  }
}
int main() {
  int x, y, k;
  scanf("%d %d", &n, &q);
  for (int i = 1; i <= n; i++)
    cin >> s[i], m += (len[i] = s[i].length()), ins(i);
  blk = sqrt(m);
  getac();
  for (int i = 1; i <= q; i++) {
    scanf("%d %d %d", &x, &y, &k);
    if (len[k] > blk)
      v1[k].push_back((node){x - 1, -i}), v1[k].push_back((node){y, i});
    else
      v2[x - 1].push_back((node){k, -i}), v2[y].push_back((node){k, i});
  }
  sub1();
  sub2();
  for (int i = 1; i <= q; i++) printf("%lld\n", ans[i]);
  return 0;
}
