#include <bits/stdc++.h>
using namespace std;
namespace p316GGoodSubstrings {
template <size_t MAXLEN, size_t ALPHABET>
struct SuffixAutomaton {
  struct Node {
    Node *child[ALPHABET], *suff, *next;
    int len, cnt;
  };
  Node pool[2 * MAXLEN], *root, *nextnode, *last, *first[MAXLEN + 1];
  Node* makenode(int length) {
    memset(nextnode, 0, sizeof(Node));
    nextnode->len = length;
    return nextnode++;
  }
  void init() {
    nextnode = pool;
    last = root = makenode(0);
    memset(first, 0, sizeof(first));
  }
  void extend(int ch) {
    Node *p = last, *cur = makenode(p->len + 1);
    cur->cnt = 1;
    for (; p != NULL && p->child[ch] == NULL; p = p->suff) p->child[ch] = cur;
    if (p == NULL)
      cur->suff = root;
    else {
      Node* q = p->child[ch];
      if (p->len + 1 == q->len)
        cur->suff = q;
      else {
        Node* copy = makenode(p->len + 1);
        memcpy(copy->child, q->child, sizeof(q->child));
        copy->suff = q->suff;
        q->suff = cur->suff = copy;
        for (; p != NULL && p->child[ch] == q; p = p->suff) p->child[ch] = copy;
      }
    }
    last = cur;
  }
  void go() {
    for (Node* i = pool; i < nextnode; i++) {
      i->next = first[i->len];
      first[i->len] = i;
    }
    for (int len = MAXLEN; len > 0; len--)
      for (Node* i = first[len]; i != NULL; i = i->next) i->suff->cnt += i->cnt;
  }
};
struct TNode {
  TNode* ch[26];
  bool bad;
  TNode() : bad(false) { memset(ch, 0, sizeof(ch)); }
};
SuffixAutomaton<55555, 26> sam;
TNode* root;
char str[55555];
int l, r, res = 0;
void go(TNode* at, SuffixAutomaton<55555, 26>::Node* cur) {
  int cnt = cur ? cur->cnt : 0;
  if (cnt < l || cnt > r) at->bad = true;
  for (int c = 0; c < 26; c++)
    if (at->ch[c] != NULL)
      go(at->ch[c], cur && cur->child[c] ? cur->child[c] : NULL);
}
void dfs(TNode* at) {
  if (!at->bad) res++;
  for (int c = 0; c < 26; c++)
    if (at->ch[c]) dfs(at->ch[c]);
}
void solve(int test_num) {
  root = new TNode();
  scanf("%s", str);
  int len = strlen(str);
  for (int i = 0; i < len; i++) {
    TNode* at = root;
    for (int j = i, c; j < len; j++) {
      c = str[j] - 'a';
      if (at->ch[c] == NULL) at->ch[c] = new TNode();
      at = at->ch[c];
    }
  }
  int cnt;
  scanf("%d", &cnt);
  for (int q = 0; q < cnt; q++) {
    scanf("%s %d %d", str, &l, &r);
    sam.init();
    for (int i = 0; str[i] > ' '; i++) sam.extend(str[i] - 'a');
    sam.go();
    go(root, sam.root);
  }
  dfs(root);
  if (!root->bad) res--;
  cout << res << endl;
}
void solve() { solve(1); }
}  // namespace p316GGoodSubstrings
int main() {
  p316GGoodSubstrings::solve();
  return 0;
}
