#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e18 + 7, NMAX = 1e5 + 5, MOD = 1000000007, N = 1e9 + 5,
                LOG = 25;
const long double EPS = 1e-8, pi = 3.14159265358979323846;
set<pair<int, int> > g[NMAX];
bool used[NMAX];
double answer[NMAX];
pair<double, double> ans[NMAX];
double x;
vector<int> comp;
bool dfs(int v, int p, pair<double, double> cur) {
  comp.push_back(v);
  used[v] = true;
  ans[v] = cur;
  for (pair<int, int> edg : g[v]) {
    int to = edg.first, color = edg.second;
    if (to == p) continue;
    if (used[to]) {
      double k1 = color - ans[v].first;
      double k2 = -ans[v].second;
      if (k1 == ans[to].first && k2 == ans[to].second) continue;
      if (ans[to].second - k2 == 0) {
        cout << "NO";
        exit(0);
      }
      x = (k1 - ans[to].first) / (ans[to].second - k2);
      return true;
    } else {
      pair<double, double> next = {color - cur.first, -cur.second};
      if (dfs(to, v, next)) return true;
    }
  }
  return false;
}
bool check_used[NMAX];
void check(int v, int p, double cur) {
  check_used[v] = used[v] = true;
  answer[v] = cur;
  for (pair<int, int> edg : g[v]) {
    int to = edg.first, color = edg.second;
    if (to == p) continue;
    if (check_used[to]) {
      double next = color - cur;
      if (abs(answer[to] - next) > EPS) {
        cout << "NO";
        exit(0);
      }
    } else {
      check(to, v, color - cur);
    }
  }
}
double first(double x) {
  double res = 0;
  for (int v : comp) {
    res += abs(ans[v].first + ans[v].second * x);
  }
  return res;
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int x, y, z;
    cin >> x >> y >> z;
    if (z == 1 && g[x].count({y, 2}) || z == 2 && g[x].count({y, 1})) {
      cout << "NO";
      return 0;
    }
    g[x].insert({y, z});
    g[y].insert({x, z});
  }
  for (int i = 1; i <= n; ++i)
    if (!used[i]) {
      comp.clear();
      if (dfs(i, -1, {0, 1})) {
        check(i, i, x);
      } else {
        vector<double> ar;
        double x;
        for (int v : comp) {
          if (ans[v].second == 0) continue;
          double a = -ans[v].first / ans[v].second;
          ar.push_back(a);
        }
        sort(ar.begin(), ar.end());
        int sz = ar.size();
        if (sz % 2 == 1) {
          x = ar[sz / 2];
        } else {
          if (first(ar[sz / 2 - 1]) < first(ar[sz / 2]))
            x = ar[sz / 2 - 1];
          else
            x = ar[sz / 2];
        }
        for (int v : comp) answer[v] = ans[v].first + ans[v].second * x;
      }
    }
  cout << "YES\n";
  for (int i = 1; i <= n; ++i)
    cout << fixed << setprecision(8) << answer[i] << " ";
}
