#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 1e6+5;
constexpr LL INF = 0x3f3f3f3f3f3f3f3f;
int n;
namespace LiChaoSegmentTree
{
struct Line {
LL k, b;
LL calc(LL x) const { return k*x+b; }
}t[4*N];
#define lc (x<<1)
#define rc (x<<1|1)
void update(int x, int l, int r, Line qval)
{
int mid = (l+r)/2;
// fprintf(stderr, "* (%d, %d)\n", l, r);
if(qval.calc(l) < t[x].calc(l) && qval.calc(r) < t[x].calc(r)) {
t[x] = qval;
} else if(qval.calc(l) < t[x].calc(l)) {
if(qval.calc(mid) > t[x].calc(mid))
update(lc, l, mid, qval);
else swap(t[x], qval), update(rc, mid+1, r, qval);
} else if(qval.calc(r) < t[x].calc(r)) {
if(qval.calc(mid+1) > t[x].calc(mid+1))
update(rc, mid+1, r, qval);
else swap(t[x], qval), update(lc, l, mid, qval);
}
}
LL query(int x, int l, int r, int qpos)
{
if(l == r) return t[x].calc(qpos);
LL res = t[x].calc(qpos);
int mid = (l+r)/2;
if(qpos <= mid) res = min(res, query(lc, l, mid, qpos));
else res = min(res, query(rc, mid+1, r, qpos));
return res;
}
void addSegment(Line qval) { update(1, 0, n, qval); }
LL queryPoint(int qpos) { return query(1, 0, n, qpos); }
void build()
{
for(int i = 1; i < 4*N; i++)
t[i].k = 0, t[i].b = INF;
}
}
using LiChaoSegmentTree::Line;
LL m;
char str[N];
LL cnta[N], cntq[N], sum[N];
LL f[N];
int main()
{
// freopen("1.in","r",stdin);
scanf("%d%lld", &n, &m);
scanf(" %s", str+1);
for(int i = 1; i <= n; i++) {
cnta[i] = cnta[i-1]+(str[i] == '+');
cntq[i] = cntq[i-1]+(str[i] == '?');
sum[i] = sum[i-1]+(str[i] == '?')*cnta[i];
}
f[0] = -m;
q[++tt] = 0;
// f[i] = f[j]+(sum[i]-sum[j])-(cntq[i]-cntq[j])*cnta[j]+m;
// f[i]-sum[i]-m = -cnta[j] * cntq[i] + cnta[j]*cntq[j]-sum[j]+f[j];
LiChaoSegmentTree::build();
auto getLine = [&](int j) {
return Line{-cnta[j], cnta[j]*cntq[j]-sum[j]+f[j]};
};
LiChaoSegmentTree::addSegment(getLine(0));
for(int i = 1; i <= n; i++) {
f[i] = LiChaoSegmentTree::queryPoint(cntq[i])+sum[i]+m;
LiChaoSegmentTree::addSegment(getLine(i));
}
printf("%lld\n", f[n]);
return 0;
return 0;
}