#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3 * 100 * 1000;
const long long INF = 1LL * 1000 * 1000 * 1000 * 1000;
int finishLine, numberOfRamps;
set<pair<int, int> > rampPositions;
vector<pair<int, pair<long long, bool> > > adj[MAXN];
set<pair<long long, int> > chosenTree;
set<pair<int, int> > ramps[MAXN];
long long dis[MAXN];
pair<int, bool> parent[MAXN];
set<pair<int, int> > bridges[MAXN];
struct comp_pair_int {
  bool operator()(const pair<int, int> &a, const int &b) {
    return (a.first < b);
  }
  bool operator()(const int &a, const pair<int, int> &b) {
    return (a < b.first);
  }
};
void dijkstra() {
  for (int i = 0; i < 2 * numberOfRamps + 2; ++i) {
    dis[i] = INF;
    chosenTree.insert(make_pair(INF, i));
  }
  dis[2 * numberOfRamps] = 0;
  chosenTree.insert(make_pair(0, 2 * numberOfRamps));
  while (chosenTree.size()) {
    int source = (*chosenTree.begin()).second;
    chosenTree.erase(chosenTree.begin());
    for (int i = 0; i < adj[source].size(); ++i) {
      int neighbor = adj[source][i].first;
      int weight = adj[source][i].second.first;
      bool isRamp = adj[source][i].second.second;
      if (dis[neighbor] > dis[source] + weight) {
        chosenTree.erase(make_pair(dis[neighbor], neighbor));
        parent[neighbor].first = source;
        parent[neighbor].second = isRamp;
        dis[neighbor] = dis[source] + weight;
        chosenTree.insert(make_pair(dis[neighbor], neighbor));
      }
    }
  }
  return;
}
int main() {
  cin >> numberOfRamps >> finishLine;
  for (int i = 0; i < numberOfRamps; ++i) {
    int start, finish, travelTime, intersection;
    cin >> start >> finish >> travelTime >> intersection;
    finish += start;
    start -= intersection;
    if (start < 0) {
      continue;
    }
    adj[2 * i].push_back(
        make_pair(2 * i + 1, make_pair(travelTime + intersection, true)));
    rampPositions.insert(make_pair(start, 2 * i));
    rampPositions.insert(make_pair(finish, 2 * i + 1));
    ramps[2 * i].insert(make_pair(2 * i + 1, i + 1));
  }
  rampPositions.insert(make_pair(0, 2 * numberOfRamps));
  rampPositions.insert(make_pair(finishLine, 2 * numberOfRamps + 1));
  {
    set<pair<int, int> >::iterator test = rampPositions.begin();
    while (test != rampPositions.end()) {
      test++;
    }
  }
  set<pair<int, int> >::iterator current = rampPositions.begin(),
                                 prev = rampPositions.begin();
  current++;
  while (current != rampPositions.end()) {
    int vertexOne = (*current).second, vertexTwo = (*prev).second,
        distance = (*current).first - (*prev).first;
    adj[vertexOne].push_back(make_pair(vertexTwo, make_pair(distance, false)));
    adj[vertexTwo].push_back(make_pair(vertexOne, make_pair(distance, false)));
    current++;
    prev++;
  }
  dijkstra();
  cout << dis[2 * numberOfRamps + 1] << endl;
  vector<int> ans;
  int root = 2 * numberOfRamps + 1, par = -1;
  bool isRamp = false;
  while (root != 2 * numberOfRamps) {
    par = parent[root].first;
    isRamp = parent[root].second;
    if (isRamp) {
      set<pair<int, int> >::iterator pos;
      pos = lower_bound(ramps[par].begin(), ramps[par].end(), root,
                        comp_pair_int());
      ans.push_back((*pos).second);
    }
    root = par;
  }
  cout << ans.size() << endl;
  while (ans.size()) {
    cout << ans[ans.size() - 1] << " ";
    ans.pop_back();
  }
  return 0;
}
