import java.io.*;
import java.util.Arrays;
import java.util.Locale;
import java.util.StringTokenizer;

public class TaskE {
    private final InputReader reader;
    private final OutputWriter writer;

    public TaskE(InputReader reader, OutputWriter writer) {
        this.reader = reader;
        this.writer = writer;
    }

    public static void main(String[] args) {
        InputReader reader = new InputReader(System.in);
        OutputWriter writer = new OutputWriter(System.out);
        new TaskE(reader, writer).run();
        writer.writer.flush();
    }

    int[] L;
    int[][] LT;
    int[] deg2;

    int lcp(int a, int b) {
        if (a > b) {
            int t = a;
            a = b;
            b = t;
        }
        if (a == b)
            throw new AssertionError();
        int k = deg2[b - a];
        return Math.min(LT[k][a], LT[k][b - (1 << k)]);
    }

    void buildSuffixArray(char[] S) {
        int n = S.length;
        int[] P, nP, eq, neq, cnt;
        P = new int[n];
        nP = new int[n];
        cnt = new int[Math.max(28, n)];
        eq = new int[n];
        neq = new int[n];
        for (int i = 0; i < n; i++)
            cnt[S[i] - 'a']++;
        for (int i = 1; i < 28; i++)
            cnt[i] += cnt[i - 1];
        for (int i = n - 1; i >= 0; i--) {
            P[--cnt[S[i] - 'a']] = i;
            eq[i] = S[i] - 'a';
        }
        int mx = 28;
        for (int k = 1; k < n && (k == 1 || mx != n); k <<= 1) {
            for (int i = 0; i < n; i++)
                P[i] = (P[i] >= k) ? P[i] - k : P[i] - k + n;
            Arrays.fill(cnt, 0);
            for (int i = 0; i < n; i++)
                cnt[eq[P[i]]]++;
            for (int i = 1; i < mx; i++)
                cnt[i] += cnt[i - 1];
            for (int i = n - 1; i >= 0; i--)
                nP[--cnt[eq[P[i]]]] = P[i];
            neq[nP[0]] = 0;
            for (int i = 1; i < n; i++)
                neq[nP[i]] = neq[nP[i - 1]] + ((eq[nP[i]] != eq[nP[i - 1]] ||
                                                eq[(nP[i] + k < n) ? nP[i] + k : nP[i] + k - n] !=
                                                eq[(nP[i - 1] + k < n) ? nP[i - 1] + k : nP[i - 1] + k - n]) ? 1 : 0);
            mx = neq[nP[n - 1]] + 1;
            for (int i = 0; i < n; i++) {
                P[i] = nP[i];
                eq[i] = neq[i];
            }
        }
        L =  new int[n];
        int[] IP = new int[n];
        for (int i = 0; i < n; i++)
            IP[P[i]] = i;
        int cur = 0;
        for (int i = 0; i < n; i++) {
            if (IP[i] + 1 != n) {
                int a = i, b = P[IP[i] + 1];
                while (S[a + cur] == S[b + cur])
                    cur++;
                L[IP[a]] = cur;
            }
            cur = Math.max(cur - 1, 0);
        }
        deg2 = new int[n + 1];
        deg2[0] = -42;
        deg2[1] = 0;
        for (int i = 2; i <= n; i++)
            deg2[i] = 1 + deg2[i >> 1];
        LT = new int[deg2[n] + 1][n];
        for (int i = 0; i < n; i++)
            LT[0][i] = L[i];
        for (int l = 1; l <= deg2[n]; l++)
            for (int i = 0; i + (1 << l) <= n; i++)
                LT[l][i] = Math.min(LT[l - 1][i], LT[l - 1][i + (1 << (l - 1))]);
        SA = P;
        ISA = IP;
    }

    class Event implements Comparable<Event> {
        int t;
        int id;
        int a, b;
        Event(int t, int id, int a, int b) {
            this.t = t;
            this.a = a;
            this.b = b;
            this.id = id;
        }
        @Override
        public int compareTo(Event other) {
            return Integer.compare(this.t, other.t);
        }
    }

    int[] SA, ISA;
    int[] beg;
    int[] len;
    int[] color;
    Event[] E;
    int ept = 0;

    void addQuery(int a, int b, int k, int id) {
        int ln = len[k];
        k = ISA[beg[k]];
        int l = -1, r = k;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (lcp(m, k) < ln)
                l = m;
            else
                r = m;
        }
        int L = r;
        l = k;
        r = SA.length;
        while (r - l > 1) {
            int m = (l + r) / 2;
            if (lcp(k, m) < ln)
                r = m;
            else
                l = m;
        }
        int R = l;
        E[ept++] = new Event(L - 1, ~id, a, b);
        E[ept++] = new Event(R, id, a, b);
    }

    int[] F;
    void inc(int x) {
        for(; x < F.length; x |= x + 1)
            F[x]++;
    }

    int get(int x) {
        int ans = 0;
        for (; x >= 0; x &= x + 1, --x)
            ans += F[x];
        return ans;
    }

    public void run() {
        int n = reader.nextInt();
        int q = reader.nextInt();
        char[] S = new char[1000 * 1000 + 42];
        beg = new int[n];
        len = new int[n];
        int pt = 0;
        for (int i = 0; i < n; i++) {
            char[] T = reader.next().toCharArray();
            len[i] = T.length;
            beg[i] = pt;
            for (int j = 0; j < T.length; j++) {
                S[pt + j] = T[j];
            }
            pt += T.length;
            S[pt++] = 'z' + 1;
        }
        S[pt++] = 'z' + 2;
        S = Arrays.copyOf(S, pt);
        color = new int[pt];
        pt = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < len[i]; j++)
                color[pt + j] = i;
            pt += len[i] + 1;
        }

        buildSuffixArray(S);
        /*for (int i = 0; i < pt; i++)
            writer.printf("%2d %2d %s\n", SA[i], L[i], String.valueOf(S, SA[i], pt - SA[i]));
        writer.printf("\n");
        writer.writer.flush();*/


        E = new Event[2 * q];
        for (int i = 0; i < q; i++) {
            int l = reader.nextInt() - 1;
            int r = reader.nextInt() - 1;
            int k = reader.nextInt() - 1;
            addQuery(l, r, k, i);
        }
        Arrays.sort(E);
        F = new int[n];
        int[] ans = new int[q];
        int cpt = 0;
        for (Event e : E) {
            while (cpt <= e.t) {
                inc(color[SA[cpt]]);
                cpt++;
            }
            int id = e.id;
            int mul = (id >= 0) ? 1 : -1;
            id = (id >= 0) ? id : ~id;
            int a = e.a;
            int b = e.b;
            ans[id] += mul * (get(b) - get(a - 1));
        }
        for (int a : ans)
            writer.printf("%d\n", a);
    }


    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }
    }

    static class OutputWriter {
        public PrintWriter writer;

        OutputWriter(OutputStream stream) {
            writer = new PrintWriter(stream);
        }

        public void printf(String format, Object... args) {
            writer.print(String.format(Locale.ENGLISH, format, args));
        }
    }
}

