#include <bits/stdc++.h>
using namespace std;
struct Aho {
  struct vertex {
    vector<int> next, go;
    int p, link;
    char pch;
    int leaf;
    vertex(int p = -1, char pch = -1)
        : next(26, -1), go(26, -1), p(p), pch(pch), link(-1), leaf(0) {}
  };
  struct STree {
    vector<int> t;
    int n;
    STree() {}
    STree(int n) : n(n), t(2 * n + 5, 0) {}
    void upd(int p, int value) {
      for (t[p += n] += value; p > 1; p >>= 1) t[p >> 1] = (t[p] + t[p ^ 1]);
    }
    int query(int l, int r) {
      int res = 0;
      for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
        if (l & 1) res = (res + t[l++]);
        if (r & 1) res = (res + t[--r]);
      }
      return res;
    }
  };
  vector<vertex> t;
  Aho() { t.push_back(vertex()); }
  int add_string(string &s) {
    int v = 0;
    for (char c : s) {
      if (t[v].next[c - 'a'] < 0) {
        t[v].next[c - 'a'] = t.size();
        t.push_back(vertex(v, c));
      }
      v = t[v].next[c - 'a'];
    }
    t[v].leaf++;
    return v;
  }
  int get_link(int v) {
    if (t[v].link < 0)
      if (!v || !t[v].p)
        t[v].link = 0;
      else
        t[v].link = go(get_link(t[v].p), t[v].pch);
    return t[v].link;
  }
  int go(int v, char c) {
    if (t[v].go[c - 'a'] < 0)
      if (t[v].next[c - 'a'] >= 0)
        t[v].go[c - 'a'] = t[v].next[c - 'a'];
      else
        t[v].go[c - 'a'] = v == 0 ? 0 : go(get_link(v), c);
    return t[v].go[c - 'a'];
  }
  vector<int> dp, tim, sz;
  vector<vector<int>> g;
  int id;
  STree st;
  int solve(int pos) {
    int &r = dp[pos];
    if (r >= 0) return r;
    r = t[pos].leaf;
    if (pos) r += solve(get_link(pos));
    return r;
  }
  int dfs(int pos) {
    tim[pos] = id++;
    sz[pos] = 1;
    for (auto x : g[pos]) sz[pos] += dfs(x);
    return sz[pos];
  }
  void prec() {
    id = 0;
    dp.resize(int(t.size()), -1);
    tim.resize(int(t.size()));
    sz.resize(int(t.size()));
    g.resize(int(t.size()));
    for (int i = 1, ThxDem = int(t.size()); i < ThxDem; ++i) {
      g[get_link(i)].push_back(i);
    }
    dfs(0);
    st = STree(int(t.size()));
  }
  int get(string &s) {
    int now = 0, ans = 0;
    for (auto x : s) {
      now = go(now, x);
      ans += solve(now);
    }
    return ans;
  }
  void push(string &s) {
    if (!int(t.size())) return;
    int now = 0;
    for (auto x : s) {
      now = go(now, x);
      st.upd(tim[now], 1);
    }
  }
  void clean(string &s) {
    if (!int(t.size())) return;
    int now = 0;
    for (auto x : s) {
      now = go(now, x);
      st.upd(tim[now], -1);
    }
  }
};
const int MAGIC = 320;
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n, q;
  cin >> n >> q;
  vector<string> s(n);
  vector<vector<pair<pair<int, int>, int>>> ops(n);
  for (int i = 0, ThxDem = n; i < ThxDem; ++i) cin >> s[i];
  for (int i = 0, ThxDem = q; i < ThxDem; ++i) {
    int l, r, k;
    cin >> l >> r >> k;
    l--;
    r--;
    k--;
    ops[k].push_back({{l, r}, i});
  }
  vector<pair<int, int>> wh(n);
  int tot = (n + MAGIC - 1) / MAGIC;
  vector<Aho> my(tot);
  for (int i = 0, ThxDem = n; i < ThxDem; ++i) {
    wh[i] = {i / MAGIC, my[i / MAGIC].add_string(s[i])};
  }
  for (int i = 0, ThxDem = tot; i < ThxDem; ++i) my[i].prec();
  vector<long long> ans(q);
  for (int i = 0, ThxDem = n; i < ThxDem; ++i) {
    vector<int> ne;
    vector<int> in(tot);
    for (auto x : ops[i]) {
      int l = x.first.first, r = x.first.second, id = x.second;
      ne.push_back(r / MAGIC);
      if (l) ne.push_back((l - 1) / MAGIC);
    }
    sort(ne.begin(), ne.end());
    ne.erase(unique(ne.begin(), ne.end()), ne.end());
    for (auto x : ne) my[x].push(s[i]);
    for (int j = 0, ThxDem = tot; j < ThxDem; ++j) in[j] = my[j].get(s[i]);
    for (auto x : ops[i]) {
      int l = x.first.first, r = x.first.second, id = x.second;
      int en = r / MAGIC;
      for (int x = 0, ThxDem = en; x < ThxDem; ++x) ans[id] += in[x];
      for (int j = en * MAGIC, ThxDem = r + 1; j < ThxDem; ++j) {
        int tt = my[wh[j].first].tim[wh[j].second];
        int zz = my[wh[j].first].sz[wh[j].second];
        ans[id] += my[wh[j].first].st.query(tt, tt + zz);
      }
      if (l) {
        en = (l - 1) / MAGIC;
        for (int x = 0, ThxDem = en; x < ThxDem; ++x) ans[id] -= in[x];
        for (int j = en * MAGIC, ThxDem = l; j < ThxDem; ++j) {
          int tt = my[wh[j].first].tim[wh[j].second];
          int zz = my[wh[j].first].sz[wh[j].second];
          ans[id] -= my[wh[j].first].st.query(tt, tt + zz);
        }
      }
    }
    for (auto x : ne) my[x].clean(s[i]);
  }
  for (int i = 0, ThxDem = q; i < ThxDem; ++i) cout << ans[i] << "\n";
}
