#include <bits/stdc++.h>
using std::cerr;
using std::make_tuple;
using std::pair;
using std::vector;
struct disjoint_set {
  vector<int> tree;
  vector<int> h;
  vector<int> cnt;
  disjoint_set(int n) {
    tree.resize(n + 1, -1);
    h.resize(n + 1, 0);
    cnt.resize(n + 1, 1);
  }
  int find(int idx) {
    if (tree[idx] == -1) return idx;
    return tree[idx] = find(tree[idx]);
  }
  void Union(int a, int b) {
    int A = find(a);
    int B = find(b);
    if (A == B) return;
    if (h[A] == h[B]) {
      tree[B] = A;
      cnt[A] += cnt[B];
      h[A]++;
    } else if (h[A] > h[B]) {
      tree[B] = A;
      cnt[A] += cnt[B];
    } else {
      tree[A] = B;
      cnt[B] += cnt[A];
    }
  }
};
int degree[150100];
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  disjoint_set set(n);
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    degree[a]++;
    degree[b]++;
    set.Union(a, b);
  }
  for (int i = 1; i <= n; i++) {
    if (degree[i] != set.cnt[set.find(i)] - 1) {
      printf("NO");
      return 0;
    }
  }
  printf("YES");
  return 0;
}
