#include <bits/stdc++.h>
class Graph {
 private:
  int V;
  std::list<int> *adj;
  std::vector<bool> visited;

 public:
  Graph(const int &V);
  ~Graph();
  void InsertEdge(const int &v1, const int &v2);
  void DFS(const int &v);
  bool IsTree();
};
int main() {
  int n, m;
  std::cin >> n >> m;
  if (m != n - 1) {
    std::cout << "no";
    return 0;
  }
  Graph g(n);
  int v1, v2;
  for (int i = 0; i < m; i++) {
    std::cin >> v1 >> v2;
    g.InsertEdge(v1 - 1, v2 - 1);
  }
  if (g.IsTree()) {
    std::cout << "yes";
    return 0;
  }
  std::cout << "no";
  return 0;
}
Graph::Graph(const int &V) : visited(V, false) {
  this->V = V;
  this->adj = new std::list<int>[V];
}
Graph::~Graph() { delete[] this->adj; }
void Graph::InsertEdge(const int &v1, const int &v2) {
  this->adj[v1].push_back(v2);
  this->adj[v2].push_back(v1);
}
void Graph::DFS(const int &v) {
  this->visited[v] = true;
  std::list<int>::iterator i;
  for (i = this->adj[v].begin(); i != this->adj[v].end(); i++) {
    if (!visited[*i]) {
      DFS(*i);
    }
  }
}
bool Graph::IsTree() {
  Graph::DFS(0);
  for (int i = 0; i < this->V; i++) {
    if (!this->visited[i]) {
      return false;
    }
  }
  return true;
}
