#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5, MAXM = 2e5;
pair<bool, double> a;
bool usedEdge[1 + MAXM];
double value[1 + MAXN];
vector<int> anchors;
vector<pair<pair<int, int>, int> > neighbours[1 + MAXN];
int k[1 + MAXN], q[1 + MAXN];
bool dfs(int node, int newK, int newQ) {
  if (q[node]) {
    if (q[node] == newQ && k[node] != newK)
      return true;
    else if (q[node] != newQ) {
      double newA = (k[node] - newK) / (double)(newQ - q[node]);
      if (!a.first)
        a.first = true, a.second = newA;
      else if (a.second != newA)
        return true;
    }
  } else {
    k[node] = newK;
    q[node] = newQ;
    anchors.push_back(-q[node] * k[node]);
  }
  for (auto &child : neighbours[node]) {
    if (usedEdge[child.second]) continue;
    usedEdge[child.second] = true;
    if (dfs(child.first.first, child.first.second - k[node], -q[node]))
      return true;
  }
  return false;
}
void dfs2(int node) {
  value[node] = k[node] + q[node] * a.second;
  q[node] = 2;
  for (auto child : neighbours[node]) {
    if (q[child.first.first] != 2) dfs2(child.first.first);
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= m; ++i) {
    int x, y, c;
    cin >> x >> y >> c;
    neighbours[x].push_back({{y, c}, i});
    if (x != y) neighbours[y].push_back({{x, c}, i});
  }
  bool possible = true;
  for (int i = 1; i <= n; ++i) {
    if (q[i]) continue;
    anchors.clear();
    a = {false, 0};
    if (dfs(i, 0, 1)) {
      possible = false;
      break;
    }
    if (!a.first) {
      sort(anchors.begin(), anchors.end());
      a.first = true, a.second = anchors[anchors.size() / 2];
    }
    dfs2(i);
  }
  if (possible) {
    cout << "YES" << endl;
    for (int i = 1; i <= n; ++i) cout << value[i] << ' ';
    cout << endl;
  } else
    cout << "NO" << endl;
  return 0;
}
