#include <bits/stdc++.h>
using namespace std;
struct data {
  int nok;
  int nod;
};
int nodf(int a, int b) {
  if (a == 0) return b;
  if (a == b) return a;
  if (a > b) return nodf(a % b, b);
  if (a < b) return nodf(b % a, a);
}
bool go(vector<int> &ans, vector<vector<data> > &a, int t) {
  for (int i = 1; i <= a.size() - 1; ++i)
    if (i != t) {
      long long nok = a[t][i].nok;
      long long nod = a[t][i].nod;
      if (((nok * nod) % ans[t]) != 0) return false;
      long long res = (nok * nod) / ans[t];
      if (res == 0) continue;
      if (nodf(res, ans[t]) != nod || res > 1000000) return false;
      if (ans[i] == 0) {
        ans[i] = res;
        if (go(ans, a, i) == false) return false;
      } else if (ans[i] != res)
        return false;
    }
  return true;
}
int main() {
  int n, m;
  cin >> n >> m;
  vector<vector<data> > a(n + 1);
  for (int i = 1; i <= n; ++i) a[i].resize(n + 1);
  for (int y = 0; y < m; ++y) {
    int j, i, nod, nok;
    cin >> i >> j >> nod >> nok;
    a[i][j].nok = a[j][i].nok = nok;
    a[i][j].nod = a[j][i].nod = nod;
    if (nok % nod != 0) {
      cout << "NO";
      return 0;
    }
  }
  vector<int> ans(n + 1);
  for (int i = 1; i <= n; ++i)
    if (ans[i] == 0) {
      bool t = false;
      int maxNOK = 1;
      for (int j = 1; j <= n; ++j) maxNOK = max(maxNOK, a[i][j].nod);
      for (ans[i] = maxNOK; ans[i] < 1000001; ans[i] += maxNOK) {
        vector<int> tmp = ans;
        if (go(tmp, a, i) == true) {
          ans = tmp;
          t = true;
          break;
        }
      }
      if (t == false) {
        cout << "NO";
        return 0;
      }
    }
  cout << "YES" << endl;
  for (int i = 1; i <= n; ++i) cout << ans[i] << ' ';
  return 0;
}
