#include <bits/stdc++.h>
using namespace std;
struct trie {
  static const int64_t sigma = 27;
  vector<int64_t> link, to[sigma], term, sum, cnt;
  int64_t sz = 0;
  int64_t add_state() {
    link.push_back(0);
    term.push_back(0);
    cnt.push_back(0);
    sum.push_back(0);
    for (int64_t c = 0; c < sigma; c++) to[c].push_back(0);
    return sz++;
  }
  trie() { add_state(); }
  int64_t add_str(string &s) {
    int64_t v = 0;
    for (auto c : s) {
      c -= 'a';
      if (!to[c][v]) {
        add_state();
        to[c][v] = sz - 1;
      }
      v = to[c][v];
    }
    term[v] = v;
    cnt[v]++;
    return v;
  }
  void push_links() {
    deque<int64_t> q(1, 0);
    while (!q.empty()) {
      int64_t v = q.front();
      q.pop_front();
      int64_t u = link[v];
      if (!term[v]) term[v] = term[u];
      cnt[v] += cnt[u];
      for (int64_t c = 0; c < sigma; c++) {
        if (to[c][v]) {
          link[to[c][v]] = v ? to[c][u] : 0;
          q.push_back(to[c][v]);
        } else {
          to[c][v] = to[c][u];
        }
      }
    }
  }
  vector<int64_t> clear_log;
  void feed(string &s) {
    for (auto it : clear_log) sum[it] = 0;
    clear_log.clear();
    int64_t v = 0;
    for (auto c : s) {
      c -= 'a';
      v = to[c][v];
      for (int64_t u = term[v]; u; u = term[link[u]]) {
        sum[u]++;
        clear_log.push_back(u);
      }
    }
  }
  int64_t ffeed(string &s) {
    int64_t v = 0;
    int64_t ret = 0;
    for (auto c : s) {
      c -= 'a';
      v = to[c][v];
      ret += cnt[v];
    }
    return ret;
  }
};
const int64_t root = 325;
const int64_t bc = 325;
trie all;
trie block[bc];
signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int64_t n, q;
  cin >> n >> q;
  string s[n];
  int64_t v[n];
  int64_t i = 0;
  for (int64_t z = 0; z < bc; z++) {
    for (int64_t j = 0; i < n && j < root; i++, j++) {
      cin >> s[i];
      v[i] = all.add_str(s[i]);
      block[z].add_str(s[i]);
    }
    block[z].push_links();
  }
  all.push_links();
  vector<int64_t> Q[n];
  int64_t l[q], r[q], k[q];
  for (int64_t i = 0; i < q; i++) {
    cin >> l[i] >> r[i] >> k[i];
    l[i]--, r[i]--, k[i]--;
    Q[k[i]].push_back(i);
  }
  int64_t ns[q];
  memset(ns, 0, sizeof(ns));
  for (int64_t i = 0; i < n; i++) {
    all.feed(s[i]);
    int64_t cnt_blocks[bc];
    memset(cnt_blocks, 0, sizeof(cnt_blocks));
    for (int64_t z = 0; z < bc; z++) cnt_blocks[z] = block[z].ffeed(s[i]);
    for (auto query : Q[i]) {
      int64_t L = l[query], R = r[query];
      int64_t Lb = L / root + 1, Rb = R / root - 1;
      int64_t ans = 0;
      for (int64_t z = Lb; z <= Rb; z++) ans += cnt_blocks[z];
      if (Lb <= Rb) {
        for (int64_t z = L; z < Lb * root; z++) ans += all.sum[v[z]];
        for (int64_t z = (Rb + 1) * root; z <= R; z++) ans += all.sum[v[z]];
      } else {
        for (int64_t z = L; z <= R; z++) ans += all.sum[v[z]];
      }
      ns[query] = ans;
    }
  }
  for (int64_t i = 0; i < q; i++) cout << ns[i] << "\n";
  return 0;
}
