class SegmentTree {
  #a; #op; #n; #e;
  constructor(a,op=Math.min,e=Infinity){
    let n = 1;
    while ( n <= a.length ) n <<= 1;
    this.#a = Array(--n).fill(e).concat(a);
    this.#n = n;
    const l = this.#a.length;
    for ( let i = n-1; i >= 0; i-- ) {
      const x = (l>i+i+1)?this.#a[i+i+1]:e;
      const y = (l>i+i+2)?this.#a[i+i+2]:e;
      this.#a[i] = op( x, y );
    }
    this.#op = op;
    this.#e = e;
  }
  update(i,v){
    const a = this.#a, l = a.length, e = this.#e;
    a[i += this.#n] = v;
    while( i > 0 ) {
      i = i-1 >> 1;
      const x = (l>i+i+1)?a[i+i+1]:e;
      const y = (l>i+i+2)?a[i+i+2]:e;
      a[i] = this.#op( x, y );
    }
  }
  get(l,r) {
    const a = this.#a, e = this.#e, op = this.#op;
    return function q(l,r,x,y,i){
      if ( l <= x && y <= r ) return a[i];
      if ( l >= y || x >= r || a.length <= i) return e;
      return op(
        q(l,r,x,x+y>>1,i+i+1),
        q(l,r,x+y>>1,y,i+i+2)
      );  
    }(l,r,0,this.#n+1,0);
  }
}
console.log((args=>{
  const tmp = args.trim().split`\n`;
  const S = tmp[1].split``.map(v=>1<<(v.charCodeAt()-97)), Q = tmp[2]|0;
  const Query = tmp.slice(3).map(r=>r.split` `);
  const st = new SegmentTree(S,(a,b)=>a|b,0);
  const o = [];
  for ( let i = 0; i < Q; i++ ) {
    const [t,x,y] = Query[i];
    if ( t === '1' ) {
      st.update(x-1,1<<(y.charCodeAt()-97));
    } else {
      const b = st.get(x-1,y|0);
      let c = 0;
      for ( let i = 0; i < 26; i++ ) if ( b&1<<i ) c++;
      o.push(c);
    }
  }
  return o.join`\n`;
})(require('fs').readFileSync('/dev/stdin', 'utf8')));
