#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100 + 10;
vector<int> primes;
int n, m;
int a[MAXN][MAXN];
int b[MAXN][MAXN];
bool pr[MAXN * MAXN * MAXN];
int ans[MAXN];
vector<int> last;
int jav[MAXN];
int c[MAXN][MAXN];
int yal[MAXN * MAXN][4];
int num;
bool mark[MAXN];
bool mish[MAXN * MAXN * MAXN];
int chi[MAXN * MAXN * MAXN];
bool ct[MAXN * MAXN * MAXN];
void init() {
  memset(pr, true, sizeof(pr));
  pr[1] = false;
  for (int i = 2; i <= 1000000; i++)
    if (pr[i])
      for (int j = i + i; j <= 1000000; j += i) pr[j] = false;
  for (int i = 1; i <= m; i++) ct[yal[i][2]] = ct[yal[i][3]] = true;
  for (int i = 1; i <= 1000000; i++)
    if (pr[i])
      for (int j = i; j <= 1000000; j += i)
        if (ct[j]) {
          primes.push_back(i);
          break;
        }
}
int get(int x, int y) {
  if (chi[x] != 0) return chi[x];
  int ans = 1;
  int jj = x;
  while (x % y == 0) {
    ans *= y;
    x /= y;
  }
  chi[jj] = ans;
  return ans;
}
void dfs(int x, int bmm, int kmm, bool z) {
  mark[x] = true;
  last.push_back(x);
  if (z) {
    jav[x] = get(bmm, num);
  } else {
    jav[x] = get(kmm, num);
  }
  for (int i = 1; i <= n; i++)
    if (a[x][i] != 0) {
      if (!mark[i]) {
        int tmp = get(a[x][i], num);
        if (jav[x] == tmp)
          dfs(i, a[x][i], b[x][i], false);
        else
          dfs(i, a[x][i], b[x][i], true);
      } else {
        int p = x;
        int q = i;
        int x = get(a[p][q], num);
        int y = get(b[p][q], num);
        if ((jav[p] != x && jav[q] != x) || (jav[p] != y && jav[q] != y))
          return;
      }
    }
}
bool wrong() {
  for (int i = 0; i < last.size(); i++)
    for (int j = 0; j < last.size(); j++)
      if (i != j && a[last[i]][last[j]] != 0) {
        int p = last[i];
        int q = last[j];
        int x = get(a[p][q], num);
        int y = get(b[p][q], num);
        if ((jav[p] != x && jav[q] != x) || (jav[p] != y && jav[q] != y) ||
            jav[p] < x || jav[p] > y || jav[q] < x || jav[q] > y)
          return true;
      }
  return false;
}
bool ok(int bmm, int kmm) { return kmm % bmm == 0; }
int main() {
  scanf(" %d %d", &n, &m);
  for (int i = 1; i <= m; i++) {
    for (int j = 0; j < 4; j++) scanf(" %d", &yal[i][j]);
    a[yal[i][0]][yal[i][1]] = yal[i][2];
    b[yal[i][0]][yal[i][1]] = yal[i][3];
    a[yal[i][1]][yal[i][0]] = yal[i][2];
    b[yal[i][1]][yal[i][0]] = yal[i][3];
  }
  init();
  for (int i = 1; i <= m; i++)
    if (!ok(yal[i][2], yal[i][3])) {
      cout << "NO" << endl;
      return 0;
    }
  for (int i = 1; i <= n; i++) ans[i] = 1;
  for (int k = 0; k < primes.size(); k++) {
    bool z = false;
    num = primes[k];
    for (int i = 1; i <= m; i++)
      if (yal[i][2] % num == 0 || yal[i][3] % num == 0) {
        z = true;
        break;
      }
    if (!z) continue;
    memset(chi, 0, sizeof(chi));
    memset(mark, false, sizeof(mark));
    for (int i = 1; i <= n; i++) jav[i] = 1;
    for (int i = 1; i <= m; i++) {
      for (int j = 0; j <= 1; j++) {
        if (!mark[yal[i][j]]) {
          last.clear();
          dfs(yal[i][j], yal[i][2], yal[i][3], true);
          if (wrong()) {
            for (int tt = 0; tt < last.size(); tt++) {
              mark[last[tt]] = 0;
              jav[last[tt]] = 0;
            }
            last.clear();
            dfs(yal[i][j], yal[i][2], yal[i][3], false);
            if (wrong()) {
              cout << "NO" << endl;
              return 0;
            }
          }
        }
      }
    }
    for (int i = 1; i <= n; i++) ans[i] *= jav[i];
  }
  cout << "YES" << endl;
  for (int i = 1; i <= n; i++) cout << ans[i] << " ";
  cout << endl;
}
