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

const int POPULATION_SIZE = 5000; 
const double MUTATION_RATE = 0.4; 

int n;
long long x;
vector<long long> w;

struct Individual {
    vector<int> chromosome;
    int rides;
    double fitness;
};

void evaluate(Individual& ind) {
    int current_rides = 1;
    long long current_weight = 0;
    double sum_squares = 0;

    for (int idx : ind.chromosome) {
        if (current_weight + w[idx] <= x) {
            current_weight += w[idx];
        } else {
            sum_squares += pow((double)current_weight / x, 2);
            current_rides++;
            current_weight = w[idx];
        }
    }

    sum_squares += pow((double)current_weight / x, 2);
    ind.rides = current_rides;
    ind.fitness = sum_squares / current_rides; 
}


Individual crossover(const Individual& p1, const Individual& p2) {
    Individual child;
    child.chromosome.assign(n, -1);
    int left = rand() % n;
    int right = rand() % n;
    if (left > right) swap(left, right);

    vector<bool> in_child(n, false);
    for (int i = left; i <= right; ++i) {
        child.chromosome[i] = p1.chromosome[i];
        in_child[p1.chromosome[i]] = true;
    }

    int curr_p2 = 0;

    for (int i = 0; i < n; ++i) {
        if (child.chromosome[i] == -1) {
            while (in_child[p2.chromosome[curr_p2]]) {
                curr_p2++;
            }
            child.chromosome[i] = p2.chromosome[curr_p2];
            in_child[p2.chromosome[curr_p2]] = true;
        }
    }

    return child;
}


void mutate(Individual& ind) {
    if ((double)rand() / RAND_MAX < MUTATION_RATE) {
        int i = rand() % n;
        int j = rand() % n;
        swap(ind.chromosome[i], ind.chromosome[j]);
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    srand(time(NULL));

    double start_time = clock(); 

    cin >> n >> x;
    w.resize(n);
    for (int i = 0; i < n; ++i) cin >> w[i];

    vector<Individual> population(POPULATION_SIZE);
    int best_global_rides = n;

    for (int i = 0; i < POPULATION_SIZE; ++i) {
        population[i].chromosome.resize(n);
        iota(population[i].chromosome.begin(), population[i].chromosome.end(), 0);
        random_shuffle(population[i].chromosome.begin(), population[i].chromosome.end());
        evaluate(population[i]);
        best_global_rides = min(best_global_rides, population[i].rides);
    }

    while ((double)(clock() - start_time) / CLOCKS_PER_SEC < 0.90) {
        sort(population.begin(), population.end(), [](const Individual& a, const Individual& b) {
            return a.fitness > b.fitness;
        });

        vector<Individual> new_population;
        
        int elitism_count = POPULATION_SIZE / 10;
        for (int i = 0; i < elitism_count; ++i) {
            new_population.push_back(population[i]);
        }

        while (new_population.size() < POPULATION_SIZE) {
            int p1_idx = rand() % (POPULATION_SIZE / 2);
            int p2_idx = rand() % (POPULATION_SIZE / 2);
            
            Individual child = crossover(population[p1_idx], population[p2_idx]);
            mutate(child);
            evaluate(child);
            
            best_global_rides = min(best_global_rides, child.rides);
            new_population.push_back(child);
        }

        population = new_population;
    }

    cout << best_global_rides << "\n";
    return 0;
}