#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
inline void smin(T &a, U b) {
  if (a > b) a = b;
}
template <typename T, typename U>
inline void smax(T &a, U b) {
  if (a < b) a = b;
}
int power(int a, int b, int m, int ans = 1) {
  for (; b; b >>= 1, a = 1LL * a * a % m)
    if (b & 1) ans = 1LL * ans * a % m;
  return ans;
}
char s[500010];
int l[12], r[12];
int sz, ed;
int cnt[500010], ord[500010 << 1];
struct node {
  int deep, fail, cnt, nxt[30], val[12];
  void clear() {
    memset(nxt, -1, sizeof nxt);
    memset(val, 0, sizeof val);
    deep = fail = cnt = 0;
  }
} mem[500010 << 1];
struct automaton {
  void init() {
    for (int i = 0; i < 26; i++) mem[0].nxt[i] = 1;
    mem[0].deep = -1;
    mem[1].clear();
    mem[1].cnt = 1;
    sz = 2, ed = 1;
  }
  void insert(int c, int id) {
    if (~mem[ed].nxt[c]) {
      int p1 = mem[ed].nxt[c];
      if (mem[p1].deep == mem[ed].deep + 1) {
        mem[p1].val[id]++;
        ed = p1;
        return;
      }
      int p2 = sz++;
      mem[p2] = mem[p1];
      mem[p2].deep = mem[ed].deep + 1;
      mem[p2].cnt = 0;
      for (int i = 0; i < 12; i++) mem[p2].val[i] = 0;
      mem[p2].val[id] = 1;
      mem[p1].fail = p2;
      while (mem[ed].nxt[c] == p1) {
        mem[ed].nxt[c] = p2;
        mem[p1].cnt -= mem[ed].cnt;
        mem[p2].cnt += mem[ed].cnt;
        ed = mem[ed].fail;
      }
      ed = p2;
      return;
    }
    int p = sz++;
    mem[p].clear();
    mem[p].deep = mem[ed].deep + 1;
    mem[p].val[id] = 1;
    while (mem[ed].nxt[c] == -1) {
      mem[ed].nxt[c] = p;
      mem[p].cnt += mem[ed].cnt;
      ed = mem[ed].fail;
    }
    int p1 = mem[ed].nxt[c];
    if (mem[p1].deep == mem[ed].deep + 1)
      mem[p].fail = p1;
    else {
      int p2 = sz++;
      mem[p2] = mem[p1];
      mem[p2].deep = mem[ed].deep + 1;
      mem[p2].cnt = 0;
      for (int i = 0; i < 12; i++) mem[p2].val[i] = 0;
      mem[p].fail = mem[p1].fail = p2;
      while (mem[ed].nxt[c] == p1) {
        mem[ed].nxt[c] = p2;
        mem[p1].cnt -= mem[ed].cnt;
        mem[p2].cnt += mem[ed].cnt;
        ed = mem[ed].fail;
      }
    }
    ed = p;
  }
  void build(int n) {
    memset(cnt, 0, sizeof cnt);
    for (int i = 1; i < sz; i++) cnt[mem[i].deep]++;
    for (int i = 1; i < 500010; i++) cnt[i] += cnt[i - 1];
    for (int i = 1; i < sz; i++) ord[--cnt[mem[i].deep]] = i;
    for (int i = sz - 2; i >= 0; i--) {
      int cur = ord[i], prv = mem[cur].fail;
      for (int j = 0; j <= n; j++) mem[prv].val[j] += mem[cur].val[j];
    }
    long long ans = 0;
    for (int i = 2; i < sz; i++)
      if (mem[i].val[n]) {
        int ok = 1;
        for (int j = 0; j < n; j++)
          if (mem[i].val[j] < l[j] || mem[i].val[j] > r[j]) {
            ok = 0;
            break;
          }
        if (ok) ans += mem[i].cnt;
      }
    printf("%I64d\n", ans);
  }
} sam;
int main() {
  int n;
  scanf("%s %d", s, &n);
  sam.init();
  int len = strlen(s);
  for (int i = 0; i < len; i++) sam.insert(s[i] - 'a', n);
  for (int i = 0; i < n; i++) {
    scanf("%s %d %d", s, l + i, r + i);
    ed = 1;
    len = strlen(s);
    for (int j = 0; j < len; j++) sam.insert(s[j] - 'a', i);
  }
  sam.build(n);
}
