#include <bits/stdc++.h>

#pragma GCC diagnostic warning "-std=c++11"

/* Raiyan Noory Rady,CSE'17,RUET
Email:raiyannooryrady@gmail.com
Smile->Desire->Unity->Effort->Struggle->Success->Again smile :)
***I_Love_Trench***/

#define ll long long int
#define pf push_front
#define mod  1000000007
#define inf  1000000000000000000
#define pi  acos(-1.0)
#define maxn  1000009
#define sorted(s)  sort(s.begin(),s.end())
#define sortarr(a) sort(a,a+n)
#define slc(n) scanf("%I64d", &n)
#define sl(n)  scanf("%lld", &n)
#define sf(n)  scanf("%lf", &n)
#define si(n)  scanf("%d", &n)
#define sch(n)  scanf(" %c", &n)
#define ss(n)  scanf("%s", n)
#define prf printf
#define pb  push_back
#define fr first
#define sc second
#define all(a)  a.begin(),a.end()
#define forl(n) for(i=0;i<n;i++)
/*STL library functions

sort(first_iterator, last_iterator) – To sort the given vector.

reverse(first_iterator, last_iterator) – To reverse a vector.

*max_element (first_iterator, last_iterator) – To find the maximum element of a vector.

*min_element (first_iterator, last_iterator) – To find the minimum element of a vector.

accumulate(first_iterator, last_iterator, initial value of sum) – Does the summation of vector elements

count(first_iterator, last_iterator,x) – To count the occurrences of x in vector.

find(first_iterator, last_iterator, x) – Points to last address of vector ((name_of_vector).end())
 if element is not present in vector.

binary_search(first_iterator, last_iterator, x) – Tests whether x exists in sorted vector or not.

lower_bound(first_iterator, last_iterator, x) – returns an iterator pointing to the first element in the range [first,last)
which has a value not less than ‘x’.

upper_bound(first_iterator, last_iterator, x) – returns an iterator pointing to the first element in the range [first,last)
 which has a value greater than ‘x’.

arr.erase(position to be deleted) – This erases selected element in vector and shifts and resizes the vector elements accordingly.

arr.erase(unique(arr.begin(),arr.end()),arr.end()) – This erases the duplicate occurrences in sorted vector in a single line.

distance(first_iterator,desired_position) – It returns the distance of desired position from the first iterator.
This function is very useful while finding the index.

next_permutation(first_iterator, last_iterator) – This modified the vector to its next permutation.

prev_permutation(first_iterator, last_iterator) – This modified the vector to its previous permutation.
*/

using namespace std;

int main()
{
    ll n,m,i,f=0,k=0,x=0,j,l=0;
    cin>>n>>m;
    ll a[n+5][m+5],b[2505],c[2505];
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            cin>>a[i][j];
            if(a[i][j]==1)
                f=1;
        }
    }
    if(f==0)
        cout<<0<<endl;
    else
    {
        f=0;
        for(i=1;i<n;i++)
        {
            for(j=1;j<m;j++)
            {
                if(a[i][j]==1 && a[i][j+1]==1&& a[i+1][j]==1&&a[i+1][j+1]==1)
                {
                    b[k++]=i;
                    c[l++]=j;
                    f=1;
                }
            }
        }
        if(f==0)
            cout<<-1<<endl;
        else
        {
            cout<<k<<endl;
            for(x=0;x<k;x++)
                cout<<b[x]<<" "<<c[x]<<endl;
        }
    }

    return 0;
}


#include <bits/stdc++.h>

#pragma GCC diagnostic warning "-std=c++11"

/* Raiyan Noory Rady,CSE'17,RUET
Email:raiyannooryrady@gmail.com
Smile->Desire->Unity->Effort->Struggle->Success->Again smile :)
***I_Love_Trench***/

#define ll long long int
#define pf push_front
#define mod  1000000007
#define inf  1000000000000000000
#define pi  acos(-1.0)
#define maxn  1000009
#define sorted(s)  sort(s.begin(),s.end())
#define sortarr(a) sort(a,a+n)
#define slc(n) scanf("%I64d", &n)
#define sl(n)  scanf("%lld", &n)
#define sf(n)  scanf("%lf", &n)
#define si(n)  scanf("%d", &n)
#define sch(n)  scanf(" %c", &n)
#define ss(n)  scanf("%s", n)
#define prf printf
#define pb  push_back
#define fr first
#define sc second
#define all(a)  a.begin(),a.end()
#define forl(n) for(i=0;i<n;i++)
/*STL library functions

sort(first_iterator, last_iterator) – To sort the given vector.

reverse(first_iterator, last_iterator) – To reverse a vector.

*max_element (first_iterator, last_iterator) – To find the maximum element of a vector.

*min_element (first_iterator, last_iterator) – To find the minimum element of a vector.

accumulate(first_iterator, last_iterator, initial value of sum) – Does the summation of vector elements

count(first_iterator, last_iterator,x) – To count the occurrences of x in vector.

find(first_iterator, last_iterator, x) – Points to last address of vector ((name_of_vector).end())
 if element is not present in vector.

binary_search(first_iterator, last_iterator, x) – Tests whether x exists in sorted vector or not.

lower_bound(first_iterator, last_iterator, x) – returns an iterator pointing to the first element in the range [first,last)
which has a value not less than ‘x’.

upper_bound(first_iterator, last_iterator, x) – returns an iterator pointing to the first element in the range [first,last)
 which has a value greater than ‘x’.

arr.erase(position to be deleted) – This erases selected element in vector and shifts and resizes the vector elements accordingly.

arr.erase(unique(arr.begin(),arr.end()),arr.end()) – This erases the duplicate occurrences in sorted vector in a single line.

distance(first_iterator,desired_position) – It returns the distance of desired position from the first iterator.
This function is very useful while finding the index.

next_permutation(first_iterator, last_iterator) – This modified the vector to its next permutation.

prev_permutation(first_iterator, last_iterator) – This modified the vector to its previous permutation.
*/

using namespace std;

int main()
{
    ll n,m,i,f=0,k=0,x=0,j,l=0;
    cin>>n>>m;
    ll a[n+5][m+5],b[3000],c[3000];
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            cin>>a[i][j];
            if(a[i][j]==1)
                f=1;
        }
    }
    if(f==0)
        cout<<0<<endl;
    else
    {
        f=0;
        for(i=1;i<n;i++)
        {
            for(j=1;j<m;j++)
            {
                if(a[i][j]==1 && a[i][j+1]==1&& a[i+1][j]==1&&a[i+1][j+1]==1)
                {
                    b[k]=i;
                    c[k]=j;
                    k++;
                    f=1;
                }
                else
                    f=0;
            }
        }
        if(f==0)
           {
               cout<<-1<<endl;

           }
        else
        {
            cout<<k<<endl;
            for(x=0;x<k;x++)
                cout<<b[x]<<" "<<c[x]<<endl;
        }
    }

    return 0;
}


#include <bits/stdc++.h>

#pragma GCC diagnostic warning "-std=c++11"

/* Raiyan Noory Rady,CSE'17,RUET
Email:raiyannooryrady@gmail.com
Smile->Desire->Unity->Effort->Struggle->Success->Again smile :)
***I_Love_Trench***/

#define ll long long int
#define pf push_front
#define mod  1000000007
#define inf  1000000000000000000
#define pi  acos(-1.0)
#define maxn  1000009
#define sorted(s)  sort(s.begin(),s.end())
#define sortarr(a) sort(a,a+n)
#define slc(n) scanf("%I64d", &n)
#define sl(n)  scanf("%lld", &n)
#define sf(n)  scanf("%lf", &n)
#define si(n)  scanf("%d", &n)
#define sch(n)  scanf(" %c", &n)
#define ss(n)  scanf("%s", n)
#define prf printf
#define pb  push_back
#define fr first
#define sc second
#define all(a)  a.begin(),a.end()
#define forl(n) for(i=0;i<n;i++)
/*STL library functions

sort(first_iterator, last_iterator) – To sort the given vector.

reverse(first_iterator, last_iterator) – To reverse a vector.

*max_element (first_iterator, last_iterator) – To find the maximum element of a vector.

*min_element (first_iterator, last_iterator) – To find the minimum element of a vector.

accumulate(first_iterator, last_iterator, initial value of sum) – Does the summation of vector elements

count(first_iterator, last_iterator,x) – To count the occurrences of x in vector.

find(first_iterator, last_iterator, x) – Points to last address of vector ((name_of_vector).end())
 if element is not present in vector.

binary_search(first_iterator, last_iterator, x) – Tests whether x exists in sorted vector or not.

lower_bound(first_iterator, last_iterator, x) – returns an iterator pointing to the first element in the range [first,last)
which has a value not less than ‘x’.

upper_bound(first_iterator, last_iterator, x) – returns an iterator pointing to the first element in the range [first,last)
 which has a value greater than ‘x’.

arr.erase(position to be deleted) – This erases selected element in vector and shifts and resizes the vector elements accordingly.

arr.erase(unique(arr.begin(),arr.end()),arr.end()) – This erases the duplicate occurrences in sorted vector in a single line.

distance(first_iterator,desired_position) – It returns the distance of desired position from the first iterator.
This function is very useful while finding the index.

next_permutation(first_iterator, last_iterator) – This modified the vector to its next permutation.

prev_permutation(first_iterator, last_iterator) – This modified the vector to its previous permutation.
*/

using namespace std;

int main()
{
    ll n,m,i,f=0,k=0,x=0,j,l=0;
    cin>>n>>m;
    ll a[n+5][m+5],b[100000],c[100000];
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            cin>>a[i][j];
            if(a[i][j]==1)
                f=1;
        }
    }
    if(f==0)
        cout<<0<<endl;
    else
    {
        f=0;
        for(i=1;i<n;i++)
        {
            for(j=1;j<m;j++)
            {
                if(a[i][j]==1 && a[i][j+1]==1&& a[i+1][j]==1&&a[i+1][j+1]==1)
                {
                    b[k++]=i;
                    c[l++]=j;
                    f=1;
                }
            }
        }
        if(f==0)
            cout<<-1<<endl;
        else
        {
            cout<<k<<endl;
            for(x=0;x<k;x++)
                cout<<b[x]<<" "<<c[x]<<endl;
        }
    }

    return 0;
}


#include <bits/stdc++.h>

#pragma GCC diagnostic warning "-std=c++11"

/* Raiyan Noory Rady,CSE'17,RUET
Email:raiyannooryrady@gmail.com
Smile->Desire->Unity->Effort->Struggle->Success->Again smile :)
***I_Love_Trench***/

#define ll long long int
#define pf push_front
#define mod  1000000007
#define inf  1000000000000000000
#define pi  acos(-1.0)
#define maxn  1000009
#define sorted(s)  sort(s.begin(),s.end())
#define sortarr(a) sort(a,a+n)
#define slc(n) scanf("%I64d", &n)
#define sl(n)  scanf("%lld", &n)
#define sf(n)  scanf("%lf", &n)
#define si(n)  scanf("%d", &n)
#define sch(n)  scanf(" %c", &n)
#define ss(n)  scanf("%s", n)
#define prf printf
#define pb  push_back
#define fr first
#define sc second
#define all(a)  a.begin(),a.end()
#define forl(n) for(i=0;i<n;i++)
/*STL library functions

sort(first_iterator, last_iterator) – To sort the given vector.

reverse(first_iterator, last_iterator) – To reverse a vector.

*max_element (first_iterator, last_iterator) – To find the maximum element of a vector.

*min_element (first_iterator, last_iterator) – To find the minimum element of a vector.

accumulate(first_iterator, last_iterator, initial value of sum) – Does the summation of vector elements

count(first_iterator, last_iterator,x) – To count the occurrences of x in vector.

find(first_iterator, last_iterator, x) – Points to last address of vector ((name_of_vector).end())
 if element is not present in vector.

binary_search(first_iterator, last_iterator, x) – Tests whether x exists in sorted vector or not.

lower_bound(first_iterator, last_iterator, x) – returns an iterator pointing to the first element in the range [first,last)
which has a value not less than ‘x’.

upper_bound(first_iterator, last_iterator, x) – returns an iterator pointing to the first element in the range [first,last)
 which has a value greater than ‘x’.

arr.erase(position to be deleted) – This erases selected element in vector and shifts and resizes the vector elements accordingly.

arr.erase(unique(arr.begin(),arr.end()),arr.end()) – This erases the duplicate occurrences in sorted vector in a single line.

distance(first_iterator,desired_position) – It returns the distance of desired position from the first iterator.
This function is very useful while finding the index.

next_permutation(first_iterator, last_iterator) – This modified the vector to its next permutation.

prev_permutation(first_iterator, last_iterator) – This modified the vector to its previous permutation.
*/

using namespace std;

int main()
{
    ll n,m,i,f=0,k=0,x=0,j,l=0;
    cin>>n>>m;
    ll a[n+5][m+5],b[3000],c[3000];
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            cin>>a[i][j];
            if(a[i][j]==1)
                f=1;
        }
    }
    if(f==0)
        cout<<0<<endl;
    else
    {
        f=0;
        for(i=1;i<n;i++)
        {
            for(j=1;j<m;j++)
            {
                if(a[i][j]==1 && a[i][j+1]==1&& a[i+1][j]==1&&a[i+1][j+1]==1)
                {
                    b[k]=i;
                    c[k]=j;
                    k++;
                    f=1;
                }
            }
        }
        if(f==0)
            cout<<-1<<endl;
        else
        {
            cout<<k<<endl;
            for(x=0;x<k;x++)
                cout<<b[x]<<" "<<c[x]<<endl;
        }
    }

    return 0;
}


#include <iostream>
#include <vector>

using namespace std;

typedef struct {
	int x, y;
} Point;

Point createNewPoint(int xx, int yy) {
	Point p;
	p.x = xx;
	p.y = yy;
	return p;
}

int main() {
	int m, n;
	cin >> m >> n;

	int** mat = new int* [m];
	for (int i = 0; i < m; i++)
		mat[i] = new int[n];

	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cin >> mat[i][j];

	vector<Point> vec;

	bool can = true;

	for (int i = 0; i < m - 1; i++) {
		for (int j = 0; j < n - 1; j++) {
			if (mat[i][j] == 1 && mat[i + 1][j] == 1 && mat[i][j + 1] == 1 && mat[i + 1][j + 1]) {
				mat[i][j] = -1;
				mat[i + 1][j] = -1;
				mat[i][j + 1] = -1;
				mat[i + 1][j + 1] = -1;
				vec.push_back(createNewPoint(i+1, j+1));
			}
			else if (mat[i][j] == -1 && mat[i + 1][j] == -1) {
				if (mat[i][j + 1] == 1 && mat[i + 1][j + 1] == 1) {
					if (j + 2 == n || (mat[i][j + 2] != 1 || mat[i + 1][j + 2] != 1)) {
						mat[i][j] = -1;
						mat[i + 1][j] = -1;
						mat[i][j + 1] = -1;
						mat[i + 1][j + 1] = -1;
						vec.push_back(createNewPoint(i+1, j+1));
					}
				}
			}
			else if (mat[i][j] == -1 && mat[i][j + 1] == -1) {
				if (mat[i + 1][j] == 1 && mat[i + 1][j + 1] == 1) {
					if (i + 2 == m || (mat[i + 2][j] != 1 || mat[i + 2][j + 1] != 1)) {
						mat[i][j] = -1;
						mat[i + 1][j] = -1;
						mat[i][j + 1] = -1;
						mat[i + 1][j + 1] = -1;
						vec.push_back(createNewPoint(i+1, j+1));
					}
				}
			}
			else if (mat[i][j] != 0 || mat[i + 1][j] != 0 || mat[i][j + 1] != 0 || mat[i + 1][j + 1] != 0) {
				can = false;
				i = m;
				break;
			}
		}
	}

	if (!can)
		cout << -1;
	else {
		if (vec.size() == 0) {
			cout << 0;
		}
		else {
			cout << vec.size() << endl;
			cout << vec[0].x << " " << vec[0].y;
			for (int i = 1; i < vec.size(); i++)
				cout << endl << vec[i].x << " " << vec[i].y;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

typedef struct {
	int x, y;
} Point;

Point createNewPoint(int xx, int yy) {
	Point p;
	p.x = xx;
	p.y = yy;
	return p;
}

int main() {
	int m, n;
	cin >> m >> n;

	int** mat = new int* [m];
	for (int i = 0; i < m; i++)
		mat[i] = new int[n];

	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cin >> mat[i][j];

	vector<Point> vec;

	bool can = true;

	for (int i = 0; i < m - 1; i++) {
		for (int j = 0; j < n - 1; j++) {
			if (mat[i][j] == 1 && mat[i + 1][j] == 1 && mat[i][j + 1] == 1 && mat[i + 1][j + 1]) {
				mat[i][j] = -1;
				mat[i + 1][j] = -1;
				mat[i][j + 1] = -1;
				mat[i + 1][j + 1] = -1;
				vec.push_back(createNewPoint(i+1, j+1));
			}
			else if (mat[i][j] == -1 && mat[i + 1][j] == -1) {
				if (mat[i][j + 1] == 1 && mat[i + 1][j + 1] == 1) {
					if (i + 2 == m || (mat[i][j + 2] != 1 || mat[i + 1][j + 2] != 1)) {
						mat[i][j] = -1;
						mat[i + 1][j] = -1;
						mat[i][j + 1] = -1;
						mat[i + 1][j + 1] = -1;
						vec.push_back(createNewPoint(i+1, j+1));
					}
				}
			}
			else if (mat[i][j] == -1 && mat[i][j + 1] == -1) {
				if (mat[i + 1][j] == 1 && mat[i + 1][j + 1] == 1) {
					if (j + 2 == n || (mat[i + 2][j] != 1 || mat[i + 2][j + 1] != 1)) {
						mat[i][j] = -1;
						mat[i + 1][j] = -1;
						mat[i][j + 1] = -1;
						mat[i + 1][j + 1] = -1;
						vec.push_back(createNewPoint(i+1, j+1));
					}
				}
			}
			else if (mat[i][j] != 0 || mat[i + 1][j] != 0 || mat[i][j + 1] != 0 || mat[i + 1][j + 1] != 0) {
				can = false;
				i = m;
				break;
			}
		}
	}

	if (!can)
		cout << -1;
	else {
		if (vec.size() == 0) {
			cout << 0;
		}
		else {
			cout << vec[0].x << " " << vec[0].y;
			for (int i = 1; i < vec.size(); i++)
				cout << endl << vec[i].x << " " << vec[i].y;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

typedef struct {
	int x, y;
} Point;

Point createNewPoint(int xx, int yy) {
	Point p;
	p.x = xx;
	p.y = yy;
	return p;
}

void print(int** mat, int m, int n) {
	for (int i = 0; i < m; i++) {
		cout << endl;
		for (int j = 0; j < n; j++) {
			cout << mat[i][j] << " ";
		}
	}
}

int main() {
	int m, n;
	cin >> m >> n;

	int** mat = new int* [m];
	for (int i = 0; i < m; i++)
		mat[i] = new int[n];

	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cin >> mat[i][j];

	vector<Point> vec;

	bool can = true;

	for (int i = 0; i < m - 1; i++) {
		for (int j = 0; j < n - 1; j++) {
			if (mat[i][j] != 0 && mat[i + 1][j] != 0 && mat[i][j + 1] != 0 && mat[i + 1][j + 1] != 0) {
				mat[i+1][j] = 2;
				mat[i][j+1] = 2;
				mat[i+1][j+1] = 2;
				mat[i][j] = 2;
				vec.push_back(createNewPoint(i + 1, j + 1));
			}
		}
	}

	for (int i = 0; i < m ; i++) {
		for (int j = 0; j < n ; j++) {
			if (mat[i][j] == 1) {
				can = false;
				i = m;
				break;
			}
		}
	}

	if (!can)
		cout << -1;
	else {
		if (vec.size() == 0) {
			cout << 0;
		}
		else {
			cout << vec.size() << endl;
			cout << vec[0].x << " " << vec[0].y;
			for (int i = 1; i < vec.size(); i++)
				cout << endl << vec[i].x << " " << vec[i].y;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

typedef struct {
	int x, y;
} Point;

Point createNewPoint(int xx, int yy) {
	Point p;
	p.x = xx;
	p.y = yy;
	return p;
}

int main() {
	int m, n;
	cin >> m >> n;

	int** mat = new int* [m];
	for (int i = 0; i < m; i++)
		mat[i] = new int[n];

	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cin >> mat[i][j];

	vector<Point> vec;

	bool can = true;

	for (int i = 0; i < m - 1; i++) {
		for (int j = 0; j < n - 1; j++) {
			if (mat[i][j] == 1 && mat[i + 1][j] == 1 && mat[i][j + 1] == 1 && mat[i + 1][j + 1]) {
				mat[i][j] = -1;
				mat[i + 1][j] = -1;
				mat[i][j + 1] = -1;
				mat[i + 1][j + 1] = -1;
				vec.push_back(createNewPoint(i + 1, j + 1));
			}
			else if (mat[i][j] == -1 && mat[i + 1][j] == -1) {
				if (mat[i][j + 1] == 1 && mat[i + 1][j + 1] == 1) {
					if (j + 2 == n || j == n - 2 || (mat[i][j + 2] != 1 || mat[i + 1][j + 2] != 1)) {
						mat[i][j] = -1;
						mat[i + 1][j] = -1;
						mat[i][j + 1] = -1;
						mat[i + 1][j + 1] = -1;
						vec.push_back(createNewPoint(i + 1, j + 1));
					}
				}
			}
			else if (mat[i][j] == -1 && mat[i][j + 1] == -1) {
				if (mat[i + 1][j] == 1 && mat[i + 1][j + 1] == 1) {
					if (i + 2 == m || i == m - 2 || (mat[i + 2][j] != 1 || mat[i + 2][j + 1] != 1)) {
						mat[i][j] = -1;
						mat[i + 1][j] = -1;
						mat[i][j + 1] = -1;
						mat[i + 1][j + 1] = -1;
						vec.push_back(createNewPoint(i + 1, j + 1));
					}
				}
			}
		}
	}

	for (int i = 0; i < m ; i++) {
		for (int j = 0; j < n ; j++) {
			if (mat[i][j] == 1) {
				can = false;
				i = m;
				break;
			}
		}
	}

	if (!can)
		cout << -1;
	else {
		if (vec.size() == 0) {
			cout << 0;
		}
		else {
			cout << vec.size() << endl;
			cout << vec[0].x << " " << vec[0].y;
			for (int i = 1; i < vec.size(); i++)
				cout << endl << vec[i].x << " " << vec[i].y;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

typedef struct {
	int x, y;
} Point;

Point createNewPoint(int xx, int yy) {
	Point p;
	p.x = xx;
	p.y = yy;
	return p;
}

int main() {
	int m, n;
	cin >> m >> n;

	int** mat = new int* [m];
	for (int i = 0; i < m; i++)
		mat[i] = new int[n];

	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cin >> mat[i][j];

	vector<Point> vec;

	bool can = true;

	for (int i = 0; i < m - 1; i++) {
		for (int j = 0; j < n - 1; j++) {
			if (mat[i][j] == 1 && mat[i + 1][j] == 1 && mat[i][j + 1] == 1 && mat[i + 1][j + 1]) {
				mat[i][j] = -1;
				mat[i + 1][j] = -1;
				mat[i][j + 1] = -1;
				mat[i + 1][j + 1] = -1;
				vec.push_back(createNewPoint(i+1, j+1));
			}
			else if (mat[i][j] == -1 && mat[i + 1][j] == -1) {
				if (mat[i][j + 1] == 1 && mat[i + 1][j + 1] == 1) {
					if (j + 2 == n || (mat[i][j + 2] != 1 || mat[i + 1][j + 2] != 1)) {
						mat[i][j] = -1;
						mat[i + 1][j] = -1;
						mat[i][j + 1] = -1;
						mat[i + 1][j + 1] = -1;
						vec.push_back(createNewPoint(i+1, j+1));
					}
				}
			}
			else if (mat[i][j] == -1 && mat[i][j + 1] == -1) {
				if (mat[i + 1][j] == 1 && mat[i + 1][j + 1] == 1) {
					if (i + 2 == m || (mat[i + 2][j] != 1 || mat[i + 2][j + 1] != 1)) {
						mat[i][j] = -1;
						mat[i + 1][j] = -1;
						mat[i][j + 1] = -1;
						mat[i + 1][j + 1] = -1;
						vec.push_back(createNewPoint(i+1, j+1));
					}
				}
			}
			else if (mat[i][j] != 0 || mat[i + 1][j] != 0 || mat[i][j + 1] != 0 || mat[i + 1][j + 1] != 0) {
				can = false;
				i = m;
				break;
			}
		}
	}

	if (!can)
		cout << -1;
	else {
		if (vec.size() == 0) {
			cout << 0;
		}
		else {
			cout << vec[0].x << " " << vec[0].y;
			for (int i = 1; i < vec.size(); i++)
				cout << endl << vec[i].x << " " << vec[i].y;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

typedef struct {
	int x, y;
} Point;

Point createNewPoint(int xx, int yy) {
	Point p;
	p.x = xx;
	p.y = yy;
	return p;
}

int main() {
	int m, n;
	cin >> m >> n;

	int** mat = new int* [m];
	for (int i = 0; i < m; i++)
		mat[i] = new int[n];

	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cin >> mat[i][j];

	vector<Point> vec;

	bool can = true;

	for (int i = 0; i < m - 1; i++) {
		for (int j = 0; j < n - 1; j++) {
			if (mat[i][j] == 1 && mat[i + 1][j] == 1 && mat[i][j + 1] == 1 && mat[i + 1][j + 1]) {
				mat[i][j] = 2;
				mat[i + 1][j] = 2;
				mat[i][j + 1] = 2;
				mat[i + 1][j + 1] = 2;
				vec.push_back(createNewPoint(i + 1, j + 1));
			}
			else if (mat[i][j] == 2 && mat[i + 1][j] == 2) {
				if (mat[i][j + 1] == 1 && mat[i + 1][j + 1] == 1) {
					if (j + 2 == n || (mat[i][j + 2] != 0 || mat[i + 1][j + 2] != 0)) {
						mat[i][j] = 2;
						mat[i + 1][j] = 2;
						mat[i][j + 1] = 2;
						mat[i + 1][j + 1] = 2;
						vec.push_back(createNewPoint(i + 1, j + 1));
					}
				}
			}
			else if (mat[i][j] == 2 && mat[i][j + 1] == 2) {
				if (mat[i + 1][j] == 1 && mat[i + 1][j + 1] == 1) {
					if (i + 2 == m || (mat[i + 2][j] == 0 || mat[i + 2][j + 1] != 0)) {
						mat[i][j] = 2;
						mat[i + 1][j] = 2;
						mat[i][j + 1] = 2;
						mat[i + 1][j + 1] = 2;
						vec.push_back(createNewPoint(i + 1, j + 1));
					}
				}
			}
		}
	}

	for (int i = 0; i < m ; i++) {
		for (int j = 0; j < n ; j++) {
			if (mat[i][j] == 1) {
				can = false;
				i = m;
				break;
			}
		}
	}

	if (!can)
		cout << -1;
	else {
		if (vec.size() == 0) {
			cout << 0;
		}
		else {
			cout << vec.size() << endl;
			cout << vec[0].x << " " << vec[0].y;
			for (int i = 1; i < vec.size(); i++)
				cout << endl << vec[i].x << " " << vec[i].y;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

typedef struct {
	int x, y;
} Point;

Point createNewPoint(int xx, int yy) {
	Point p;
	p.x = xx;
	p.y = yy;
	return p;
}

int main() {
	int m, n;
	cin >> m >> n;

	int** mat = new int* [m];
	for (int i = 0; i < m; i++)
		mat[i] = new int[n];

	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cin >> mat[i][j];

	vector<Point> vec;

	bool can = true;

	for (int i = 0; i < m - 1; i++) {
		for (int j = 0; j < n - 1; j++) {
			if (mat[i][j] == 1 && mat[i + 1][j] == 1 && mat[i][j + 1] == 1 && mat[i + 1][j + 1]) {
				mat[i][j] = 2;
				mat[i + 1][j] = 2;
				mat[i][j + 1] = 2;
				mat[i + 1][j + 1] = 2;
				vec.push_back(createNewPoint(i + 1, j + 1));
			}
			else if (mat[i][j] == 2 && mat[i + 1][j] == 2) {
				if (mat[i][j + 1] == 1 && mat[i + 1][j + 1] == 1) {
					if (j + 2 == n || (mat[i][j + 2] != 0 && mat[i + 1][j + 2] != 0)) {
						mat[i][j] = 2;
						mat[i + 1][j] = 2;
						mat[i][j + 1] = 2;
						mat[i + 1][j + 1] = 2;
						vec.push_back(createNewPoint(i + 1, j + 1));
					}
				}
			}
			else if (mat[i][j] == 2 && mat[i][j + 1] == 2) {
				if (mat[i + 1][j] == 1 && mat[i + 1][j + 1] == 1) {
					if (i + 2 == m || (mat[i + 2][j] == 0 && mat[i + 2][j + 1] != 0)) {
						mat[i][j] = 2;
						mat[i + 1][j] = 2;
						mat[i][j + 1] = 2;
						mat[i + 1][j + 1] = 2;
						vec.push_back(createNewPoint(i + 1, j + 1));
					}
				}
			}
		}
	}

	for (int i = 0; i < m ; i++) {
		for (int j = 0; j < n ; j++) {
			if (mat[i][j] == 1) {
				can = false;
				i = m;
				break;
			}
		}
	}

	if (!can)
		cout << -1;
	else {
		if (vec.size() == 0) {
			cout << 0;
		}
		else {
			cout << vec.size() << endl;
			cout << vec[0].x << " " << vec[0].y;
			for (int i = 1; i < vec.size(); i++)
				cout << endl << vec[i].x << " " << vec[i].y;
		}
	}

	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

typedef struct {
	int x, y;
} Point;

Point createNewPoint(int xx, int yy) {
	Point p;
	p.x = xx;
	p.y = yy;
	return p;
}

int main() {
	int m, n;
	cin >> m >> n;

	int** mat = new int* [m];
	for (int i = 0; i < m; i++)
		mat[i] = new int[n];

	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cin >> mat[i][j];

	vector<Point> vec;

	bool can = true;

	for (int i = 0; i < m - 1; i++) {
		for (int j = 0; j < n - 1; j++) {
			if (mat[i][j] == 1 && mat[i + 1][j] == 1 && mat[i][j + 1] == 1 && mat[i + 1][j + 1]) {
				mat[i][j] = -1;
				mat[i + 1][j] = -1;
				mat[i][j + 1] = -1;
				mat[i + 1][j + 1] = -1;
				vec.push_back(createNewPoint(i + 1, j + 1));
			}
			else if (mat[i][j] == -1 && mat[i + 1][j] == -1) {
				if (mat[i][j + 1] == 1 && mat[i + 1][j + 1] == 1) {
					if (j + 2 == n || (mat[i][j + 2] != 1 || mat[i + 1][j + 2] != 1)) {
						mat[i][j] = -1;
						mat[i + 1][j] = -1;
						mat[i][j + 1] = -1;
						mat[i + 1][j + 1] = -1;
						vec.push_back(createNewPoint(i + 1, j + 1));
					}
				}
			}
			else if (mat[i][j] == -1 && mat[i][j + 1] == -1) {
				if (mat[i + 1][j] == 1 && mat[i + 1][j + 1] == 1) {
					if (i + 2 == m || (mat[i + 2][j] != 1 || mat[i + 2][j + 1] != 1)) {
						mat[i][j] = -1;
						mat[i + 1][j] = -1;
						mat[i][j + 1] = -1;
						mat[i + 1][j + 1] = -1;
						vec.push_back(createNewPoint(i + 1, j + 1));
					}
				}
			}
		}
	}

	for (int i = 0; i < m ; i++) {
		for (int j = 0; j < n ; j++) {
			if (mat[i][j] == 1) {
				can = false;
				i = m;
				break;
			}
		}
	}

	if (!can)
		cout << -1;
	else {
		if (vec.size() == 0) {
			cout << 0;
		}
		else {
			cout << vec.size() << endl;
			cout << vec[0].x << " " << vec[0].y;
			for (int i = 1; i < vec.size(); i++)
				cout << endl << vec[i].x << " " << vec[i].y;
		}
	}

	return 0;
}


#include <stdio.h>

int main() {
    int n,m;
    scanf("%d %d", &n, &m);
    int tab[n][m];
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            scanf("%d", &tab[i][j]);
        }
    }
    int k = 0;
    int minusik = -1;
    int x[n*m], y[n*m];
    int pointer = 0;
    for (int i=0; i<(n-1); i++)
    {
        for (int j=0; j<(m-1); j++)
        {
            if ((tab[i][j] * tab[i+1][j] * tab[i][j+1] * tab[i+1][j+1]) > 0)
            {
                tab[i][j] = 2;
                tab[i+1][j] = 2;
                tab[i][j+1] = 2;
                tab[i+1][j+1] = 2;
                x[pointer] = i;
                y[pointer] = j;
                pointer++;
            }
        }
    }
    int counter = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j] == 1)
            {
                counter++;
            }
        }
    }
    if (counter != 0)
    {
        printf("%d", minusik);
    }
    else
    {
        printf("%d\n", pointer);
        for (int i=0; i<pointer; i++)
        {
            printf("%d", x[i] + 1);
            printf(" ");
            printf("%d\n", y[i] + 1);
        }
    }

    return 0;
}


#include <stdio.h>

int main() {
    int n,m;
    scanf("%d %d", &n, &m);
    int tab[n][m];
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            scanf("%d", &tab[i][j]);
        }
    }
    int k = 0;
    int minusik = -1;
    int x[n], y[n];
    int pointer = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if ((tab[i][j] * tab[i+1][j] * tab[i][j+1] * tab[i+1][j+1]) > 0)
            {
                tab[i][j] = 2;
                tab[i+1][j] = 2;
                tab[i][j+1] = 2;
                tab[i+1][j+1] = 2;
                x[pointer] = i;
                y[pointer] = j;
                pointer++;
            }
        }
    }
    int counter = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j] == 1)
            {
                counter++;
            }
        }
    }
    if (counter != 0)
    {
        printf("%d", minusik);
    }
    else
    {
        printf("%d\n", pointer);
        for (int i=0; i<pointer; i++)
        {
            printf("%d", x[i] + 1);
            printf(" ");
            printf("%d\n", y[i] + 1);
        }
    }

    return 0;
}


#include <stdio.h>

int main() {
    int n,m;
    scanf("%d %d", &n, &m);
    int tab[n][m];
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            scanf("%d", &tab[i][j]);
        }
    }
    int k = 0;
    int minusik = -1;
    int x[n], y[n];
    int pointer = 0;
    for (int i=0; i<(n-1); i++)
    {
        for (int j=0; j<(m-1); j++)
        {
            if ((tab[i][j] * tab[i+1][j] * tab[i][j+1] * tab[i+1][j+1]) > 0)
            {
                tab[i][j] = 2;
                tab[i+1][j] = 2;
                tab[i][j+1] = 2;
                tab[i+1][j+1] = 2;
                x[pointer] = i;
                y[pointer] = j;
                pointer++;
            }
        }
    }
    int counter = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j] == 1)
            {
                counter++;
            }
        }
    }
    if (counter != 0)
    {
        printf("%d", minusik);
    }
    else
    {
        printf("%d\n", pointer);
        for (int i=0; i<pointer; i++)
        {
            printf("%d", x[i] + 1);
            printf(" ");
            printf("%d\n", y[i] + 1);
        }
    }

    return 0;
}


#include <stdio.h>

int main() {
    int n,m;
    scanf("%d %d", &n, &m);
    int tab[n][m];
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            scanf("%d", &tab[i][j]);
        }
    }
    int k = 0;
    int minusik = -1;
    int x[n], y[n];
    int pointer = 0;
    for (int i=0; i<(n-1); i++)
    {
        for (int j=0; j<(m-1); j++)
        {
            if ((tab[i][j] * tab[i+1][j] * tab[i][j+1] * tab[i+1][j+1]) > 0)
            {
                tab[i][j] = 11;
                tab[i+1][j] = 11;
                tab[i][j+1] = 11;
                tab[i+1][j+1] = 11;
                x[pointer] = i;
                y[pointer] = j;
                pointer++;
            }
        }
    }
    int counter = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j] == 1)
            {
                counter++;
            }
        }
    }
    if (counter != 0)
    {
        printf("%d", minusik);
    }
    else
    {
        printf("%d\n", pointer);
        for (int i=0; i<pointer; i++)
        {
            printf("%d", x[i] + 1);
            printf(" ");
            printf("%d\n", y[i] + 1);
        }
    }

    return 0;
}


#include <stdio.h>

int main() {
    int n,m;
    scanf("%d %d", &n, &m);
    int tab[n][m];
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            scanf("%d", &tab[i][j]);
        }
    }
    int k = 0;
    int minusik = -1;
    int x[n], y[n];
    int pointer = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j]  * tab[i+1][j] * tab[i][j+1] * tab[i+1][j+1] > 0)
            {
                tab[i][j] = 2;
                tab[i+1][j] = 2;
                tab[i][j+1] = 2;
                tab[i+1][j+1] = 2;
                x[pointer] = i;
                y[pointer] = j;
                pointer++;
                k++;

            }
        }
    }
    pointer = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j] == 1)
            {
                pointer++;
            }
        }
    }
    if (pointer != 0)
    {
        printf("%d", minusik);
    }
    else
    {
        printf("%d\n", k);
        for (int i=0; i<k; i++)
        {
            printf("%d", x[i] + 1);
            printf(" ");
            printf("%d\n", y[i] + 1);
        }
    }

    return 0;
}


#include <stdio.h>

int main() {
    int n,m;
    scanf("%d %d", &n, &m);
    int tab[n][m];
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            scanf("%d", &tab[i][j]);
        }
    }
    int k = 0;
    int minusik = -1;
    int x[n], y[n];
    int pointer = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j]  * tab[i+1][j] * tab[i][j+1] * tab[i+1][j+1] > 0)
            {
                tab[i][j] = 11;
                tab[i+1][j] = 11;
                tab[i][j+1] = 11;
                tab[i+1][j+1] = 11;
                x[pointer] = i;
                y[pointer] = j;
                pointer++;
                k++;

            }
        }
    }
    pointer = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j] == 1)
            {
                pointer++;
            }
        }
    }
    if (pointer != 0)
    {
        printf("%d", minusik);
    }
    else
    {
        printf("%d\n", k);
        for (int i=0; i<k; i++)
        {
            printf("%d", x[i] + 1);
            printf(" ");
            printf("%d\n", y[i] + 1);
        }
    }

    return 0;
}


#include <stdio.h>

int main() {
    int n,m;
    scanf("%d %d", &n, &m);
    int tab[n+1][m+1];
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            scanf("%d", &tab[i][j]);
        }
    }
    int k = 0;
    int minusik = -1;
    int x[n], y[n];
    int pointer = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j]  * tab[i+1][j] * tab[i][j+1] * tab[i+1][j+1] > 0)
            {
                tab[i][j] = 11;
                tab[i+1][j] = 11;
                tab[i][j+1] = 11;
                tab[i+1][j+1] = 11;
                x[pointer] = i;
                y[pointer] = j;
                pointer++;
                k++;

            }
        }
    }
    pointer = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j] == 1)
            {
                pointer++;
            }
        }
    }
    if (pointer != 0)
    {
        printf("%d", minusik);
    }
    else
    {
        printf("%d\n", k);
        for (int i=0; i<k; i++)
        {
            printf("%d", x[i] + 1);
            printf(" ");
            printf("%d\n", y[i] + 1);
        }
    }

    return 0;
}


#include <stdio.h>

int main() {
    int n,m;
    scanf("%d %d", &n, &m);
    int tab[n][m];
    for (int i=0; i<n-1; i++)
    {
        for (int j=0; j<m-1; j++)
        {
            scanf("%d", &tab[i][j]);
        }
    }
    int k = 0;
    int minusik = -1;
    int x[n], y[n];
    int pointer = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j]  * tab[i+1][j] * tab[i][j+1] * tab[i+1][j+1] > 0)
            {
                tab[i][j] = 11;
                tab[i+1][j] = 11;
                tab[i][j+1] = 11;
                tab[i+1][j+1] = 11;
                x[pointer] = i;
                y[pointer] = j;
                pointer++;
                k++;

            }
        }
    }
    pointer = 0;
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (tab[i][j] == 1)
            {
                pointer++;
            }
        }
    }
    if (pointer != 0)
    {
        printf("%d", minusik);
    }
    else
    {
        printf("%d\n", k);
        for (int i=0; i<k; i++)
        {
            printf("%d", x[i] + 1);
            printf(" ");
            printf("%d\n", y[i] + 1);
        }
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main(){

  int n,m,i,j,k,l,cnt=0,flag=0;
  cin>>n>>m;
  int arr[n][m];
  vector<int> a,b;
  for(i=0;i<n;i++)
   for(j=0;j<m;j++)
    cin>>arr[i][j];

  for(i=0;i<n-1;i++)
   for(j=0;j<m-1;j++)
    {
      if(arr[i][j]==1)
       {
         if(arr[i+1][j+1]==1 && arr[i][j+1]==1 && arr[i+1][j]==1)
           {
             a.push_back(i);
             b.push_back(j);
           }
       }
    }

    cout<<a.size()<<endl;
    for(i=0;i<a.size();i++)
     {
       cout<<a[i]+1<<" "<<b[i]+1<<endl;
     }
}


#include<bits/stdc++.h>
using namespace std;
int main(){

  int n,m,i,j,k,l,cnt=0,flag=0;
  cin>>n>>m;
  int arr[n][m];
  vector<int> a,b;
  for(i=0;i<n;i++)
   for(j=0;j<m;j++)
    cin>>arr[i][j];

  for(i=0;i<n-1;i++)
   for(j=0;j<m-1;j++)
    {
      if(arr[i][j]==1)
       {
         if(arr[i+1][j+1]==1 && arr[i][j+1]==1 && arr[i+1][j]==1)
           {
             a.push_back(i);
             b.push_back(j);
           }
       }
    }
    if(a.size()>0){
    cout<<a.size()<<endl;

    for(i=0;i<a.size();i++)
     {
       cout<<a[i]+1<<" "<<b[i]+1<<endl;
     }
     }
     else
      cout<<"-1\n";
}


#include<bits/stdc++.h>
using namespace std;
int main(){

  int n,m,i,j,k,l,cnt=0,flag=0;
  cin>>n>>m;
  int arr[n][m];
  vector<int> a,b;
  for(i=0;i<n;i++)
   for(j=0;j<m;j++)
    cin>>arr[i][j];

  for(i=0;i<n-1;i++)
   for(j=0;j<m-1;j++)
    {
      if(arr[i][j]==1)
       {
         flag=1;
         if(arr[i+1][j+1]==1 && arr[i][j+1]==1 && arr[i+1][j]==1)
           {
             a.push_back(i);
             b.push_back(j);
           }
       }
    }
    if(a.size()>0){
    cout<<a.size()<<endl;

    for(i=0;i<a.size();i++)
     {
       cout<<a[i]+1<<" "<<b[i]+1<<endl;
     }
     }
     else if(flag==0)
      cout<<"0\n";
     else
      cout<<"-1\n";
}


#include<bits/stdc++.h>
#define li long int
#define uli unsigned long int
#define lli long long int
#define ulli unsigned long long int

using namespace std;

vector<ulli> graph[150005];

ulli parent[150005];
ulli size[150005];

void union_f(ulli x, ulli y) {
	if (x == parent[x] && y == parent[y]) {
		if (x == y)
			return;
		if (size[x] >= size[y]) {
			parent[y] = x;
			size[x] += size[y];
		}
		else {
			parent[x] = y;
			size[y] += size[x];
		}
	}
	else
		union_f(parent[x], parent[y]);
}

ulli find_f(ulli x) {
	if (parent[x] == x)
		return x;
	else {
		ulli temp = find_f(parent[x]);
		parent[x] = temp;
		return temp;
	}
}

int main(int argc, char **argv) {
	ulli n, m;
	cin >> n >> m;
	while(m--) {
		ulli x,y ;
		cin >> x >> y;
		graph[x].push_back(y);
		graph[y].push_back(x);
	}
	for (ulli i=1; i<=n; i++) {
		parent[i] = i;
		size[i] = 1;
	}
	for (ulli i=1; i<=n; i++)
		for (ulli j=0; j<graph[i].size(); j++) {
			union_f(i, graph[i][j]);
		}
	for (ulli i=1; i<=n; i++) {
		if (size[find_f(i)] != (graph[i].size()+1)) {
			cout << "NO" << endl;
			return 0;
		}
	}
	cout << "YES" << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,m,head[150005],tot = 1,t1,t2,instack[150005];
bool vis[150005];
set<int> st;
struct node {
    int from,to;
}edge[150005];
void addEdge(int from,int to) { edge[tot] = (node){head[from],to}; head[from] = tot++; }
bool dfs(int nowp, int fa) {
    vis[nowp] = true;
    for(int i = head[nowp]; i ; i = edge[i].from) {
        int to = edge[i].to;
        if(to == fa) continue;
        if(vis[to]) {
            if(st.size()>3) return false; instack[to] = false;st.erase(to);
        }else {
            instack[to] = true, st.insert(to);
            if(st.size() > 3) return false;
            bool as = dfs(to,nowp); if(!as) return false;
        }
    }
    if(st.size() < 3) {
        st.clear();
        return true;
    }else {
        st.clear(); return false;
    }
}
int main() {
    cin >> n >> m;
    for(int i = 1; i <= m;i++) cin >> t1 >> t2, addEdge(t1,t2),addEdge(t2,t1);
    for(int i = 1; i<=n;i++) if(!vis[i]) {
        st.insert(i);
        bool as = dfs(i,0);
        if(!as) {
            cout << "NO" << endl; return 0;
        }
    }
    cout << "YES" << endl;
}


#include<iostream>
#include<cstdio>
#include<map>
using namespace std;

const int N = 150010;

int n,m;
int f[N],p[N],size[N];

int find(int x)
{
	if(p[x]!=x) p[x]=find(p[x]);
	return p[x];
}

void merge(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x!=y)
	{
		p[x]=y;
		size[y]+=size[x];
	}
}

int main()
{
	scanf("%d%d",&n,&m);

	for(int i=1;i<=n;i++)
	{
		p[i]=i;;
		size[i]++;
	}

	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		merge(x,y);
		f[x]++;
		f[y]++;
	}
	for(int i=1;i<=n;i++)
	{
		if(size[find(i)]-1!=f[i])
		{
			puts("NO");
			return 0;
		}
	}
	puts("YES");
	return 0;
}


#include <cstdio>

struct node {
    int fa, ncnt, mcnt;
} p[150005];

int find(int x) {
    return p[x].fa == x ? x : p[x].fa = find(p[x].fa);
}

void mer(int x, int y) {
    if (find(x) == find(y)) return;
    p[p[x].fa].ncnt += p[p[y].fa].ncnt;
    p[p[x].fa].mcnt += p[p[y].fa].mcnt;
    p[p[y].fa].fa = p[x].fa;
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) p[i] = {i, 1, 0};
    for (int i = 0; i < m; ++i) {
        int a, b;
        scanf("%d%d", &a, &b);
        mer(a, b);
        ++p[find(a)].mcnt;
    }
    for (int i = 1; i <= n; ++i) if (p[i].fa == i) {
        if (p[i].ncnt > 10000 || p[i].ncnt * (p[i].ncnt - 1) != p[i].mcnt * 2) {
            puts("NO");
            return 0;
        }
    }
    puts("YES");
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define ll long long

bool flag=true;
bool vis[150005];
vector<int> v[150005];
ll st=0;
ll su=0;

void dfs(int x,ll step,ll sum)
{
    //cout<<x<<' '<<step<<' '<<sum<<endl;
    for(int i=0;i<v[x].size();i++)
    {
        int y=v[x][i];
        if(!vis[y])
        {
            vis[y]=true;
            dfs(y,step+1,sum+v[y].size());
        }
    }
    st=max(st,step);
    su=max(su,sum);
    return;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        v[a].push_back(b);
        v[b].push_back(a);
    }
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])
        {
            st=0;su=0;
            vis[i]=true;
            dfs(i,1,v[i].size());
            if(!(st*(st-1)==su))
            {
                flag=false;
            }
        }
    }
    if(flag) printf("YES\n");
    else printf("NO\n");

    return 0;
}


#include <iostream>
using namespace std;
int n;
int main()
{
	int m;
	cin>>n>>m;
    bool t[n][n];
	int a,b;
	for(int i=0;i<n;i++)
	   for(int j=0;j<n;j++)
		   t[i][j]=false;
	for(int i=0;i<m;i++)
	{
		cin>>a>>b;
		a--;b--;
		t[a][b]=true;
		t[b][a]=true;
    }
    for(int i=0;i<n;i++)
    {
    	for(int j=0;j<n;j++)
    	{
    		if(t[i][j])
    		{
    			for(int h=j+1;h<n;h++)
    			{
    				if(t[i][h] && !t[j][h])
    				{
    					cout<<"NO"<<endl;
    					return 0;
					}
				}
			}
		}
	}
	cout<<"YES"<<endl;
	return 0;
}


#include <iostream>
#include <set>
using namespace std;
int n;
set <int> *s;
bool f(int i,int j)
{
	if(s[i].size()!=s[j].size())
	   return false;
	set <int> :: iterator a,b;
	int x=0;
	for(a=s[i].begin(),b=s[j].begin();x<(int)(s[i].size());a++,b++,x++)
	{
		if(*a==j || *b==i)
		   continue;
		if(*a!=*b)
		   return false;
	}
	return true;
}
int main()
{
	int m;
	cin>>n>>m;
	s=new set <int>[n];
    bool t[n][n];
	int a,b;
	for(int i=0;i<n;i++)
	   for(int j=0;j<n;j++)
		   t[i][j]=false;
	for(int i=0;i<m;i++)
	{
		cin>>a>>b;
		a--;b--;
		t[a][b]=true;
		t[b][a]=true;
		s[a].insert(b);
		s[b].insert(a);
    }
    for(int i=0;i<n;i++)
    {
    	for(int j=0;j<n;j++)
    	{
    		if(t[i][j] && !f(i,j))
    		{
    			cout<<"NO"<<endl;
    			return 0;
			}
		}
	}
	cout<<"YES"<<endl;
	return 0;
}


#include <iostream>
#include <set>
using namespace std;
set <int> *v;
int n;
bool *t;
bool f(int i,int j)
{
	if(v[i].size()!=v[j].size())
	   return false;
	t[i]=true;
	t[j]=true;
	set <int> :: iterator a,b;
	for(a=v[i].begin(),b=v[j].begin();a!=v[i].end() && b!=v[j].end();a++,b++)
	{
		if(*a!=*b)
		{
			//cout<<i+1<<' '<<j+1 ;
			return false;
		}
	}
	return true;
}
int main()
{
	int m;
	cin>>n>>m;
	v=new set <int> [n];
	t=new bool [n];
	int x,y;
	for(int i=0;i<n;i++)
	{
		v[i].insert(i);
    }
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		v[--x].insert(--y);
		v[y].insert(x);
	}
	set <int> :: iterator a;
	for(int i=0;i<n;i++)
	{
		if(!t[i]){
		for(a=v[i].begin();a!=v[i].end();a++)
		{
			if(!t[*a] && !f(i,*a))
			{
				cout<<"NO\n";
				return 0;
			}
		}
	}
	}
	cout<<"YES\n";
	return 0;
}


#include <iostream>
#include <vector>
using namespace std;
vector <int> *v;
int n;
int main()
{
	int m;
	cin>>n>>m;
	v=new vector <int> [n];
	int x,y;
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		v[--x].push_back(--y);
		v[y].push_back(x);
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<(int)(v[i].size());j++)
		{
			if(v[i].size()!=v[v[i][j]].size())
			{
				cout<<"NO\n";
				return 0;
			}
		}
	}
	cout<<"YES\n";
	return 0;
}


#include <iostream>
#include <set>
using namespace std;
int n,m;
set <int> *s;
bool f(int i,int j)
{
	set <int> :: iterator a,b;
	for(a=s[i].begin();a!=s[i].end();a++)
	{
		for(b=s[j].begin();b!=s[j].end();b++)
		{
			if(*a==*b)
			   return true;
		}
	}
	return false;
}
int main()
{
	cin>>n>>m;
	s= new set<int> [n];
	int x,y;
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		s[--x].insert(--y);
		s[y].insert(x);
	}
	set <int> :: iterator j;
	/*for(int i=0;i<n;i++)
	{
		for(j=s[i].begin();j!=s[i].end();j++)
		{
			cout<<*j<<' ';
		}
		cout<<endl;
	}*/
	for(int i=0;i<n;i++)
	{
		if((int)(s[i].size())==1)
		{
			continue;
		}

		for(j=s[i].begin();j!=s[i].end();j++)
		{
			if((int)(s[*j].size())==1 || !f(i,*j) )
			{
				cout<<"NO"<<endl;
			    return 0;
			}
		}
	}
	cout<<"YES"<<endl;
	return 0;
}


#include <iostream>
#include <set>
using namespace std;
int n,m;
set <int> *s;
int main()
{
	cin>>n>>m;
	s= new set<int> [n];
	int x,y;
	bool p[n][n];
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		s[--x].insert(--y);
		s[y].insert(x);
		p[x][y]=true;
		p[y][x]=true;
	}
	set <int> :: iterator a,b,j;
	/*for(int i=0;i<n;i++)
	{
		for(j=s[i].begin();j!=s[i].end();j++)
		{
			cout<<*j<<' ';
		}
		cout<<endl;
	}*/
	for(int i=0;i<n;i++)
	{
		for(a=s[i].begin();a!=s[i].end();a++)
		{
			for(b=a;b!=s[i].end();b++)
			{
				if(a!=b && !p[*a][*b])
				{
					cout<<"NO"<<endl;
					return 0;
				}
			}

		}
	}
	cout<<"YES"<<endl;
	return 0;
}


#include <iostream>
#include <set>
using namespace std;
set <int> *v;
int n;
bool *t;
bool f(int i,int j)
{
	if(v[i].size()!=v[j].size())
	   return false;
	t[i]=true;
	t[j]=true;
	set <int> :: iterator a,b;
	for(a=v[i].begin(),b=v[j].begin();a!=v[i].end() && b!=v[j].end();a++,b++)
	{
		if(*a!=*b)
		{
			//cout<<i+1<<' '<<j+1 ;
			return false;
		}
	}
	return true;
}
int main()
{
	int m;
	cin>>n>>m;
	v=new set <int> [n];
	t=new bool [n];
	int x,y;
	for(int i=0;i<n;i++)
	{
		v[i].insert(i);
		t[i]=false;
    }
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		v[--x].insert(--y);
		v[y].insert(x);
	}
	set <int> :: iterator a;
	for(int i=0;i<n;i++)
	{
		if(!t[i]){
		for(a=v[i].begin();a!=v[i].end();a++)
		{
			if(!t[*a] && !f(i,*a))
			{
				cout<<"NO\n";
				return 0;
			}
		}
	}
	}
	cout<<"YES\n";
	return 0;
}


#include <iostream>
#include <set>
using namespace std;
int n,m;
set <int> *s;
int main()
{
	cin>>n>>m;
	s= new set<int> [n];
	int x,y;
	bool p[n][n];
	for(int i=0;i<n;i++)
	   for(int j=0;j<n;j++)
	       p[i][j]=false;
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		s[--x].insert(--y);
		s[y].insert(x);
		p[x][y]=true;
		p[y][x]=true;
	}
	set <int> :: iterator a,b,j;
	/*for(int i=0;i<n;i++)
	{
		for(j=s[i].begin();j!=s[i].end();j++)
		{
			cout<<*j<<' ';
		}
		cout<<endl;
	}*/
	for(int i=0;i<n;i++)
	{
		for(a=s[i].begin();a!=s[i].end();a++)
		{
			for(b=a;b!=s[i].end();b++)
			{
				if(a!=b && !p[*a][*b])
				{
					cout<<"NO"<<endl;
					return 0;
				}
			}

		}
	}
	cout<<"YES"<<endl;
	return 0;
}


#include <iostream>
#include <set>
using namespace std;
set <int> *v;
int n;
bool f(int i,int j)
{
	set <int> :: iterator a,b;
	for(a=v[i].begin(),b=v[j].begin();a!=v[i].end() && b!=v[j].end();a++,b++)
	{
		if(*a!=*b)
		{
			//cout<<i+1<<' '<<j+1;
			return false;
		}
	}
	return true;
}
int main()
{
	int m;
	cin>>n>>m;
	v=new set <int> [n];
	int x,y;
	for(int i=0;i<n;i++)
	{
		v[i].insert(i);
    }
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		v[--x].insert(--y);
		v[y].insert(x);
	}
	set <int> :: iterator a;
	for(int i=0;i<n;i++)
	{
		for(a=v[i].begin();a!=v[i].end();a++)
		{
			if(!f(i,*a))
			{
				cout<<"NO\n";
				return 0;
			}
		}
	}
	cout<<"YES\n";
	return 0;
}


#include <iostream>
#include <set>
using namespace std;
int n,m;
int main()
{
	cin>>n>>m;
	int x,y;
	bool p[n][n];
	for(int i=0;i<n;i++)
	   for(int j=0;j<n;j++)
	       p[i][j]=((i==j) ? true : false);

	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		p[--x][--y]=true;
		p[y][x]=true;
	}
	/*for(int i=0;i<n;i++)
	{
		for(j=s[i].begin();j!=s[i].end();j++)
		{
			cout<<*j<<' ';
		}
		cout<<endl;
	}*/
	for(int i=0;i<n;i++)
	{
		for(int a=0;a<n;a++)
		{
			if(p[i][a])
			{
			   for(int b=a+1;b<n;b++)
				{
					if(p[i][b])
					{
						if(!p[a][b])
						{
							cout<<"NO"<<endl;
							return 0;
						}
					}
				}
			}

		}
	}
	cout<<"YES"<<endl;
	return 0;
}


#include <iostream>
#include <set>
using namespace std;
set <int> *v;
int n;
bool f(int i,int j)
{
	if(v[i].size()!=v[j].size())
	   return false;
	set <int> :: iterator a,b;
	for(a=v[i].begin(),b=v[j].begin();a!=v[i].end() && b!=v[j].end();a++,b++)
	{
		if(*a!=*b)
		{
			//cout<<i+1<<' '<<j+1;
			return false;
		}
	}
	return true;
}
int main()
{
	int m;
	cin>>n>>m;
	v=new set <int> [n];
	int x,y;
	for(int i=0;i<n;i++)
	{
		v[i].insert(i);
    }
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		v[--x].insert(--y);
		v[y].insert(x);
	}
	set <int> :: iterator a;
	for(int i=0;i<n;i++)
	{
		for(a=v[i].begin();a!=v[i].end();a++)
		{
			if(!f(i,*a))
			{
				cout<<"NO\n";
				return 0;
			}
		}
	}
	cout<<"YES\n";
	return 0;
}


#include <iostream>
#include <set>
using namespace std;
set <int> *v;
int n;
bool *t;
bool f(int i,int j)
{
	if(v[i].size()!=v[j].size())
	   return false;
	t[i]=true;
	t[j]=true;
	set <int> :: iterator a,b;
	for(a=v[i].begin(),b=v[j].begin();a!=v[i].end() && b!=v[j].end();a++,b++)
	{
		if(*a!=*b)
		{
			//cout<<i+1<<' '<<j+1;
			return false;
		}
	}
	return true;
}
int main()
{
	int m;
	cin>>n>>m;
	v=new set <int> [n];
	t=new bool [n];
	int x,y;
	for(int i=0;i<n;i++)
	{
		v[i].insert(i);
    }
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		v[--x].insert(--y);
		v[y].insert(x);
	}
	set <int> :: iterator a;
	for(int i=0;i<n;i++)
	{
		if(!t[i]){
		for(a=v[i].begin();a!=v[i].end();a++)
		{
			if(!t[*a] && !f(i,*a))
			{
				cout<<"NO\n";
				return 0;
			}
		}
	}
	}
	cout<<"YES\n";
	return 0;
}


#include <iostream>
#include <set>
using namespace std;
int n,m;
set <int> *s;
bool f(int i,int j)
{
	set <int> :: iterator a;
	for(a=s[j].begin();a!=s[j].end();a++)
	{
		if(*a==i)
		   return true;
	}
	return false;
}
int main()
{
	cin>>n>>m;
	s= new set<int> [n];
	int x,y;
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		s[--x].insert(--y);
		s[y].insert(x);
	}
	set <int> :: iterator a,b,j;
	/*for(int i=0;i<n;i++)
	{
		for(j=s[i].begin();j!=s[i].end();j++)
		{
			cout<<*j<<' ';
		}
		cout<<endl;
	}*/
	for(int i=0;i<n;i++)
	{
		for(a=s[i].begin();a!=s[i].end();a++)
		{
			for(b=a;b!=s[i].end();b++)
			{
				if(a!=b && !f(*a,*b))
				{
					cout<<"NO"<<endl;
					return 0;
				}
			}

		}
	}
	cout<<"YES"<<endl;
	return 0;
}


#include <bits/stdc++.h>
#define MAX 150005
using namespace std;
typedef long long ll;
vector<ll>adj[MAX];
bool v[MAX];
ll n, m;
ll cnt=0, c_edges;
void resetv()
{
	for (int i = 1; i <= n; ++i)
		v[i]=0;
}
void dfs(ll x)
{
    if (v[x])
    	return;
//    cout << x << endl;
    v[x] = 1;
    cnt++;
    c_edges+=adj[x].size();
    for (int i = 0; i < adj[x].size(); ++i)
        dfs(adj[x][i]);
}

int main()
{
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        ll a, b;
        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    for (int i = 1; i <= n; ++i)
    {
    	if  (adj[i].size() == 0) continue;
    	resetv();
//    	memset(v,0,sizeof(v));
    	cnt=0;
    	c_edges=0;
	    dfs(i);
	    c_edges /= 2;
//	    cout << "edges " << c_edges << endl;
//	    cout << "v " << cnt << endl;
	    if (c_edges != cnt*(cnt-1)/2)
	    {
	    	cout << "NO" << endl;
	    	return 0;
	    }
    }
    cout << "YES" << endl;
    //e = v(v-1)/2
}


#include <bits/stdc++.h>
#define MAX 150005
using namespace std;
vector<int>adj[MAX];
bool v[MAX];
int n, m;
int cnt=0, c_edges;
void dfs(int x)
{
    if (v[x])
    	return;
//    cout << x << endl;
    v[x] = 1;
    cnt++;
    c_edges+=adj[x].size();
    for (int i = 0; i < adj[x].size(); ++i)
        dfs(adj[x][i]);
}

int main()
{
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        int a, b;
        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    for (int i = 1; i <= n; ++i)
    {
    	if  (adj[i].size() == 0) continue;
    	memset(v,0,sizeof(v));
    	cnt=0;
    	c_edges=0;
	    dfs(i);
	    c_edges /= 2;
//	    cout << "edges " << c_edges << endl;
//	    cout << "v " << cnt << endl;
	    if (c_edges != cnt*(cnt-1)/2)
	    {
	    	cout << "NO" << endl;
	    	return 0;
	    }
    }
    cout << "YES" << endl;
    //e = v(v-1)/2
}


#include <bits/stdc++.h>
#define MAX 150123
using namespace std;
typedef long long ll;
vector<ll>adj[MAX];
bool v[MAX];
ll n, m;
ll cnt=0, c_edges;
void resetv()
{
	for (int i = 1; i <= n; ++i)
		v[i]=0;
}
void dfs(ll x)
{
    if (v[x])
    	return;
    v[x] = 1;
    cnt++;
    c_edges+=adj[x].size();
    for (int i = 0; i < adj[x].size(); ++i)
        dfs(adj[x][i]);
}

int main()
{
	scanf("%d%d", &n, &m);
    for (int i = 0; i < m; ++i)
    {
        ll a, b;
        scanf("%d%d", &a, &b);
//        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    for (int i = 1; i <= n; ++i)
    {
    	if  (adj[i].size() == 0) continue;
    	resetv();
//    	memset(v,0,sizeof(v));
    	cnt=0;
    	c_edges=0;
	    dfs(i);
	    if (c_edges != (long long)cnt*(cnt-1))
	    {
	    	puts("NO");
	    	return 0;
	    }
    }
    puts("YES");
    //e = v(v-1)/2
}


#include <bits/stdc++.h>
#define MAX 150123
using namespace std;
typedef long long ll;
vector<ll>adj[MAX];
bool v[MAX];
ll n, m;
ll cnt=0, c_edges;
void resetv()
{
	for (int i = 1; i <= n; ++i)
		v[i]=0;
}
void dfs(ll x)
{
    if (v[x])
    	return;
    v[x] = 1;
    cnt++;
    c_edges+=adj[x].size();
    for (int i = 0; i < adj[x].size(); ++i)
        dfs(adj[x][i]);
}

int main()
{
	scanf("%d%d", &n, &m);
    for (int i = 0; i < m; ++i)
    {
        ll a, b;
        scanf("%d%d", &a, &b);
//        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    for (int i = 1; i <= n; ++i)
    {
    	if  (adj[i].size() == 0) continue;
    	resetv();
//    	memset(v,0,sizeof(v));
    	cnt=0;
    	c_edges=0;
	    dfs(i);
	    c_edges /= 2;
//	    cout << "edges " << c_edges << endl;
//	    cout << "v " << cnt << endl;
	    if (c_edges != cnt*(cnt-1)/2)
	    {
	    	puts("NO");
//	    	cout << "NO" << endl;
	    	return 0;
	    }
    }
    puts("YES");
    //e = v(v-1)/2
}


#include <bits/stdc++.h>
#define MAX 150123
using namespace std;
typedef long long ll;
vector<ll>adj[MAX];
bool v[MAX];
ll n, m;
ll cnt=0, c_edges;
void dfs(ll x)
{
    if (v[x])
    	return;
    v[x] = 1;
    cnt++;
    c_edges+=adj[x].size();
    for (int i = 0; i < adj[x].size(); ++i)
        dfs(adj[x][i]);
}

int main()
{
	scanf("%d%d", &n, &m);
    for (int i = 0; i < m; ++i)
    {
        ll a, b;
        scanf("%d%d", &a, &b);
//        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    for (int i = 1; i <= n; ++i)
    {
    	if  (adj[i].size() == 0 || v[i]) continue;
    	cnt=0;
    	c_edges=0;
	    dfs(i);
	    if (c_edges != (long long)cnt*(cnt-1))
	    {
	    	puts("NO");
	    	return 0;
	    }
    }
    puts("YES");
    //e = v(v-1)/2
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <cstring>
#include <queue>
#include <bitset>
#include <stack>
#define hzwer ShenBen
using namespace std;
const int maxn=100010;
int q[maxn], sq, s[maxn];
int a[maxn], b[maxn];
struct node {
	vector<int> to;
	int s;
};
map<int, node> mp;
map<int, int> flg;
int n, m;
int dfs(int k) {
	int s=1;
	flg[k]=0; //k isn't used
	for(int i=0; i<mp[k].to.size(); i++)
		if(flg[mp[k].to[i]]==mp[k].to[i]) s+=dfs(mp[k].to[i]);
	return s;
}
int cnt=0;
int main() {
	scanf("%d%d", &n, &m);
	for(int i=1; i<=m; i++) {
		scanf("%d%d", &a[i], &b[i]);
		if(flg[a[i]]!=i) {
			q[++sq]=a[i];
			flg[a[i]]=a[i];
			mp[a[i]].s=0;
		}
		if(flg[b[i]]!=i) {
			q[++sq]=b[i];
			flg[b[i]]=b[i];
			mp[b[i]].s=0;
		}
		mp[a[i]].to.push_back(b[i]);
		mp[b[i]].to.push_back(a[i]);
	}
	for(int i=1; i<=sq; i++) {
		int k=q[i];
		if(flg[k]==k) {
			s[++cnt]=dfs(k);
		}
	}
	int tot=0;
	for(int i=1; i<=sq; i++) {
		tot+=s[i]*(s[i]-1)/2;
	}
	if(tot==m) printf("YES\n");
	else printf("NO\n");
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <cstring>
#include <queue>
#include <bitset>
#include <stack>
#define hzwer ShenBen
using namespace std;
const int maxn=10000100;
int q[maxn], sq, s[maxn];
int a[maxn], b[maxn];
struct node {
	vector<int> to;
	int s;
};
map<int, node> mp;
map<int, int> flg;
int n, m;
int dfs(int k) {
	int s=1;
	flg[k]=0; //k isn't used
	for(int i=0; i<mp[k].to.size(); i++)
		if(flg[mp[k].to[i]]==mp[k].to[i]) s+=dfs(mp[k].to[i]);
	return s;
}
int cnt=0;
int main() {
	scanf("%d%d", &n, &m);
	for(int i=1; i<=m; i++) {
		scanf("%d%d", &a[i], &b[i]);
		if(flg[a[i]]!=i) {
			q[++sq]=a[i];
			flg[a[i]]=a[i];
			mp[a[i]].s=0;
		}
		if(flg[b[i]]!=i) {
			q[++sq]=b[i];
			flg[b[i]]=b[i];
			mp[b[i]].s=0;
		}
		mp[a[i]].to.push_back(b[i]);
		mp[b[i]].to.push_back(a[i]);
	}
	for(int i=1; i<=sq; i++) {
		int k=q[i];
		if(flg[k]==k) {
			s[++cnt]=dfs(k);
		}
	}
	int tot=0;
	for(int i=1; i<=sq; i++) {
		tot+=s[i]*(s[i]-1)/2;
	}
	if(tot==m) printf("YES\n");
	else printf("NO\n");
	return 0;
}


#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
long long f[150077],u[150077],v[150077],n,m,size_e[150077],size_v[150077];
int gf(int x)
{
	return x==f[x]?x:f[x]=gf(f[x]);
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) f[i]=i;
	for(int i=1; i<=m; i++)
	{
		scanf("%d%d",&u[i],&v[i]);
		int uu=gf(u[i]),vv=gf(v[i]);
		if(uu!=vv) f[uu]=vv;
	}
	for(int i=1; i<=m; i++) size_e[gf(u[i])]++;
    for(int i=1; i<=n; i++) size_v[gf(i)]++;
    for(int i=1; i<=n; i++)
    if(gf(i)==i)
    {
        long long sv=size_v[i],se=size_e[i];
        if(sv*(sv-1)>>1!=se)
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <cstring>
#include <queue>
#include <bitset>
#include <stack>
#include <cassert>
#define hzwer ShenBen
using namespace std;
const int maxn=1000100;
int q[maxn], sq, s[maxn];
int a[maxn], b[maxn];
struct node {
	vector<int> to;
	int s;
};
map<int, node> mp;
map<int, int> flg;
bool vis[maxn];
int n, m;
int dfs(int k) {
	int s=1;
	flg[k]=0; //k isn't used
	for(int i=0; i<mp[k].to.size(); i++)
		if(flg[mp[k].to[i]]==mp[k].to[i]) s+=dfs(mp[k].to[i]);
	return s;
}
int cnt=0;
namespace small {
	long long f[150077],u[150077],v[150077],size_e[150077],size_v[150077];
	int gf(int x) {
		return x==f[x]?x:f[x]=gf(f[x]);
	}
}
void solve() {
	using namespace small;
	for(int i=1; i<=n; i++) f[i]=i;
	for(int i=1; i<=m; i++) {
		scanf("%d%d",&u[i],&v[i]);
		int uu=gf(u[i]),vv=gf(v[i]);
		if(uu!=vv) f[uu]=vv;
	}
	for(int i=1; i<=m; i++) size_e[gf(u[i])]++;
	for(int i=1; i<=n; i++) size_v[gf(i)]++;
	for(int i=1; i<=n; i++)
		if(gf(i)==i) {
			long long sv=size_v[i],se=size_e[i];
			if(sv*(sv-1)>>1!=se) {
				printf("NO\n");
				return;
			}
		}
	printf("YES\n");
}
int main() {
	scanf("%d%d", &n, &m);
	if(n<=100000) {
		solve();
		return 0;
	}
	for(int i=1; i<=m; i++) {
		scanf("%d%d", &a[i], &b[i]);
		if(flg[a[i]]!=i) {
			q[++sq]=a[i];
			flg[a[i]]=a[i];
			mp[a[i]].s=0;
		}
		if(flg[b[i]]!=i) {
			q[++sq]=b[i];
			flg[b[i]]=b[i];
			mp[b[i]].s=0;
		}
		mp[a[i]].to.push_back(b[i]);
		mp[b[i]].to.push_back(a[i]);
	}
	for(int i=1; i<=sq; i++) {
		int k=q[i];
		if(flg[k]==k) {
			s[++cnt]=dfs(k);
		}
	}
	int tot=0;
	for(int i=1; i<=sq; i++) {
		tot+=s[i]*(s[i]-1)/2;
	}
	if(tot==m) printf("YES\n");
	else printf("NO\n");
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <cstring>
#include <queue>
#include <bitset>
#include <stack>
#include <cassert>
#define hzwer ShenBen
using namespace std;
const int maxn=1000100;
int q[maxn], sq, s[maxn];
int a[maxn], b[maxn];
struct node {
	vector<int> to;
	int s;
};
map<int, node> mp;
map<int, int> flg;
bool vis[maxn];
int n, m;
int dfs(int k) {
	int s=1;
	flg[k]=0; //k isn't used
	for(int i=0; i<mp[k].to.size(); i++)
		if(flg[mp[k].to[i]]==mp[k].to[i]) s+=dfs(mp[k].to[i]);
	return s;
}
int cnt=0;
vector<int> edges[maxn];
void Dfs(int a, int & cnt_vertices, int & cnt_edges) {
	assert(!vis[a]);
	vis[a] = true;
	++cnt_vertices;
	cnt_edges += edges[a].size();
	for(int i=1; i<=edges[a].size(); i++) {
		int b=edges[a][i];
		if(!vis[b])
			Dfs(b, cnt_vertices, cnt_edges);
	}
}
void solve() {
while(m--) {
		int a, b;
		scanf("%d%d", &a, &b);
		edges[a].push_back(b);
		edges[b].push_back(a);
	}
	for(int i = 1; i <= n; ++i)
		if(!vis[i]) {
			int cnt_vertices = 0, cnt_edges = 0;
			Dfs(i, cnt_vertices, cnt_edges);
			if(cnt_edges != (long long) cnt_vertices * (cnt_vertices - 1)) {
				puts("NO");
				return ;
			}
		}
	puts("YES");
	return ;
}
int main() {
	//freopen("group.in", "r", stdin);
	//freopen("group.out", "w", stdout);
	scanf("%d%d", &n, &m);
	if(n<=1000) {
		solve();
		return 0;
	}
	for(int i=1; i<=m; i++) {
		scanf("%d%d", &a[i], &b[i]);
		if(flg[a[i]]!=i) {
			q[++sq]=a[i];
			flg[a[i]]=a[i];
			mp[a[i]].s=0;
		}
		if(flg[b[i]]!=i) {
			q[++sq]=b[i];
			flg[b[i]]=b[i];
			mp[b[i]].s=0;
		}
		mp[a[i]].to.push_back(b[i]);
		mp[b[i]].to.push_back(a[i]);
	}
	for(int i=1; i<=sq; i++) {
		int k=q[i];
		if(flg[k]==k) {
			s[++cnt]=dfs(k);
		}
	}
	int tot=0;
	for(int i=1; i<=sq; i++) {
		tot+=s[i]*(s[i]-1)/2;
	}
	if(tot==m) printf("YES\n");
	else printf("NO\n");
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<string>
#include<map>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
#include<ctime>
#include<iostream>
#define ps puts("")
#define fi first
#define nd second
#define mset(x) memset((x), 0, sizeof (x))
#define mk make_pair
#define sqr(x) ((x)*(x))
#define pii pair<ll,int>
using namespace std;
typedef long long ll;
inline ll read() {
    ll x = 0; char f = 1, ch = getchar(); while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }return x * f;
}
void write(ll x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); }
inline void writeln(ll x) { write(x); puts(""); }
const int N = 1500000, M = 2500000;

int n, m;
int head[N], en;
struct Edge {
	int u, v, nxt;
}e[M];
void add(int x, int y) {
	e[++en].u = x, e[en].v = y, e[en].nxt = head[x], head[x] = en;
}
set<int>v[N];
bool vis[N];
int t[N], tot, num;
void dfs(int x){
	vis[x] = num;
	t[++tot] = x;
	for(int i = head[x]; i; i = e[i].nxt) {
		if(!vis[e[i].v])
			dfs(e[i].v);
		v[x].insert(e[i].v);
	}

}
int main() {
	n = read(), m = read();
	for(int i = 1; i <= m; ++i) {
		int x = read(), y = read();
		add(x, y);
		add(y, x);
	}
	for(int i = 1; i <= n; ++i)
		if(!vis[i]) {
			++num;
			tot = 0;
			dfs(i);
			for(int j = 1; j <= tot; ++j)
				if(v[t[j]].size() != tot - 1)
					{
						puts("NO");
						return 0;
					}
		}
	puts("YES");
	return 0;
}


#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
using namespace std;

typedef long long ll;
const ll maxn = 150000 + 10;
ll vis[maxn];
ll num[maxn];
map<ll, vector<ll> > v;
ll n, m, t, t2;

bool bfs(ll u) {
    vis[u] = 1;
    bool flag = true;
    for(ll i = 0; i < v[u].size() && flag; i++) {
        if(vis[v[u][i]]) continue;
        if(num[u] == num[v[u][i]]) flag = bfs(v[u][i]);
        else flag = false;
    }
    return flag;
}

int main() {
    scanf("%lld%lld", &n, &m);
    for(ll i = 0; i < m; i++) {
        scanf("%lld%lld", &t, &t2);
        num[t]++;
        num[t2]++;
        v[t].push_back(t2);
        v[t2].push_back(t);
    }
    bool flag = true;
    for(ll i = 1; i <= n && flag; i++) {
        if(!vis[i]) flag = bfs(i);
    }
    printf("%s\n", flag? "YES": "NO");
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll maxn = 150000 + 10;
ll n ,m, k, t, t1;
ll vis[maxn];
map<ll, queue<ll> > p;
queue<ll> q;

void bfs(ll u) {
    q.push(p[u].front()); p[u].pop();
    k++;
    while(!q.empty()) {
        ll c = q.front(); q.pop();
        k++;
        while(!p[c].empty()) {
            q.push(p[c].front());
            p[c].pop();
        }
    }
}

int main() {
    scanf("%lld%lld", &n, &m);
    for(ll i = 0; i < m; i++) {
        scanf("%lld%lld", &t, &t1);
        if(t > t1) swap(t, t1);
        p[t].push(t1);
    }
    ll sum = 0;
    for(auto u: p) {
        ll uu = u.first;
        while(!p[uu].empty()) {
            k = 0;
            bfs(uu);
            sum = sum + k*(k-1)/2;
        }
    }
    printf("%s\n", sum == m? "YES": "NO");
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll maxn = 150000 + 10;
ll n ,m, k, t, t1;
ll vis[maxn];
map<ll, vector<ll> > p;

void bfs(ll u) {
    k++;
    vis[u] = 1;
    for(int i = 0; i < p[u].size(); i++) {
        if(!vis[p[u][i]]) bfs(p[u][i]);
    }
}

int main() {
    scanf("%lld%lld", &n, &m);
    for(ll i = 0; i < m; i++) {
        scanf("%lld%lld", &t, &t1);
        if(t > t1) swap(t, t1);
        p[t].push_back(t1);
    }
    ll sum = 0;
    for(auto u: p) {
        if(!vis[u.first]) {
            k = 0;
            bfs(u.first);
            sum = sum + k*(k-1)/2;
        }
    }
    printf("%s\n", sum == m? "YES": "NO");
    return 0;
}


/*

  ______      _                _____
  |  ____/\   | |        /\    / ____|
  | |__ /  \  | |       /  \  | (___
  |  __/ /\ \ | |      / /\ \  \___ \
  | | / ____ \| |____ / ____ \ ____) |
  |_|/_/    \_\______/_/    \_\_____/

*/
#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define INF 1000000
#define MOD 1000000007

typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef pair<ii, ll> iii;
typedef vector<ii> vii;

#define F first
#define S second

#define mp make_pair
#define endl '\n'
#define priority_queue pq

vector<vi> adj;
bool vis[1000000];
vi group[180000];

void dfs(int s, int pos){
    vis[s] = true;
    group[pos].push_back(s);

    for(int i=0;i<adj[s].size();i++){
        if(!vis[adj[s][i]]){
            dfs(adj[s][i], pos);
        }
    }
}

int main(){
    int n, m;
    cin>>n>>m;
    map<int, int> cnt;
    adj.assign(n+1, vi());
    for(int i=0;i<m;i++){
        int a, b;
        cin>>a>>b;
        cnt[a]++, cnt[b]++;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    int pos=0;
    for(int i=1;i<=n;i++){
        if(!vis[i]){
            dfs(i, pos);
            pos++;
        }
    }
    for(int i=0;i<pos;i++){
        int to=0;
        for(int j=0;j<group[i].size();j++){
            to+=cnt[group[i][j]];
        }
        if(group[i].size()*(group[i].size()-1)/2!=to){
            cout<<"NO\n";
            return 0;
        }
    }
    cout<<"YES\n";

}


/*

  ______      _                _____
  |  ____/\   | |        /\    / ____|
  | |__ /  \  | |       /  \  | (___
  |  __/ /\ \ | |      / /\ \  \___ \
  | | / ____ \| |____ / ____ \ ____) |
  |_|/_/    \_\______/_/    \_\_____/

*/
#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define INF 1000000
#define MOD 1000000007

typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef pair<ii, ll> iii;
typedef vector<ii> vii;

#define F first
#define S second

#define mp make_pair
#define endl '\n'
#define priority_queue pq

vector<vi> adj;
bool vis[1000000];
vi group[180000];

void dfs(int s, int pos){
    vis[s] = true;
    group[pos].push_back(s);

    for(int i=0;i<adj[s].size();i++){
        if(!vis[adj[s][i]]){
            dfs(adj[s][i], pos);
        }
    }
}

int main(){
    int n, m;
    cin>>n>>m;
    map<int, int> cnt;
    adj.assign(n+1, vi());
    for(int i=0;i<m;i++){
        int a, b;
        cin>>a>>b;
        cnt[a]++, cnt[b]++;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    int pos=0;
    for(int i=1;i<=n;i++){
        if(!vis[i]){
            dfs(i, pos);
            pos++;
        }
    }
    for(int i=0;i<pos;i++){
        for(int j=0;j<group[i].size();j++){
            if(cnt[group[i][j]]!=cnt[group[i][0]]){
                cout<<"NO\n";
                return 0;
            }
        }
    }
    cout<<"YES\n";

}


/*

  ______      _                _____
  |  ____/\   | |        /\    / ____|
  | |__ /  \  | |       /  \  | (___
  |  __/ /\ \ | |      / /\ \  \___ \
  | | / ____ \| |____ / ____ \ ____) |
  |_|/_/    \_\______/_/    \_\_____/

*/
#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define INF 1000000
#define MOD 1000000007

typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef pair<ii, ll> iii;
typedef vector<ii> vii;

#define F first
#define S second

#define mp make_pair
#define endl '\n'
#define priority_queue pq

vector<vi> adj;
bool vis[1000000];
vi group[180000];

void dfs(int s, int pos){
    vis[s] = true;
    group[pos].push_back(s);

    for(int i=0;i<adj[s].size();i++){
        if(!vis[adj[s][i]]){
            dfs(adj[s][i], pos);
        }
    }
}

int main(){
    int n, m;
    cin>>n>>m;
    map<int, int> cnt;
    adj.assign(n+1, vi());
    for(int i=0;i<m;i++){
        int a, b;
        cin>>a>>b;
        cnt[a]++, cnt[b]++;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    int pos=0;
    for(int i=1;i<=n;i++){
        if(!vis[i]){
            dfs(i, pos);
            pos++;
        }
    }
    for(int i=0;i<pos;i++){
        int to=0;
        for(int j=0;j<group[i].size();j++){
            to+=cnt[group[i][j]];
        }
        to/=2;
        if(group[i].size()*(group[i].size()-1)/2!=to){
            cout<<"NO\n";
            return 0;
        }
    }
    cout<<"YES\n";

}


/*

  ______      _                _____
  |  ____/\   | |        /\    / ____|
  | |__ /  \  | |       /  \  | (___
  |  __/ /\ \ | |      / /\ \  \___ \
  | | / ____ \| |____ / ____ \ ____) |
  |_|/_/    \_\______/_/    \_\_____/

*/
#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define INF 1000000
#define MOD 1000000007

typedef pair<ll, ll> ii;
typedef vector<ll> vi;
typedef pair<ii, ll> iii;
typedef vector<ii> vii;

#define F first
#define S second

#define mp make_pair
#define endl '\n'
#define priority_queue pq

vector<vi> adj;
bool vis[1000000];
vi group[180000];

void dfs(int s, int pos){
    vis[s] = true;
    group[pos].push_back(s);

    for(int i=0;i<adj[s].size();i++){
        if(!vis[adj[s][i]]){
            dfs(adj[s][i], pos);
        }
    }
}

int main(){
    int n, m;
    cin>>n>>m;
    map<int, int> cnt;
    adj.assign(n+1, vi());
    for(int i=0;i<m;i++){
        int a, b;
        cin>>a>>b;
        cnt[a]++, cnt[b]++;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    int pos=0;
    for(int i=1;i<=n;i++){
        if(!vis[i]){
            dfs(i, pos);
            pos++;
        }
    }
    for(int i=0;i<pos;i++){
        ll to=0;
        for(int j=0;j<group[i].size();j++){
            to+=cnt[group[i][j]];
        }
        to/=2;
        ll cn = group[i].size();
        if(cn*(cn-1)/2!=to){
            cout<<"NO\n";
            return 0;
        }
    }
    cout<<"YES\n";

}


/*input
4 3
1 3
3 4
1 4
*/

#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define sz(x) (int) x.size()
#define pb push_back
#define fst first
#define snd second

typedef long long int ll;
typedef unsigned long long int ull;
typedef vector <int> vi;
typedef pair <ll, ll> ii;
typedef pair <ll, ii> iii;
typedef pair <ll, iii> iiii;

#define maxn 150003

vi g[maxn], see;
ll cnte;
set <int> cntv;

void dfs(int u){
    cntv.insert(u);
    cnte += sz(g[u]);
    see[u] = 1;
    for(auto i : g[u])
        if(!see[i])
            dfs(i);
}

int main(){
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < m; i++){
        int x, y;
        cin >> x >> y;
        g[x].pb(y);
        g[y].pb(x);
    }
    bool ans = true;
    see.assign(n+1, 0);
    for(int i = 1; i <= n; i++){
        if(!see[i]){
            cnte = 0;
            cntv.clear();
            dfs(i);
            ll temp = sz(cntv);
            ans &= cnte == (temp*(temp-1));
        }
    }
    cout << (ans ? "YES" : "NO") << endl;
    return 0;
}
// 1523125615364


#include <bits/stdc++.h>
#define pf printf
#define sc(i) scanf("%d", &i)
#define sc2(x,y) scanf("%d %d", &x, &y)
#define sc3(x,y,z) scanf("%d %d %d", &x, &y, &z)
#define scd(i) scanf("%lf", &i)
#define scd2(x,y) scanf("%lf %lf", &x, &y)
#define scd3(x,y,z) scanf("%lf %lf %lf", &x, &y, &z)
#define MP(x,y) make_pair(x,y)
#define PDD pair<double,double>
#define PII pair<int,int>
#define fr(i,n) for(int i = 0 ; i < n ; ++i)
#define frf(i,o,n) for(int i = o ; i < n ; ++i)
#define frd(i,n) for(int i = n ; i ; --i)
typedef long long int lli;
typedef unsigned long long ull;

using namespace std;

int ds[150001];
int cel[150001];
int ctot[150001];
void init_set(int n){for(int i = 0 ; i < n ; ++i) {ds[i] = i; ctot[i] = 0; cel[i] = 1;}}
int fset(int t){ return (ds[t] == t ? t : (ds[t] = fset(ds[t])));}
bool sset(int t1, int t2){return fset(t1) == fset(t2);}
void uset(int t1, int t2){
	int temp1 = fset(t1), temp2 = fset(t2);
	ds[temp2] = temp1;
	if(temp1 != temp2){
		cel[temp1] += cel[temp2];
		ctot[temp1] += ctot[temp2];
	}
	ctot[temp1] += 2;
}

int main()
{
	int n,m;
	sc2(n,m);
	init_set(n);
	for(int i = 0 ; i < m ; ++i){
		int a,b;
		sc2(a,b);
		uset(a-1,b-1);
	}
	int i = 0;
	for(; i < n ; ++i){
		int k = fset(i);
		if(cel[k] > 1 && cel[k]*(cel[k]-1) != ctot[k])
			break;
	}
	if(i==n)
		printf("YES");
	else
		printf("NO");
	return 0;
}

// 1496107753437


#include <bits/stdc++.h>
#define pf printf
#define sc(i) scanf("%d", &i)
#define sc2(x,y) scanf("%d %d", &x, &y)
#define sc3(x,y,z) scanf("%d %d %d", &x, &y, &z)
#define scd(i) scanf("%lf", &i)
#define scd2(x,y) scanf("%lf %lf", &x, &y)
#define scd3(x,y,z) scanf("%lf %lf %lf", &x, &y, &z)
#define MP(x,y) make_pair(x,y)
#define PDD pair<double,double>
#define PII pair<int,int>
#define fr(i,n) for(int i = 0 ; i < n ; ++i)
#define frf(i,o,n) for(int i = o ; i < n ; ++i)
#define frd(i,n) for(int i = n ; i ; --i)
typedef long long int lli;
typedef unsigned long long ull;

using namespace std;

vector<vector<bool>> g;

int main()
{
	int n,m;
	sc2(n,m);
	g.resize(n);
	for(int i = 0 ; i < g.size() ; ++i)
		g[i].resize(n);
	for(int i = 0 ; i < m ; ++i){
		int a,b;
		sc2(a,b);
		--a; --b;
		g[a][b] = g[b][a] = true;
	}
	bool ok = true;
	for(int i = 0 ; ok && i < n ; ++i){
		for(int j = i+1; ok && j < n ; ++j){
			if(g[i][j]){
				for(int k = j+1 ; ok && k < n ; ++k){
					if(g[j][k] && !g[i][k]){
						ok = false;
					}
				}
			}
		}
	}
	if(ok)
		printf("YES\n");
	else
		printf("NO\n");
	return 0;
}

// 1496099930327


#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define sz(x) (int) x.size()
#define pb push_back
#define fst first
#define snd second

typedef long long ll;
typedef unsigned long long int ull;
typedef vector <int> vi;
typedef pair <int, int> ii;
typedef pair <int, ii> iii;

const int maxn = (int) 1e7;

vi adj[150005];
int see[150005];
ll tam=0;

void dfs(int s){
  tam++;
  see[s] = 1;
  for(auto i:adj[s])
    if(see[i] == 0)
      dfs(i);
}

int main(){
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  memset(see, 0, sizeof see);
  int n,m;
  cin >> n >> m;
  for(int k=0;k<m;k++){
    int a,b; cin >> a >> b;
    adj[a].pb(b);
  }
  ll ans = 0;
  for(int i=1;i<=n;i++){
    if(see[i] == 0 && sz(adj[i]) > 0 ){ //nao considera ele p ele mesmo
      tam = 0;
      dfs(i);
      ans += tam * (tam-1);
      /* tam representa o numero de arestas percorridas, multiplicado pelo seu antecessor
         representa 2*(n de arestas totais) caso o grafo forme ciclo com todos os nós com excessao dos que nao possuem arestas
      */
    }
  }
  cout << (ans==2*m?"YES":"NO") << endl;
  return 0;
}

// 1523128216659


#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define sz(x) (int) x.size()
#define pb push_back
#define fst first
#define snd second

typedef long long int ll;
typedef unsigned long long int ull;
typedef vector <int> vi;
typedef pair <int, int> ii;
typedef pair <int, ii> iii;

const int maxn = (int) 1e7;

vi adj[150105];
int see[150105];
ll tam=0;

void dfs(int s){
  tam++;
  see[s] = 1;
  for(auto i:adj[s])
    if(see[i] == 0)
      dfs(i);
}

int main(){
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  memset(see, 0, sizeof see);
  int n,m;
  cin >> n >> m;
  for(int k=0;k<m;k++){
    int a,b; cin >> a >> b;
    adj[a].pb(b);
    adj[b].pb(a);
  }
  ll ans = 0;
  for(int i=1;i<=n;i++){
    if(see[i] == 0 && sz(adj[i]) > 0 ){ //nao considera ele p ele mesmo
      tam = 0;
      dfs(i);
      ans += tam * (tam-1);
      /* tam representa o numero de arestas percorridas, multiplicado pelo seu antecessor
         representa 2*(n de arestas totais) caso o grafo forme ciclo com todos os nós com excessao dos que nao possuem ligação
      */
    }
  }
  cout << (ans==2*m?"YES":"NO") << endl;
  return 0;
}

// 1523130678545


#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
const int maxn = 150005;
bitset <maxn> viz;
vector <int> v[maxn];

long long s = 0;
int nrnod = 0;
void _fill_(int nod)
{
    nrnod++;
    s = s + v[nod].size();
    viz[nod] = 1;
    for(auto it : v[nod])
        if(!viz[it])
            _fill_(it);
    return;
}

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        int x, y;
        cin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(int i = 1; i <= n; i++)
    {
        s = 0;
        nrnod = 0;
        if(!viz[i])
        {
            _fill_(i);
            if(s != 1LL * nrnod * (nrnod - 1) / 2 && nrnod != 0)
            {
                cout << "NO";
                return 0;
            }
        }
    }
    cout << "YES";
    return 0;
}


#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
const int maxn = 150005;
bitset <maxn> viz;
vector <int> v[maxn];

int s = 0;
int nrnod = 0;
void _fill_(int nod)
{
    nrnod++;
    s = s + v[nod].size();
    viz[nod] = 1;
    for(auto it : v[nod])
        if(!viz[it])
            _fill_(it);
    return;
}

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        int x, y;
        cin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(int i = 1; i <= n; i++)
    {
        s = 0;
        nrnod = 0;
        if(!viz[i] && v[i].size() > 0)
        {
            _fill_(i);
            //cerr << i << " " << s << " " << nrnod << "\n";
            if(1LL * s * (s + 1) == 1LL * nrnod * (nrnod - 1) / 2)
            {
                cout << "YES";
                return 0;
            }
        }
    }
    cout << "NO";
    return 0;
}


#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
const int maxn = 150005;
bitset <maxn> viz;
vector <int> v[maxn];

long long s = 0;
int nrnod = 0;
void _fill_(int nod)
{
    nrnod++;
    s = s + v[nod].size();
    viz[nod] = 1;
    for(auto it : v[nod])
        if(!viz[it])
            _fill_(it);
    return;
}

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        int x, y;
        cin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(int i = 1; i <= n; i++)
    {
        s = 0;
        nrnod = 0;
        if(!viz[i])
        {
            _fill_(i);
            if(s != 1LL * nrnod * (nrnod - 1) / 2 && nrnod != 1)
            {
                cout << "NO";
                return 0;
            }
        }
    }
    cout << "YES";
    return 0;
}


#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
const int maxn = 150005;
bitset <maxn> viz;
vector <int> v[maxn];

int s = 0;
int nrnod = 0;
void _fill_(int nod)
{
    nrnod++;
    s = s + v[nod].size();
    viz[nod] = 1;
    for(auto it : v[nod])
        if(!viz[it])
            _fill_(it);
    return;
}

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        int x, y;
        cin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(int i = 1; i <= n; i++)
    {
        s = 0;
        nrnod = 0;
        if(!viz[i])
        {
            _fill_(i);
            if(1LL * s * (s + 1) == 1LL * nrnod * (nrnod - 1) / 2)
            {
                cout << "YES";
                return 0;
            }
        }
    }
    cout << "NO";
    return 0;
}


#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
const int maxn = 150005;
bitset <maxn> viz;
vector <int> v[maxn];

long long s = 0;
long long nrnod = 0;
void _fill_(int nod)
{
    nrnod++;
    s = s + v[nod].size();
    viz[nod] = 1;
    for(auto it : v[nod])
        if(!viz[it])
            _fill_(it);
    return;
}

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        int x, y;
        cin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(int i = 1; i <= n; i++)
    {
        s = 0;
        nrnod = 0;
        if(!viz[i])
        {
            _fill_(i);
            if(s != 1LL * nrnod * (nrnod - 1) / 2)
            {
                cout << "NO";
                return 0;
            }
        }
    }
    cout << "YES";
    return 0;
}


#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
const int maxn = 150005;
bitset <maxn> viz;
vector <int> v[maxn];

int s = 0;
int nrnod = 0;
void _fill_(int nod)
{
    nrnod++;
    s = s + v[nod].size();
    viz[nod] = 1;
    for(auto it : v[nod])
        if(!viz[it])
            _fill_(it);
    return;
}

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        int x, y;
        cin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(int i = 1; i <= n; i++)
    {
        s = 0;
        nrnod = 0;
        if(!viz[i])
        {
            _fill_(i);
            if(s == 1LL * nrnod * (nrnod - 1) / 2)
            {
                cout << "YES";
                return 0;
            }
        }
    }
    cout << "NO";
    return 0;
}


#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
const int maxn = 150005;
bitset <maxn> viz;
vector <int> v[maxn];

long long s = 0;
int nrnod = 0;
void _fill_(int nod)
{
    nrnod++;
    s = s + v[nod].size();
    viz[nod] = 1;
    for(auto it : v[nod])
        if(!viz[it])
            _fill_(it);
    return;
}

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        int x, y;
        cin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(int i = 1; i <= n; i++)
    {
        s = 0;
        nrnod = 0;
        if(!viz[i])
        {
            _fill_(i);
            if(s != 1LL * nrnod * (nrnod - 1))
            {
                cout << "NO";
                return 0;
            }
        }
    }
    cout << "YES";
    return 0;
}


#include<iostream>
using namespace std;
const int MAX=1.5e5+7;
int n,m;
int pre[MAX],a[MAX],b[MAX],c[MAX]={0},d[MAX]={0},e[MAX]={0};
int find(int x)
{
	int r=x;
	while(pre[r]!=r)
	r=pre[r];
	int i=x,j;
	while(r!=i)
	{
		j=pre[i];
		pre[i]=r;
		i=j;
	}
	return r;
}
int main()
{
#ifdef AC
	freopen("data.txt", "r", stdin);
#endif
	cin>>n>>m;

	// add
	for(int i = 1; i <= n; i++) pre[i] = i;
	for(int i = 1; i <= n; i++) d[i] = 1, e[i] = 0;
	// d[i]代表这个集合中的点数，e[i]代表这个集合中的边数
	// 初始时有n个点，没有边，相当于每个点独立
	//

	for(int i=0;i<m;i++)
	{
		// 这里不需要用数组存储两个点，每次直接把信息用并查集维护起来就行
		// scanf("%d %d",&a[i], &b[i]);
		int x, y;
		scanf("%d %d",&x, &y);

		//add
		x = find(x);
		y = find(y);
		//

		if(x!=y)
		{
			// 把y接到x下面,并且把y上的e[y]和d[y]都迁移到e[x]和d[x]上
			// 相当于合并两个集合
			pre[y] = x;
			e[x] += e[y] + 1; e[y] = 0;
			d[x] += d[y]; d[y] = 0;
			//printf("e[%d]=%d\n", x, e[x]);
			//printf("d[%d]=%d\n", x, d[x]);
			//

		} // add
		else e[x]++;

		//
	}
	bool flag=1;
	for(int i=1;i<=n;i++)
	{
		//printf("%d %d\n", e[i], d[i]);
		if(d[i] && e[i]!=(d[i]-1)*d[i]/2) {flag=0;break;}
	}
	if(flag) cout<<"YES"<<endl;
	else cout<<"NO"<<endl;
	return 0;
}


#include<iostream>
using namespace std;
const int MAX=1.5e5+7;
int n,m;
long long pre[MAX],a[MAX],b[MAX],c[MAX]={0},d[MAX]={0},e[MAX]={0};
int find(int x)
{
	int r=x;
	while(pre[r]!=r)
	r=pre[r];
	int i=x,j;
	while(r!=i)
	{
		j=pre[i];
		pre[i]=r;
		i=j;
	}
	return r;
}
int main()
{
#ifdef AC
	freopen("data.txt", "r", stdin);
#endif
	cin>>n>>m;

	// add
	for(int i = 1; i <= n; i++) pre[i] = i;
	for(int i = 1; i <= n; i++) d[i] = 1, e[i] = 0;
	// d[i]代表这个集合中的点数，e[i]代表这个集合中的边数
	// 初始时有n个点，没有边，相当于每个点独立
	//

	for(int i=0;i<m;i++)
	{
		// 这里不需要用数组存储两个点，每次直接把信息用并查集维护起来就行
		// scanf("%d %d",&a[i], &b[i]);
		int x, y;
		scanf("%d %d",&x, &y);

		//add
		x = find(x);
		y = find(y);
		//

		if(x!=y)
		{
			// 把y接到x下面,并且把y上的e[y]和d[y]都迁移到e[x]和d[x]上
			// 相当于合并两个集合
			pre[y] = x;
			e[x] += e[y] + 1; e[y] = 0;
			d[x] += d[y]; d[y] = 0;
			//printf("e[%d]=%d\n", x, e[x]);
			//printf("d[%d]=%d\n", x, d[x]);
			//

		} // add
		else e[x]++;

		//
	}
	bool flag=1;
	for(int i=1;i<=n;i++)
	{
		//printf("%d %d\n", e[i], d[i]);
		if(d[i] && e[i]!=(d[i]-1)*d[i]/2) {flag=0;break;}
	}
	if(flag) cout<<"YES"<<endl;
	else cout<<"NO"<<endl;
	return 0;
}


// http://codeforces.com/problemset/problem/771/A
#include<bits/stdc++.h>
using namespace std;
#define clr(a, b) memset(a, b, sizeof(a))
typedef long long ll;
typedef pair<int, int> P;

const int maxn = 2e5;
vector<int> g[maxn];
int n, m, vis[maxn];
ll x, y;

void dfs(int t) {
	vis[t] = true;
	x += g[t].size();
	y ++;
	for (auto v : g[t]) {
		if (vis[v]) continue;
		dfs(v);
	}
}

void solve() {
	for (int i = 1; i <= n; i++) {
		if (vis[i]) continue;
		x = y = 0;
		dfs(i);
		if (x != y * (y - 1) / 2) {
			puts("NO");
			return;
		}
	}
	puts("YES");
}

int main() {
#ifdef AC
	freopen("data.txt", "r", stdin);
#endif
	int u, v;
	while (scanf("%d%d", &n, &m) != EOF) {
		for (int i = 1; i <= n; i++) g[i].clear();
		clr(vis, 0);

		for (int i = 0; i < m; i++) {
			scanf("%d%d", &u, &v);
			g[u].push_back(v);
			g[v].push_back(u);
		}
		solve();
	}

	return 0;
}


// http://codeforces.com/problemset/problem/771/A
#include<bits/stdc++.h>
using namespace std;
#define clr(a, b) memset(a, b, sizeof(a))
typedef long long ll;
typedef pair<int, int> P;

const int maxn = 2e5;
vector<int> g[maxn];
int n, m, vis[maxn];
ll x, y;

void dfs(int t) {
	vis[t] = true;
	x += g[t].size();
	y ++;
	for (auto v : g[t]) {
		if (vis[v]) continue;
		dfs(v);
	}
}

void solve() {
	for (int i = 1; i <= n; i++) {
		if (vis[i]) continue;
		x = y = 0;
		dfs(i);
		if (x != y * (y - 1)){
			//printf("%lld %lld\n", x, y);
			puts("NO");
			return;
		}
	}
	puts("YES");
}

int main() {
#ifdef AC
	freopen("data.txt", "r", stdin);
#endif
	int u, v;
	while (scanf("%d%d", &n, &m) != EOF) {
		for (int i = 1; i <= n; i++) g[i].clear();
		clr(vis, 0);

		for (int i = 0; i < m; i++) {
			scanf("%d%d", &u, &v);
			g[u].push_back(v);
			g[v].push_back(u);
		}
		solve();
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxn=100;

void dfs(int r, vector<int>& vis , vector<int> g [],int & s1, int & s2){
	vis[r]=1;

	for(int v:g[r]){
		s2++;
		if(!vis[v]){
			dfs(v,vis,g,s1,s2);
		}
	}

	s1++;
}

int main(void){
	vector<int> g[maxn];
	vector<int> vis;
	int n , m;
	int possible=1;

	cin >> n >> m ;

	for(int i=0;i<m;i++){
		int u ,v;

		cin >> u >>v;

		u--;
		v--;

		g[u].push_back(v);
		g[v].push_back(u);
	}

	/*
	for(int i=0;i<n;i++){
		cout << i+1<<":";
		for(int j:g[i]){
			cout << j+1 << " ";
		}
		cout << endl;
	}
	*/

	vis.assign(n,0);

	int s1=0,s2=0;

	for(int i=0;i<n;i++){
		s1=0;
		s2=0;
		if(!vis[i]){
			dfs(i, vis,g,s1,s2);
			if(s1>=3){
				if((s1*(s1-1))!=s2){
					possible=0;
				}
			}
		}
	}

	if(possible){
		cout <<"YES"<< endl;
	}else{
		cout <<"NO"<< endl;
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxn=1e6;

void dfs(int r, vector<int>& vis , vector<int> g [],int & s1, int & s2){
	vis[r]=1;

	for(int v:g[r]){
		s2++;
		if(!vis[v]){
			dfs(v,vis,g,s1,s2);
		}
	}

	s1++;
}

int main(void){
	vector<int> g[maxn];
	vector<int> vis;
	int n , m;
	int possible=1;

	cin >> n >> m ;

	for(int i=0;i<m;i++){
		int u ,v;

		cin >> u >>v;

		u--;
		v--;

		g[u].push_back(v);
		g[v].push_back(u);
	}

	/*
	for(int i=0;i<n;i++){
		cout << i+1<<":";
		for(int j:g[i]){
			cout << j+1 << " ";
		}
		cout << endl;
	}
	*/

	vis.assign(n,0);

	int s1=0,s2=0;

	for(int i=0;i<n;i++){
		s1=0;
		s2=0;
		if(!vis[i]){
			dfs(i, vis,g,s1,s2);
			if(s1>=3){
				if((s1*(s1-1))!=s2){
					possible=0;
				}
			}
		}
	}

	if(possible){
		cout <<"YES"<< endl;
	}else{
		cout <<"NO"<< endl;
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxn=1e6;

void dfs(int r, vector<int>& vis , vector<int> g [],int & s1, int & s2){
	vis[r]=1;

	for(int v:g[r]){
		s2++;
		if(!vis[v]){
			dfs(v,vis,g,s1,s2);
		}
	}

	s1++;
}

int main(void){
	vector<int> g[maxn];
	vector<int> vis;
	int n , m;
	int possible=1;

	cin >> n >> m ;

	for(int i=0;i<m;i++){
		int u ,v;

		cin >> u >>v;

		u--;
		v--;

		g[u].push_back(v);
		g[v].push_back(u);
	}

	/*
	for(int i=0;i<n;i++){
		cout << i+1<<":";
		for(int j:g[i]){
			cout << j+1 << " ";
		}
		cout << endl;
	}
	*/

	vis.assign(n,0);

	long long int s1=0,s2=0;

	for(int i=0;i<n;i++){
		s1=0;
		s2=0;
		if(!vis[i]){
			dfs(i, vis,g,s1,s2);
			if(s1>=3){
				long long mult;
				mult=s1*(s1-1);
				if(mult!=s2){
					possible=0;
				}
			}
		}
	}

	if(possible){
		cout <<"YES"<< endl;
	}else{
		cout <<"NO"<< endl;
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxn=1e6;

void dfs(int r, vector<int>& vis , vector<int> g [],long long int & s1,long long  int & s2){
	vis[r]=1;

	for(int v:g[r]){
		s2++;
		if(!vis[v]){
			dfs(v,vis,g,s1,s2);
		}
	}

	s1++;
}

int main(void){
	vector<int> g[maxn];
	vector<int> vis;
	int n , m;
	int possible=1;

	cin >> n >> m ;

	for(int i=0;i<m;i++){
		int u ,v;

		cin >> u >>v;

		u--;
		v--;

		g[u].push_back(v);
		g[v].push_back(u);
	}

	/*
	for(int i=0;i<n;i++){
		cout << i+1<<":";
		for(int j:g[i]){
			cout << j+1 << " ";
		}
		cout << endl;
	}
	*/

	vis.assign(n,0);

	long long int s1=0,s2=0;

	for(int i=0;i<n;i++){
		s1=0;
		s2=0;
		if(!vis[i]){
			dfs(i, vis,g,s1,s2);
			if(s1>=3){
				long long int  mult;
				mult=s1*(s1-1);
				if(mult!=s2){
					possible=0;
				}
			}
		}
	}

	if(possible){
		cout <<"YES"<< endl;
	}else{
		cout <<"NO"<< endl;
	}

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define inputInt(a) scanf("%d", &a)
#define inputStr(a) getline(cin, a)
#define inputLong(a) scanf("%I64d", &a)
#define clr(a) memset(a, 0, sizeof(a))
#define printn(a) cout<<a<<"\n"
#define print(a) cout<<a

int const N = 150000+10;
int parent[N];
vector<int>graph[N];
bool used[N];
int edge;
int node;
int calculated_edge;

void dfs(int u)
{
	used[u] = 1;
	node++;

	for(int v: graph[u])
	{
		edge++;

		if(!used[v])
		{
			dfs(v);
		}
	}
}

int main()
{
	#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	#endif

	int n,m,u,v;
	cin>>n>>m;

	for(int i=0;i<m;i++)
	{
		cin>>u>>v;
		graph[u].push_back(v);
		graph[v].push_back(u);
	}

	for(int i=1;i<=n;i++)
	{
		if(!used[i])
		{
			node = 0;
			edge = 0;
			dfs(i);

			calculated_edge = int(node)*(node-1)/2;
			edge/=2;

			if(edge!=calculated_edge)
			{
				puts("NO");
				return 0;
			}
		}
	}
	printf("YES\n");

  return 0;

}


#include<bits/stdc++.h>

using namespace std;

#define inputInt(a) scanf("%d", &a)
#define inputStr(a) getline(cin, a)
#define inputLong(a) scanf("%I64d", &a)
#define clr(a) memset(a, 0, sizeof(a))
#define printn(a) cout<<a<<"\n"
#define print(a) cout<<a

int const N = 150000+10;
vector<int>graph[N];
bool used[N];
long long calculated_edge,edge,node;

void dfs(int u)
{
	used[u] = 1;
	node++;

	for(int v: graph[u])
	{
		edge++;

		if(!used[v])
		{
			dfs(v);
		}
	}
}

int main()
{
	#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	#endif

	int n,m,u,v;
	cin>>n>>m;

	for(int i=0;i<m;i++)
	{
		cin>>u>>v;
		graph[u].push_back(v);
		graph[v].push_back(u);
	}

	for(int i=1;i<=n;i++)
	{
		if(!used[i])
		{
			node = 0;
			edge = 0;
			dfs(i);

			calculated_edge = (long long) (node*(node-1)/2);
			edge/=2;

			if(edge!=calculated_edge)
			{
				puts("NO");
				return 0;
			}
		}
	}
	printf("YES\n");

  return 0;

}


#include<bits/stdc++.h>

using namespace std;

#define inputInt(a) scanf("%d", &a)
#define inputStr(a) getline(cin, a)
#define inputLong(a) scanf("%I64d", &a)
#define clr(a) memset(a, 0, sizeof(a))
#define printn(a) cout<<a<<"\n"
#define print(a) cout<<a

int const N = 150000+10;
vector<int>graph[N];
bool used[N];
long long calculated_edge,edge,node;

void dfs(int u)
{
	used[u] = 1;
	node++;

	for(int v: graph[u])
	{
		edge++;

		if(!used[v])
		{
			dfs(v);
		}
	}
}

int main()
{
	#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	#endif

	int n,m,u,v;
	cin>>n>>m;

	for(int i=0;i<m;i++)
	{
		cin>>u>>v;
		graph[u].push_back(v);
		graph[v].push_back(u);
	}

	for(int i=1;i<=n;i++)
	{
		if(!used[i])
		{
			node = 0;
			edge = 0;
			dfs(i);

			calculated_edge = long long(node)*(node-1)/2;
			edge/=2;

			if(edge!=calculated_edge)
			{
				puts("NO");
				return 0;
			}
		}
	}
	printf("YES\n");

  return 0;

}


#include<bits/stdc++.h>

using namespace std;

#define inputInt(a) scanf("%d", &a)
#define inputStr(a) getline(cin, a)
#define inputLong(a) scanf("%I64d", &a)
#define clr(a) memset(a, 0, sizeof(a))
#define printn(a) cout<<a<<"\n"
#define print(a) cout<<a

int const N = 150000+10;
int parent[N];
vector<int>graph[N];
bool used[N];
int edge;
int node;
int calculated_edge;

void dfs(int u)
{
	used[u] = 1;
	node++;

	for(int v: graph[u])
	{
		edge++;

		if(!used[v])
		{
			dfs(v);
		}
	}
}

int main()
{
	#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	#endif

	int n,m,u,v;
	cin>>n>>m;

	for(int i=0;i<m;i++)
	{
		cin>>u>>v;
		graph[u].push_back(v);
		graph[v].push_back(u);
	}

	for(int i=1;i<=n;i++)
	{
		if(!used[i])
		{
			node = 0;
			edge = 0;
			dfs(i);

			calculated_edge = int(node)*(node-1)/2;
			edge/=2;

			if(edge!=calculated_edge)
			{
				puts("NO");
				return 0;
			}
		}
	}
	puts("YES");

  return 0;

}


#include <bits/stdc++.h>
using namespace std;
int visited[150010]={0};
vector<int>a[150010];
int ct=0;
int dfs(int i,int si)
{
    //cout<<i<<" ";
    visited[i]=1;
    int siz=a[i].size();
    for(int i1=0;i1<siz;i1++)
    {
        if(visited[a[i][i1]]==0){
        if(a[a[i][i1]].size()!=si)
        {
        cout<<"NO"<<endl;
        exit(0);
        }
        ct++;
        dfs(a[i][i1],a[a[i][i1]].size());}
    }
return ct;
}
main()
{
    int n,m,i,x,y,cou,flag=0;
    scanf("%d%d",&n,&m);
    for(i=0;i<m;i++)
    {
        cin>>x>>y;
        a[x].push_back(y);
        a[y].push_back(x);
    }
    for(i=1;i<=n;i++)
    {
        int si=a[i].size();
        ct=1;
        if(visited[i]==0)
        {
           // cout<<i<<endl;
        cou=dfs(i,si);
        //cout<<cou<<" "<<si<<endl;
        if(cou==1||cou==2)
        continue;
        else if(cou!=((si+1)*si)/2)
        {
        cout<<"NO"<<endl;
        exit(0);
        }
        }
    }
        cout<<"YES"<<endl;
}


#include <bits/stdc++.h>
using namespace std;
int visited[150010]={0};
vector<int>a[150010];
int ct=1;
int dfs(int i,int si)
{
    //cout<<i<<" ";
    visited[i]=1;
    int siz=a[i].size();
    for(int i1=0;i1<siz;i1++)
    {
        if(visited[a[i][i1]]==0){
        if(a[a[i][i1]].size()!=si)
        {
        cout<<"NO"<<endl;
        exit(0);
        }
        ct++;
        dfs(a[i][i1],a[a[i][i1]].size());}
    }
return ct;
}
main()
{
    int n,m,i,x,y,cou,flag=0;
    scanf("%d%d",&n,&m);
    for(i=0;i<m;i++)
    {
        cin>>x>>y;
        a[x].push_back(y);
        a[y].push_back(x);
    }
    for(i=1;i<=n;i++)
    {
        int si=a[i].size();
        ct=1;
        if(visited[i]==0)
        {
        cou=dfs(i,si);
        if(cou>2&&cou!=((si+1)*si)/2)
        {
        cout<<"NO"<<endl;
        exit(0);
        }
        }
    }
        cout<<"YES"<<endl;
}