/**
 *    author:  otera    
**/
#include<bits/stdc++.h>
using namespace std;

#define int long long
typedef long long ll;
typedef long double ld;
#define rep(i, n) for(int i = 0; i < n; ++ i)
#define per(i,n) for(int i=n-1;i>=0;i--)
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int n, m;
vector<int> ans;
vector<vector<P>> g;

void dfs(int v, int p, int k) {
    ans[v] = k;
    for(auto e: g[v]) {
        int nv = e.fr, c = e.sc;
        if(nv == p) continue;
        if(ans[nv] != -1) continue;
        if(k == c) {
            dfs(nv, v, (k == n ? 1 : k + 1));
        } else {
            dfs(nv, v, c);
        }
    }
}

void solve() {
    cin >> n >> m;
    g.assign(n, vector<P>());
    rep(i, m) {
        int u, v, c; cin >> u >> v >> c;
        -- u, -- v;
        g[u].push_back({v, c});
        g[v].push_back({u, c});
    }
    ans.assign(n, -1);
    dfs(0, -1, 1);
    rep(i, n) {
        if(ans[i] == -1) {
            cout << "No" << endl;
            return;
        }
    }
    rep(i, n) {
        cout << ans[i] << "\n";
    }
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(20);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

vector<ll> parent, rk;

void make_set(ll v) {
    parent[v] = v;
    rk[v] = 0;
}

ll find_set(ll v) {
    if (v == parent[v]) return v;
    return parent[v] = find_set(parent[v]);
}

void union_sets(ll a, ll b) {
    a = find_set(a);
    b = find_set(b);
    if (a != b) {
        if (rk[a] < rk[b])  swap(a, b);
        parent[b] = a;
        if (rk[a] == rk[b])      rk[a]++;
    }
}

struct Edge {
    ll u, v, weight;
    bool operator<(Edge const& other) {
        return weight < other.weight;
    }
};

vector<pair<ll, ll> > adj[100010];
ll vis[100010], a[100010];
ll n, m;
    vector<Edge> edges;
    vector<Edge> result;

void dfs(ll x){
    vis[x] = 10;
    for(auto &i: adj[x]) if(!vis[i.first]) {
        if(a[x] == i.second) a[i.first] = (a[x]+1)%n;
        else a[i.first] = i.second;
        dfs(i.first);
    }
}

void solve(){
    cin >> n >> m;
    for(ll i = 0; i < m; i++){
        Edge x;
        cin >> x.u >> x.v >> x.weight;
        --x.u, --x.v, --x.weight;
        edges.push_back(x);
    }
    parent.resize(n);
    rk.resize(n);
    for (ll i = 0; i < n; i++)  make_set(i);
    sort(edges.begin(), edges.end());
    for (Edge e : edges) {
        if (find_set(e.u) != find_set(e.v)) {
            //cost += e.weight;
            result.push_back(e);
            union_sets(e.u, e.v);
        }
    }
    //cout << "here " << endl;
    for(ll i = 0; i < n; i++) a[i] = -1;
    for(Edge e: result){
        //cout << e.u << " - " << e.v << e.weight << endl;
        adj[e.u].push_back({e.v, e.weight});
        adj[e.v].push_back({e.u, e.weight});
    }
    a[0] = 1;
    dfs(0);
    for(ll i = 0; i < n; i++) cout << a[i] + 1 << endl;
}

int main(){
    ll t = 1;
    //cin >> t;
    while(t--)
    solve();
    return 0;
}
