/* 2003 MO P-I-1
 *
 * Petr Baudis
 * OKTAVA, gymnazium Ad Fontes Jihlava
 *
 * Reseni, ktere se nabizi, spociva ve vyuziti skutecnosti, ze i po odebrani
 * kterekoliv jedne hrany grafu musi tento graf zustat souvislym. Neni tedy nic
 * jednodussiho, nez postupne zkusit odebrat kteroukoliv hranu a otestovat
 * souvislost grafu. Pokud graf po celou dobu zustane souvisly, je vse v
 * nejlepsim poradku.
 *
 * Souvislost grafu budeme kontrolovat jednoduse obarvovanim jednotlivych uzlu
 * pri prohledavani do hloubky (tzn. zacneme prohledavat do hloubky a
 * navstivene uzly si oznacime, pokud narazime na oznaceny uzel, jiz po te
 * hrane znovu nepokracujeme). Pokud jsme obarvili vsechny uzly, je graf
 * souvisly.
 *
 * Casova narocnost obarvovani je O(N+M), a tento test souvislosti provedeme
 * pro kazdou hranu, celkova casova narocnost tedy bude O(M * (N+M)). Musime si
 * v pameti pamatovat cely graf, pametova narocnost tedy bude take O(N+M).
 */

#include <stdio.h>
#include <string.h>

static struct node_t {
  int degree;
  int edges[100];
} graph[100];

int watermark[100];
int watermarked;

static int degree;
static struct { int node1, edge1, node2, edge2; } edges[10000];

int n, m;

void
depth_first_walk(int from)
{
  int i;

  for (i = 0; i < graph[from].degree; i++) {
    if (graph[from].edges[i] < 0 || watermark[graph[from].edges[i]])
      continue;

    watermark[graph[from].edges[i]] = 1;
    watermarked++;
    depth_first_walk(graph[from].edges[i]);
  }
}

int
is_contignuous()
{
  memset(watermark, 0, 100);
  watermarked = 0;

  depth_first_walk(0);
  return (watermarked == n);
}

int
main()
{
  int i;

  scanf("%d %d", &n, &m);

  for (i = 0; i < m; i++) {
    int node1, node2;

    scanf("%d %d", &node1, &node2);
    node1--, node2--;
    edges[degree].node1 = node1;
    edges[degree].edge1 = graph[node1].degree;
    edges[degree].node2 = node2;
    edges[degree++].edge2 = graph[node2].degree;
    graph[node1].edges[graph[node1].degree++] = node2;
    graph[node2].edges[graph[node2].degree++] = node1;
  }

  for (i = 0; i < m; i++) {
    graph[edges[i].node1].edges[edges[i].edge1] = -1;
    graph[edges[i].node2].edges[edges[i].edge2] = -1;
    if (!is_contignuous()) {
      printf("NE\n");
      return 0;
    }
    graph[edges[i].node1].edges[edges[i].edge1] = edges[i].node2;
    graph[edges[i].node2].edges[edges[i].edge2] = edges[i].node1;
  }

  printf("ANO\n");

  return 0;
}
