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 block_size = 320;
const long long mod = 1e9 + 7;
const long long inf = 1e9 + 7;
const long double eps = 1e-9;
const double PI = atan(1) * 4;
template <typename T>
inline int sign(const T& a) {
  if (a < 0) return -1;
  if (a > 0) return 1;
  return 0;
}
template <typename T>
inline void in(T& x) {
  x = 0;
  T f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  x *= f;
}
long long twop(int x) { return 1LL << x; }
template <typename A, typename B>
inline void in(A& x, B& y) {
  in(x);
  in(y);
}
template <typename A, typename B, typename C>
inline void in(A& x, B& y, C& z) {
  in(x);
  in(y);
  in(z);
}
template <typename A, typename B, typename C, typename D>
inline void in(A& x, B& y, C& z, D& d) {
  in(x);
  in(y);
  in(z);
  in(d);
}
template <class T>
void upd(T& a, T b) {
  a = max(a, b);
}
map<pair<unsigned, unsigned>, int> m;
struct node {
  int l, r;
  pair<unsigned, unsigned> val;
};
unsigned long long pw[2][100010];
unsigned long long seed[2] = {2333, 1233};
unsigned long long mo[2] = {123432127, 1212121217};
string seq;
pair<unsigned, unsigned> getHash(const string& s) {
  pair<unsigned, unsigned> ans = make_pair(0, 0);
  for (long long i = ((int)s.size()) - 1; i >= 0; i--) {
    ans.first = (1LL * ans.first * seed[0] + s[i]) % mo[0];
    ans.second = (1LL * ans.second * seed[1] + s[i]) % mo[1];
  }
  return ans;
}
map<pair<unsigned, unsigned>, int> bit[100010];
void update(int a, const pair<unsigned, unsigned>& value, int wei) {
  a++;
  while (a < 100010) {
    bit[a][value] += wei;
    a += (a & (-a));
  }
}
int query(const pair<unsigned, unsigned>& haa, int a) {
  a++;
  if (a <= 0) return 0;
  int ans = 0;
  while (a) {
    auto ptr = bit[a].find(haa);
    if (ptr != bit[a].end()) ans += ptr->second;
    a -= (a & (-a));
  }
  return ans;
}
const int bound = 2;
int cnt[100010];
int nxt[100010];
void calcNext(const string& s, int nxt[]) {
  int p = nxt[0] = -1;
  for (int i = 1; i < ((int)s.size()); i++) {
    while (p != -1 && s[p + 1] != s[i]) p = nxt[p];
    p += s[p + 1] == s[i];
    nxt[i] = p;
  }
}
void calcOCC(const string& s, int nxt[], int l, int r, int& ans) {
  int p = -1;
  for (int i = l; i < r + 1; i++) {
    if (seq[i] == s[p + 1]) {
      p++;
    }
    if (p == ((int)s.size()) - 1) {
      ans++;
      p = nxt[p];
    }
  }
}
string qs;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  pw[0][0] = pw[1][0] = 1;
  for (int i = 1; i < 100010; i++) {
    pw[0][i] = pw[0][i - 1] * seed[0] % mo[0];
    pw[1][i] = pw[1][i - 1] * seed[1] % mo[1];
  }
  cin >> seq;
  int q;
  cin >> q;
  for (int r = ((int)seq.size()) - 1; r >= 0; r--) {
    pair<unsigned, unsigned> haa = make_pair(0, 0);
    for (int l = r; l >= 0 && r - l + 1 <= bound; l--) {
      haa.first = (1LL * haa.first * seed[0] + seq[l]) % mo[0];
      haa.second = (1LL * haa.second * seed[1] + seq[l]) % mo[1];
      update(l, haa, 1);
    }
  }
  for (int i = 0; i < q; i++) {
    int t;
    cin >> t;
    if (t == 1) {
      int pos;
      char c;
      cin >> pos;
      pos--;
      char sss[3];
      cin >> sss;
      c = sss[0];
      for (int r = pos; r < ((int)seq.size()) && (r - pos + 1) <= bound; r++) {
        pair<unsigned, unsigned> haa = make_pair(0, 0);
        for (int j = r; j > pos; j--) {
          haa.first = (1LL * haa.first * seed[0] + seq[j]) % mo[0];
          haa.second = (1LL * haa.second * seed[1] + seq[j]) % mo[1];
        }
        for (int l = pos; l >= 0 && r - l + 1 <= bound; l--) {
          haa.first = (1LL * haa.first * seed[0] + seq[l]) % mo[0];
          haa.second = (1LL * haa.second * seed[1] + seq[l]) % mo[1];
          update(l, haa, -1);
        }
      }
      seq[pos] = c;
      for (int r = pos; r < ((int)seq.size()) && (r - pos + 1) <= bound; r++) {
        pair<unsigned, unsigned> haa = make_pair(0, 0);
        for (int j = r; j > pos; j--) {
          haa.first = (1LL * haa.first * seed[0] + seq[j]) % mo[0];
          haa.second = (1LL * haa.second * seed[1] + seq[j]) % mo[1];
        }
        for (int l = pos; l >= 0 && r - l + 1 <= bound; l--) {
          haa.first = (1LL * haa.first * seed[0] + seq[l]) % mo[0];
          haa.second = (1LL * haa.second * seed[1] + seq[l]) % mo[1];
          update(l, haa, 1);
        }
      }
    } else {
      int l, r;
      cin >> l >> r >> qs;
      l--;
      r--;
      int ans = 0;
      if (((int)qs.size()) > r - l + 1) {
        cout << "0\n";
        continue;
      }
      if (((int)qs.size()) <= bound) {
        auto haa = getHash(qs);
        int qr = r - ((int)qs.size()) + 1;
        int ql = l - 1;
        ans = query(haa, qr) - query(haa, ql);
      } else {
        calcNext(qs, nxt);
        calcOCC(qs, nxt, l, r, ans);
      }
      cout << ans << "\n";
    }
  }
  return 0;
}
