#include <bits/stdc++.h>
#pragma GCC optimize("Ofast", "unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int MAXN = (int)1e5 * 8;
const int INF = (int)1e9 * 2;
bool rec = false;
struct tree {
  int arr[26] = {};
  tree operator+(const tree &r) const {
    tree out;
    for (int i = 0; i < 26; i++) {
      out.arr[i] = arr[i] + r.arr[i];
    }
    return out;
  }
};
int n, tt;
string s;
tree t[MAXN];
tree empt;
map<char, int> hh;
tree get(int v, int tl, int tr, int l, int r) {
  if (l <= tl && tr <= r) {
    return t[v];
  }
  if (tr < l || tl > r) return empt;
  int mid = (tl + tr) / 2;
  return get(v + v, tl, mid, l, r) + get(v + v + 1, mid + 1, tr, l, r);
}
void upd(int v, int l, int r, int pos, char val) {
  if (l == r) {
    tree ne;
    ne.arr[val - 'a']++;
    t[v] = ne;
    return;
  }
  int mid = (l + r) / 2;
  if (pos <= mid) {
    upd(v + v, l, mid, pos, val);
  } else {
    upd(v + v + 1, mid + 1, r, pos, val);
  }
  t[v] = t[v + v] + t[v + v + 1];
}
void recalc(int v, int l, int r, int pos, char val) {
  if (l == r) {
    return;
  }
  int mid = (l + r) / 2;
  recalc(v + v, l, mid, pos, val);
  recalc(v + v + 1, mid + 1, r, pos, val);
  t[v] = t[v + v] + t[v + v + 1];
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> s;
  n = s.size();
  for (int i = 0; i < s.size(); i++) {
    upd(1, 1, n, i + 1, s[i]);
  }
  rec = true;
  recalc(1, 1, n, 1, 'a');
  cin >> tt;
  for (int i = 1; i <= tt; i++) {
    int x;
    cin >> x;
    if (x == 1) {
      int pos;
      char ch;
      cin >> pos >> ch;
      upd(1, 1, n, pos, ch);
    } else {
      int l, r;
      cin >> l >> r;
      tree tree = get(1, 1, n, l, r);
      int ans = 0;
      for (int i = 0; i < 26; i++)
        if (tree.arr[i] > 0) ans++;
      cout << ans << endl;
    }
  }
}
