#include <bits/stdc++.h>
using namespace std;
const int Maxn = 100010;
const int inf = 2147483647;
int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
  return x * f;
}
int n, q, N, len[Maxn], tag[400], v[Maxn], End[Maxn], bel[Maxn], st[400],
    ed[400], totlen = 0;
long long sum[Maxn], ans[Maxn];
struct Query1 {
  int l, r, k, id;
} q1[Maxn];
int l1 = 0;
bool cmp1(Query1 a, Query1 b) { return a.k < b.k; }
struct Query2 {
  int x, k, id, type;
} q2[Maxn << 1];
int l2 = 0;
bool cmp2(Query2 a, Query2 b) { return a.x < b.x; }
string s[Maxn];
struct Trie {
  int son[26], fail;
} tr[Maxn];
int tot = 0;
void insert(int p) {
  len[p] = s[p].size();
  int t = 0;
  totlen += len[p];
  for (int i = 0; i < len[p]; i++) {
    int x = s[p][i] - 'a';
    if (!tr[t].son[x]) tr[t].son[x] = ++tot;
    t = tr[t].son[x];
  }
  End[p] = t;
}
void get_fail() {
  queue<int> q;
  q.push(0);
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = 0; i < 26; i++) {
      int Son = tr[x].son[i], Fail = tr[x].fail;
      if (Son) {
        if (!x)
          tr[Son].fail = 0;
        else
          tr[Son].fail = tr[Fail].son[i];
        q.push(Son);
      } else
        tr[x].son[i] = tr[Fail].son[i];
    }
  }
}
struct Edge {
  int y, next;
} e[Maxn];
int last[Maxn], ll = 0;
void ins(int x, int y) {
  int t = ++ll;
  e[t].y = y;
  e[t].next = last[x];
  last[x] = t;
}
int in[Maxn], out[Maxn], dfn = 0, T = 0, mark[Maxn];
int cnt[Maxn];
int DFS(int x, int fa) {
  int re = (mark[x] == T);
  for (int i = last[x]; i; i = e[i].next) {
    int y = e[i].y;
    if (y == fa) continue;
    re += DFS(y, x);
  }
  cnt[x] = re;
  return re;
}
void dfs(int x, int fa) {
  in[x] = ++dfn;
  for (int i = last[x]; i; i = e[i].next) {
    int y = e[i].y;
    if (y == fa) continue;
    dfs(y, x);
  }
  out[x] = dfn;
}
void build() {
  for (int i = 1; i <= tot; i++) ins(tr[i].fail, i);
  dfs(0, -1);
}
void solve1() {
  sort(q1 + 1, q1 + 1 + l1, cmp1);
  q1[0].k = 0;
  for (int i = 1; i <= l1; i++) {
    if (q1[i].k != q1[i - 1].k) {
      int k = q1[i].k, t = 0;
      T++;
      for (int j = 0; j < len[k]; j++) mark[t = tr[t].son[s[k][j] - 'a']] = T;
      DFS(0, -1);
      sum[0] = 0;
      for (int j = 1; j <= n; j++) sum[j] = (long long)sum[j - 1] + cnt[End[j]];
    }
    ans[q1[i].id] = sum[q1[i].r] - sum[q1[i].l - 1];
  }
}
void solve2() {
  bel[0] = 0;
  for (int i = 1; i <= dfn; i++) {
    bel[i] = (i - 1) / N + 1;
    if (bel[i] != bel[i - 1]) st[bel[i]] = i;
    ed[bel[i]] = i;
  }
  sort(q2 + 1, q2 + 1 + l2, cmp2);
  q2[0].x = 0;
  for (int i = 1; i <= l2; i++) {
    if (q2[i].x != q2[i - 1].x) {
      for (int X = q2[i - 1].x + 1; X <= q2[i].x; X++) {
        int L = in[End[X]], R = out[End[X]];
        if (bel[L] == bel[R]) {
          for (int j = L; j <= R; j++) v[j]++;
        } else {
          for (int j = L; j <= ed[bel[L]]; j++) v[j]++;
          for (int j = st[bel[R]]; j <= R; j++) v[j]++;
          for (int j = bel[L] + 1; j < bel[R]; j++) tag[j]++;
        }
      }
    }
    int t = 0, tmp = 0, k = q2[i].k;
    for (int j = 0; j < len[k]; j++) {
      t = tr[t].son[s[k][j] - 'a'];
      tmp += v[in[t]] + tag[bel[in[t]]];
    }
    ans[q2[i].id] += q2[i].type * tmp;
  }
}
int main() {
  memset(tr, 0, sizeof(tr));
  n = read(), q = read();
  for (int i = 1; i <= n; i++) cin >> s[i], insert(i);
  N = (int)sqrt(totlen);
  get_fail();
  build();
  for (int i = 1; i <= q; i++) {
    int l = read(), r = read(), k = read();
    if (len[k] >= N)
      q1[++l1].l = l, q1[l1].r = r, q1[l1].k = k, q1[l1].id = i;
    else {
      if (l > 1)
        q2[++l2].x = l - 1, q2[l2].k = k, q2[l2].type = -1, q2[l2].id = i;
      q2[++l2].x = r, q2[l2].k = k, q2[l2].type = 1, q2[l2].id = i;
    }
  }
  solve1();
  solve2();
  for (int i = 1; i <= q; i++) printf("%lld\n", ans[i]);
}
