#include <algorithm>  
#include <iostream>  
#include <sstream>  
#include <string>  
#include <cstring>
#include <vector>  
#include <queue>  
#include <set>  
#include <map>  
#include <cstdio>  
#include <cstdlib>  
#include <cctype>  
#include <cmath>  
#include <list>  
#include <cassert>
#include <ctime>
#include <climits>
using namespace std;  

#define PB push_back  
#define MP make_pair  
#define SZ(v) ((int)(v).size())  
#define FOR(i,a,b) for(int i=(a);i<(b);++i)  
#define REP(i,n) FOR(i,0,n)  
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)  
#define REPE(i,n) FORE(i,0,n)  
#define FORSZ(i,a,v) FOR(i,a,SZ(v))  
#define REPSZ(i,v) REP(i,SZ(v))  
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN=200000;
struct Block { int l,r,val; int mid; vector<int> pref,suff; };

int n,need;
int a[MAXN];

int ufpar[MAXN],ufsz[MAXN];
Block block[MAXN];
pair<int,int> o[MAXN];

int uffind(int x) { if(ufpar[x]==x) return x; return ufpar[x]=uffind(ufpar[x]); }
void ufunite(int a,int b) { a=uffind(a),b=uffind(b); if(a==b) return; if(ufsz[a]<ufsz[b]) swap(a,b); ufpar[b]=a,ufsz[a]+=ufsz[b]; }

void levelup(Block &b) {
	vector<int> npref(SZ(b.pref)/need,0); FORSZ(i,need-1,b.pref) npref[(i+1)/need-1]+=b.pref[i]; b.pref=npref;
	vector<int> nsuff(SZ(b.suff)/need,0); FORSZ(i,need-1,b.suff) nsuff[(i+1)/need-1]+=b.suff[i]; b.suff=nsuff;
	b.mid/=need; if(b.mid>0) ++b.val; else b.val=-1;
}
Block merge(const Block &a,const Block &b,ll &ans) {
	assert(a.r+1==b.l); assert(a.val==b.val);
	Block ret; ret.l=a.l; ret.r=b.r; ret.val=a.val; ret.mid=a.mid+b.mid;
	vector<int> npref=a.pref; REPSZ(i,b.pref) { int x=a.mid+i; while(x>=SZ(npref)) npref.PB(0); npref[x]+=b.pref[i]; } ret.pref=npref;
	vector<int> nsuff=b.suff; REPSZ(i,a.suff) { int x=b.mid+i; while(x>=SZ(nsuff)) nsuff.PB(0); nsuff[x]+=a.suff[i]; } ret.suff=nsuff;
	int sum=0,at=0; REPSZ(i,b.pref) sum+=b.pref[i]; for(int i=SZ(a.suff)-1;i>=0;--i) { while(i+1+at+1<need) sum-=b.pref[at],++at; ans+=(ll)a.suff[i]*sum; }
	//printf("merged: [%d..%d] val=%d mid=%d pref=",ret.l,ret.r,ret.val,ret.mid); REPSZ(i,ret.pref) { if(i!=0) printf(","); printf("%d",ret.pref[i]); } printf(" suff="); REPSZ(i,ret.suff) { if(i!=0) printf(","); printf("%d",ret.suff[i]); } puts("");
	return ret;
}
Block merge(const vector<Block> &blocks,ll &ans) {
	FORSZ(i,1,blocks) assert(blocks[i-1].r+1==blocks[i].l),assert(blocks[i-1].val==blocks[i].val);
	Block ret; ret.l=blocks[0].l,ret.r=blocks[SZ(blocks)-1].r,ret.val=blocks[0].val,ret.mid=0; REPSZ(i,blocks) ret.mid+=blocks[i].mid;
	{ vector<int> npref; int off=0; REPSZ(i,blocks) { REPSZ(j,blocks[i].pref) { int x=off+j; while(x>=SZ(npref)) npref.PB(0); npref[x]+=blocks[i].pref[j]; } off+=blocks[i].mid; } ret.pref=npref; }
	{ vector<int> nsuff; int off=0; for(int i=SZ(blocks)-1;i>=0;--i) { REPSZ(j,blocks[i].suff) { int x=off+j; while(x>=SZ(nsuff)) nsuff.PB(0); nsuff[x]+=blocks[i].suff[j]; } off+=blocks[i].mid; } ret.suff=nsuff; }
	{
		int sum=0; REPSZ(i,blocks) REPSZ(j,blocks[i].pref) sum+=blocks[i].pref[j];
		int ii=0,jj=0,off=0;
		REPSZ(i,blocks) { 
			off-=blocks[i].mid;
			for(int j=SZ(blocks[i].suff)-1;j>=0;--j) { 
				while(ii<=i||ii<SZ(blocks)&&j+1+jj+1+off<need) { sum-=blocks[ii].pref[jj]; ++jj; if(jj==SZ(blocks[ii].pref)) off+=blocks[ii].mid,++ii,jj=0; }
				ans+=(ll)blocks[i].suff[j]*sum;
			}
		} 
	}
	//printf("merged: [%d..%d] val=%d mid=%d pref=",ret.l,ret.r,ret.val,ret.mid); REPSZ(i,ret.pref) { if(i!=0) printf(","); printf("%d",ret.pref[i]); } printf(" suff="); REPSZ(i,ret.suff) { if(i!=0) printf(","); printf("%d",ret.suff[i]); } puts("");
	return ret;
}



ll solve() {
	REP(i,n) ufpar[i]=i,ufsz[i]=1;
	REP(i,n) { block[i].l=block[i].r=i,block[i].val=a[i],block[i].mid=1; block[i].pref=block[i].suff=vector<int>(1,1); }
	REP(i,n) o[i]=MP(a[i],i);
	sort(o,o+n);
	ll ret=n;
	for(int l=0,r=l;l<n;l=r) {
		int val=o[l].first;
		while(r<n&&o[r].first==val) ++r;
		vector<int> cur;
		cur.PB(-1);
		FOR(i,l,r) {
			int at=o[i].second,prv=-1,nxt=-1;
			if(at-1>=0&&a[at-1]<=val) { int x=uffind(at-1); while(block[x].val!=-1&&block[x].val<val) levelup(block[x]); if(block[x].val!=-1) prv=x; }
			if(at+1 <n&&a[at+1]<=val) { int x=uffind(at+1); while(block[x].val!=-1&&block[x].val<val) levelup(block[x]); if(block[x].val!=-1) nxt=x; }
			if((SZ(cur)<1||cur[SZ(cur)-1]!=prv)&&(SZ(cur)<2||cur[SZ(cur)-2]!=prv)) { cur.PB(-1); cur.PB(prv); }
			if(SZ(cur)<1||cur[SZ(cur)-1]!=at) cur.PB(at);
			cur.PB(nxt);
		}
		cur.PB(-1);
		//printf("cur:"); REPSZ(i,cur) printf(" %d",cur[i]); puts("");
		REPSZ(i,cur) if(cur[i]!=-1&&cur[i-1]==-1) {
			int j=i; while(cur[j+1]!=-1) ++j;
			vector<Block> blocks; FORE(k,i,j) blocks.PB(block[cur[k]]);
			//Block me=blocks[0]; FORSZ(k,1,blocks) me=merge(me,blocks[k],ret);
			Block me=merge(blocks,ret);
			FORE(k,i+1,j) ufunite(cur[i],cur[k]);
			block[uffind(cur[i])]=me;
		}
	}
	return ret;
}


void run() {
	scanf("%d%d",&n,&need);
	REP(i,n) scanf("%d",&a[i]);
	printf("%lld\n",solve());
}

void stress() {
	REP(rep,10000) {
		n=100; need=2; REP(i,n) a[i]=rand()%4+1;
		//printf("%d %d\n",n,need); REP(i,n) { if(i!=0) printf(" "); printf("%d",a[i]); } puts("");
		solve();
		printf(".");
	}
}

int main() {
	run();
	//stress();
	return 0;
}
