#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;   }