#include <bits/stdc++.h>
using namespace std;
void fail() {
  cout << "NO" << endl;
  exit(0);
}
vector<long long> GetDivisors(long long number) {
  vector<long long> ret;
  for (long long i = 1; i <= ceil(sqrt(number)); ++i) {
    if (number % i == 0) {
      ret.push_back(i);
      ret.push_back(number / i);
    }
  }
  sort(ret.begin(), ret.end());
  ret.erase(unique(ret.begin(), ret.end()), ret.end());
  return ret;
}
long long GCD(long long abc, long long def) {
  if (abc < def) return GCD(def, abc);
  if (!def) return abc;
  return GCD(def, abc % def);
}
long long LCM(long long abc, long long def) {
  return (abc * def / GCD(abc, def));
}
int main() {
  int n;
  int m;
  cin >> n >> m;
  vector<int> adj[150];
  vector<long long> adjgcd[150];
  vector<long long> adjlcm[150];
  vector<long long> adjm[150];
  for (int(i) = 0; (i) < (m); ++(i)) {
    int from, to, gcd, lcm;
    cin >> from >> to >> gcd >> lcm;
    --from;
    --to;
    adj[from].push_back(to);
    adjgcd[from].push_back(gcd);
    adjlcm[from].push_back(lcm);
    adjm[from].push_back((long long)gcd * (long long)lcm);
    adj[to].push_back(from);
    adjgcd[to].push_back(gcd);
    adjlcm[to].push_back(lcm);
    adjm[to].push_back((long long)gcd * (long long)lcm);
  }
  vector<long long> values(n, -1LL);
  for (int(i) = 0; (i) < (n); ++(i)) {
    if (values[i] != -1LL) continue;
    if (((int)adj[i].size()) == 0) {
      values[i] = 1LL;
      continue;
    }
    vector<long long> divisors = GetDivisors(adjlcm[i][0]);
    int success = 0;
    for (int(j) = 0; (j) < (((int)divisors.size())); ++(j)) {
      vector<long long> newval = values;
      newval[i] = divisors[j];
      stack<int> s;
      s.push(i);
      int ok = 1;
      while (!s.empty()) {
        int stop = s.top();
        s.pop();
        for (int(k) = 0; (k) < (((int)adj[stop].size())); ++(k)) {
          if (newval[adj[stop][k]] == -1LL) {
            if (adjm[stop][k] % newval[stop] != 0LL) {
              ok = 0;
              break;
            }
            newval[adj[stop][k]] = adjm[stop][k] / newval[stop];
            s.push(adj[stop][k]);
          }
        }
        for (int(k) = 0; (k) < (((int)adj[stop].size())); ++(k)) {
          if (newval[adj[stop][k]] * newval[stop] != adjm[stop][k]) {
            ok = 0;
            break;
          }
          if (newval[adj[stop][k]] > adjlcm[stop][k] ||
              newval[stop] > adjlcm[stop][k]) {
            ok = 0;
            break;
          }
          if (GCD(newval[stop], newval[adj[stop][k]]) != adjgcd[stop][k]) {
            ok = 0;
            break;
          }
          if (LCM(newval[stop], newval[adj[stop][k]]) != adjlcm[stop][k]) {
            ok = 0;
            break;
          }
        }
        if (!ok) break;
      }
      if (ok) {
        values = newval;
        success = 1;
        break;
      }
    }
    if (!success) fail();
  }
  cout << "YES" << endl;
  for (int(i) = 0; (i) < (n); ++(i)) {
    if (i) cout << " ";
    cout << values[i];
  }
  cout << endl;
  return 0;
}
