#include <bits/stdc++.h>
using namespace std;
template <class T>
using vv = vector<vector<T>>;
template <class T>
ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "{";
  for (int(i) = 0; (i) < (t.size()); ++(i)) {
    os << t[i] << ",";
  }
  os << "}" << endl;
  return os;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &t) {
  return os << "(" << t.first << "," << t.second << ")";
}
template <class T>
inline bool MX(T &l, const T &r) {
  return l < r ? l = r, 1 : 0;
}
template <class T>
inline bool MN(T &l, const T &r) {
  return l > r ? l = r, 1 : 0;
}
const long long MOD = 1e9 + 7;
struct Scc {
  stack<int> S;
  vector<int> inS, low, num;
  int time;

 public:
  vv<int> dag;
  vector<int> inv;
  vv<int> scc;
  void visit(const vv<int> &g, int v) {
    low[v] = num[v] = ++time;
    S.push(v);
    inS[v] = 1;
    for (const int &w : g[v]) {
      if (!num[w]) {
        visit(g, w);
        low[v] = min(low[v], low[w]);
      } else if (inS[w])
        low[v] = min(low[v], num[w]);
    }
    if (low[v] == num[v]) {
      scc.push_back(vector<int>());
      while (1) {
        int w = S.top();
        S.pop();
        inS[w] = 0;
        scc.back().push_back(w);
        if (v == w) break;
      }
    }
  }
  Scc(const vv<int> &g) {
    const int n = g.size();
    num.resize(n);
    low.resize(n);
    inS.resize(n);
    for (int(u) = 0; (u) < (n); ++(u))
      if (!num[u]) visit(g, u);
    reverse((scc).begin(), (scc).end());
    inv.resize(n);
    dag.resize(n);
    for (int(i) = 0; (i) < (scc.size()); ++(i))
      for (int(j) = 0; (j) < (scc[i].size()); ++(j)) inv[scc[i][j]] = i;
    for (int(i) = 0; (i) < (scc.size()); ++(i))
      for (int(j) = 0; (j) < (scc[i].size()); ++(j))
        for (auto e : g[scc[i][j]])
          if (inv[e] != i) dag[i].push_back(inv[e]);
  }
};
class Bcc {
  vector<int> num, inS;
  stack<int> roots, st;
  int cnt;

 public:
  vv<int> bcc, tree;
  vector<int> brdg, inv;
  void dfs(const vv<int> &g, const vector<pair<int, int>> &es, int v, int e) {
    num[v] = ++cnt;
    st.push(v);
    inS[v] = 1;
    roots.push(v);
    for (const int &i : g[v])
      if (i != e) {
        int w = es[i].first + es[i].second - v;
        if (!num[w]) {
          dfs(g, es, w, i);
        } else if (inS[w]) {
          while (num[roots.top()] > num[w]) roots.pop();
        }
      }
    if (v == roots.top()) {
      brdg.push_back(e);
      bcc.push_back(vector<int>());
      while (1) {
        int w = st.top();
        st.pop();
        inS[w] = 0;
        bcc.back().push_back(w);
        if (v == w) break;
      }
      roots.pop();
    }
  }
  Bcc(vv<int> &g, vector<pair<int, int>> es) {
    const int n = g.size();
    num.resize(n);
    inS.resize(n);
    int cnt = 0;
    for (int(i) = 0; (i) < (n); ++(i))
      if (!num[i]) {
        dfs(g, es, i, -1);
        brdg.pop_back();
      }
    const int m = bcc.size();
    inv.resize(n);
    for (int(i) = 0; (i) < (m); ++(i))
      for (const int &v : bcc[i]) inv[v] = i;
    for (pair<int, int> &p : es) {
      p.first = inv[p.first];
      p.second = inv[p.second];
    }
    sort((es).begin(), (es).end());
    (es).erase(unique((es).begin(), (es).end()), (es).end());
    tree.resize(m);
    for (const pair<int, int> &p : es)
      if (p.first != p.second) {
        tree[p.first].push_back(p.second);
        tree[p.second].push_back(p.first);
      }
  }
};
struct UF {
  vector<int> data;
  UF(int size) : data(size, -1) {}
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
int ok(vv<int> &g) {
  int n = g.size();
  UF uf(n);
  Scc h(g);
  if (h.scc.size() != n) return 0;
  vv<int> a(n);
  vector<pair<int, int>> b;
  for (int(i) = 0; (i) < (n); ++(i))
    for (int v : g[i]) {
      uf.unite(i, v);
      a[i].push_back(b.size());
      a[v].push_back(b.size());
      b.emplace_back(i, v);
    }
  Bcc c(a, b);
  int f = 0;
  for (int(i) = 0; (i) < (n); ++(i))
    if (!uf.findSet(i, 0)) f = 1;
  return c.brdg.size() + f >= 2;
}
int main() {
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(0);
  int n, m;
  cin >> n >> m;
  vector<pair<int, int>> es(m);
  for (int(i) = 0; (i) < (m); ++(i)) {
    int x, y;
    cin >> x >> y;
    --x;
    --y;
    es[i] = pair<int, int>(x, y);
  }
  for (int(i) = 0; (i) < (m); ++(i)) {
    vv<int> g(n);
    for (int(j) = 0; (j) < (m); ++(j))
      if (i != j) g[es[j].first].push_back(es[j].second);
    if (ok(g)) {
      cout << "YES" << endl;
      return 0;
    }
  }
  cout << "NO" << endl;
  return 0;
}
