#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse2")
using namespace std;
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
  std::cerr << name << " : " << arg1 << '\n';
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
  const char* comma = strchr(names + 1, ',');
  std::cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
long long max(long long a, long long b) { return (a > b) ? a : b; }
long long min(long long a, long long b) { return (a < b) ? a : b; }
void amax(long long& a, long long b) { a = max(a, b) % 1000000007; }
void amin(long long& a, long long b) { a = min(a, b) % 1000000007; }
void inc(long long& a, long long b) { a = (a + b) % 1000000007; }
void dec(long long& a, long long b) { a = (a - b + 1000000007) % 1000000007; }
string s;
unsigned long long t[4 * 100005];
vector<long long> arr[4 * 100005];
void build(long long v, long long tl, long long tr) {
  if (tr < tl) return;
  if (tl == tr) {
    t[v] = 1;
    arr[v][s[tl] - 'a']++;
    return;
  } else {
    long long tm = (tl + tr) / 2;
    build(v * 2, tl, tm);
    build(v * 2 + 1, tm + 1, tr);
    for (long long i = 0; i < 26; i++) {
      if (arr[v * 2][i] || arr[v * 2 + 1][i]) {
        if (arr[v][i] == 0) t[v]++;
        arr[v][i] = 1;
      }
    }
  }
}
void query(long long v, long long tl, long long tr, long long l, long long r,
           vector<long long>& ans) {
  if (l > r) return;
  if (l == tl && r == tr) {
    for (long long i = 0; i < 26; i++) ans[i] |= arr[v][i];
    return;
  }
  long long tm = (tl + tr) / 2;
  query(v * 2, tl, tm, l, min(r, tm), ans);
  query(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, ans);
}
void update(long long v, long long tl, long long tr, long long pos,
            char new_val) {
  if (tl == tr) {
    s[tl] = new_val;
    for (long long i = 0; i < 26; i++) arr[v][i] = 0;
    arr[v][new_val - 'a'] = 1;
  } else {
    long long tm = (tl + tr) / 2;
    if (pos <= tm)
      update(v * 2, tl, tm, pos, new_val);
    else
      update(v * 2 + 1, tm + 1, tr, pos, new_val);
    for (long long i = 0; i < 26; i++) {
      arr[v][i] = 0;
      arr[v][i] |= arr[v * 2][i] | arr[v * 2 + 1][i];
    }
  }
  long long temp = 0;
}
long long solve() {
  cin >> s;
  for (long long i = 0; i < 4 * 100005; i++) {
    t[i] = 0;
    arr[i].resize(26);
    for (long long j = 0; j < 26; j++) arr[i][j] = 0;
  }
  build(1, 0, s.size() - 1);
  long long q;
  cin >> q;
  while (q--) {
    long long c, l;
    cin >> c >> l;
    l--;
    if (c == 1) {
      char let;
      cin >> let;
      update(1, 0, s.size() - 1, l, let);
    } else {
      long long r;
      cin >> r;
      r--;
      vector<long long> ans(26, 0);
      query(1, 0, s.size() - 1, l, r, ans);
      long long count = 0;
      for (long long i = 0; i < 26; i++) {
        count += ans[i];
      }
      cout << count << '\n';
      ;
    }
  }
  return 0;
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  long long t = 1;
  while (t--) {
    solve();
  }
}
