#include <bits/stdc++.h>
using namespace std;
const int MAXN = 110;
bool visit[MAXN];
struct node {
  int nxt, gcd, lcm;
  node(int nxt_, int gcd_, int lcm_) {
    nxt = nxt_;
    gcd = gcd_;
    lcm = lcm_;
  }
};
vector<node> e[MAXN];
int n, m;
int a[MAXN], da[MAXN], mx[MAXN];
vector<int> now;
int get_gcd(int x, int y) {
  if (x % y == 0) return y;
  return get_gcd(y, x % y);
}
void dfs(int u) {
  visit[u] = true;
  now.push_back(u);
  for (int i = 0; i < e[u].size(); i++) {
    if (!visit[e[u][i].nxt]) dfs(e[u][i].nxt);
  }
}
bool dfs(int u, int val) {
  a[u] = val;
  for (int i = 0; i < e[u].size(); i++) {
    int v = e[u][i].nxt;
    if (a[v] == 0) {
      int av = (long long)e[u][i].lcm * e[u][i].gcd / a[u];
      if (av == 0) return false;
      if ((long long)a[u] * av != (long long)e[u][i].lcm * e[u][i].gcd)
        return false;
      if (get_gcd(av, a[u]) == e[u][i].gcd) {
        if (!dfs(v, av)) return false;
      } else
        return false;
    } else {
      if (get_gcd(a[v], a[u]) != e[u][i].gcd) return false;
    }
  }
  return true;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) da[i] = 1, mx[i] = 1000000;
  for (int i = 0; i < m; i++) {
    int x, y, gcd, lcm;
    scanf("%d%d%d%d", &x, &y, &gcd, &lcm);
    x--;
    y--;
    e[x].push_back(node(y, gcd, lcm));
    e[y].push_back(node(x, gcd, lcm));
    da[x] = max(da[x], gcd);
    da[y] = max(da[y], gcd);
    mx[x] = min(mx[x], lcm);
    mx[y] = min(mx[y], lcm);
  }
  for (int i = 0; i < n; i++)
    if (!visit[i]) {
      bool flag = false;
      now.clear();
      dfs(i);
      for (int j = da[i]; j <= mx[i]; j += da[i]) {
        for (int k = 0; k < now.size(); k++) a[now[k]] = 0;
        if (dfs(i, j)) {
          flag = true;
          break;
        }
      }
      if (!flag) {
        printf("NO\n");
        return 0;
      }
      for (int k = 0; k < now.size(); k++) visit[now[k]] = true;
    }
  printf("YES\n");
  for (int i = 0; i < n; i++) printf("%d%c", a[i], (i == n - 1) ? '\n' : ' ');
  return 0;
}
