#include <iostream>
#include <cstdio>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <utility>
#include <numeric>
#include <algorithm>
#include <functional>
#include <cctype>
#include <complex>
#include <string>
#include <sstream>
#include <cassert>
using namespace std;

//common
#define BR "\n"

#define ALL(c) (c).begin(),(c).end()
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define EACH(it,o) for(auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l,v,r) ((l)<=(v) && (v)<(r))

typedef vector<int> vi; typedef pair<int,int> pii; typedef vector<pair<int,int> > vpii;
typedef long long ll; typedef vector<long long> vl; typedef pair<long long,long long> pll; typedef vector<pair<long long,long long> > vpll;
typedef vector<string> vs; typedef long double ld;

//config
#define MODE_DEBUG
//#define INF 1<<30
//#define EPS 1e-8
//const ll MOD =100000007;

//debug
#ifdef MODE_DEBUG
#define  DUMP(x)  cerr << #x << " = " << (x) <<endl
#define DEBUG(x) DUMP(x) << " (L" << __LINE__ << ")" << " " << __FILE__<<endl
#define CHECK(exp,act)  if(exp!=act){DUMP(exp);DEBUG(act);}
#define STOP(e)  CHECK(e,true);if(!(e)) exit(1);
#else
#define DUMP(x)
#define DEBUG(x)
#define CHECK(exp,act)
#define STOP(e)
#endif

template<class T> inline string toString(const vector<T>& x) {
	stringstream ss;
	REP(i,x.size()){
		if(i!=0)ss<<" ";
		ss<< x[i];
	}
	return ss.str();
}
template<class T> inline string toString(const vector<vector<T>>& map) {
	stringstream ss;
	REP(i,map.size()){
		if(i!=0)ss<<BR;
		ss<< toString(map[i]);
	}
	return ss.str();
}
template<class K,class V>  string toString(map<K,V>& x) {
	string res;stringstream ss;
	for(auto& p:x)ss<< p.first<<":" << p.second<<" ";
	return ss.str();
}

template<typename T,typename V> inline T mod(T v,V MOD){
	return (v%MOD+MOD)%MOD;
}


namespace SegmentTreeSpace{
	const int INF =1<<28;
	
	//RMQ
	struct SegmentTree{
		vector<int> dat;//dat[i] .. i,i+1のLCP
		int n,size;
		SegmentTree(int _n){
			n=pow2Fit(_n);size=2*n-1;
			dat=vector<int>(size);
			fill(ALL(dat),INF);
		}
		SegmentTree(){
			SegmentTree(0);			
		}
		
		int pow2Fit(int n){
			int v=1;
			while(v<n)v<<=1;
			return v;
		}
		void update(int v,int a){
			v+=n-1;
			dat[v]=a;
			while(v>0){
				int parent=v=(v-1)/2;
				int chl=parent*2+1,chr=parent*2+2;
				dat[parent]=min(dat[chl],dat[chr]);
			}
		}
		//0<=a<=b<n
		int query(int a,int b){
			return query(0,a,b,0,n);
		}
		private:
		//[a,...,b] =min(dat[a],...,dat[b-1])
		int query(int v,int a,int b,int l,int r){
			if(r<=a || b<=l)return INF;//out range
			if(a<=l && r<=b)return dat[v];

			int vl=query(v*2+1,a,b,l,(l+r)/2);
			int vr=query(v*2+2,a,b,(l+r)/2,r);
			return min(vl,vr);
		}
	};
}


/*
Suffix array O(n lg^2 n)
LCP table O(n)
*/
namespace SuffixArraySpace{

	using namespace SegmentTreeSpace;
	class SuffixArray{
		public:
			//sa 辞書順i番目の接尾辞の開始位置 [s...)
			//pos 文字列[i...)の辞書順位置 s
			/// LCP …Longest Common Prefix
			vector<int> sa,pos;

			SegmentTree lcp;
			SuffixArray(string S):S(S){
				lcp=SegmentTree(S.size());
				N=S.size();
				sa=vector<int>(N);pos=vector<int>(N);
				rank=vector<int>(N);
				buildSA();buildLCP();
			};
			int N,k;
		private:
			string S;
			vector<int> rank;

			// class SufCmp{
			// 	public:
			// 		const SuffixArray& suf;
			// 		SufCmp(const SuffixArray& suf):suf(suf){
			// 		}
			// 		bool operator()(const int i,const int j) const{
			// 			if (suf.pos[i] != suf.pos[j])return suf.pos[i] < suf.pos[j];
			// 			int i2=i+suf.k,j2=j+suf.k;
			// 			return (i2 < suf.N && j2< suf.N) ? suf.pos[i2] < suf.pos[j2] : i2 > j2;
			// 		}
			// };

			//O(nlog^2(n))
			void buildSA(){
				auto sufCmp=[&,this](int i,int j){
					if (pos[i] != pos[j])return pos[i] < pos[j];
					i += k;j += k;
					return (i < N && j < N) ? pos[i] < pos[j] : i > j;
				};
				REP(i, N) sa[i] = i, pos[i] = S[i];
				for (k = 1;; k *= 2){
					sort(ALL(sa), sufCmp);
					REP(i, N - 1) rank[i + 1] = rank[i] + sufCmp(sa[i], sa[i + 1]);
					REP(i, N) pos[sa[i]] = rank[i];
					if (rank[N - 1] == N - 1) break;
				}
			}
			//O(n)
			void buildLCP(){
				for (int i = 0, k = 0; i < N; ++i) if (pos[i] != N - 1){
					for (int j = sa[pos[i] + 1]; S[i + k] == S[j + k];)++k;
					lcp.update(pos[i],k);
					if (k)--k;
				}
			}
		public:
			//libs
			//LCP[a,...b]を求める． Zを含む
			//O(log(n))
			int LCP(int a,int b){
				if(a==b) return N-sa[a];
				return lcp.query(a,b);
			}

			// k-ミスマッチマッチング
			//O(k*n)
			static int mis_match_contains(const string& S,const string& T,int k){
				string st=S+"#"+T;
				SuffixArray suf(st);
				int res=0;
				for(int i=0;i+(int)T.size()<=(int)S.size() ;i++){
					DUMP(i);
					int si=i,ti=S.size()+1;
					DUMP(si);DUMP(ti);
					int match=0;
					for(int j=0;j<=k;j++){
						if(!(si<(int)S.size() && ti<(int)st.size()))break;
						int l=suf.pos[si],r=suf.pos[ti];
						if(l>r)swap(l,r);
						int lcp=suf.LCP(l,r);
						match+=lcp;
						si+=lcp+1;ti+=lcp+1;
					}
					DUMP(match);
					if(match==(int)T.size()-k)res++;
					DUMP(si);DUMP(ti);DUMP(res);
					
				}
				return res;
			}
			//:TODO 最長回文
	};
}

using namespace SuffixArraySpace;

int main(){
	while(true){
		int n;cin >> n;
		if(n==0)break;
		int m;cin >> m;
		string s;cin >>s;

		string ioi="I";REP(i,n)ioi+="OI";
		//DUMP(ioi.size());
		SuffixArray suf(ioi+"#"+s);
		int res=0;
		REP(i,suf.N){
		}
		for(int i=ioi.size()+1;i<suf.N;i++){
			if(suf.LCP(suf.pos[0],suf.pos[i])==ioi.size())res++;
		}
		cout << res <<endl;

	}
	return 0;
}

Measured memory_bytes: 24160