#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9 + 333;
const long long linf = 1e18 + inf;
const int N = 1e5 + 5;
const int SQRT = 50;
int n, q, ptr;
char str[N];
string s[N];
long long ans[N];
int fin[N], fail[N], trie[N][26];
vector<int> v[N], ___ends[N];
int x[N], y[N], k[N];
vector<int> ord;
vector<int> qu[N];
void build() {
  for (int i = 1; i <= n; i++) {
    int x = 0;
    for (int j = 0; j < s[i].size(); j++) {
      int u = s[i][j];
      if (!trie[x][u]) {
        trie[x][u] = ++ptr;
      }
      x = trie[x][u];
    }
    fin[i] = x;
    ___ends[x].push_back(i);
  }
  ord.push_back(0);
  for (int it = 0; it < ord.size(); it++) {
    int x = ord[it];
    for (int i = 0; i < 26; i++) {
      if (trie[x][i]) {
        int u = trie[x][i];
        int q = fail[x];
        while (q and !trie[q][i]) {
          q = fail[q];
        }
        if (q != x and trie[q][i]) q = trie[q][i];
        v[q].push_back(u);
        fail[u] = q;
        ord.push_back(u);
      }
    }
  }
}
vector<pair<pair<int, int>, int> > sq[N];
void get(int l, int r, int x, int id) {
  int q = 0;
  for (int i = 0; i < s[x].size(); i++) {
    int u = s[x][i];
    while (q and !trie[q][u]) {
      q = fail[q];
    }
    if (trie[q][u]) q = trie[q][u];
    sq[q].push_back(make_pair(pair<int, int>(l, r), id));
  }
}
int fen[N];
void up(int x, int k) {
  for (; x < N; x += x & -x) fen[x] += k;
}
int get(int x, int y) {
  int res = 0;
  for (; y; y -= y & -y) res += fen[y];
  for (x--; x; x -= x & -x) res -= fen[x];
  return res;
}
void dfs(int x) {
  for (__typeof((___ends[x]).begin()) it = (___ends[x]).begin();
       it != (___ends[x]).end(); it++) {
    int u = *it;
    up(u, 1);
  }
  for (__typeof((sq[x]).begin()) it = (sq[x]).begin(); it != (sq[x]).end();
       it++) {
    int l = it->first.first;
    int r = it->first.second;
    int i = it->second;
    ans[i] += get(l, r);
  }
  for (__typeof((v[x]).begin()) it = (v[x]).begin(); it != (v[x]).end(); it++) {
    int u = *it;
    dfs(u);
  }
  for (__typeof((___ends[x]).begin()) it = (___ends[x]).begin();
       it != (___ends[x]).end(); it++) {
    int u = *it;
    up(u, -1);
  }
}
long long dp[N], cnt[N];
void solve(int x) {
  memset(dp, 0, sizeof(dp));
  memset(cnt, 0, sizeof(cnt));
  int q = 0;
  for (int i = 0; i < s[x].size(); i++) {
    int u = s[x][i];
    while (q and !trie[q][u]) {
      q = fail[q];
    }
    if (trie[q][u]) q = trie[q][u];
    cnt[q]++;
  }
  for (int i = (int)ord.size() - 1; i >= 0; i--) {
    int x = ord[i];
    cnt[fail[x]] += cnt[x];
  }
  for (int i = 1; i <= n; i++) {
    dp[i] = dp[i - 1] + cnt[fin[i]];
  }
  for (__typeof((qu[x]).begin()) it = (qu[x]).begin(); it != (qu[x]).end();
       it++) {
    int i = *it;
    int l = ::x[i];
    int r = ::y[i];
    ans[i] = dp[r] - dp[l - 1];
  }
}
int main() {
  scanf("%d %d", &n, &q);
  for (int i = 1; i <= n; i++) {
    scanf("%s", str);
    s[i] = str;
    for (int j = 0; j < s[i].size(); j++) s[i][j] -= 'a';
  }
  build();
  for (int i = 1; i <= q; i++) {
    scanf("%d %d %d", x + i, y + i, k + i);
    if (s[k[i]].size() <= SQRT) {
      get(x[i], y[i], k[i], i);
    } else {
      qu[k[i]].push_back(i);
    }
  }
  dfs(0);
  for (int i = 1; i <= n; i++) {
    if (qu[i].size()) {
      solve(i);
    }
  }
  for (int i = 1; i <= q; i++) {
    printf("%lld\n", ans[i]);
  }
  return 0;
}
