#include <bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 9, B = 511;
inline long long read() {
  long long res = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    res = (res << 3) + (res << 1) + ch - '0';
    ch = getchar();
  }
  return res * f;
}
struct query {
  long long p, id;
  query(long long _p = 0, long long _id = 0) { p = _p, id = _id; }
};
long long m, n, tri[N][27], fail[N], cnt = 1, siz[N], ind, dfn[N];
long long len[N], fa[N], ed[N], tr[N], ans[N], a[N];
char s[N];
vector<long long> G[N];
vector<query> L[N], R[N], ll[N], rr[N];
inline bool cmp(query a, query b) { return a.p > b.p; }
inline void insert(long long x) {
  long long p = 1;
  for (long long i = 1; i <= len[x]; i++) {
    long long v = s[i] - 'a';
    if (!tri[p][v]) tri[p][v] = ++cnt, fa[tri[p][v]] = p;
    p = tri[p][v];
  }
  ed[x] = p;
}
inline void build_fail() {
  queue<long long> Q;
  for (long long i = 0; i < 26; i++)
    if (tri[1][i])
      Q.push(tri[1][i]), fail[tri[1][i]] = 1;
    else
      tri[1][i] = 1;
  while (!Q.empty()) {
    long long u = Q.front();
    Q.pop();
    for (long long i = 0; i < 26; i++)
      if (tri[u][i])
        Q.push(tri[u][i]), fail[tri[u][i]] = tri[fail[u]][i];
      else
        tri[u][i] = tri[fail[u]][i];
  }
}
void dfs(long long u) {
  for (auto v : G[u]) dfs(v), a[u] += a[v];
}
void Dfs(long long u) {
  siz[u] = 1;
  dfn[u] = ++ind;
  for (auto v : G[u]) Dfs(v), siz[u] += siz[v];
}
inline void add(long long x, long long c) {
  while (x <= ind) tr[x] += c, x += (x & -x);
}
inline long long ask(long long x) {
  long long res = 0;
  while (x) res += tr[x], x -= (x & -x);
  return res;
}
signed main() {
  n = read(), m = read();
  for (long long i = 1; i <= n; i++) {
    scanf("%s", s + 1);
    len[i] = strlen(s + 1);
    insert(i);
  }
  build_fail();
  for (long long i = 2; i <= cnt; i++) G[fail[i]].push_back(i);
  for (long long i = 1; i <= m; i++) {
    long long l, r, k;
    l = read(), r = read(), k = read();
    if (len[k] > B)
      L[k].push_back(query(l, i)), R[k].push_back(query(r, i));
    else
      ll[l].push_back(query(k, i)), rr[r].push_back(query(k, i));
  }
  for (long long i = 1; i <= n; i++)
    if (L[i].size() || R[i].size()) {
      sort(L[i].begin(), L[i].end(), cmp);
      sort(R[i].begin(), R[i].end(), cmp);
    }
  for (long long i = 1; i <= n; i++)
    if (len[i] > B) {
      long long p = ed[i];
      while (p != 1) a[p] = 1, p = fa[p];
      dfs(1);
      for (long long j = 1, val = 0; j <= n; j++) {
        while (L[i].size() && L[i].back().p == j)
          ans[L[i].back().id] -= val, L[i].pop_back();
        val += a[ed[j]];
        while (R[i].size() && R[i].back().p == j)
          ans[R[i].back().id] += val, R[i].pop_back();
      }
      memset(a, 0, sizeof a);
    }
  Dfs(1);
  for (long long i = 1; i <= n; i++) {
    for (auto j : ll[i]) {
      long long p = ed[j.p];
      while (p != 1) ans[j.id] -= ask(dfn[p]), p = fa[p];
    }
    add(dfn[ed[i]], 1), add(dfn[ed[i]] + siz[ed[i]], -1);
    for (auto j : rr[i]) {
      long long p = ed[j.p];
      while (p != 1) ans[j.id] += ask(dfn[p]), p = fa[p];
    }
  }
  for (long long i = 1; i <= m; i++) printf("%lld\n", ans[i]);
  return 0;
}
