#include <iostream>
#include <deque>
#include <cstring>


using namespace std;

#define INF 100000000
#define YJ 1145141919
#define INF_INT_MAX 2147483647
#define INF_LL 9223372036854775
#define INF_LL_MAX 9223372036854775807
#define EPS 1e-10
#define MOD 1000000007
#define MOD9 998244353
#define Pi acos(-1)
#define LL long long
#define ULL unsigned long long
#define LD long double

#define int long long

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(a)  begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())

#define MAX_SEG 1000005

struct Node{
  int sum;
  int delay;
  bool delayFlag;
  Node(){
    sum = delay = delayFlag = 0;
  }
};

int n;
Node seg[2*MAX_SEG];

//セグメントツリーの要素数の設定
void Init(int _n){
  n = 1;
  while(_n > n)
    n *= 2;
}

//遅延値の評価
inline void DelayEvaluate(int k, int a, int b){

  //遅延評価フラグが立っていないなら遅延評価を行わない
  if(!seg[k].delayFlag)
    return;

  //現在の値を遅延値に基づいて更新
  seg[k].sum += seg[k].delay * (b-a);
  
  //今見ているノードに子がある場合
  if(k < n-1){
    //遅延値を子に伝播させる
    seg[2*k+1].delay += seg[k].delay;
    seg[2*k+2].delay += seg[k].delay;
    //遅延評価フラグを立てる
    seg[2*k+1].delayFlag = seg[2*k+2].delayFlag = true;
  }

  //遅延評価を行ったので自分の遅延値等は初期化しておく
  seg[k].delay = seg[k].delayFlag = 0;

}

//ノードkの値の計算
//子の値が計算終了していることが前提
inline void UpdateNode(int k){
  seg[k].sum = seg[2*k+1].sum + seg[2*k+2].sum;
}

//[l,r)の範囲一様にvを加算する
void UpdateRange(int l, int r, int v, int k = 0, int a = 0, int b = n){

  //とりあえず遅延計算
  DelayEvaluate(k,a,b);
  
  //見ているノードが[l,r)と全く被っていない場合
  if(b <= l || r <= a){
    return;
  }
  //完全に被っている場合
  else if(l <= a && b <= r){
    seg[k].delay += v;
    seg[k].delayFlag = true;
    DelayEvaluate(k,a,b);
    return;
  }
  //ちょい被りの場合
  else{
    int mid = (a+b)/2;
    UpdateRange(l,r,v,2*k+1,a,mid);
    UpdateRange(l,r,v,2*k+2,mid,b);
    UpdateNode(k);
    return;
  }

}

//[l,r)の値の合計を出力する
int Query(int l, int r, int k = 0, int a = 0, int b = n){

  //とりあえず遅延計算
  DelayEvaluate(k,a,b);

  //今見ているノードが[l,r)と全く被っていない場合
  if(b <= l || r <= a)
    return 0;
  //完全に被っている場合
  else if(l <= a && b <= r){
    return seg[k].sum;
  }
  //ちょい被りの場合
  else{
    int vl,vr;
    int mid = (a+b)/2;
    vl = Query(l,r,2*k+1,a,mid);
    vr = Query(l,r,2*k+2,mid,b);
    return vl+vr;
  }

}

const int MAX_N = 1000005;
const int MAX_Q = 75;

int N;
string S;
int Q;
int K[MAX_Q];

int sumM[MAX_N];

class SlideMinDeque {
public:
    SlideMinDeque(int size) : _size(size) {
        deq.clear();
    }

    void add(int index) {
        deq.push_back(index);
    }

    int get(int index) { //何かを排出した
      int ret = -1;
      while(deq.size()) {
          if(deq.front() <= index-_size) {
              ret = deq.front();
              deq.pop_front();
          } else {
              return ret;
          }
      }
      return ret;
    }

    int getSize()
    {
      return deq.size();
    }

private:
    int _size;
    deque<int> deq; 
};

signed main()
{
  cin >> N;
  cin >> S;
  cin >> Q;
  REP(q,Q) {
    cin >> K[q];
  }

  REP(n,N) {
    sumM[n+1] = sumM[n] + (S[n] == 'M');
  }

  Init(N);

  REP(q,Q) {
    
    memset(seg, 0, sizeof(seg));

    SlideMinDeque deq(K[q]);

    int ans = 0;
    int tmp = 0;
    REP(n,N) {
      int r = deq.get(n);
      if(r >= 0) {
        // cerr << n << " ! " << r << endl;
        tmp -= (sumM[n] - sumM[r]);
      }
      if(S[n] == 'D') {
        deq.add(n);
      }
      if(S[n] == 'M') {
        tmp += deq.getSize();
      }
      if(S[n] == 'C') {
        ans += tmp;
      }
      // cerr << n << " " << tmp << endl;
    
    }

    cout << ans << endl;
  }

  return 0;
}

Measured memory_bytes: 63800