#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

// 定义一个极大值
const ll INF = 1e18;

// 线段树支持区间最小查询和点更新
struct SegmentTree {
    int n;
    vector<ll> tree;

    SegmentTree(int size) {
        n = 1;
        while(n < size) n <<= 1;
        tree.assign(2*n, INF);
    }

    // 更新位置 pos (0-based) 的值为val
    void update(int pos, ll val) {
        pos += n;
        tree[pos] = min(tree[pos], val);
        while(pos > 1){
            pos >>= 1;
            tree[pos] = min(tree[2*pos], tree[2*pos+1]);
        }
    }

    // 查询区间 [l, r) 的最小值
    ll query(int l, int r) const {
        ll res = INF;
        int left = l + n;
        int right = r + n;
        while(left < right){
            if(left & 1){
                res = min(res, tree[left++]);
            }
            if(right & 1){
                res = min(res, tree[--right]);
            }
            left >>= 1;
            right >>= 1;
        }
        return res;
    }
};

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    ll m;
    cin >> n >> m;
    vector<ll> a(n);
    for(auto &x:a) cin >> x;
    
    // 计算前缀和
    vector<ll> s(n+1, 0);
    for(int i=1;i<=n;i++) s[i] = s[i-1] + a[i-1];
    
    // 离散化前缀和
    vector<ll> all_s = s;
    // 还需要 x = s[i] - m
    for(int i=0;i<=n;i++) all_s.push_back(s[i] - m);
    sort(all_s.begin(), all_s.end());
    all_s.erase(unique(all_s.begin(), all_s.end()), all_s.end());
    
    // 映射 s[j] 和 x 到离散化后的索引
    auto get_idx = [&](ll val) -> int {
        return lower_bound(all_s.begin(), all_s.end(), val) - all_s.begin();
    };
    
    int size = all_s.size();
    // 初始化两个线段树
    SegmentTree st1(size); // 存 dp[j] - s[j]
    SegmentTree st2(size); // 存 dp[j] + s[j]
    
    // 初始化 dp[0] = 0
    // 插入 j=0 的情况
    st1.update(get_idx(s[0]), 0 - s[0]);
    st2.update(get_idx(s[0]), 0 + s[0]);
    
    // 初始化 dp array
    // 可以不存储全 dp array，因为只需要 dp[j] 继续更新下去
    vector<ll> dp(n+1, INF);
    dp[0] = 0;
    
    for(int i=1;i<=n;i++){
        ll x = s[i] - m;
        // 找到 x 在 all_s 中的离散化索引
        // 对于 st1，查询 s[j] <= x
        // 找最大的 s[j] <= x，即 upper_bound(x) - 1
        int pos1 = upper_bound(all_s.begin(), all_s.end(), x) - all_s.begin() - 1;
        ll res1 = INF;
        if(pos1 >= 0){
            res1 = st1.query(0, pos1+1) + x;
        }
        // 对于 st2，查询 s[j] >= x
        // 找最小的 s[j] >= x，即 lower_bound(x)
        int pos2 = lower_bound(all_s.begin(), all_s.end(), x) - all_s.begin();
        ll res2 = INF;
        if(pos2 < size){
            res2 = st2.query(pos2, size) - x;
        }
        // 取两者最小值作为 dp[i]
        dp[i] = min(res1, res2);
        // 更新线段树
        st1.update(get_idx(s[i]), dp[i] - s[i]);
        st2.update(get_idx(s[i]), dp[i] + s[i]);
    }
    
    cout << dp[n] << "\n";
}