/**
 *    author:  math2do
 *    created: 04.03.2020 04:06:25 IST
**/

#include <bits/stdc++.h>

using namespace std;

class segtree {
 public:
  struct node {
    // don't forget to set default value (used for leaves)
    // not necessarily neutral element!
    vector <int> fre;
    int ch = -1;
    bool leaf = false;
    node() {
      fre.resize(26);
      fill(fre.begin(), fre.end(), 0);
    } 

    void apply(int l, int h, int v) {
      assert(l == h);
      assert(v >= 0 && v <= 25);
      assert((int) fre.size() == 26);
      if (ch != -1) { 
        fre[ch]--;
      } 
      ch = v;
      fre[v]++;
    }
  };
 
  node unite(const node &a, const node &b) const {
    node res;
    for (int i = 0; i < 26; i++) {
      res.fre[i] = a.fre[i] + b.fre[i];
    } 
    return res;
  }
 
  inline void push(int i, int l, int h) {
    int m = (l + h) >> 1;
    // push from i into left child and right child, Also no push in point-update
   /*
    if (tree[i].mark) {
      tree[i << 1].apply(l, m, tree[i].add);
      tree[(i << 1) + 1].apply(m + 1, h, tree[i].add);
      tree[i].add = 0;
      tree[i].mark = false;
    }
    */
  }
 
  inline void pull(int i) {
    tree[i] = unite(tree[i << 1], tree[(i << 1) + 1]);
  }
 
  int n;
  vector<node> tree;
 
  void build(int i, int l, int h) {
    if (l == h) {
      tree[i].leaf = true;
      return;
    }
    int m = (l + h) >> 1;
    build(i << 1, l, m);
    build((i << 1) + 1, m + 1, h);
    pull(i);
  }
 
  template <typename M>
  void build(int i, int l, int h, const vector<M> &v) {
    if (l == h) {
      tree[i].apply(l, h, v[l]);
      tree[i].leaf = true;
      return;
    }
    int m = (l + h) >> 1;
    build(i << 1, l, m, v);
    build((i << 1) + 1, m + 1, h, v);
    pull(i);
  }
 
  node get(int i, int l, int h, int ql, int qh) {
    if (ql <= l && h <= qh) {
      return tree[i];
    }
    int m = (l + h) >> 1;
    push(i, l, h);
    node res{};
    if (qh <= m) {
      res = get(i << 1, l, m, ql, qh);
    } else {
      if (ql > m) {
        res = get((i << 1) + 1, m + 1, h, ql, qh);
      } else {
        res = unite(get(i << 1, l, m, ql, qh), get((i << 1) + 1, m + 1, h, ql, qh));
      }
    }
    pull(i);
    return res;
  }
 
  template <typename... M>
  void modify(int i, int l, int h, int ql, int qh, const M&... v) {
    if (ql <= l && h <= qh) {
      tree[i].apply(l, h, v...);
      return;
    }
    int m = (l + h) >> 1;
    push(i, l, h);
    if (ql <= m) {
      modify(i << 1, l, m, ql, qh, v...);
    }
    if (qh > m) {
      modify((i << 1) + 1, m + 1, h, ql, qh, v...);
    }
    pull(i);
  }
 
  int find_first_knowingly(int i, int l, int h, const function<bool(const node&)> &f) {
    if (l == h) {
      return l;
    }
    push(i, l, h);
    int m = (l + h) >> 1;
    int res;
    if (f(tree[i << 1])) {
      res = find_first_knowingly(i << 1, l, m, f);
    } else {
      res = find_first_knowingly((i << 1) + 1, m + 1, h, f);
    }
    pull(i);
    return res;
  }
 
  int find_first(int i, int l, int h, int ql, int qh, const function<bool(const node&)> &f) {
    if (ql <= l && h <= qh) {
      if (!f(tree[i])) {
        return -1;
      }
      return find_first_knowingly(i, l, h, f);
    }
    push(i, l, h);
    int m = (l + h) >> 1;
    int res = -1;
    if (ql <= m) {
      res = find_first(i << 1, l, m, ql, qh, f);
    }
    if (qh > m && res == -1) {
      res = find_first((i << 1) + 1, m + 1, h, ql, qh, f);
    }
    pull(i);
    return res;
  }
 
  int find_last_knowingly(int i, int l, int h, const function<bool(const node&)> &f) {
    if (l == h) {
      return l;
    }
    push(i, l, h);
    int m = (l + h) >> 1;
    int res;
    if (f(tree[(i << 1) + 1])) {
      res = find_last_knowingly((i << 1) + 1, m + 1, h, f);
    } else {
      res = find_last_knowingly(i << 1, l, m, f);
    }
    pull(i);
    return res;
  }
 
  int find_last(int i, int l, int h, int ql, int qh, const function<bool(const node&)> &f) {
    if (ql <= l && h <= qh) {
      if (!f(tree[i])) {
        return -1;
      }
      return find_last_knowingly(i, l, h, f);
    }
    push(i, l, h);
    int m = (l + h) >> 1;
    int res = -1;
    if (qh > m) {
      res = find_last((i << 1) + 1, m + 1, h, ql, qh, f);
    }
    if (ql <= m && res == -1) {
      res = find_last(i << 1, l, m, ql, qh, f);
    }
    pull(i);
    return res;
  }
 
  segtree(int _n) : n(_n) {
    assert(n > 0);
    tree.resize(4 * n);
    build(1, 0, n - 1);
  }
 
  template <typename M>
  segtree(const vector<M> &v) {
    n = v.size();
    assert(n > 0);
    tree.resize(4 * n);
    build(1, 0, n - 1, v);
  }
 
  node get(int ql, int qh) {
    assert(0 <= ql && ql <= qh && qh <= n - 1);
    return get(1, 0, n - 1, ql, qh);
  }
 
  node get(int p) {
    assert(0 <= p && p <= n - 1);
    return get(1, 0, n - 1, p, p);
  }
 
  template <typename... M>
  void modify(int ql, int qh, const M&... v) {
    assert(0 <= ql && ql <= qh && qh <= n - 1);
    modify(1, 0, n - 1, ql, qh, v...);
  }
 
  // find_first and find_last call all FALSE elements
  // to the left (right) of the sought position exactly once
 
  int find_first(int ql, int qh, const function<bool(const node&)> &f) {
    assert(0 <= ql && ql <= qh && qh <= n - 1);
    return find_first(1, 0, n - 1, ql, qh, f);
  }
 
  int find_last(int ql, int qh, const function<bool(const node&)> &f) {
    assert(0 <= ql && ql <= qh && qh <= n - 1);
    return find_last(1, 0, n - 1, ql, qh, f);
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, q;
  cin >> n;
  string s;
  cin >> s;
  vector <int> arr(n);
  for (int i = 0; i < n; i++) {
    arr[i] = (int) (s[i] - 'a');
  } 
  cin >> q;
  segtree st(arr);
  for (int i = 0; i < q; i++) {
    int type;
    cin >> type;
    if (type == 1) {
      int pos; char ch;
      cin >> pos >> ch;
      pos--;
      if (s[pos] == ch) continue;
      st.modify(pos, pos, (int) (ch - 'a'));
      s[pos] = ch;
    } else {
      int x, y;
      cin >> x >> y;
      x--; y--;
      int cnt = 0;
      auto ans = st.get(x, y);
      for (int j = 0; j < 26; j++) {
        cnt += ans.fre[j] > 0;
      } 
      cout << cnt << '\n';
    }  
  } 
  return 0;
}


Measured memory_bytes: 284060