Bear Limak examines a social network. Its main functionality is that two members can become friends (then they can talk with each other and share funny pictures).

There are n members, numbered 1 through n. m pairs of members are friends. Of course, a member can't be a friend with themselves.

Let A-B denote that members A and B are friends. Limak thinks that a network is reasonable if and only if the following condition is satisfied: For every three distinct members (X, Y, Z), if X-Y and Y-Z then also X-Z.

For example: if Alan and Bob are friends, and Bob and Ciri are friends, then Alan and Ciri should be friends as well.

Can you help Limak and check if the network is reasonable? Print "YES" or "NO" accordingly, without the quotes.


-----Input-----

The first line of the input contain two integers n and m (3 ≤ n ≤ 150 000, $0 \leq m \leq \operatorname{min}(150000, \frac{n \cdot(n - 1)}{2})$) — the number of members and the number of pairs of members that are friends.

The i-th of the next m lines contains two distinct integers a_{i} and b_{i} (1 ≤ a_{i}, b_{i} ≤ n, a_{i} ≠ b_{i}). Members a_{i} and b_{i} are friends with each other. No pair of members will appear more than once in the input.


-----Output-----

If the given network is reasonable, print "YES" in a single line (without the quotes). Otherwise, print "NO" in a single line (without the quotes).


-----Examples-----
Input
4 3
1 3
3 4
1 4

Output
YES

Input
4 4
3 1
2 3
3 4
1 2

Output
NO

Input
10 4
4 3
5 10
8 9
1 2

Output
YES

Input
3 2
1 2
2 3

Output
NO



-----Note-----

The drawings below show the situation in the first sample (on the left) and in the second sample (on the right). Each edge represents two members that are friends. The answer is "NO" in the second sample because members (2, 3) are friends and members (3, 4) are friends, while members (2, 4) are not.

 [Image]

Difficulty: interview

Starter code:

Solutions:
from collections import deque


def bfs(start):
    res = []
    queue = deque([start])
    while queue:
        vertex = queue.pop()
        if not vis[vertex]:
            vis[vertex] = 1
            res.append(vertex)
            for i in s[vertex]:
                if not vis[i]:
                    queue.append(i)
    return res

n, m = [int(i) for i in input().split()]
s = [[] for i in range(n)]
for i in range(m):
    a, b = [int(i) for i in input().split()]
    s[a-1].append(b-1)
    s[b-1].append(a-1)
vis = [0 for i in range(n)]
r = 0
for i in range(n):
    if not vis[i]:
        d = bfs(i)
        for j in d:
            if len(s[j]) != len(d)-1:
                r = 1
                print("NO")
                break
    if r:
        break
else:
    print("YES")

import sys

def main():
    n,m = map(int,sys.stdin.readline().split())

    l = [[] for i in range(n+1)]
    u = [False]*(n+1)

    for i in range(m):
        a, b = map(int,sys.stdin.readline().split())
        l[a].append(b)
        l[b].append(a)
        
    for i in range(n):
        j = i+1
        if u[j]:
            continue
        u[j] = True        
        q = []
        cl = len(l[j])
        cn = 1
        for a in l[j]:
            q.append(a)

        while len(q)!=0 :
            cur = q.pop()
            if u[cur]:
                continue
            u[cur] = True
            cn+=1
            cl+=len(l[cur])
            for a in l[cur]:
                if u[a]:
                    continue
                q.append(a)
        if cl!=cn*(cn-1):
            #print(j, cl, cn)
            print("NO")
            return
    print("YES")


main()

n, m = [int(x) for x in input().split()]

l = [] 
for i in range(m):
    x, y = [int(x) for x in input().split()]
    if x>y: x,y = y,x
    l.append((x, y))
l.sort(key=lambda x: x[0])

labels = {}
rels_count = {}
class_count = {}
for x, y in l:
    if x not in labels:
        labels[x] = len(rels_count)
        rels_count[labels[x]] = 0
        class_count[labels[x]] = 1
    if y not in labels:
        class_count[labels[x]] += 1
    labels[y] = labels[x]
    rels_count[labels[x]]+=1
    
flag = True
for i in range(len(rels_count)):
    l_n = class_count[i]
    l_m = rels_count[i]
    if l_n*(l_n-1) != 2*l_m:
        flag = False
        break
if flag:
    print("YES")
else:
    print("NO")

import sys
import collections


def bfs(u, adjList, vis):
    dq = collections.deque()

    dq.append(u)
    vis[u] = True
    edgeCnt = 0
    vertexCnt = 0

    while dq:
        u = dq.popleft()

        vertexCnt += 1
        edgeCnt += len(adjList[u])

        for v in adjList[u]:
            if not vis[v]:
                vis[v] = True
                dq.append(v)

    edgeCnt = edgeCnt // 2
    return bool(edgeCnt == ((vertexCnt * vertexCnt - vertexCnt) // 2))


def main():
    # sys.stdin = open("in.txt", "r")

    it = iter(map(int, sys.stdin.read().split()))

    n = next(it)
    m = next(it)

    adjList = [[] for _ in range(n+3)]

    for _ in range(m):
        u = next(it)
        v = next(it)
        adjList[u].append(v)
        adjList[v].append(u)

    vis = [False] * (n+3)

    for u in range(1, n+1):
        if not vis[u]:
            if not bfs(u, adjList, vis):
                sys.stdout.write("NO\n")
                return

    sys.stdout.write("YES\n")


def __starting_point():
    main()

__starting_point()

# http://codeforces.com/contest/791/problem/B

nax = 150123

edges = [[] for _ in range(nax)]
vis = [False for j in range(nax)]


def dfs(a, cnt_vertices, cnt_edges):
    stack = [a]
    while len(stack) > 0:
        a = stack.pop()
        if vis[a]:
            continue
        vis[a] = True
        cnt_vertices[0] += 1
        cnt_edges[0] += len(edges[a])
        for b in edges[a]:
            if not vis[b]:
                stack.append(b)


def main():
    n, m = list(map(int, str(input()).strip().split()))

    for _ in range(m):
        a, b = list(map(int, str(input()).strip().split()))
        edges[a].append(b)
        edges[b].append(a)

    for i in range(1, n + 1):
        if not vis[i]:
            cnt_vertices = [0]
            cnt_edges = [0]
            dfs(i, cnt_vertices, cnt_edges)
            if cnt_edges[0] != cnt_vertices[0] * (cnt_vertices[0] - 1):
                print('NO')
                return 0

    print('YES')


def __starting_point():
    main()

__starting_point()


n,m=[int(x)for x in input().split()]
d={}
con=set()
for x in range(m):
    a,b=input().split()
    d.setdefault(a,{a}).add(b)
    d.setdefault(b,{b}).add(a)
res=None
for x,y in d.items():
    if x not in con:
        if all([d[u]==y for u in y]):
            con.update(y)
        else:
            res='NO'
            break
if not res:
    res='YES'
print(res)

n,m=[int(x)for x in input().split()]
d={}
con=set()
for x in range(m):
    a,b=input().split()
    d.setdefault(a,{a}).add(b)
    d.setdefault(b,{b}).add(a)
res=None
for x,y in d.items():
    if x not in con:
        if all([d[u]==y for u in y]):
            con.update(y)
        else:
            res='NO'
            break
if not res:
    res='YES'
print(res)

def read():
    n, m = list(map(int, input().rstrip().split()))
    graph = [set() for _ in range(n + 1)]
    for _ in range(m):
        a, b = list(map(int, input().rstrip().split()))
        graph[a].add(b)
        graph[b].add(a)
        graph[a].add(a)
        graph[b].add(b)
    return (graph, n)

def main():
    graph, n = read()
    seen = set()
    for i in range(1, n + 1):
        if len(graph[i]) > 0 and i not in seen:
            if not all(graph[i] == graph[j] for j in graph[i]):
                return False
            seen |= graph[i]
    return True

def __starting_point():
    if main():
        print('YES')
    else:
        print('NO')

__starting_point()

def read():
    n, m = list(map(int, input().rstrip().split()))
    graph = [set() for _ in range(n + 1)]
    for _ in range(m):
        a, b = list(map(int, input().rstrip().split()))
        graph[a].add(b)
        graph[b].add(a)
        graph[a].add(a)
        graph[b].add(b)
    return (graph, n)

def main():
    graph, n = read() 
    seen = set()
    for i in range(1, n + 1):
        if len(graph[i]) > 0 and i not in seen:
            if not all(graph[i] == graph[j] for j in graph[i]):
                return False
            seen |= graph[i]
    return True

def __starting_point():
    if main():
        print('YES')
    else:
        print('NO')

__starting_point()

n, m = [int(x) for x in input().split()]
d = {}
visited = set()
for x in range(m):
    a, b = input().split()
    d.setdefault(a, {a}).add(b)
    d.setdefault(b, {b}).add(a)
res='YES'
for x, y in d.items():
    if x not in visited:
        if all([d[u]==y for u in y]):
            visited.update(y)
        else:
            res='NO'
            break
print(res)

from sys import *
f = lambda: map(int, stdin.readline().split())
n, m = f()
g = [[i] for i in range(n + 1)]
for j in range(m):
    u, v = f()
    g[u].append(v)
    g[v].append(u)
k = 'YES'
for t in g: t.sort()
for t in g:
    s = len(t)
    if s > 1 and not all(g[x] == t for x in t):
        k = 'NO'
        break
    for j in t: g[j] = []
print(k)

from sys import *
f = lambda: map(int, stdin.readline().split())
n, m = f()
g = [[x] for x in range(n + 1)]
p = [0] * (n + 1)
for j in range(m):
    u, v = f()
    g[u].append(v)
    g[v].append(u)
k = 'YES'
for y, t in enumerate(g):
    if not p[y]:
        if any(len(g[x]) != len(t) or any(p[y] for y in g[x]) for x in t):
            k = 'NO'
            break
        for x in t: p[x] = 1
print(k)

from collections import Counter as cntr
from math import inf
def cin():
	return list(map(int, input().split(' ')))
def dfs(graph, src, n):
	q = [src]
	h = 0
	nonlocal visited
	edges = 0
	while q:
		idx = q.pop()
		h += 1

		for v in graph[idx]:
			edges += 1
			if visited[v] == False:
				visited[v] = True
				q.append(v)
	return h,edges
n,m = cin()
g = {i:[] for i in range(n)}
for i in range(m):
	a, b = cin()
	a -= 1
	b -= 1
	g[a].append(b)
	g[b].append(a)
visited = [False for i in range(n)]
for i in range(n):
	if visited[i] == False:
		visited[i] = True
		v,e = dfs(g, i, n)
		e = e//2

		if e != (v*(v-1))//2:
			print('NO')
			return
print('YES')




n, m = [int(x) for x in input().split()]
d = {}
visited = set()
for x in range(m):
    a, b = input().split()
    d.setdefault(a, {a}).add(b)
    d.setdefault(b, {b}).add(a)
for x, y in d.items():
       if x not in visited:
              if all([d[u]==y for u in y]):
                     visited.update(y)
              else:
                     print('NO');return
                     break
print('YES')

n,m=[int(x)for x in input().split()]
d={}
con=set()
for x in range(m):
    a,b=input().split()
    d.setdefault(a,{a}).add(b)
    d.setdefault(b,{b}).add(a)
res=None
for x,y in list(d.items()):
    if x not in con:
        if all([d[u]==y for u in y]):
            con.update(y)
        else:
            res='NO'
            break
if not res:
    res='YES'
print(res)




# Made By Mostafa_Khaled


n,m=map(int,input().split())
v=[0]*150005
s=[set([i])for i in range(150005)]
for _ in ' '*m:
    a,b=map(int,input().split())
    s[a].add(b)
    s[b].add(a)
for i in range(n):
    if not v[i]:
        for j in s[i]:
            v[j]=1
            if s[j]!=s[i]:print('NO');return
print('YES')

n,m=map(int,input().split())
v=[0]*150005
s=[set([i])for i in range(150005)]
for _ in ' '*m:
    a,b=map(int,input().split())
    s[a].add(b)
    s[b].add(a)
for i in range(n):
    if not v[i]:
        for j in s[i]:
            v[j]=1
            if s[j]!=s[i]:print('NO');return
print('YES')

# -*- coding: utf-8 -*-
n, m = map(int, input().split(' '))
edges = [[] for i in range(n + 1)]
vis = [False] * (n + 1)

def dfs(a):
    nonlocal cnt_vertices
    nonlocal cnt_edges
    stack = [a]
    while len(stack) > 0:
        a = stack.pop()
        if vis[a]:
            continue
        vis[a] = True
        cnt_vertices += 1
        cnt_edges += len(edges[a])
        for b in edges[a]:
            if not vis[b]:
                stack.append(b)

while m > 0:
    a, b = map(int, input().split(' '))
    edges[a].append(b)
    edges[b].append(a)
    m -= 1
for i in range(1, n+1):
    if vis[i] == False:
        cnt_vertices = 0
        cnt_edges = 0
        dfs(i)
        if cnt_edges != cnt_vertices*(cnt_vertices-1):
            print("NO")
            return
print("YES")

inp = lambda : list(map(int, input().split()))
n, m = inp()
lines = [set([i]) for i in range(n + 1)]
for i in range(m):
    x, y = inp()
    lines[x].add(y)
    lines[y].add(x)
f = [True] * (n + 1)
for i in range(n):
    if f[i]:
        f[i] = False
        for j in lines[i]:
            f[j] = False
            if lines[i] != lines[j]:
                print("NO")
                quit()
print("YES")


n, m = list(map(int, input().split()))
d = {}
for i in range(m):
    a, b = list(map(int, input().split()))
    if a not in d:
        d[a] = {b}
    else:
        d[a].add(b)
    if b not in d:
        d[b] = {a}
    else:
        d[b].add(a)

not_visited = set(range(2, n+1))
visited = set()
current = set()
stack = [1]
succ = True
while len(visited) < n:

    if not stack:
        t = not_visited.pop()
        stack = [t]
        current = set()

    p = stack.pop()
    visited.add(p)
    if p in d:
        for y in current:
            if y not in d[p]:
                succ = False
                break
        if not succ:
            break
        current.add(p)
        for x in d[p]:
            if x in not_visited:
                stack.append(x)
                not_visited.remove(x)

if succ:
    print('YES')
else:
    print('NO')


'''
n,m = map(int,input().split())
eg,deg = [[] for _ in range(n+1)],[0 for _ in range(n+1)]
f,rk = list(range(n+1)),[0 for _ in range(n+1)]
def fd(a):
    if f[a]!=a :return fd(f[a]) 
    return f[a]
def un(a,b):
    ra,rb = fd(a),fd(b)
    if ra==rb:return 
    if rk[ra]>=rk[rb]:
        f[rb] = ra
        if rk[ra]==rk[rb]:rk[ra] +=1
    else :f[ra] = rb
for i in range(1,n+1):
    for j in eg[i]:
        un(j,i)
for x,y in [map(int,input().split()) for _ in range(m)]:
    un(x,y)
    deg[x],deg[y] = deg[x]+1,deg[y]+1
table = [0 for _ in range(n+1)]
for i in range(1,n+1):
    table[f[i]] += 1
ok = 1
for i in range(1,n+1):
    if deg[i]!=table[f[i]]-1:
        ok = 0
        break
print("YES") if ok else print("NO")
'''
n, m = [int(x) for x in input().split()]
d = {}
visited = set()
for x in range(m):
    a, b = input().split()
    d.setdefault(a, {a}).add(b)
    d.setdefault(b, {b}).add(a)
res='YES'
for x, y in d.items():
    if x not in visited:
        if all([d[u]==y for u in y]):
            visited.update(y)
        else:
            res='NO'
            break
print(res)

from collections import defaultdict 
n,m=map(int,input().split())
d=defaultdict(list)
for i in range(m):
    a,b=map(int,input().split())
    a-=1 
    b-=1
    d[a].append(b)
    d[b].append(a)
vis=[0]*n 
for i in range(n):
    if vis[i]==0:
        q=[i]
        ce=0
        cv=0 
        vis[i]=1 
        while q:
            t=q.pop()
            cv+=1 
            ce+=len(d[t])
            for i in d[t]:
                if not vis[i]:
                    vis[i]=1 
                    q.append(i)
    if ce!=cv*(cv-1):
        print('NO')
        return
print('YES')

#   In this template you are not required to write code in main

import sys
inf = float("inf")

sys.setrecursionlimit(1000000)
#from cmath import sqrt
#from collections import deque, Counter, OrderedDict,defaultdict
#from heapq import nsmallest, nlargest, heapify,heappop ,heappush, heapreplace
#from math import ceil,floor,log,sqrt,factorial,pow,pi,gcd
#from bisect import bisect_left,bisect_right
#import numpy as np

abc='abcdefghijklmnopqrstuvwxyz'
abd={'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25}
mod,MOD=1000000007,998244353
vow=['a','e','i','o','u']
dx,dy=[-1,1,0,0],[0,0,1,-1]

def dfs(start):
    stack=[start]
    ct_vertex=1;ct_edges=0
    while stack:
        x=stack.pop()
        visited[x]=True
        for i in graph[x]:
            ct_edges+=1
            if not visited[i]:
                visited[i]=True
                ct_vertex+=1
                stack.append(i)
    # print(ct_vertex,ct_edges)
    if ct_edges==(ct_vertex*(ct_vertex-1)):
        return True
    else:
        return False


def get_array(): return list(map(int, sys.stdin.readline().strip().split()))
def get_ints(): return map(int, sys.stdin.readline().strip().split())
def input(): return sys.stdin.readline().strip()

n,m=get_ints()
graph={i:[] for i in range(1,n+1)}
for i in range(m):
    x,y=get_ints()
    graph[x].append(y)
    graph[y].append(x)

visited=[False]*(n+1);flag=0
for i in range(1,n+1):
    if not visited[i]:
        if not dfs(i):
            flag=1
            break
if flag==0:
    print('YES')
else:
    print("NO")