#include <bits/stdc++.h>
int pprime[1010] = {0};
int prime[1010];
int total;
void Getprime() {
  int i, j;
  for (i = 2; i * i <= 1010; i++) {
    if (!pprime[i]) {
      for (j = i; j * i <= 1010; j++) pprime[j * i] = 1;
    }
  }
  total = 0;
  for (i = 2; i <= 1010; i++)
    if (!pprime[i]) prime[total++] = i;
}
struct Edge {
  int next;
  int v;
  int gcd, lcm;
} edge[10010];
int head[110];
int pos;
void insert(int x, int y, int gcd, int lcm) {
  edge[pos].next = head[x];
  edge[pos].v = y;
  edge[pos].gcd = gcd;
  edge[pos].lcm = lcm;
  head[x] = pos++;
}
int ans[110];
int mark[110];
bool dfs(int now, int pre) {
  int i;
  int l, r;
  for (i = head[now]; i; i = edge[i].next) {
    int v = edge[i].v;
    if (v == pre) continue;
    l = edge[i].gcd;
    r = edge[i].lcm;
    if (mark[now] != l && mark[now] != r) return false;
    if (mark[now] == l) {
      if (mark[v] == r)
        continue;
      else if (mark[v] == -1) {
        mark[v] = r;
        if (!dfs(v, now)) {
          mark[v] = -1;
          return false;
        }
      } else
        return false;
    } else {
      if (mark[v] == l)
        continue;
      else if (mark[v] == -1) {
        mark[v] = l;
        if (!dfs(v, now)) {
          mark[v] = -1;
          return false;
        }
      } else
        return false;
    }
  }
  return true;
}
struct fff {
  int x, y, gcd, lcm;
} ooxx[10010];
int judge(int m) {
  for (int i = 0; i < m; i++) {
    if (ooxx[i].gcd != 1) return ooxx[i].gcd;
    if (ooxx[i].lcm != 1) return ooxx[i].lcm;
  }
  return 0;
}
int main() {
  Getprime();
  int n, m;
  int x, y;
  int l, r;
  int now;
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) ans[i] = 1;
  for (int i = 0; i < m; i++)
    scanf("%d %d %d %d", &ooxx[i].x, &ooxx[i].y, &ooxx[i].gcd, &ooxx[i].lcm);
  for (int i = 0; i < m; i++)
    if (ooxx[i].lcm % ooxx[i].gcd != 0) {
      printf("NO\n");
      return 0;
    }
  int flag;
  for (int k = 0; k < total; k++) {
    flag = judge(m);
    if (!flag) break;
    now = prime[k];
    memset(head, 0, sizeof(head));
    pos = 1;
    for (int i = 0; i < m; i++) {
      x = ooxx[i].x;
      y = ooxx[i].y;
      l = 0;
      r = 0;
      while (ooxx[i].gcd % now == 0) {
        l++;
        ooxx[i].gcd /= now;
      }
      while (ooxx[i].lcm % now == 0) {
        r++;
        ooxx[i].lcm /= now;
      }
      insert(x, y, l, r);
      insert(y, x, l, r);
    }
    memset(mark, -1, sizeof(mark));
    for (int i = 1; i <= n; i++)
      if (mark[i] == -1) {
        if (!head[i]) {
          mark[i] = 0;
          continue;
        }
        int j = head[i];
        l = edge[j].gcd;
        r = edge[j].lcm;
        mark[i] = l;
        if (dfs(i, -1)) continue;
        mark[i] = r;
        if (dfs(i, -1)) continue;
        printf("NO\n");
        return 0;
      }
    for (int i = 1; i <= n; i++) {
      int add = 1;
      int time = mark[i];
      while (time--) add *= now;
      ans[i] *= add;
    }
  }
  while (1) {
    flag = judge(m);
    if (!flag) break;
    now = flag;
    memset(head, 0, sizeof(head));
    pos = 1;
    for (int i = 0; i < m; i++) {
      x = ooxx[i].x;
      y = ooxx[i].y;
      l = 0;
      r = 0;
      while (ooxx[i].gcd % now == 0) {
        l++;
        ooxx[i].gcd /= now;
      }
      while (ooxx[i].lcm % now == 0) {
        r++;
        ooxx[i].lcm /= now;
      }
      insert(x, y, l, r);
      insert(y, x, l, r);
    }
    memset(mark, -1, sizeof(mark));
    for (int i = 1; i <= n; i++)
      if (mark[i] == -1) {
        if (!head[i]) {
          mark[i] = 0;
          continue;
        }
        int j = head[i];
        l = edge[j].gcd;
        r = edge[j].lcm;
        mark[i] = l;
        if (dfs(i, -1)) continue;
        mark[i] = r;
        if (dfs(i, -1)) continue;
        printf("NO\n");
        return 0;
      }
    for (int i = 1; i <= n; i++) {
      int add = 1;
      int time = mark[i];
      while (time--) add *= now;
      ans[i] *= add;
    }
  }
  printf("YES\n");
  for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
  printf("\n");
  return 0;
}
