#include <bits/stdc++.h>
using namespace std;
const int N = 300010;
int read() {
  int x = 0, f = 1;
  char c = getchar();
  while (c > '9' || c < '0') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  return x * f;
}
int n, m, ch[N][26], fail[N], cnt, block = 420, pos[N];
long long bk[N];
vector<int> book[N];
string S[N];
long long ans[N];
void insert(int i) {
  int len = S[i].size();
  int now = 0;
  for (int j = 0; j < len; ++j) {
    int x = S[i][j] - 'a';
    if (!ch[now][x]) ch[now][x] = ++cnt;
    now = ch[now][x];
  }
  pos[i] = now;
  book[now].push_back(i);
}
queue<int> q;
void LesAC() {
  for (int i = 0; i < 26; ++i)
    if (ch[0][i]) q.push(ch[0][i]);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = 0; i < 26; ++i) {
      if (ch[u][i]) {
        fail[ch[u][i]] = ch[fail[u]][i];
        q.push(ch[u][i]);
      } else
        ch[u][i] = ch[fail[u]][i];
    }
  }
}
struct Edge {
  int v, nxt;
} e[N];
int head[N], size;
void link(int u, int v) {
  e[++size].v = v;
  e[size].nxt = head[u];
  head[u] = size;
}
long long sze[N], res, t[N];
struct Node {
  int x, y;
};
vector<Node> Q[N], Q1[N];
void add(int i, int k) {
  for (; i < N; i += (i & -i)) t[i] += k;
}
long long query(int i) {
  long long res = 0;
  for (; i > 0; i -= (i & -i)) res += t[i];
  return res;
}
void dfs(int u, int flag) {
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].v;
    dfs(v, flag);
    if (~flag) sze[u] += sze[v];
  }
  for (int i = book[u].size() - 1; i >= 0; --i) add(book[u][i], flag * sze[u]);
  if (flag == -1) sze[u] = 0;
}
int work(int m) {
  res = 0;
  int len = S[m].size();
  int now = 0;
  for (int i = 0; i < len; ++i) {
    now = ch[now][S[m][i] - 'a'];
    sze[now] = 1;
  }
  dfs(0, 1);
  for (int i = Q[m].size() - 1; i >= 0; --i) {
    if (Q[m][i].x < 0)
      ans[Q[m][i].y] -= query(-Q[m][i].x);
    else
      ans[Q[m][i].y] += query(Q[m][i].x);
  }
  dfs(0, -1);
  return res;
}
int work1(int m) {
  res = 0;
  int len = S[m].size();
  int now = 0;
  for (int i = 0; i < len; ++i) {
    now = ch[now][S[m][i] - 'a'];
    for (int j = now; j; j = fail[j]) res += bk[j];
  }
  return res;
}
int main() {
  n = read();
  m = read();
  for (int i = 1; i <= n; ++i) {
    cin >> S[i];
    insert(i);
  }
  LesAC();
  for (int i = 1; i <= cnt; ++i) link(fail[i], i);
  for (int i = 1; i <= m; ++i) {
    int l = read(), r = read(), k = read();
    if (S[k].size() > block) {
      Q[k].push_back((Node){-l + 1, i});
      Q[k].push_back((Node){r, i});
    } else {
      Q1[l - 1].push_back((Node){-k, i});
      Q1[r].push_back((Node){k, i});
    }
  }
  for (int i = 0; i <= n; ++i) {
    ++bk[pos[i]];
    for (int j = Q1[i].size() - 1; j >= 0; --j) {
      if (Q1[i][j].x < 0)
        ans[Q1[i][j].y] -= work1(-Q1[i][j].x);
      else
        ans[Q1[i][j].y] += work1(Q1[i][j].x);
    }
  }
  for (int i = 1; i <= n; ++i)
    if (!Q[i].empty()) work(i);
  for (int i = 1; i <= m; ++i) printf("%lld\n", ans[i]);
  return 0;
}
