#include <bits/stdc++.h>
using namespace std;
const int maxn = 2500;
const int mod = 1000000000;
char buf[maxn], s[maxn];
char str[15][maxn];
int L[15];
int l[15], r[15];
int cnt[15][maxn];
bool flag[maxn][maxn];
int n, sa[maxn], height[maxn], rak[maxn], tmp[maxn], top[maxn];
const int MAXK = 26;
const int MAXS = 250000;
int nxt[MAXS][MAXK], cs;
int fail[MAXS], cid;
vector<int> vec[MAXS];
void initNode(int id) {
  vec[id].clear();
  memset(nxt[id], 0, sizeof(nxt[id]));
}
void clear() {
  cs = 1, initNode(0);
  cid = 0;
}
void insert(char *s) {
  int p = 0;
  for (; *s; ++s) {
    int c = *s - 'a';
    if (!nxt[p][c]) {
      initNode(cs);
      nxt[p][c] = cs++;
    }
    p = nxt[p][c];
    vec[p].push_back(cid++);
  }
}
void buildAc() {
  queue<int> Q;
  Q.push(0);
  while (!Q.empty()) {
    int p = Q.front();
    Q.pop();
    for (int i = 0; i < MAXK; ++i) {
      if (nxt[p][i]) {
        if (p)
          fail[nxt[p][i]] = nxt[fail[p]][i];
        else
          fail[nxt[p][i]] = 0;
        Q.push(nxt[p][i]);
      } else {
        if (p)
          nxt[p][i] = nxt[fail[p]][i];
        else
          nxt[p][i] = 0;
      }
    }
  }
}
void makesa() {
  int i, j, len, na;
  na = (n < 256 ? 256 : n);
  memset(top, 0, na * sizeof(int));
  for (i = 0; i < n; i++) top[rak[i] = s[i] & 0xff]++;
  for (i = 1; i < na; i++) top[i] += top[i - 1];
  for (i = 0; i < n; i++) sa[--top[rak[i]]] = i;
  for (len = 1; len < n; len <<= 1) {
    for (i = 0; i < n; i++) {
      j = sa[i] - len;
      if (j < 0) j += n;
      tmp[top[rak[j]]++] = j;
    }
    sa[tmp[top[0] = 0]] = j = 0;
    for (i = 1; i < n; i++) {
      if (rak[tmp[i]] != rak[tmp[i - 1]] ||
          rak[tmp[i] + len] != rak[tmp[i - 1] + len])
        top[++j] = i;
      sa[tmp[i]] = j;
    }
    memcpy(rak, sa, n * sizeof(int));
    memcpy(sa, tmp, n * sizeof(int));
    if (j >= n - 1) break;
  }
}
void lcp() {
  int i, j, k;
  for (j = rak[height[i = k = 0] = 0]; i < n - 1; i++, k++)
    while (k >= 0 && s[i] != s[sa[j - 1] + k])
      height[j] = (k--), j = rak[sa[j] + 1];
}
void query(char *s, int ans[]) {
  int p = 0;
  for (; *s; s++) {
    p = nxt[p][*s - 'a'];
    for (int i = p; i; i = fail[i])
      for (size_t j = 0; j < vec[i].size(); j++) ans[vec[i][j]]++;
  }
}
void gao(char *s, int len, int sp) {
  clear();
  insert(s);
  buildAc();
  memset(cnt, 0, sizeof(cnt));
  memset(flag[sp], true, sizeof(flag[sp]));
  for (int i = 0; i < n; ++i) {
    query(str[i], cnt[i]);
    for (int j = 0; j < len; ++j) {
      if (cnt[i][j] >= l[i] && cnt[i][j] <= r[i]) continue;
      flag[sp][j] = false;
    }
  }
}
int main() {
  scanf("%s", buf);
  int len = strlen(buf);
  memcpy(s, buf, sizeof(buf));
  n = len + 1;
  makesa();
  lcp();
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%s %d %d", str[i], &l[i], &r[i]);
    L[i] = strlen(str[i]);
  }
  for (int i = 0; i < len; i++) gao(buf + i, len - i, i);
  int ans = 0;
  for (int i = 1; i <= len; i++)
    for (int j = sa[i] + height[i] + 1; j <= len; j++)
      if (flag[sa[i]][j - sa[i] - 1]) ans++;
  printf("%d\n", ans);
}
