#include <bits/stdc++.h>
using namespace std;
bool debug = 0;
int n, m, k;
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
long long ln, lk, lm;
const int maxn = 100105;
vector<int> ed[maxn], v[maxn];
int endPos[100105];
vector<int> mp[maxn];
struct Aca {
  int next[maxn][26], fail[maxn];
  int root, L;
  int newNode() {
    for (int i = 0; i < 26; i++) next[L][i] = -1;
    L++;
    return L - 1;
  }
  void init() {
    L = 0;
    root = newNode();
  }
  void insert(string &str, int id) {
    int now = root;
    int len = str.length();
    for (int i = 0; i < len; i++) {
      int temp = str[i] - 'a';
      if (next[now][temp] == -1) {
        next[now][temp] = newNode();
      }
      now = next[now][temp];
      v[now].push_back(id);
    }
    ed[now].push_back(id);
    endPos[id] = now;
  }
  void build() {
    queue<int> que;
    fail[root] = root;
    for (int i = 0; i < 26; i++) {
      if (next[root][i] == -1) {
        next[root][i] = root;
      } else {
        fail[next[root][i]] = root;
        mp[root].push_back(next[root][i]);
        que.push(next[root][i]);
      }
    }
    while (!que.empty()) {
      int now = que.front();
      que.pop();
      for (int i = 0; i < 26; i++) {
        int t = next[now][i];
        if (t == -1) {
          next[now][i] = next[fail[now]][i];
        } else {
          fail[t] = next[fail[now]][i];
          mp[next[fail[now]][i]].push_back(t);
          que.push(t);
        }
      }
    }
  }
} ac;
string s[100105];
int Len, GL;
struct qy {
  int l, r, id;
};
vector<qy> q[100105];
long long ps[100105], Ans[100105];
int dfs(int x, int id) {
  int cnt = 0;
  for (int pass : v[x])
    if (pass == id) cnt++;
  for (int c : mp[x]) cnt += dfs(c, id);
  for (int z : ed[x]) ps[z] = cnt;
  return cnt;
}
void cal(int id) {
  dfs(ac.root, id);
  for (int i = 2; i <= n; i++) ps[i] += ps[i - 1];
}
int b[100105];
void update(int x, int v) {
  for (int i = x; i <= n; i += i & -i) {
    b[i] += v;
  }
}
int query(int x) {
  int ret = 0;
  for (; x > 0; ret += b[x], x -= x & -x)
    ;
  return ret;
}
void dfs2(int x) {
  for (int z : ed[x]) update(z, 1);
  for (int pass : v[x])
    if (s[pass].size() < GL) {
      for (qy uz : q[pass]) {
        Ans[uz.id] += query(uz.r) - query(uz.l - 1);
      }
    }
  for (int c : mp[x]) dfs2(c);
  for (int z : ed[x]) update(z, -1);
}
void fmain() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  ac.init();
  for (int(i) = 1; (i) <= (int)(n); (i)++) {
    cin >> s[i];
    Len += s[i].size();
    ac.insert(s[i], i);
  }
  ac.build();
  GL = sqrt(Len);
  for (int(i) = 1; (i) <= (int)(m); (i)++) {
    int l, r;
    cin >> l >> r >> k;
    q[k].push_back({l, r, i});
  }
  for (int(i) = 1; (i) <= (int)(n); (i)++)
    if (!q[i].empty()) {
      if (s[i].length() >= GL) {
        cal(i);
        for (qy uz : q[i]) {
          Ans[uz.id] = ps[uz.r] - ps[uz.l - 1];
        }
      }
    }
  dfs2(ac.root);
  for (int(i) = 1; (i) <= (int)(m); (i)++) printf("%lld\n", Ans[i]);
}
int main() {
  fmain();
  return 0;
}
