abcdabcdab
5
2 2 8 ab
2 1 10 ab
1 3 a
1 4 b
2 1 4 ab

1
3
2

#include <bits/stdc++.h>
using namespace std;
const int sa = 2 * 150 + 10;
const int LEN = 100010;
char s[LEN], sq[LEN], zstring[2 * LEN];
int z[2 * LEN];
string temps;
struct SuffixAutomaton {
  int edges[26][sa], link[sa], length[sa], isTerminal[sa], dp1[sa], last;
  int sz;
  SuffixAutomaton() {
    last = 0;
    sz = 0;
  }
  void set(int k) {
    for (int i = 0; i < 26; ++i) edges[i][k] = -1;
  }
  void build(string &s) {
    link[0] = -1;
    length[0] = 0;
    last = 0;
    sz = 1;
    set(0);
    for (int i = 0; i < s.size(); i++) {
      set(sz);
      length[sz] = i + 1;
      link[sz] = 0;
      int r = sz;
      ++sz;
      int p = last;
      while (p >= 0 && edges[s[i] - 'a'][p] == -1) {
        edges[s[i] - 'a'][p] = r;
        p = link[p];
      }
      if (p != -1) {
        int q = edges[s[i] - 'a'][p];
        if (length[p] + 1 == length[q]) {
          link[r] = q;
        } else {
          for (int i = 0; i < 26; ++i) {
            edges[i][sz] = edges[i][q];
          }
          length[sz] = length[p] + 1;
          link[sz] = link[q];
          int qq = sz;
          ++sz;
          link[q] = qq;
          link[r] = qq;
          while (p >= 0 && edges[s[i] - 'a'][p] == q) {
            edges[s[i] - 'a'][p] = qq;
            p = link[p];
          }
        }
      }
      last = r;
    }
    for (int i = 0; i < sz; ++i) isTerminal[i] = 0, dp1[i] = -1;
    int p = last;
    while (p > 0) {
      isTerminal[p] = 1;
      p = link[p];
    }
  }
  int solve(int pos) {
    if (dp1[pos] != -1) return dp1[pos];
    dp1[pos] = isTerminal[pos];
    for (int i = 0; i < 26; ++i) {
      if (edges[i][pos] != -1) dp1[pos] += solve(edges[i][pos]);
    }
    return dp1[pos];
  }
  int run() {
    int cur = 0;
    for (int i = 1; sq[i] != '\0'; ++i) {
      auto it = edges[sq[i] - 'a'][cur];
      if (it == -1)
        return 0;
      else
        cur = it;
    }
    return solve(cur);
  }
} SA[800];
void computeZ() {
  int l, r;
  z[0] = 0;
  l = r = -1;
  for (int i = 1; zstring[i] != '\0'; ++i) {
    z[i] = 0;
    if (r > i) {
      z[i] = min(z[i - l], r - i + 1);
    }
    while (zstring[i + z[i]] == zstring[z[i]]) ++z[i];
    if (i + z[i] - 1 > r) {
      r = i + z[i] - 1;
      l = i;
    }
  }
}
int computeBrute(int l, int r, int sqlen) {
  int zslen = 0, ans = 0;
  for (int i = 1; i <= sqlen; ++i) {
    zstring[zslen++] = sq[i];
  }
  zstring[zslen++] = '$';
  for (int i = l; i <= r; ++i) {
    zstring[zslen++] = s[i];
  }
  zstring[zslen] = '\0';
  computeZ();
  for (int i = 1; i < zslen; ++i) {
    if (z[i] >= sqlen) {
      ++ans;
    }
  }
  return ans;
}
int main() {
  int q, typ, l, r, slen;
  char ch;
  scanf(" %s", &s[1]);
  slen = strlen(&s[1]);
  scanf("%d", &q);
  for (int i = 0; i <= slen; i += 150) {
    temps = "";
    int tempr = min(i + 150 - 1, slen);
    for (int j = max(1, i); j <= tempr; ++j) {
      temps += s[j];
    }
    SA[i / 150].build(temps);
  }
  while (q--) {
    scanf("%d", &typ);
    if (typ == 1) {
      scanf("%d %c", &l, &ch);
      s[l] = ch;
      temps = "";
      int bkt = l / 150;
      int tempr = min(slen, (bkt + 1) * 150 - 1);
      for (int i = max(1, bkt * 150); i <= tempr; ++i) {
        temps += s[i];
      }
      SA[bkt].build(temps);
    } else {
      scanf("%d %d %s", &l, &r, &sq[1]);
      int sqlen = strlen(&sq[1]);
      if (sqlen >= 150 || r - l <= 2 * 150) {
        printf("%d\n", computeBrute(l, r, sqlen));
      } else {
        int lbkt = l / 150, rbkt = r / 150, ans = 0;
        for (int i = lbkt + 1; i < rbkt; ++i) {
          ans += SA[i].run();
        }
        ans += computeBrute(l, (lbkt + 1) * 150 - 1, sqlen);
        ans += computeBrute(rbkt * 150, r, sqlen);
        for (int i = lbkt + 1; i <= rbkt; ++i) {
          ans += computeBrute(max(l, i * 150 - sqlen + 1),
                              min(r, i * 150 + sqlen - 2), sqlen);
        }
        printf("%d\n", ans);
      }
    }
  }
  return 0;
}
