#include <bits/stdc++.h>
using namespace std;
struct Node {
  int l, r, cnt[11], pardp;
  Node *par, *sLink;
  map<char, Node *> chd;
  bool isLeaf;
  Node() {
    l = r = pardp = 0;
    par = sLink = NULL;
    for (int i = 0; i < 11; i++) cnt[i] = 0;
    chd.clear();
    isLeaf = true;
  }
  int len() { return r - l; }
  int depth() { return pardp + len(); }
  bool inEdge(int pos) { return pos >= pardp && pos < depth(); }
  void setEdge(Node *child, int l, int r, char *S) {
    child->par = this;
    child->pardp = depth();
    chd[S[l]] = child;
    child->l = l, child->r = r;
    isLeaf = false;
  }
  void print(char *S) {
    for (int i = l; i < r; i++) putchar(S[i]);
    for (int i = 0; i < 11; i++) printf(" %d", cnt[i]);
    puts("");
  }
};
struct STree {
  Node *root, *needSLink, *cur;
  int jj, m, size, *p, N, *st, *en;
  long long ans;
  bool needWalk;
  vector<Node> nodes;
  char *S;
  STree(char *str, int pp[11], int sst[11], int een[11], int n) {
    p = pp, st = sst, en = een;
    N = n;
    m = strlen(str);
    ans = 0;
    S = str;
    nodes.reserve(m * 2 + 10);
    jj = 1, size = 0;
    root = newNode();
    cur = newNode();
    root->setEdge(cur, 0, m, S);
    needSLink = NULL;
    needWalk = true;
    for (int i = 0; i < m - 1; i++) extend(i);
  }
  Node *newNode() {
    nodes.push_back(Node());
    return &nodes[size++];
  }
  Node *walk_down(Node *c, int j, int i) {
    if (i - j + 1 > 0)
      for (int h = j + c->depth(); !c->inEdge(i - j); h += c->len())
        c = c->chd[S[h]];
    return c;
  }
  void addSLink(Node *c) {
    if (needSLink) needSLink->sLink = c;
    needSLink = NULL;
  }
  void extend(int i) {
    char c = S[i + 1];
    Node *leaf, *split;
    int k, pos;
    for (; jj <= i + 1; jj++) {
      if (needWalk) {
        if (!cur->sLink && cur->par) cur = cur->par;
        cur = (cur->sLink) ? cur->sLink : root;
        cur = walk_down(cur, jj, i);
      }
      needWalk = true;
      k = i + 1 - jj;
      if (cur->depth() == k) {
        addSLink(cur);
        if (cur->chd[c]) {
          cur = cur->chd[c];
          needWalk = false;
          break;
        } else {
          leaf = newNode();
          cur->setEdge(leaf, i + 1, m, S);
        }
      } else {
        pos = cur->l + k - cur->pardp;
        if (S[pos] == c) {
          addSLink(cur);
          needWalk = false;
          break;
        } else {
          leaf = newNode();
          split = newNode();
          cur->par->setEdge(split, cur->l, pos, S);
          split->setEdge(cur, pos, cur->r, S);
          split->setEdge(leaf, i + 1, m, S);
          addSLink(split);
          if (split->depth() == 1)
            split->sLink = root;
          else
            needSLink = split;
          cur = split;
        }
      }
    }
  }
  void print(Node *c, int dp = 0) {
    for (int i = 0; i < dp; i++) printf("\t");
    c->print(S);
    for (map<char, Node *>::iterator it = c->chd.begin(); it != c->chd.end();
         it++)
      print(it->second, dp + 1);
  }
  void mark(Node *c) {
    int i;
    if (c->isLeaf) {
      for (i = 0; i < N; i++)
        if (c->l <= p[i]) break;
      c->cnt[i] = 1;
    }
    for (map<char, Node *>::iterator it = c->chd.begin(); it != c->chd.end();
         it++) {
      mark(it->second);
      for (i = 0; i < N; i++) c->cnt[i] += it->second->cnt[i];
    }
  }
  void calc(Node *c) {
    for (map<char, Node *>::iterator it = c->chd.begin(); it != c->chd.end();
         it++)
      calc(it->second);
    int i, k;
    for (i = 0; i < N; i++)
      if (!(c->cnt[i] >= st[i] && c->cnt[i] <= en[i])) return;
    k = c->len();
    if (c->isLeaf) {
      for (i = 0; i < N; i++)
        if (c->l <= p[i]) break;
      k = p[i] - c->l;
    }
    ans += k;
  }
};
char str[11 * 50005], tmp[50005];
int Q, l[11], r[11], en[11];
int main() {
  int i;
  scanf("%s", str);
  scanf("%d", &Q);
  l[0] = 1, r[0] = 50005;
  for (i = 0; i < Q; i++) {
    scanf("%s", tmp);
    scanf("%d%d", l + i + 1, r + i + 1);
    en[i] = strlen(str);
    str[en[i]] = 'A' + i;
    strcat(str, tmp);
  }
  en[i] = strlen(str);
  str[en[i]] = 'A' + i;
  STree tree(str, en, l, r, Q + 1);
  tree.mark(tree.root);
  tree.calc(tree.root);
  cout << tree.ans << endl;
}
