#include <bits/stdc++.h>
using namespace std;
const long long MAXN = 3e5 + 5;
int n, m;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) (ch == '-') && (f = -f), ch = getchar();
  while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
  return x * f;
}
struct Vector {
  long long x, y;
  Vector(long long x = 0, long long y = 0) : x(x), y(y){};
  inline void print() { printf("(%lld,%lld)\n", x, y); }
  inline Vector operator+(const Vector &tmp) const {
    return Vector(x + tmp.x, y + tmp.y);
  }
  inline Vector operator-(const Vector &tmp) const {
    return Vector(x - tmp.x, y - tmp.y);
  }
  inline long long operator%(const Vector &tmp) const {
    return x * tmp.y - y * tmp.x;
  }
  inline bool operator==(const Vector &tmp) const {
    return x == tmp.x && y == tmp.y;
  }
};
namespace Tree2 {
const int MAXN = 5e5 + 5;
int head[MAXN], trump = 1;
struct Edge {
  int to, next;
  Vector val;
  Edge(int u = 0, int v = 0, Vector w = 0) : to(v), next(head[u]), val(w){};
} e[MAXN << 1];
inline void addedge(int u, int v, Vector w) {
  e[++trump] = Edge(u, v, w);
  head[u] = trump;
  e[++trump] = Edge(v, u, w);
  head[v] = trump;
}
int size[MAXN], mx[MAXN];
int tot, edge;
bool vis[MAXN];
void debug(int u, int fa) {
  for (register int i = head[u]; i; i = e[i].next) {
    int v = e[i].to;
    if (v == fa) continue;
    printf("%d %d ", u, v);
    e[i].val.print();
    debug(v, u);
  }
}
void findedge(int u, int fa) {
  size[u] = 1;
  for (register int i = head[u]; i; i = e[i].next) {
    int v = e[i].to;
    if (v == fa || vis[i >> 1]) continue;
    findedge(v, u);
    size[u] += size[v];
    mx[i >> 1] = max(size[v], tot - size[v]);
    if (mx[i >> 1] < mx[edge >> 1]) edge = i;
  }
}
inline bool cmpx(const Vector &a, const Vector &b) {
  return a.x != b.x ? a.x < b.x : a.y > b.y;
}
Vector stk[MAXN];
int top;
void tuke(Vector *a, int &n) {
  register int i;
  sort(a + 1, a + n + 1, cmpx);
  stk[top = 1] = a[1];
  for (i = 2; i <= n; ++i) {
    if (a[i].x == a[i - 1].x) continue;
    while (top > 1 && (a[i] - stk[top - 1]) % (stk[top] - stk[top - 1]) <= 0)
      --top;
    stk[++top] = a[i];
  }
  for (i = 1; i <= top; ++i) a[i] = stk[i];
  for (i = top + 1; i <= n; ++i) a[i] = 0;
  n = top;
}
Vector s1[MAXN], s2[MAXN];
void minkowski(Vector *a, int n, Vector *b, int m, Vector *c, int &s) {
  int i, j;
  for (i = 1; i < n; ++i) s1[i] = a[i + 1] - a[i];
  s1[n] = 0;
  for (i = 1; i < m; ++i) s2[i] = b[i + 1] - b[i];
  s2[m] = 0;
  i = 1;
  j = 1;
  c[s = 1] = a[1] + b[1];
  while (i < n && j < m)
    ++s, c[s] = c[s - 1] + (s1[i] % s2[j] < 0 ? s1[i++] : s2[j++]);
  while (i < n) ++s, c[s] = c[s - 1] + s1[i++];
  while (j < m) ++s, c[s] = c[s - 1] + s2[j++];
  for (i = 1; i <= n; ++i) a[i] = 0;
  for (i = 1; i <= m; ++i) b[i] = 0;
  tuke(c, s);
}
Vector D[MAXN * 18], A[MAXN], B[MAXN], C[MAXN];
int cnta, cntb, cntc, cntd;
void work(int u, int fa, Vector dis, bool type) {
  if (u <= n) type ? A[++cnta] = dis : B[++cntb] = dis;
  for (register int i = head[u]; i; i = e[i].next) {
    int v = e[i].to;
    if (v == fa || vis[i >> 1]) continue;
    work(v, u, dis + e[i].val, type);
  }
}
void solve(int b) {
  if (!b) return;
  vis[b >> 1] = 1;
  cnta = cntb = 0;
  int u = e[b ^ 1].to, v = e[b].to;
  work(u, v, 0, 1);
  work(v, u, e[b].val, 0);
  tuke(A, cnta);
  tuke(B, cntb);
  minkowski(A, cnta, B, cntb, C, cntc);
  for (register int i = 1; i <= cntc; ++i) D[++cntd] = C[i];
  int szeA = tot - size[v], szeB = size[v];
  tot = szeA;
  edge = 0;
  findedge(u, v);
  solve(edge);
  tot = szeB;
  edge = 0;
  findedge(v, u);
  solve(edge);
}
int main() {
  mx[0] = MAXN << 1;
  findedge(1, 0);
  solve(edge);
  tuke(D, cntd);
  int i, j = 1;
  for (i = 0; i < m; ++i) {
    while (j < cntd &&
           1ll * i * D[j].x + D[j].y < 1ll * i * D[j + 1].x + D[j + 1].y)
      ++j;
    printf("%lld ", 1ll * i * D[j].x + D[j].y);
  }
  return 0;
}
}  // namespace Tree2
namespace Tree1 {
int head[MAXN], trump;
struct Edge {
  int to, next;
  Vector val;
  Edge(int u = 0, int v = 0, Vector w = 0) : to(v), next(head[u]), val(w){};
} e[MAXN << 1];
inline void addedge(int u, int v, Vector w) {
  e[++trump] = Edge(u, v, w);
  head[u] = trump;
  e[++trump] = Edge(v, u, w);
  head[v] = trump;
}
int son[MAXN], top, tot;
void rebuild(int u, int fa) {
  int last = u;
  top = 0;
  register int i;
  for (i = head[u]; i; i = e[i].next) {
    if (e[i].to == fa) continue;
    son[++top] = i;
  }
  for (i = 1; i <= top - 2; ++i) {
    Tree2::addedge(last, e[son[i]].to, e[son[i]].val);
    Tree2::addedge(last, ++tot, 0);
    last = tot;
  }
  if (top > 1) Tree2::addedge(last, e[son[top - 1]].to, e[son[top - 1]].val);
  if (top > 0) Tree2::addedge(last, e[son[top]].to, e[son[top]].val);
  for (i = head[u]; i; i = e[i].next) {
    if (e[i].to == fa) continue;
    rebuild(e[i].to, u);
  }
}
}  // namespace Tree1
int main() {
  register int i;
  n = read();
  m = read();
  for (i = 1; i < n; ++i) {
    int u = read(), v = read(), k = read(), b = read();
    Tree1::addedge(u, v, Vector(k, b));
  }
  Tree1::tot = n;
  Tree1::rebuild(1, 0);
  Tree2::tot = Tree1::tot;
  return Tree2::main();
}
