package main
import (
"bufio"
"os"
"strconv"
)
type TrieNode struct {
child [26]int
fail int
}
type Query struct {
l, r, k, idx int
}
type LightQuery struct {
idx int
sign int
k int
}
func readWord(r *bufio.Reader) string {
var res []byte
for {
b, err := r.ReadByte()
if err != nil {
break
}
if b > ' ' {
res = append(res, b)
break
}
}
if len(res) == 0 {
return ""
}
for {
b, err := r.ReadByte()
if err != nil {
break
}
if b <= ' ' {
break
}
res = append(res, b)
}
return string(res)
}
func nextInt(r *bufio.Reader) int {
res := 0
sign := 1
for {
b, err := r.ReadByte()
if err != nil {
break
}
if b == '-' {
sign = -1
break
}
if b >= '0' && b <= '9' {
res = int(b - '0')
break
}
}
for {
b, err := r.ReadByte()
if err != nil || b < '0' || b > '9' {
break
}
res = res*10 + int(b-'0')
}
return res * sign
}
func main() {
reader := bufio.NewReaderSize(os.Stdin, 65536)
n := nextInt(reader)
if n == 0 {
return
}
q := nextInt(reader)
strs := make([]string, n+1)
pos := make([]int, n+1)
nodes := make([]TrieNode, 1, 100005)
for i := 1; i <= n; i++ {
strs[i] = readWord(reader)
u := 0
s := strs[i]
for j := 0; j < len(s); j++ {
c := s[j] - 'a'
if nodes[u].child[c] == 0 {
nodes[u].child[c] = len(nodes)
nodes = append(nodes, TrieNode{})
}
u = nodes[u].child[c]
}
pos[i] = u
}
queue := make([]int, 0, len(nodes))
for c := 0; c < 26; c++ {
if nodes[0].child[c] != 0 {
queue = append(queue, nodes[0].child[c])
}
}
for i := 0; i < len(queue); i++ {
u := queue[i]
for c := 0; c < 26; c++ {
v := nodes[u].child[c]
if v != 0 {
nodes[v].fail = nodes[nodes[u].fail].child[c]
queue = append(queue, v)
} else {
nodes[u].child[c] = nodes[nodes[u].fail].child[c]
}
}
}
failAdj := make([][]int, len(nodes))
for i := 1; i < len(nodes); i++ {
failAdj[nodes[i].fail] = append(failAdj[nodes[i].fail], i)
}
in := make([]int, len(nodes))
out := make([]int, len(nodes))
postOrder := make([]int, 0, len(nodes))
timer := 1
var dfs func(int)
dfs = func(u int) {
in[u] = timer
timer++
for _, v := range failAdj[u] {
dfs(v)
}
out[u] = timer
postOrder = append(postOrder, u)
}
dfs(0)
const B = 316
heavyQueries := make(map[int][]Query)
lightQueries := make([][]LightQuery, n+1)
for i := 0; i < q; i++ {
l := nextInt(reader)
r := nextInt(reader)
k := nextInt(reader)
if len(strs[k]) > B {
heavyQueries[k] = append(heavyQueries[k], Query{l, r, k, i})
} else {
lightQueries[r] = append(lightQueries[r], LightQuery{i, 1, k})
lightQueries[l-1] = append(lightQueries[l-1], LightQuery{i, -1, k})
}
}
ans := make([]int64, q)
count := make([]int64, len(nodes))
pref := make([]int64, n+1)
for k, queries := range heavyQueries {
for i := range count {
count[i] = 0
}
u := 0
s := strs[k]
for j := 0; j < len(s); j++ {
u = nodes[u].child[s[j]-'a']
count[u]++
}
for _, u := range postOrder {
if u != 0 {
count[nodes[u].fail] += count[u]
}
}
for i := 1; i <= n; i++ {
pref[i] = pref[i-1] + count[pos[i]]
}
for _, q := range queries {
ans[q.idx] = pref[q.r] - pref[q.l-1]
}
}
bit := make([]int64, len(nodes)+2)
add := func(idx int, val int64) {
for ; idx < len(bit); idx += idx & -idx {
bit[idx] += val
}
}
query := func(idx int) int64 {
var sum int64 = 0
for ; idx > 0; idx -= idx & -idx {
sum += bit[idx]
}
return sum
}
for i := 0; i <= n; i++ {
if i > 0 {
u := pos[i]
add(in[u], 1)
add(out[u], -1)
}
for _, lq := range lightQueries[i] {
var sum int64 = 0
u := 0
s := strs[lq.k]
for j := 0; j < len(s); j++ {
u = nodes[u].child[s[j]-'a']
sum += query(in[u])
}
if lq.sign == 1 {
ans[lq.idx] += sum
} else {
ans[lq.idx] -= sum
}
}
}
outWriter := bufio.NewWriter(os.Stdout)
for i := 0; i < q; i++ {
outWriter.WriteString(strconv.FormatInt(ans[i], 10))
outWriter.WriteByte('\n')
}
outWriter.Flush()
}