#include <bits/stdc++.h>
using namespace std;
const int N = 50010;
struct EXSAM_node {
  EXSAM_node *next[26], *pre;
  int step;
  int bel;
  int size;
  int visit;
  int cnt[11];
  void clear() {
    pre = NULL;
    step = 0;
    size = 0;
    visit = 0;
    memset(next, 0, sizeof(next));
  }
};
EXSAM_node EXSAM_Pool[N * 2];
EXSAM_node *EXpool[N * 2];
long d[N * 2];
struct EXSAM {
  EXSAM_node *root, *last;
  EXSAM_node *cur;
  void init() {
    cur = EXSAM_Pool;
    root = last = cur++;
    root->clear();
    root->visit = 0;
  }
  void Insert(int w, int i) {
    EXSAM_node *p = last;
    if (p->next[w] && p->next[w]->step == p->step + 1) {
      last = p->next[w];
      last->cnt[i]++;
      last->size++;
      return;
    }
    EXSAM_node *np = cur++;
    np->clear();
    np->step = p->step + 1;
    while (p && !p->next[w]) {
      p->next[w] = np, p = p->pre;
    }
    if (p == 0)
      np->pre = root;
    else {
      EXSAM_node *q = p->next[w];
      if (p->step + 1 == q->step)
        np->pre = q;
      else {
        EXSAM_node *nq = cur++;
        nq->clear();
        nq->step = p->step + 1;
        memcpy(nq->next, q->next, sizeof(q->next));
        nq->pre = q->pre;
        q->pre = nq;
        np->pre = nq;
        while (p && p->next[w] == q) {
          p->next[w] = nq, p = p->pre;
        }
      }
    }
    last = np;
    last->cnt[i] = 1;
    last->size++;
  }
  void topo() {
    int cnt = cur - EXSAM_Pool;
    int maxVal = 0;
    memset(d, 0, sizeof(d));
    for (int i = 1; i < cnt; i++) {
      maxVal = max(maxVal, EXSAM_Pool[i].step), d[EXSAM_Pool[i].step]++;
    }
    for (int i = 1; i <= maxVal; i++) d[i] += d[i - 1];
    for (int i = 1; i < cnt; i++)
      EXpool[d[EXSAM_Pool[i].step]--] = &EXSAM_Pool[i];
    EXpool[0] = root;
  }
};
pair<int, int> LR[15];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  string str1, str2;
  int a, b, c;
  EXSAM part;
  part.init();
  cin >> str1;
  for (int i = 0; i < str1.size(); ++i) part.Insert(str1[i] - 'a', 0);
  part.last = part.root;
  cin >> c;
  for (int i = 1; i <= c; ++i) {
    cin >> str2 >> LR[i].first >> LR[i].second;
    for (auto s : str2) part.Insert(s - 'a', i);
    part.last = part.root;
  }
  part.topo();
  int cnt = part.cur - EXSAM_Pool;
  for (int i = cnt - 1; i > 0; --i)
    for (int j = 0; j <= c; ++j) EXpool[i]->pre->cnt[j] += EXpool[i]->cnt[j];
  long long ans = 0;
  bool flag = 0;
  for (int i = cnt - 1; i > 0; --i) {
    flag = 0;
    for (int j = 1; j <= c; ++j)
      if (EXpool[i]->cnt[j] < LR[j].first || EXpool[i]->cnt[j] > LR[j].second)
        flag = 1;
    if (flag == 0 && EXpool[i]->cnt[0] > 0)
      ans += EXpool[i]->step - EXpool[i]->pre->step;
  }
  cout << ans << endl;
}
