#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int MAX = 100005;
const int SQRT = 300;
int nxt[MAX][26], f[MAX], state[MAX], sz = 1;
int insert(string &s)
{
	int v = 0;
	for (int i = 0; i < (int)s.size(); i++)
	{
		if (nxt[v][s[i] - 'a'] == 0)
			nxt[v][s[i] - 'a'] = sz++;
		v = nxt[v][s[i] - 'a'];
	}
	return v;
}
int q[MAX];
void aho()
{
	int h = 0, t = 0;
	for (int i = 0; i < 26; i++)
		if (nxt[0][i])
			q[t++] = nxt[0][i];
	while (h < t)
	{
		int v = q[h++];
		for (int i = 0; i < 26; i++)
			if (nxt[v][i])
			{
				f[nxt[v][i]] = nxt[f[v]][i];
				q[t++] = nxt[v][i];
			}
			else
				nxt[v][i] = nxt[f[v]][i];
	}
}
vector<int> adj[MAX];
int st[MAX], fi[MAX], cnt;
void dfs(int v)
{
	st[v] = cnt++;
	for (int i = 0; i < (int)adj[v].size(); i++)
		dfs(adj[v][i]);
	fi[v] = cnt;
}
int fen[MAX];
void _add(int p, int val)
{
	for (; p > 0; p -= p & -p)
		fen[p] += val;
}
void add(int l, int r, int val)
{
	_add(r, val);
	_add(l, -val);
}
int get(int p)
{
	int ans = 0;
	for (p++; p < MAX; p += p & -p)
		ans += fen[p];
	return ans;
}
struct query
{
	int r, k, id, sign;
	query(int _r = 0, int _k = 0, int _id = 0, int _sign = 0)
	{
		r = _r;
		k = _k;
		id = _id;
		sign = _sign;
	}
} que[2 * MAX];
bool cmp(query x, query y)
{
	return (x.r < y.r);
}
vector<query> qq[MAX];
long long ps[MAX], ans[MAX];
int sum[MAX], n;
void pre(int v)
{
	for (int i = 0; i < (int)adj[v].size(); i++)
	{
		int u = adj[v][i];
		pre(u);
		sum[v] += sum[u];
	}
}
string s[MAX];
void solve(int id)
{
	memset(sum, 0, sizeof(sum));
	int v = 0;
	for (int i = 0; i < (int)s[id].size(); i++)
	{
		v = nxt[v][s[id][i] - 'a'];
		sum[v]++;
	}
	pre(0);
	for (int i = 0; i < n; i++)
		ps[i + 1] = ps[i] + sum[state[i]];
	for (int i = 0; i < (int)qq[id].size(); i++)
		ans[qq[id][i].id] += qq[id][i].sign * ps[qq[id][i].r];
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int q;
	cin >> n >> q;
	for (int i = 0; i < n; i++)
	{
		cin >> s[i];
		state[i] = insert(s[i]);
	}
	aho();
	for (int i = 1; i < sz; i++)
		adj[f[i]].push_back(i);
	dfs(0);
	sz = 0;
	for (int i = 0; i < q; i++)
	{
		int l, r, k;
		cin >> l >> r >> k;
		l--;
		k--;
		if (s[k].size() <= SQRT)
		{
			que[sz++] = query(r, k, i, 1);
			que[sz++] = query(l, k, i, -1);
		}
		else
		{
			qq[k].push_back(query(r, k, i, 1));
			qq[k].push_back(query(l, k, i, -1));
		}
	}
	for (int i = 0; i < n; i++)
		if (s[i].size() > SQRT)
			solve(i);
	sort(que, que + sz, cmp);
	int ptr = 0;
	for (int i = 0; i < sz; i++)
	{
		while (ptr < que[i].r)
		{
			add(st[state[ptr]], fi[state[ptr]], 1);
			ptr++;
		}
		int v = 0;
		for (int j = 0; j < (int)s[que[i].k].size(); j++)
		{
			v = nxt[v][s[que[i].k][j] - 'a'];
			ans[que[i].id] += que[i].sign * get(st[v]);
		}
	}
	for (int i = 0; i < q; i++)
		cout << ans[i] << "\n";
	return 0;
}
