#include <bits/stdc++.h>
using namespace std;
const int maxx = 1e6;
int n, m;
long long nod[105][105], nok[105][105], ab[105][105];
bool was[105], nn[105];
long long val[105], vv[105];
long long tt[105];
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
long long lcm(long long a, long long b) { return a * b / gcd(a, b); }
bool dfs(int v) {
  if (nn[v]) return true;
  nn[v] = true;
  if (val[v] > maxx) return false;
  for (int i = 0; i < n; ++i)
    if (nod[v][i] != 0) {
      if (val[i] == 0) val[i] = ab[v][i] / val[v];
      if (val[i] * val[v] != ab[v][i]) return false;
      if (gcd(val[i], val[v]) != nod[v][i]) return false;
      if (lcm(val[i], val[v]) != nok[v][i]) return false;
      if (!dfs(i)) return false;
    }
  return true;
}
void dfs2(int v) {
  if (was[v]) return;
  was[v] = true;
  for (int i = 0; i < n; ++i)
    if (nod[v][i] != 0) {
      if (vv[i] == 0) vv[i] = ab[v][i] / vv[v];
      dfs2(i);
    }
}
bool tryit(int i, long long x) {
  memset(nn, 0, sizeof(nn));
  memset(val, 0, sizeof(val));
  val[i] = x;
  if (dfs(i)) {
    vv[i] = x;
    dfs2(i);
    return true;
  }
  return false;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; ++i) tt[i] = 1ll;
  for (int i = 0; i < m; ++i) {
    int x, y, a, b;
    scanf("%d%d%d%d", &x, &y, &a, &b);
    --x, --y;
    nod[x][y] = nod[y][x] = a;
    nok[x][y] = nok[y][x] = b;
    ab[x][y] = ab[y][x] = (long long)a * b;
    tt[x] = (long long)a * b;
    tt[y] = (long long)a * b;
  }
  for (int i = 0; i < n; ++i)
    if (!was[i]) {
      bool ok = false;
      for (int j = 1; j * j <= tt[i]; ++j)
        if (tt[i] % j == 0)
          if (tryit(i, j) || tryit(i, tt[i] / j)) {
            ok = true;
            break;
          }
      if (!ok) {
        printf("NO\n");
        exit(0);
      }
    }
  printf("YES\n");
  for (int i = 0; i < n; ++i) cout << vv[i] << (char)(" \n"[i + 1 == n]);
  return 0;
}
