#include <bits/stdc++.h>
using std::lower_bound;
using std::max;
using std::min;
using std::random_shuffle;
using std::reverse;
using std::sort;
using std::swap;
using std::unique;
using std::upper_bound;
using std::vector;
void open(const char *s) {}
int rd() {
  int s = 0, c, b = 0;
  while (((c = getchar()) < '0' || c > '9') && c != '-')
    ;
  if (c == '-') {
    c = getchar();
    b = 1;
  }
  do {
    s = s * 10 + c - '0';
  } while ((c = getchar()) >= '0' && c <= '9');
  return b ? -s : s;
}
void put(int x) {
  if (!x) {
    putchar('0');
    return;
  }
  static int c[20];
  int t = 0;
  while (x) {
    c[++t] = x % 10;
    x /= 10;
  }
  while (t) putchar(c[t--] + '0');
}
int upmin(int &a, int b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
int upmax(int &a, int b) {
  if (b > a) {
    a = b;
    return 1;
  }
  return 0;
}
const int N = 100010;
int n, m;
int f[N];
int nodecnt;
struct edge {
  int v, a, b;
  bool used;
  edge(int _v = 0, int _a = 0, int _b = 0) : v(_v), a(_a), b(_b), used(0) {}
};
vector<edge> g1[N];
void dfs1(int x, int fa) {
  f[x] = fa;
  for (auto v : g1[x])
    if (v.v != fa) dfs1(v.v, x);
}
int lastnode[N];
vector<edge> g[2 * N];
struct info {
  long long x, y;
  int id;
  info(long long _x = 0, long long _y = 0, int _id = 0)
      : x(_x), y(_y), id(_id) {}
  long long val(int t) { return x * t + y; }
};
info operator-(info a, info b) { return info(a.x - b.x, a.y - b.y); }
long long cross(info a, info b) { return a.x * b.y - a.y * b.x; }
info a1[N];
int cnt1;
int cmp(info a, info b) {
  if (a.x != b.x) return a.x < b.x;
  if (a.y != b.y) return a.y < b.y;
  return a.id < b.id;
}
int lx[N], ly[N], la[N], lb[N];
int op(int x) { return ((x - 1) ^ 1) + 1; }
int d[2 * N];
vector<std::pair<long long, long long> > dist[2 * N];
int cnt;
int c1[2 * N];
int c2[2 * N];
std::pair<int, int> c3[2 * N];
int sz[2 * N];
int cf[2 * N];
int cc[2 * N];
vector<info> c[4 * N], temp;
int now[4 * N];
int num;
int mx;
void dfs3(int x, int fa) {
  sz[x] = 1;
  for (auto v : g[x])
    if (v.v != fa && !v.used) {
      dfs3(v.v, x);
      sz[x] += sz[v.v];
    }
}
void dfs4(int x, int fa) {
  for (auto v : g[x])
    if (v.v != fa && !v.used) {
      dfs4(v.v, x);
      if (max(sz[v.v], num - sz[v.v]) < mx) {
        mx = max(sz[v.v], num - sz[v.v]);
        c1[cnt] = x;
        c2[cnt] = v.v;
      }
    }
}
void dfs5(int x, int fa, long long v1, long long v2) {
  if (x <= n) {
    dist[x].push_back(std::pair<long long, long long>(v1, v2));
    temp.push_back(info(v1, v2, x));
  }
  for (auto v : g[x])
    if (v.v != fa && !v.used) dfs5(v.v, x, v1 + v.a, v2 + v.b);
}
void build(int ti) {
  static info a[N];
  int top = 0;
  sort(temp.begin(), temp.end(), cmp);
  int len = temp.size();
  for (int i = 0; i < len; i++) {
    while (top >= 2 && cross(temp[i] - a[top], a[top] - a[top - 1]) <= 0) top--;
    a[++top] = temp[i];
  }
  for (int i = 1; i <= top; i++) c[ti].push_back(a[i]);
  temp.clear();
}
void divide(int x, int fa) {
  dfs3(x, 0);
  num = sz[x];
  if (num == 1) {
    cc[x] = fa;
    return;
  }
  mx = 0x7fffffff;
  cnt++;
  dfs4(x, 0);
  for (auto &v : g[c1[cnt]])
    if (v.v == c2[cnt]) {
      v.used = 1;
      c3[cnt].first = v.a;
      c3[cnt].second = v.b;
    }
  for (auto &v : g[c2[cnt]])
    if (v.v == c1[cnt]) v.used = 1;
  cf[cnt] = fa;
  dfs5(c1[cnt], 0, 0, 0);
  build(2 * cnt - 1);
  dfs5(c2[cnt], 0, 0, 0);
  build(2 * cnt);
  int cur = cnt;
  divide(c1[cur], 2 * cur - 1);
  divide(c2[cur], 2 * cur);
}
void dfs2(int x, int fa, long long v1, long long v2) {
  if (x <= n) temp.push_back(info(v1, v2, x));
  for (auto v : g[x])
    if (v.v != fa) dfs2(v.v, x, v1 + v.a, v2 + v.b);
}
std::pair<long long, long long> query1(int t) {
  while (now[0] < (int)c[0].size() - 1 &&
         c[0][now[0] + 1].val(t) >= c[0][now[0]].val(t))
    now[0]++;
  return std::pair<long long, long long>(c[0][now[0]].val(t), c[0][now[0]].id);
}
std::pair<long long, long long> operator+(std::pair<long long, long long> a,
                                          std::pair<long long, long long> b) {
  return std::pair<long long, long long>(a.first + b.first,
                                         a.second + b.second);
}
std::pair<long long, long long> query(int x, int t) {
  std::pair<long long, long long> s(0, x);
  for (int i = (int)dist[x].size() - 1, y = cc[x]; i >= 0;
       i--, y = cf[(y + 1) / 2]) {
    y = op(y);
    if (c[y].size()) {
      while (now[y] < (int)c[y].size() - 1 &&
             c[y][now[y] + 1].val(t) >= c[y][now[y]].val(t))
        now[y]++;
      s = max(s, std::pair<long long, long long>(
                     (dist[x][i].first + c3[(y + 1) / 2].first) * t +
                         dist[x][i].second + c3[(y + 1) / 2].second +
                         c[y][now[y]].val(t),
                     c[y][now[y]].id));
    }
  }
  return s;
}
long long ans[1000010];
int main() {
  open("raining");
  scanf("%d%d", &n, &m);
  for (int i = 1; i < n; i++) {
    scanf("%d%d%d%d", &lx[i], &ly[i], &la[i], &lb[i]);
    g1[lx[i]].push_back(ly[i]);
    g1[ly[i]].push_back(lx[i]);
  }
  dfs1(1, 0);
  nodecnt = n;
  for (int i = 1; i <= n; i++) lastnode[i] = i;
  for (int i = 1; i < n; i++) {
    if (f[ly[i]] == lx[i]) swap(lx[i], ly[i]);
    nodecnt++;
    g[nodecnt].push_back(edge(lastnode[ly[i]], 0, 0));
    g[lastnode[ly[i]]].push_back(edge(nodecnt, 0, 0));
    lastnode[ly[i]] = nodecnt;
    g[nodecnt].push_back(edge(lx[i], la[i], lb[i]));
    g[lx[i]].push_back(edge(nodecnt, la[i], lb[i]));
  }
  dfs2(1, 0, 0, 0);
  build(0);
  divide(1, 0);
  int last1 = 0, last2 = 0;
  int cnt = 0;
  for (int i = 0; i < m; i++) {
    std::pair<long long, long long> s1 = query1(i);
    std::pair<long long, long long> s2 = query(s1.second, i);
    printf("%I64d\n", s2.first);
    if (s1.second > s2.second) swap(s1.second, s2.second);
    if (s1.second != last1 || s2.second != last2) {
      last1 = s1.second;
      last2 = s2.second;
      cnt++;
    }
  }
  return 0;
}
