#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:200000000")
using namespace std;
const int INF = (int)1E9;
const long long INF64 = (long long)1E18;
const double EPS = 1E-9;
const double PI = acos((double)0) * 2;
const int MAXR = 10;
const int MAXN = 2010;
const int PR = 3;
const int B[PR] = {29, 53, 97};
const int P[PR] = {1073676287, 1190494667, 1190494699};
string s, p[MAXR];
int n, minc[MAXR], maxc[MAXR];
bool read() {
  if (!(cin >> s >> n)) return false;
  for (int i = 0; i < int(n); ++i) cin >> p[i] >> minc[i] >> maxc[i];
  return true;
}
struct strhash {
  int h[PR];
  strhash() { memset(h, 0, sizeof h); }
  void add_char(char c) {
    for (int i = 0; i < int(PR); ++i)
      h[i] = (c - 'a' + h[i] * 1ll * B[i]) % P[i];
  }
  bool operator<(const strhash& other) const {
    return memcmp(h, other.h, sizeof h) < 0;
  }
  bool operator==(const strhash& other) const {
    return memcmp(h, other.h, sizeof h) == 0;
  }
};
vector<strhash> ans[MAXN];
struct state {
  int len, link, cnt, dcnt;
  map<char, int> next;
  vector<int> ilink;
};
state st[MAXR][MAXN * 2];
int sz, last;
void sa_init(int idx) {
  sz = last = 0;
  st[idx][0].len = 0;
  st[idx][0].link = -1;
  ++sz;
  for (int i = 0; i < MAXN * 2; ++i) {
    st[idx][i].cnt = 0;
    st[idx][i].dcnt = -1;
    st[idx][i].next.clear();
    st[idx][i].ilink.clear();
  }
}
int get_cnt(int idx, int v) {
  int& my = st[idx][v].dcnt;
  if (my != -1) return my;
  my = st[idx][v].cnt;
  for (int i = 0; i < int(st[idx][v].ilink.size()); ++i)
    my += get_cnt(idx, st[idx][v].ilink[i]);
  return my;
}
void sa_extend(int idx, char c) {
  state* st = ::st[idx];
  int cur = sz++;
  st[cur].len = st[last].len + 1;
  st[cur].cnt = 1;
  int p;
  for (p = last; p != -1 && !st[p].next.count(c); p = st[p].link)
    st[p].next[c] = cur;
  if (p == -1)
    st[cur].link = 0;
  else {
    int q = st[p].next[c];
    if (st[p].len + 1 == st[q].len)
      st[cur].link = q;
    else {
      int clone = sz++;
      st[clone].len = st[p].len + 1;
      st[clone].next = st[q].next;
      st[clone].link = st[q].link;
      for (; p != -1 && st[p].next[c] == q; p = st[p].link)
        st[p].next[c] = clone;
      st[q].link = st[cur].link = clone;
    }
  }
  last = cur;
}
void solve() {
  for (int i = 0; i < int(n); ++i) {
    sa_init(i);
    for (int j = 0; j < int(p[i].length()); ++j) sa_extend(i, p[i][j]);
    for (int j = 0; j < int(sz); ++j) {
      int l = st[i][j].link;
      if (l != -1) st[i][l].ilink.push_back(j);
    }
  }
  for (int i = 0; i < int(MAXN); ++i) ans[i].clear();
  for (int l = 0; l < int(s.length()); ++l) {
    strhash h;
    int v[MAXR] = {0};
    for (int r = int(l); r < int(s.length()); ++r) {
      h.add_char(s[r]);
      bool ok = true;
      for (int i = 0; i < int(n); ++i) {
        if (v[i] != -1)
          if (st[i][v[i]].next.count(s[r]))
            v[i] = st[i][v[i]].next[s[r]];
          else
            v[i] = -1;
        int c = v[i] == -1 ? 0 : get_cnt(i, v[i]);
        if (c < minc[i]) goto end;
        if (!(minc[i] <= c && c <= maxc[i])) ok = false;
      }
      if (ok) ans[r - l + 1].push_back(h);
    }
  end:;
  }
  int ansc = 0;
  for (int i = 0; i < int(MAXN); ++i) {
    sort(ans[i].begin(), ans[i].end());
    ansc += int(unique(ans[i].begin(), ans[i].end()) - ans[i].begin());
  }
  cout << ansc << endl;
}
int main(int argc, char* argv[]) {
  if (!read()) throw;
  solve();
}
