#include <bits/stdc++.h>
using namespace std;
struct str {
  int u;
  long long nod;
  long long nok;
};
bool ok;
int n, m;
str g[104][104];
int ng[104];
bool done[104];
int color[104];
bool use[104];
inline long long NOD(long long a, long long b) {
  while (a > 0 && b > 0)
    if (a > b)
      a %= b;
    else
      b %= a;
  return a + b;
}
void DFS(int v, long long val) {
  use[v] = true;
  color[v] = val;
  for (int i = 0; i < ng[v]; i++) {
    if (!use[g[v][i].u] &&
        (val % g[v][i].nod != 0 ||
         (g[v][i].nok / g[v][i].nod) % (val / g[v][i].nod) != 0)) {
      ok = false;
      return;
    }
  }
  for (int i = 0; i < ng[v]; i++) {
    if (!use[g[v][i].u]) {
      long long v2 = g[v][i].nok * g[v][i].nod / val;
      if (NOD(val, v2) != g[v][i].nod) {
        ok = false;
        return;
      }
      DFS(g[v][i].u, v2);
      if (!ok) return;
    }
  }
}
int main() {
  cin >> n >> m;
  int x, y, nod, nok;
  for (int i = 0; i < m; i++) {
    cin >> x >> y >> nod >> nok;
    if (nok % nod != 0) {
      cout << "NO" << endl;
      return 0;
    }
    g[x][ng[x]].u = y;
    g[x][ng[x]].nod = nod;
    g[x][ng[x]].nok = nok;
    ng[x]++;
    g[y][ng[y]].u = x;
    g[y][ng[y]].nod = nod;
    g[y][ng[y]].nok = nok;
    ng[y]++;
  }
  memset(done, false, sizeof(done));
  memset(color, 0, sizeof(color));
  for (int i = 1; i <= n; i++) {
    if (!done[i]) {
      if (ng[i] == 0) {
        color[i] = 1;
        done[i] = true;
        continue;
      }
      ok = false;
      for (int z = g[i][0].nod; z <= g[i][0].nok; z++) {
        if (z % g[i][0].nod != 0 || g[i][0].nok % z != 0) continue;
        ok = true;
        memset(use, false, sizeof(use));
        DFS(i, z);
        if (ok) {
          for (int j = 1; j <= n; j++) done[j] |= use[j];
          break;
        }
      }
      if (!ok) {
        cout << "NO" << endl;
        return 0;
      }
    }
  }
  cout << "YES" << endl;
  for (int i = 1; i <= n; i++) cout << color[i] << ' ';
  cout << endl;
  return 0;
}
