BOI 2020 - gra

// https://codeforces.com/contest/1387/problem/A
// BOI 2020 day 2 problem 1
// https://cses.fi/336/list/

#include <bits/stdc++.h>

using namespace std;

#define int long long

constexpr int sizik = 1000 * 1001;

#define ar std::array
#define pr std::pair
#define vec std::vector

// #define GARY_DBG

typedef vec<vec<int>> _kra;
typedef ar<int, 3> Trio;
typedef long double ld;

bool visited[sizik];
std::vector<ar<int, 2>> kra[sizik];
ld ans[sizik];
std::pair<int, ld> pot_ans[sizik];
std::queue<int> qq;
int n, m;

ld findMedian(const std::vector<ld>& sortedVector);
bool areEqual(ld a, ld b, ld epsilon = 1e-9) {
    return std::fabs(a - b) < epsilon;
}
ld v1, v3;
int v2;

void DFS(int v, int p) {
    if (visited[v]) return;
    visited[v] = true;

    qq.push(v);
    v3++;

    for (const auto& [u, c] : kra[v]) {
        if (!visited[u]) {
            pot_ans[u].first = -pot_ans[v].first;
            pot_ans[u].second = c - pot_ans[v].second;
            DFS(u, v);
        } else if (pot_ans[u].first + pot_ans[v].first == 0) {
            if (!areEqual(pot_ans[u].second + pot_ans[v].second, c)) {
                v2 = -1;
            }
        } else {
            ld res = (c - pot_ans[u].second - pot_ans[v].second);
            res /= pot_ans[u].first + pot_ans[v].first;
            if (!v2)
                v2 = 1, v1 = res;
            else if (!areEqual(v1, res)) {
                v2 = -1;
            }
        }
    }
}

void solve() {
    std::cin >> n >> m;

    std::vector<Trio> v(m);
    for (int i = 0; i <= n; i++) {
        pot_ans[i] = {-2, 0.0};
    }

    for (int i = 0; i < m; i++) {
        int a, b, c;
        std::cin >> a >> b >> c;

        v[i] = {a, b, 2 * c};
    }

    v.push_back({-1, -1, -1});
    std::sort(v.begin(), v.end(),
              [](const Trio& a, const Trio& b) { return std::less<std::pair<int, int>>()(std::make_pair(a[0], a[1]), std::make_pair(b[0], b[1])); });

    for (int i = 1; i <= m; i++) {
        const auto [a, b, c] = v[i];
        if (a == v[i - 1][0] && b == v[i - 1][1]) {
            if (c != v[i - 1][2]) {
                std::cout << "NO\n";
                return;
            } else {
                continue;
            }
        }

        kra[a].push_back({b, c});
        kra[b].push_back({a, c});
    }

    for (int i = 1; i <= n; i++) {
        if (!visited[i]) {
            if (kra[i].size() == 0) {
                visited[i] = true;
                ans[i] = 0.0;
                pot_ans[i] = {0, ans[i]};
            } else if (kra[i].size() == 1 && kra[i][0][0] == i) {
                visited[i] = true;
                ans[i] = (ld)(kra[i][0][1]) / 2.0;
                pot_ans[i] = {0, ans[i]};
            } else {
                pot_ans[i] = {1, 0};
                v1 = 0, v2 = 0, v3 = 0;
                DFS(i, i);
                if (v2 == -1) {
                    cout << "NO\n";
                    exit(0);
                }

                std::vector<int> q1;
                while (!qq.empty()) {
                    q1.push_back(qq.front());
                    qq.pop();
                }

                std::vector<ld> vdf;
                if (v2 == 0) {
                    for (const auto& d : q1) {
                        vdf.push_back(pot_ans[d].second * pot_ans[d].first);
                    }
                    std::sort(vdf.begin(), vdf.end());
                    v1 = -vdf[(int)vdf.size() / 2];
                }

                for (const auto& d : q1) {
                    ans[d] = pot_ans[d].first * v1 + pot_ans[d].second;
                }
            }
        }
    }

    std::cout << "YES\n";
    for (int i = 1; i <= n; i++) {
        std::cout << (ans[i] / (ld)2.0) << ' ';
    }
    std::cout << '\n';
}

int32_t main() {
    std::ios_base::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);

    int t = 1;
    // std::cin >> t;
    std::cout << std::fixed << std::setprecision(7);

    for (; t > 0; t--) {
        solve();
    }

    return 0;
}

ld findMedian(const std::vector<ld>& sv) {
    int nh = sv.size();

    // std::cout << "nh: " << nh << '\n';

    if (nh % 2 == 1) {
        return sv[nh / 2];
    } else {
        return (sv[nh / 2 - 1] + sv[nh / 2]) / (ld)2.0;
    }
}