#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 5;
char str[N];
struct SegTree {
  int l, r, state;
  int num[26];
} t[N << 2];
void merge(int p) {
  for (int i = 0; i < 26; i++) {
    t[p].num[i] = t[p << 1].num[i] + t[p << 1 | 1].num[i];
  }
  t[p].state = 0;
  t[p].state |= t[p << 1].state;
  t[p].state |= t[p << 1 | 1].state;
}
void build(int p, int l, int r) {
  t[p].l = l, t[p].r = r;
  t[p].state = 0;
  memset(t[p].num, 0, sizeof(t[p].num));
  if (t[p].l == t[p].r) {
    t[p].num[str[l] - 'a']++;
    t[p].state |= 1 << (str[l] - 'a');
    return;
  }
  int mid = (l + r) >> 1;
  build(p << 1, l, mid);
  build(p << 1 | 1, mid + 1, r);
  merge(p);
}
void change(int p, int pos, char ch) {
  if (t[p].l == t[p].r) {
    int k = log2(t[p].state);
    t[p].num[k]--;
    if (!t[p].num[k]) t[p].state ^= (1 << k);
    t[p].num[ch - 'a']++;
    t[p].state |= 1 << (ch - 'a');
    return;
  }
  int mid = (t[p].l + t[p].r) >> 1;
  if (pos <= mid)
    change(p << 1, pos, ch);
  else
    change(p << 1 | 1, pos, ch);
  merge(p);
}
int ask(int p, int l, int r) {
  if (l <= t[p].l && t[p].r <= r) {
    return t[p].state;
  }
  int mid = (t[p].l + t[p].r) >> 1;
  int val = 0;
  if (l <= mid) val |= ask(p << 1, l, r);
  if (r > mid) val |= ask(p << 1 | 1, l, r);
  return val;
}
int main() {
  int q, len;
  scanf("%s%d", str + 1, &q);
  len = strlen(str + 1);
  build(1, 1, len);
  while (q--) {
    int op;
    scanf("%d", &op);
    if (op == 1) {
      int pos;
      char ch;
      scanf("%d %c", &pos, &ch);
      change(1, pos, ch);
    } else {
      int l, r;
      scanf("%d%d", &l, &r);
      int val = ask(1, l, r);
      int ans = 0;
      for (; val; val -= (val & -val)) ans++;
      printf("%d\n", ans);
    }
  }
  return 0;
}
