#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int MAXN = 6e5 + 10;
const int LG = 21;
string s_;
vector<char> s;
pair<pair<int, int>, int> arr[MAXN];
int sufrank[LG][MAXN], n, m, l_, sz[11], lo[11], hi[11];
int revrank[MAXN], lcp[MAXN];
int par[2 * MAXN], level[2 * MAXN], now = 2, cnt = 1;
vector<int> adj[2 * MAXN];
long long have[11][2 * MAXN], answer;
int valid[2 * MAXN];
void dfs(int v) {
  for (auto e : adj[v]) {
    dfs(e);
    for (int i = 0; i < m; i++) have[i][v] += have[i][e];
    valid[v] = max(valid[v], valid[e] + level[e] - level[v]);
  }
  for (int i = 0; i < m; i++)
    if (have[i][v] > hi[i] || have[i][v] < lo[i]) return;
  int ok = max(0, n - l_ - valid[v]);
  answer += max(0, level[v] - level[par[v]] - ok);
  return;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> s_ >> m;
  l_ = s_.size();
  for (auto e : s_) s.push_back(e);
  for (int i = 0; i < m; i++) {
    cin >> s_ >> lo[i] >> hi[i];
    s.push_back(char('a' - 1));
    for (auto e : s_) s.push_back(e);
    sz[i] = s_.size();
  }
  n = s.size();
  revrank[n] = -1;
  for (int i = 0; i < n; i++) sufrank[0][i] = s[i] - 'a' + 2;
  for (int l = 1; l < LG; l++) {
    for (int i = 0, j = 1 << (l - 1); i < n; i++, j++)
      arr[i] = {{sufrank[l - 1][i], j < n ? sufrank[l - 1][j] : -1}, i};
    sort(arr, arr + n);
    for (int i = 1; i < n; i++)
      sufrank[l][arr[i].second] = (arr[i].first == arr[i - 1].first)
                                      ? sufrank[l][arr[i - 1].second]
                                      : sufrank[l][arr[i - 1].second] + 1;
  }
  for (int i = 0; i < n; i++) revrank[sufrank[LG - 1][i]] = i;
  for (int i = 0, E = 0; i < n; i++) {
    int A = revrank[sufrank[LG - 1][i] + 1];
    if (A == -1) {
      E = 0;
      continue;
    }
    while ((A + E) < n && (i + E) < n && s[A + E] == (s[i + E])) E++;
    lcp[sufrank[LG - 1][i]] = E;
    if (E) E--;
  }
  par[++cnt] = 1;
  level[cnt] = n - revrank[0];
  for (int i = 1; i < n; i++) {
    while (level[par[now]] > lcp[i - 1]) now = par[now];
    if (level[now] != lcp[i - 1] && level[par[now]] < lcp[i - 1]) {
      par[++cnt] = par[now];
      level[cnt] = lcp[i - 1];
      par[now] = cnt;
    }
    if (level[now] != lcp[i - 1]) now = par[now];
    if (lcp[i - 1] == (n - revrank[i])) continue;
    par[++cnt] = now;
    now = cnt;
    level[cnt] = n - revrank[i];
    for (int j = 0, go = l_; j < m; go += sz[j] + 1, j++)
      if (revrank[i] > go && revrank[i] < (go + sz[j] + 1)) have[j][now]++;
  }
  for (int i = 2; i <= cnt; i++) adj[par[i]].push_back(i);
  dfs(1);
  cout << answer << endl;
  return 0;
}
