#include <bits/stdc++.h>
using namespace std;
struct SuffixAutomaton {
  SuffixAutomaton(const string& s) {
    t.push_back(node());
    last = 0;
    for (int i = 0; i < (int)(s).size(); ++i) {
      add(s[i]);
    }
    vector<int> order;
    for (int v = 0; v < (int)(t).size(); ++v) {
      order.push_back(v);
    }
    sort((order).begin(), (order).end(),
         [&](int u, int v) { return t[u].len < t[v].len; });
    reverse((order).begin(), (order).end());
    int tmp = order[0];
    ++t[tmp].num;
    ++t[tmp].sum;
    while (true) {
      tmp = t[tmp].link;
      if (tmp == -1) {
        break;
      }
      ++t[tmp].num;
      ++t[tmp].sum;
    }
    for (int v : order) {
      for (auto it : t[v].to) {
        t[v].num += t[it.second].num;
      }
    }
    for (int v : order) {
      for (auto it : t[v].to) {
        t[v].sum += t[it.second].sum + t[it.second].num;
      }
    }
  }
  struct node {
    int link;
    int len;
    map<char, int> to;
    int num;
    long long sum;
    int firstpos;
    int lastpos;
    node() : link(-1), len(0), num(0), sum(0) {}
  };
  vector<node> t;
  int last;
  void add(char c) {
    int curr = (int)(t).size();
    t.push_back(node());
    t[curr].len = t[last].len + 1;
    t[curr].firstpos = t[curr].lastpos = t[last].len;
    int p = last;
    while (p != -1 && !t[p].to.count(c)) {
      t[p].to[c] = curr;
      p = t[p].link;
    }
    if (p == -1) {
      t[curr].link = 0;
      last = curr;
      return;
    }
    int q = t[p].to[c];
    if (t[q].len == t[p].len + 1) {
      t[curr].link = q;
      last = curr;
      return;
    }
    int clone = (int)(t).size();
    t.push_back(node());
    t[clone].len = t[p].len + 1;
    t[clone].firstpos = t[q].firstpos;
    t[q].lastpos = t[last].len;
    t[clone].link = t[q].link;
    t[clone].to = t[q].to;
    t[curr].link = clone;
    t[q].link = clone;
    last = curr;
    while (p != -1 && t[p].to[c] == q) {
      t[p].to[c] = clone;
      p = t[p].link;
    }
  }
};
const int magic = 10;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  string s;
  cin >> s;
  int q;
  cin >> q;
  vector<string> p(q);
  vector<int> lf(q), rg(q);
  for (int i = 0; i < q; ++i) {
    cin >> p[i] >> lf[i] >> rg[i];
  }
  string str = s;
  str += char(magic);
  for (int i = 0; i < q; ++i) {
    str += p[i];
    str += char(magic + i + 1);
  }
  SuffixAutomaton automaton(str);
  vector<int> order;
  for (int v = 0; v < (int)(automaton.t).size(); ++v) {
    order.push_back(v);
  }
  sort((order).begin(), (order).end(),
       [&](int x, int y) { return automaton.t[x].len > automaton.t[y].len; });
  vector<vector<int> > cnt((int)(automaton.t).size(), vector<int>(q + 1));
  for (int v : order) {
    for (auto it : automaton.t[v].to) {
      if (isalpha(it.first)) {
        for (int i = 0; i <= q; ++i) {
          cnt[v][i] += cnt[it.second][i];
        }
      } else {
        ++cnt[v][it.first - magic];
      }
    }
  }
  long long ans = 0;
  for (int v = 1; v < (int)(automaton.t).size(); ++v) {
    if (cnt[v][0] == 0) {
      continue;
    }
    bool ok = true;
    for (int i = 0; i < q; ++i) {
      if (cnt[v][i + 1] >= lf[i] && cnt[v][i + 1] <= rg[i]) {
        continue;
      } else {
        ok = false;
        break;
      }
    }
    if (!ok) {
      continue;
    }
    ans += automaton.t[v].len - automaton.t[automaton.t[v].link].len;
  }
  cout << ans << "\n";
}
