#include <bits/stdc++.h>
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx,tune=native")
using namespace std;
template <typename T>
void uin(T &a, T b) {
  if (b < a) {
    a = b;
  }
}
template <typename T>
void uax(T &a, T b) {
  if (b > a) {
    a = b;
  }
}
const int N = 100 * 1000 + 228;
const double eps = 1e-7;
struct edge {
  int a, b, c;
  edge() {}
  edge(int _a, int _b, int _c) {
    a = _a;
    b = _b;
    c = _c;
  }
};
vector<edge> edges;
bool eq(double first, double second) { return abs(first - second) <= eps; }
vector<pair<int, int> > g[N];
pair<double, double> f[N];
bool used[N];
double VALUE[N];
void GO(int V) {
  queue<int> q;
  q.push(V);
  f[V] = {1, 0};
  used[1] = 1;
  vector<int> uv;
  uv.emplace_back(V);
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    for (auto go : g[v]) {
      int to = go.first;
      int type = go.second;
      if (to == v && f[v].first != 0) {
        double X = ((double)type / 2.0 - f[v].second) / (double)f[v].first;
        for (auto ve : uv) {
          double a = f[ve].first, b = f[ve].second;
          f[ve].first = 0;
          f[ve].second = a * X + b;
        }
        continue;
      }
      if (!used[to]) {
        used[to] = 1;
        f[to].first = -f[v].first;
        f[to].second = type - f[v].second;
        uv.emplace_back(to);
        q.push(to);
      } else {
        int A = -f[v].first;
        int B = type - f[v].second;
        if (A && eq(f[to].first, A) && !eq(f[to].second, B)) {
          cout << "NO\n";
          exit(0);
        }
        if (!eq(f[to].first, A)) {
          double X = (f[to].second - B) / (A - f[to].first);
          for (auto ve : uv) {
            double a = f[ve].first, b = f[ve].second;
            f[ve].first = 0;
            f[ve].second = a * X + b;
          }
        }
      }
    }
  }
  if (eq(f[uv[0]].first, 0)) {
    for (int first : uv) {
      VALUE[first] = f[first].second;
    }
  } else {
    vector<double> t;
    for (int first : uv) {
      if (f[first].first == 1) {
        t.emplace_back(-f[first].second);
      } else {
        t.emplace_back(f[first].second);
      }
    }
    sort(t.begin(), t.end());
    double X = t[(int)t.size() / 2];
    for (int first : uv) {
      VALUE[first] = f[first].first * X + f[first].second;
    }
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int u, v, col;
    cin >> u >> v >> col;
    edges.emplace_back(u, v, col);
    g[u].emplace_back(v, col);
    g[v].emplace_back(u, col);
  }
  for (int v = 1; v <= n; ++v) {
    if (!used[v]) {
      GO(v);
    }
  }
  for (auto e : edges) {
    int a = e.a, b = e.b, c = e.c;
    if (!eq(VALUE[a] + VALUE[b], c)) {
      cout << "NO\n";
      return 0;
    }
  }
  cout << "YES\n";
  cout.precision(20);
  for (int i = 1; i <= n; ++i) {
    cout << VALUE[i] << ' ';
  }
  cout << '\n';
  return 0;
}
