#include <bits/stdc++.h>
using namespace std;
const int maxn = 400000 + 10;
const long long inf = 1ll << 50;
int n, m, N, rt, mx, sum, siz[maxn], vis[maxn], head[maxn], tot = 1;
long long ans[maxn];
inline int read() {
  register int x = 0, f = 1;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) x = (x << 3) + (x << 1) + ch - '0';
  return (f == 1) ? x : -x;
}
void print(long long x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) print(x / 10);
  putchar(x % 10 + '0');
}
struct Edge {
  int to, next, a, b;
} e[maxn << 1];
vector<Edge> son[maxn];
inline void addedge(int x, int y, int a, int b) {
  e[++tot] = (Edge){y, head[x], a, b};
  head[x] = tot;
}
void dfs(int x, int f) {
  for (int i = head[x]; i; i = e[i].next)
    if (e[i].to != f) son[x].push_back(e[i]), dfs(e[i].to, x);
}
inline void rebuild() {
  memset(head, 0, sizeof(head));
  tot = 1;
  N = n;
  for (int i = 1; i <= n; i++) {
    int l = son[i].size();
    if (l <= 2) {
      for (int j = 0; j < l; j++) {
        const Edge &p = son[i][j];
        addedge(i, p.to, (p.to <= N) ? p.a : 0, (p.to <= N) ? p.b : 0);
        addedge(p.to, i, (p.to <= N) ? p.a : 0, (p.to <= N) ? p.b : 0);
      }
    } else {
      int ls = ++n, rs = ++n;
      addedge(i, ls, 0, 0);
      addedge(ls, i, 0, 0);
      addedge(i, rs, 0, 0);
      addedge(rs, i, 0, 0);
      for (int j = 0; j < l; j++) {
        if (!(j & 1))
          son[ls].push_back(son[i][j]);
        else
          son[rs].push_back(son[i][j]);
      }
    }
  }
}
struct node {
  long long x, y;
  node(long long _x = 0, long long _y = 0) : x(_x), y(_y) {}
  friend inline node operator+(const node &a, const node &b) {
    return node(a.x + b.x, a.y + b.y);
  }
  friend inline node operator-(const node &a, const node &b) {
    return node(a.x - b.x, a.y - b.y);
  }
  friend inline bool operator<=(const node &a, const node &b) {
    return a.y * b.x <= a.x * b.y;
  }
};
inline bool cmp(const node &a, const node &b) {
  return a.x < b.x || (a.x == b.x && a.y > b.y);
}
node sta[maxn * 10], All[maxn * 10], A[maxn], B[maxn];
struct hull {
  node *s;
  int T;
  inline node operator[](const int &x) { return s[x]; }
  inline const node operator[](const int &x) const { return s[x]; }
  inline void clear() { T = 0; }
  inline void push(const node &p) { s[++T] = p; }
  inline void build() {
    sort(s + 1, s + T + 1, cmp);
    int top = 0;
    for (int i = 1; i <= T; i++) {
      if (i > 1 && s[i].x == s[i - 1].x) continue;
      while (top > 1 && (sta[top] - sta[top - 1]) <= (s[i] - sta[top - 1]))
        top--;
      sta[++top] = s[i];
    }
    for (int i = 1; i <= top; i++) s[i] = sta[i];
    T = top;
  }
  inline void merge(const hull &a, const hull &b) {
    int i = 1, j = 1;
    push(a[i] + b[j]);
    while (i < a.T || j < b.T) {
      if (j >= b.T || (i < a.T && (b[j + 1] - b[j]) <= (a[i + 1] - a[i])))
        i++;
      else
        j++;
      push(a[i] + b[j]);
    }
  }
  inline void query() {
    int o = 1;
    for (int i = 0; i < m; i++) {
      while (o != T && i * s[o + 1].x + s[o + 1].y > i * s[o].x + s[o].y) o++;
      ans[i] = i * s[o].x + s[o].y;
    }
  }
};
hull all, a, b;
inline void init() {
  all.s = All;
  a.s = A;
  b.s = B;
}
void getrt(int x, int f) {
  siz[x] = 1;
  for (int i = head[x]; i; i = e[i].next) {
    int y = e[i].to;
    if (y == f || vis[i >> 1]) continue;
    getrt(y, x);
    siz[x] += siz[y];
    int ret = min(siz[y], sum - siz[y]);
    if (ret > mx) mx = ret, rt = i;
  }
}
void getPoint(int x, int f, hull &u, long long A, long long B) {
  if (x <= N) u.push(node(A, B));
  for (int i = head[x]; i; i = e[i].next)
    if (e[i].to != f && !vis[i >> 1])
      getPoint(e[i].to, x, u, A + e[i].a, B + e[i].b);
}
void divide(int x, int pre) {
  mx = -1e9;
  rt = 0;
  sum = pre;
  getrt(x, 0);
  if (mx == -1e9) return;
  vis[rt >> 1] = 1;
  a.clear();
  b.clear();
  getPoint(e[rt].to, 0, a, e[rt].a, e[rt].b);
  getPoint(e[rt ^ 1].to, 0, b, 0, 0);
  a.push(node(0, 0));
  b.push(node(0, 0));
  a.build();
  b.build();
  all.merge(a, b);
  int now = rt, size = pre - siz[e[now].to];
  divide(e[now].to, siz[e[now].to]);
  divide(e[now ^ 1].to, size);
}
int main() {
  init();
  n = read(), m = read();
  int x, y, a, b;
  for (int i = 1; i < n; i++) {
    x = read(), y = read(), a = read(), b = read();
    addedge(x, y, a, b), addedge(y, x, a, b);
  }
  dfs(1, 0);
  rebuild();
  divide(1, n);
  all.build();
  all.query();
  for (int i = 0; i < m; i++) print(ans[i]), putchar(' ');
  putchar('\n');
  return 0;
}
