#include <bits/stdc++.h>
using namespace std;
template <typename T>
void maxtt(T &t1, T t2) {
  t1 = max(t1, t2);
}
template <typename T>
void mintt(T &t1, T t2) {
  t1 = min(t1, t2);
}
bool debug = 0;
int n, m, k;
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
string direc = "RDLU";
long long ln, lk, lm;
void etp(bool f = 0) {
  puts(f ? "YES" : "NO");
  exit(0);
}
void addmod(int &x, int y, int mod = 998244353) {
  assert(y >= 0);
  x += y;
  if (x >= mod) x -= mod;
  assert(x >= 0 && x < mod);
}
void et(int x = -1) {
  printf("%d\n", x);
  exit(0);
}
long long fastPow(long long x, long long y, int mod = 998244353) {
  long long ans = 1;
  while (y > 0) {
    if (y & 1) ans = (x * ans) % mod;
    x = x * x % mod;
    y >>= 1;
  }
  return ans;
}
long long gcd1(long long x, long long y) { return y ? gcd1(y, x % y) : x; }
struct Point {
  long long x, y;
  int id;
  Point() {}
  Point(long long x, long long y) : x(x), y(y) {}
  long double abs() const { return hypot(x, y); }
  long double arg() const { return atan2(y, x); }
  Point operator*(double o) const { return Point(x * o, y * o); }
  Point operator+(const Point &o) const { return Point(x + o.x, y + o.y); }
  Point operator-(const Point &o) const { return Point(x - o.x, y - o.y); }
  Point operator/(double o) const { return Point(x / o, y / o); }
  bool operator<(const Point &o) const {
    return x < o.x || (x == o.x && y > o.y);
  }
  friend bool operator==(const Point &r1, const Point &r2) {
    return r1.x == r2.x && r1.y == r2.y;
  }
  Point scale(double o) const { return *this * (o / abs()); }
  Point rotY() const { return Point(-y, x); }
  Point rotX() const { return Point(y, -x); }
  long long cross(Point b) const { return x * b.y - b.x * y; }
  long long dot(Point b) const { return x * b.x + y * b.y; }
  long double disToSeg(Point &a, Point &b) {
    return fabs(((*this) - a).cross(b - a) / (b - a).abs());
  }
  pair<long long, long long> getVec() {
    if (x == 0) return {0, y > 0 ? 1 : -1};
    if (y == 0) return {x < 0 ? -1 : 1, 0};
    long long gg = gcd1(::abs(x), ::abs(y));
    long long px = x / gg, py = y / gg;
    return {px, py};
  }
  void readin() { scanf("%lld%lld", &x, &y); }
  void pp() { printf("%lld %lld\n", x, y); }
  long long val(long long t) { return x * t + y; }
};
vector<Point> l, r, all;
Point dis[200105];
vector<pair<int, Point>> mp[200105];
void addE(int u, int v, Point pp) {
  mp[u].push_back({v, pp});
  mp[v].push_back({u, pp});
}
vector<Point> convex(vector<Point> &vp) {
  sort(vp.begin(), vp.end());
  vector<Point> ans;
  for (int(i) = 0; (i) < (int)(vp.size()); (i)++) {
    if (!ans.empty() && ans.back().x == vp[i].x) continue;
    while (ans.size() > 1) {
      if ((vp[i] - ans[ans.size() - 2])
              .cross(ans.back() - ans[ans.size() - 2]) <= 0) {
        ans.pop_back();
      } else
        break;
    }
    ans.push_back(vp[i]);
  }
  return ans;
}
void mkfMerge(vector<Point> &a, vector<Point> &b) {
  all.push_back(a[0] + b[0]);
  for (int i = 0, j = 0; i + 1 < a.size() || j + 1 < b.size();)
    if (j + 1 == b.size() ||
        (i + 1 < a.size() && (a[i + 1] - a[i]).cross(b[j + 1] - b[j]) < 0))
      all.push_back(a[++i] + b[j]);
    else
      all.push_back(a[i] + b[++j]);
}
struct edgeHld {
  int rt, rtFather;
  bool vis[200105];
  int sz[200105];
  vector<pair<int, Point>> E[200105];
  void addEg(int u, int v, Point pp) {
    E[u].push_back({v, pp});
    E[v].push_back({u, pp});
  }
  void buildBinaryTree(int x, int pa) {
    vector<pair<int, Point>> son;
    for (auto p : mp[x])
      if (p.first != pa) {
        son.push_back(p);
        buildBinaryTree(p.first, x);
      }
    for (int i = 0, t = x; i < son.size(); i++) {
      if (i && i + 1 < son.size()) {
        ++n;
        addEg(t, n, {0, 0});
        t = n;
      }
      addEg(t, son[i].first, son[i].second);
    }
  }
  void center(int x, int pa, int Sz) {
    sz[x] = 1;
    for (auto p : E[x])
      if (p.first != pa && !vis[p.first]) {
        center(p.first, x, Sz);
        sz[x] += sz[p.first];
      }
    if (rt == -1 || max(sz[x], Sz - sz[x]) < max(sz[rt], Sz - sz[rt])) {
      rt = x;
      rtFather = pa;
    }
  }
  void dfs(int x, int pa, bool w) {
    if (w)
      r.push_back(dis[x]);
    else
      l.push_back(dis[x]);
    for (auto p : E[x])
      if (p.first != pa && !vis[p.first]) {
        dis[p.first] = dis[x] + p.second;
        dfs(p.first, x, w || p.first == rt);
      }
  }
  void cal(int x, int Sz) {
    if (Sz == 1) return;
    rt = -1;
    center(x, 0, Sz);
    int u = rt, v = rtFather, szu = sz[u], szv = Sz - sz[u];
    dis[v] = {0, 0};
    l.clear();
    r.clear();
    dfs(v, 0, 0);
    l = convex(l);
    r = convex(r);
    mkfMerge(l, r);
    vis[v] = 1;
    cal(u, szu);
    vis[v] = 0;
    vis[u] = 1;
    cal(v, szv);
    vis[u] = 0;
  }
} ynk;
void fmain(int ID) {
  scanf("%d%d", &n, &m);
  for (int(i) = 1; (i) <= (int)(n - 1); (i)++) {
    int u, v, a, b;
    scanf("%d%d%d%d", &u, &v, &a, &b);
    addE(u, v, {a, b});
  }
  ynk.buildBinaryTree(1, 0);
  ynk.cal(1, n);
  all = convex(all);
  for (int i = 0, j = 0; i < m; i++) {
    while (j + 1 < all.size() && all[j].val(i) <= all[j + 1].val(i)) j++;
    printf("%lld ", j < all.size() ? all[j].val(i) : 0);
  }
}
int main() {
  int t = 1;
  for (int(i) = 1; (i) <= (int)(t); (i)++) {
    fmain(i);
  }
  return 0;
}
