#include <bits/stdc++.h>
using namespace std;
struct CNode {
  char c;
  int isOk;
  CNode* child;
  CNode* sib;
};
void addNode(CNode* node, const string& s, int pos, int isOk, bool canAdd) {
  if (pos == s.size()) {
    if (node->isOk) {
      node->isOk = isOk;
    }
    return;
  }
  if (node->child == 0) {
    if (!canAdd) {
      return;
    }
    node->child = new CNode;
    CNode* child = node->child;
    child->c = s[pos];
    child->child = 0;
    child->sib = 0;
    child->isOk = isOk;
    assert(pos + 1 == s.size());
    addNode(child, s, pos + 1, isOk, canAdd);
    return;
  }
  CNode* child = node->child;
  while (true) {
    if (child->c == s[pos]) {
      addNode(child, s, pos + 1, isOk, canAdd);
      return;
    }
    if (child->sib == 0) {
      break;
    }
    child = child->sib;
  }
  if (!canAdd) {
    return;
  }
  child->sib = new CNode;
  child = child->sib;
  child->c = s[pos];
  child->child = 0;
  child->sib = 0;
  child->isOk = isOk;
  assert(pos + 1 == s.size());
  addNode(child, s, pos + 1, isOk, canAdd);
}
CNode* find(CNode* node, const string& s, int pos) {
  if (pos == s.size()) {
    return node;
  }
  CNode* child = node->child;
  while (child) {
    if (child->c == s[pos]) {
      return find(child, s, pos + 1);
    }
    child = child->sib;
  }
  return 0;
}
void walk(CNode* node, int isOk) {
  if (!node) {
    return;
  }
  if (node->isOk < isOk) {
    node->isOk = 0;
  }
  CNode* child = node->child;
  while (child) {
    walk(child, isOk);
    child = child->sib;
  }
}
int main() {
  string s;
  while (cin >> s) {
    int n;
    cin >> n;
    CNode root;
    root.child = 0;
    root.sib = 0;
    bool canNull = true;
    for (int k = 0; k < n; k++) {
      string ps;
      cin >> ps;
      int l, r;
      cin >> l >> r;
      map<string, int> scount;
      for (int i = 0; i < ps.size(); i++) {
        for (int j = 1; j + i <= ps.size(); j++) {
          string subs = ps.substr(i, j);
          if (scount.find(subs) != scount.end()) {
            scount[subs]++;
          } else {
            scount[subs] = 1;
          }
        }
      }
      map<string, int>::iterator it;
      for (it = scount.begin(); it != scount.end(); it++) {
        const bool isOk = (it->second >= l) && (it->second <= r);
        addNode(&root, it->first, 0, isOk ? k + 1 : 0, canNull);
      }
      canNull &= (l == 0);
      if (l > 0) {
        walk(&root, k + 1);
      }
    }
    set<string> sSet;
    int ans = 0;
    for (int i = 0; i < s.size(); i++) {
      for (int j = 1; j + i <= s.size(); j++) {
        string subs = s.substr(i, j);
        sSet.insert(subs);
      }
    }
    set<string>::iterator it;
    for (it = sSet.begin(); it != sSet.end(); it++) {
      CNode* node = find(&root, *it, 0);
      if (node != 0) {
      }
      if (node == 0 && canNull) {
        ans++;
      } else if (node != 0 && node->isOk) {
        ans++;
      }
    }
    cout << ans << endl;
  }
  return 0;
}
