#include <cstdio>
#include <algorithm>
using namespace std;
#define ll long long

ll n; bool flag;
ll ans1; ll ans2;

int main(){
	scanf("%lld",&n);
	for(ll i=6;i>=0;--i){
		ll tmp=i*4;
		if(tmp>n) continue;
		if((n-tmp)%7==0){
			flag=true;
			ans1=i; ans2=(n-tmp)/7;
		}
	}
	if(!flag){
		printf("-1\n");
	}
	else{
		for(ll i=1;i<=ans1;++i) printf("4");
		for(ll i=1;i<=ans2;++i) printf("7");
		printf("\n");
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n/4;i++){
		int s=n-i*4;
		if(s%7==0){
			for(int j=1;j<=i;j++){
				cout<<4;
			}
			for(int j=1;j<=s/7;j++){
				cout<<7;
			}
			return 0;
		}
	}
	cout<<-1;
	return 0;
}


#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
#include<stdio.h>
#include<cstdio>
using namespace std;
int main()
{
int a,n,i,j,flag=333;
cin>>n;
a=n/4;
for(i=0;i<=a;i++)
{
	if((n-i*4)%7==0)
	{
	 for(j=1;j<=i;j++)
	 cout<<"4";
	 for(j=1;j<=(n-i*4)/7;j++)
	 cout<<"7";
	flag=0;
	break;
    }
}
if(flag!=0)
cout<<"-1";
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n/7;i++){
		int s=n-i*4;
		if(s%7==0){
			for(int j=1;j<=i;j++){
				cout<<4;
			}
			for(int j=1;j<=s/7;j++){
				cout<<7;
			}
			return 0;
		}
	}
	cout<<-1;
	return 0;
}


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

int n;
int a[]={1,2,3,5,6,9,10,13,17};
int s4, s7;
int main ( ) {
	cin>>n;
	for( int i = 0 ; i <= 8 ; i++)
		if(a[i] == n){
			cout<<-1;
			return 0;
		}
	while(1){
		if(n%4 != 0){
			n -= 7;
			s7++;
		}
		else{
			s4 = n / 4;
			break;
		}
	}
	for(int i = 1 ; i <= s4 ;i++)
		cout<<4;
	for(int i = 1 ; i <= s7 ;i++)
		cout<<7;
	cout<<endl;
	return 0;
}


#include<iostream>
using namespace std;
int h[100000],s=0;
int su(int x)
{
	int ans=0;
	while(x)
	{
		ans+=x%10;
		x/=10;
	}
	return ans;
}
void fun(int x)
{
	int a=x*10+4;
	int b=x*10+7;
	h[s++]=a;
	h[s++]=b;
	if(a<=10e+6)
	{
		fun(a);
		fun(b);
	}
}
int main(void)
{
	fun(0);
	int n,sum=0;
	cin>>n;
	for(int i=0;sum<=n;i++)
	{
		sum=su(h[i]);
		if(sum==n)
		{
			cout<<h[i];
			return 0;
		}
	}
	cout<<"-1";
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	long n,i,x;
	cin>>n;
     if(n%7!=4&&n%11!=7){cout<<-1<<endl;return 0;}
      for(i=n/4;i>=1;i--)
      	if ((n-i*4)%7==0)
      	{
      	x=i;
		  break;
		}
		for(i=1;i<=x;i++)cout<<4;
		  n-=x*4;
		  for(i=1;i<=n/7;i++)
		  cout<<7;
		cout<<"\n";
     return 0;
}


#include<iostream>
using namespace std;
int main()
{
    int x,y,i,n;
    cin>>n;
    for(y=n/7;y>=0;y--)
    {
        if((x-7*y)%4==0)
        {
            x=(x-7*y)/4;
            for(i=0;i<x;i++)
            {
                cout<<4;
            }
            for(i=0;i<y;i++)
            {
                cout<<7;
            }
            return 0;
        }
    }
    cout<<-1;
return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n;
int cnt=4,a;
int flag;
bool check(int x){
	int s=0;
	while(x>0){
		if(x%10!=4&&x%10!=7){
			return false;
		}
		s+=x%10;
		x/=10;
	}
	if(s==n) return true;
	return false;
}
int k;
int main(){
	scanf("%d",&n);
	int x=n;
	while(x-4>0){
		x-=4;
		a+=cnt;
		cnt*=10;
		k++;
	}
	cnt=1;
	while(k>0){
		if(check(a)){
			printf("%d",a);
			return 0;
		}
		k--;
		a-=cnt*4;
		a+=cnt*7;
		cnt*=10;
	}
	printf("%d",-1);

	return 0;
}


#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int n,i,j,t;
	bool b;
	cin>>n;
	b=0;
	for(i=1;i<=n/4;i++)
	{
		t=n-i*4;
		if(t%7==0)
		{
			b=1;
			for(j=1;j<=i;j++)
			{
				cout<<"4";
			}
			for(j=1;j<=t/7;j++)
			{
				cout<<"7";
			}
			cout<<endl;
			break;
		}
	}
	if(b==0)
		cout<<"-1"<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main() {
	int n,s=0;
	cin>>n;
	while(!(n%4==0&&n<28)&&n-7>=0) {
		n-=7;
		s++;
	}
	if(n%4!=0) {
		cout<<"-1";
		return 0;
	}
	for(int i=1;i<=n/4;i++)cout<<"4";
	for(int i=1;i<=s;i++)cout<<"7";
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespac#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int main()
{
	cin >> n;
	int ans, num;
	for (int i = 1; i <= n / 4; i++)
	{
		ans = i * 4;
		num = n - ans;
		if(num % 7 == 0)
		{
			for (int j = 0; j < i; j++)
				cout << "4";
			num /= 7;
			for (int j = 0; j < num; j++)
				cout << "7";
			return 0;
		}
	}
	cout << "-1" << endl;
	return 0;
}
e std;
int n;
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
		for (int j = 0; j <= n; j++)
		{
			if (4 * i + j * 7 == n)
			{
				for (int k = 0; k < i; k++)
					cout << "4";
				for (int l = 0; l < j; l++)
					cout << "7";
				cout << endl;
				return 0;
			}
		}
	cout << "-1" << endl;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int main()
{
	cin >> n;
	for (int i = 0; i <= n; i++)
		for (int j = 0; j <= n; j++)
		{
			if (4 * i + j * 7 == n)
			{
				for (int k = 0; k < i; k++)
					cout << "4";
				for (int l = 0; l < j; l++)
					cout << "7";
				cout << endl;
				return 0;
			}
		}
	cout << "-1" << endl;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
		for (int j = 0; j <= n; j++)
		{
			if (4 * i + j * 7 == n)
			{
				for (int k = 0; k < i; k++)
					cout << "4";
				for (int l = 0; l < j; l++)
					cout << "7";
				cout << endl;
				return 0;
			}
		}
	cout << "-1" << endl;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int main()
{
	cin >> n;
	int ans, num;
	for (int i = 0; i <= n / 4; i++)
	{
		ans = i * 4;
		num = n - ans;
		if(num % 7 == 0)
		{
			for (int j = 0; j < i; j++)
				cout << "4";
			num /= 7;
			for (int j = 0; j < num; j++)
				cout << "7";
			return 0;
		}
	}
	cout << "-1" << endl;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int main()
{
	cin >> n;
	int ans, num;
	for (int i = 1; i <= n / 4; i++)
	{
		ans = i * 4;
		num = n - ans;
		if(num % 7 == 0)
		{
			for (int j = 0; j < i; j++)
				cout << "4";
			num /= 7;
			for (int j = 0; j < num; j++)
				cout << "7";
			return 0;
		}
	}
	cout << "-1" << endl;
	return 0;
}


#include <iostream>
using namespace std;

int main() {
	int n, a = 0, b = 0;
	cin >> n;
	for (int i = 0; i <= 1000000; i++)
	{
		if ( (n-i*7)%4 == 0 ){
			a = i;
			b = (n-i*7)/4;
			break;
		}
	}
	if ((!a && !b) || a < 0 || b < 0) cout << -1;
	else {
		for (int i = 0; i < b; i++)cout << 4;
		for (int i = 0; i < a; i++)cout << 7;
	}

	return 0;
}


#include <iostream>
using namespace std;

int main() {
	int n, a = 0, b = 0;
	cin >> n;
	for (int i = 1; i <= 1000000; i++)
	{
		if ( (n-i*7)%4 == 0 ){
			a = i;
			b = (n-i*7)/4;
			break;
		}
	}
	if (a < 0 || b < 0) cout << -1;
	else {
		for (int i = 0; i < b; i++)cout << 4;
		for (int i = 0; i < a; i++)cout << 7;
	}

	return 0;
}


#include<bits/stdc++.h>
#define all(s) s.begin(), s.end()
#define pb push_back
#define pf push_front
#define mp make_pair
#define ins insert
#define ll long long
#define ull unsigned long long
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);
#define F first
#define S second
#define sz size()
using namespace std;

int main () {
	int a,c = 0,d = 0,r = 0;
	cin >> a;
	vector<pair<int,pair<int,int> > >v;
	for(int i = 0; i <= 1000; i++){
		for(int j = 0; j <= 1000; j++){
			if(i * 4 + j * 7 == a){
				c = i;
				d = j;
				r = i + j;
				v.pb( mp( r, mp(c, d)));
			}
		}
	}
	if(c == 0 && d == 0){

	cout << -1;
	return 0;
	}
	sort(all(v));
	c = v[0].S.F;
	d = v[0].S.S;
		for(int i = 1; i <= c; i++)
		cout << 4;
		for(int i = 1; i <= d; i++)
		cout << 7;

	return 0;
}
/*
24 -298
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

Press any key to continue . . .
*/


#include<bits/stdc++.h>
#define all(s) s.begin(), s.end()
#define pb push_back
#define pf push_front
#define mp make_pair
#define ins insert
#define ll long long
#define ull unsigned long long
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);
#define F first
#define S second
#define sz size()
using namespace std;

int main () {
	int a,c = 0,d = 0,r = 0;
	cin >> a;
	vector<pair<int,pair<int,int> > >v;
	for(int i = 0; i * 4 <= a; i++){
			if((a - (i * 4) ) % 7 == 0){
				c = i;
				d = (a - (i * 4) ) / 7;
				r = c + d;
				v.pb( mp( r, mp(c, d)));

		}
	}
	if(c == 0 && d == 0){
	    cout << -1;
    	return 0;
	}
	sort(all(v));
	c = v[0].S.F;
	d = v[0].S.S;
		for(int i = 1; i <= c; i++)
		cout << 4;
		for(int i = 1; i <= d; i++)
		cout << 7;

	return 0;
}


#include<bits/stdc++.h>
#define all(s) s.begin(), s.end()
#define pb push_back
#define pf push_front
#define mp make_pair
#define ins insert
#define ll long long
#define ull unsigned long long
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);
#define F first
#define S second
#define sz size()
using namespace std;

int main () {
	int a,c = 0,d = 0;
	cin >> a;
	for(int i = 1; i <= 100; i++){
		for(int j = 1; j <= 100; j++){
			if(i * 4 + j * 7 == a){
				c = i;
				d = j;
				break;
			}
		}
	}
	if(c == 0 && d == 0)
	cout << -1;
	else{
		for(int i = 1; i <= c; i++)
		cout << 4;
		for(int i = 1; i <= d; i++)
		cout << 7;
	}
	return 0;
}
/*
24 -298
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

Press any key to continue . . .
*/


#include<bits/stdc++.h>
#define all(s) s.begin(), s.end()
#define pb push_back
#define pf push_front
#define mp make_pair
#define ins insert
#define ll long long
#define ull unsigned long long
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);
#define F first
#define S second
#define sz size()
using namespace std;

int main () {
	int a,c = 0,d = 0,r = 0;
	cin >> a;
	vector<pair<int,pair<int,int> > >v;
	for(int i = 0; i <= 100; i++){
		for(int j = 0; j <= 100; j++){
			if(i * 4 + j * 7 == a){
				c = i;
				d = j;
				r = i + j;
				v.pb( mp( r, mp(c, d)));
			}
		}
	}
	if(c == 0 && d == 0){

	cout << -1;
	return 0;
	}
	sort(all(v));
	c = v[0].S.F;
	d = v[0].S.S;
		for(int i = 1; i <= c; i++)
		cout << 4;
		for(int i = 1; i <= d; i++)
		cout << 7;

	return 0;
}
/*
24 -298
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

Press any key to continue . . .
*/


#include<bits/stdc++.h>
#define all(s) s.begin(), s.end()
#define pb push_back
#define pf push_front
#define mp make_pair
#define ins insert
#define ll long long
#define ull unsigned long long
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);
#define F first
#define S second
#define sz size()
using namespace std;

int main () {
	int a,c = 0,d = 0,r = 0;
	cin >> a;
	vector<pair<int,pair<int,int> > >v;
	for(int i = 1; i <= 100; i++){
		for(int j = 1; j <= 100; j++){
			if(i * 4 + j * 7 == a){
				c = i;
				d = j;
				r = i + j;
				v.pb( mp( r, mp(c, d)));
			}
		}
	}
	if(c == 0 && d == 0){

	cout << -1;
	return 0;
	}
	sort(all(v));
	c = v[0].S.F;
	d = v[0].S.S;
		for(int i = 1; i <= c; i++)
		cout << 4;
		for(int i = 1; i <= d; i++)
		cout << 7;

	return 0;
}
/*
24 -298
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

Press any key to continue . . .
*/


#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n;cin>>n;
    int a=0,i=0;
    for(int b=1;b<1000;b++)
    {
        if(((float)n-7*b)/4==(n-7*b)/4&&(n-7*b)/4>a){
            a=(n-7*b)/4;
            i=b;
        }
    }
    for(int b=0;b<a;b++)
        cout<<4;
    for(int b=0;b<i;b++)
        cout<<7;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n;cin>>n;
    int a=1000000,i=0,j=0;
    for(int b=1;b<=n;b++)
    {
        if(n-7*b>0&&(float)(n-7*b)/4==(n-7*b)/4){
            a=(n-7*b)/4;
            i=b;
            j=1;
        }
    }
    for(int b=0;b<a;b++)
        cout<<4;
    for(int b=0;b<i;b++)
        cout<<7;
    if(j==0)
        cout<<-1;
    return 0;
}


//
//  main.cpp
//  cf_109_a
//
//  Created by Sidharth Raja on 04/09/15.
//  Copyright (c) 2015 Sidharth Raja. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <stack>
#include <queue>

#define LL long long
#define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair

using namespace std;

struct cmp
{
    bool operator()(const pair<int,string> &p1, const pair<int,string> &p2)
    {
        return p1.first>p2.first;
    }
};
int main(int argc, const char * argv[]) {
    int n,flag=0;
    string ans,s;
    int k;
    cin>>n;

    priority_queue<pair<int,string>,vector<pair<int,string> >, cmp> q;
    q.push(mp(4,"4"));
    q.push(mp(7,"7"));

    while (1)
    {
        s = q.top().second;
        k = q.top().first;
//        cout<<s<<"\n";
        if (k>n)
            break;
        if (k == n)
        {
            ans = s;
            flag = 1;
            break;
        }

        q.push(mp(k+4,"4"+s));
        q.push(mp(k+7,"7"+s));
        q.pop();
    }

    if (flag)
    {
        reverse(ans.begin(),ans.end());
        cout<<ans;
    }
    else
        cout<<"-1";
    return 0;
}


//
//  main.cpp
//  cf_109_a
//
//  Created by Sidharth Raja on 04/09/15.
//  Copyright (c) 2015 Sidharth Raja. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <stack>
#include <queue>

#define LL long long
#define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair

using namespace std;

int main(int argc, const char * argv[]) {
    int n,flag=0;
    string ans;
    cin>>n;

    queue<pair<string,int> > q;
    q.push(mp("4",4));
    q.push(mp("7",7));

    while (1)
    {
        if (q.front().second + 4 > n)
            break;

        if (q.front().second + 4 == n)
        {
            ans = "4"+q.front().first;
            flag = 1;
            break;
        }
        if (q.front().second + 7 == n)
        {
            ans = "7"+q.front().first;
            flag = 1;
            break;
        }

        q.push(mp("4"+q.front().first,q.front().second + 4));
        q.push(mp("7"+q.front().first,q.front().second + 7));
        q.pop();
    }

    if (flag)
    {
        reverse(ans.begin(),ans.end());
        cout<<ans;
    }
    else
        cout<<"-1";
    return 0;
}


//
//  main.cpp
//  cf_109_a
//
//  Created by Sidharth Raja on 04/09/15.
//  Copyright (c) 2015 Sidharth Raja. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <stack>
#include <queue>

#define LL long long
#define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair

using namespace std;
int main(int argc, const char * argv[]) {
    int n,t,four=0,seven=0;
    string ans;
    cin>>n;
    t = n - n%4;

    if (n%4==0)
    {
        ans = string(n/4,'4');
        cout<<ans;
        return 0;
    }

    for (int i=0; i<15; i++)
    {
        t -= 4;
        if (t<0)
            break;
        if ((n-t)%7==0)
        {
            four = t/4;
            seven = (n-t)/7;
            string s1 = string(four,'4')+string(seven,'7');
            cout<<s1;
            return 0;
        }
    }

    cout<<"-1";
    return 0;
}


//
//  main.cpp
//  cf_109_a
//
//  Created by Sidharth Raja on 04/09/15.
//  Copyright (c) 2015 Sidharth Raja. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <stack>
#include <queue>

#define LL long long
#define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair

using namespace std;
int main(int argc, const char * argv[]) {
    int n,t,four=0,seven=0;
    string ans;
    cin>>n;
    t = n - n%7;

    if (n%7==0)
    {
        ans = string(n/7,'7');
        cout<<ans;
        return 0;
    }

    for (int i=0; i<20; i++)
    {
        t -= 7;
        if (t<0)
            break;
        if ((n-t)%4==0)
        {
            four = (n-t)/4;
            seven = t/7;
            string s1 = string(four,'4')+string(seven,'7');
            cout<<s1;
            return 0;
        }
    }

    cout<<"-1";
    return 0;
}


//
//  main.cpp
//  cf_109_a
//
//  Created by Sidharth Raja on 04/09/15.
//  Copyright (c) 2015 Sidharth Raja. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <stack>
#include <queue>

#define LL long long
#define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair

using namespace std;
int main(int argc, const char * argv[]) {
    int n,flag=0;
    string ans,s;
    int k;
    cin>>n;

    queue<pair<int,string> > q;
    q.push(mp(4,"4"));
    q.push(mp(7,"7"));

    while (!q.empty())
    {
        s = q.front().second;
        k = q.front().first;
        q.pop();
        if (k>n)
            continue;
        else if (k == n)
        {
            ans = s;
            flag = 1;
            break;
        }
        else
        {
            q.push(mp(k+4,"4"+s));
            q.push(mp(k+7,"7"+s));
        }
    }

    if (flag)
    {
        reverse(ans.begin(),ans.end());
        cout<<ans;
    }
    else
        cout<<"-1";
    return 0;
}


//
//  main.cpp
//  cf_109_a
//
//  Created by Sidharth Raja on 04/09/15.
//  Copyright (c) 2015 Sidharth Raja. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <stack>
#include <queue>

#define LL long long
#define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair

using namespace std;

int main(int argc, const char * argv[]) {
    int n,flag=0;
    string ans;
    cin>>n;

    queue<pair<string,int> > q;
    q.push(mp("4",4));
    q.push(mp("7",7));

    while (1)
    {
        if (q.front().second> n)
            break;
        if (q.front().second == n)
        {
            ans = q.front().first;
            flag = 1;
            break;
        }

        q.push(mp("4"+q.front().first,q.front().second + 4));
        q.push(mp("7"+q.front().first,q.front().second + 7));
        q.pop();
    }

    if (flag)
    {
        reverse(ans.begin(),ans.end());
        cout<<ans;
    }
    else
        cout<<"-1";
    return 0;
}


//
//  main.cpp
//  cf_109_a
//
//  Created by Sidharth Raja on 04/09/15.
//  Copyright (c) 2015 Sidharth Raja. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <stack>
#include <queue>

#define LL long long
#define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair

using namespace std;
int main(int argc, const char * argv[]) {
    int n,t,four=0,seven=0;
    string ans;
    cin>>n;
    t = n - n%7;

    if (n%7==0)
    {
        ans = string(n/7,'7');
        cout<<ans;
        return 0;
    }

    for (int i=0; i<20; i++)
    {
        if (t<0)
            break;
        if ((n-t)%4==0)
        {
            four = (n-t)/4;
            seven = t/7;
            string s1 = string(four,'4')+string(seven,'7');
            cout<<s1;
            return 0;
        }
        t -= 7;
    }

    cout<<"-1";
    return 0;
}


#include <iostream>
using namespace std;

int A[2]={1,0};

int main() {

    long long int sum=4, x, t=1;
    cin>>x;

    bool ok=true;

    while(sum<x+10&&ok){

        if(sum==x){
            ok=false;
            break;
        }
            if(A[0]==0){
                t++;
                A[0]+=t;
                A[1]=0;
            }else{
                A[0]--;
                A[1]++;
            }

        sum=4*A[0]+7*A[1];

        if(sum==x){
            ok=false;
            break;
        }
    }

//  cout<<A[0]<<","<<A[1]<<endl;

    if(!ok){

    for(int i=0; i<A[0]; ++i){
        cout<<4;
    }

    for(int i=0; i<A[1]; ++i){
        cout<<7;
    }

    cout<<endl;

}
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
using namespace std;

int main(){

    long long int x, A[2]={0,0};

    cin>>x;

    if(x==0){
        cout<<-1<<endl;
        return 0;
    }

    if((x%7)%4==0){

//      cout<<1<<endl;

        A[1]=x/7;
        A[0]=(x%7)/4;

        for(long long int i=0; i<A[0]; ++i)
            cout<<4;

        for(long long int i=0; i<A[1]; ++i)
            cout<<7;

        cout<<endl;

        return 0;

    }else if(x%4==0&&x%7!=0){

//      cout<<2<<endl;

        A[0]=x/4;

        while(A[0]>=7){
            A[0]-=7;
            A[1]+=4;
        }

    for(long long int i=0; i<A[0]; ++i)
        cout<<4;
    for(long long int i=0; i<A[1]; ++i)
        cout<<7;

    cout<<endl;

    return 0;

    }else if(x%7==0&&x%4!=0){

//      cout<<3<<endl;

    for(long long int i=0; i<x/7; ++i)
        cout<<7;

    cout<<endl;

    return 0;

    }else if(x%7!=0&&x%4!=0){
        int t=1;
        int sum=4;
        A[0]=1;A[1]=0;
//      bool ok=true;

        while(sum<x+25){

            if(A[0]==0){
                ++t;
                A[0]=t;
                A[1]=0;
            }else{
                A[0]--;
                A[1]++;
            }

            sum=4*A[0]+7*A[1];

            if(sum==x){
                for(int i=0; i<A[0]; ++i)
                    cout<<4;
                for(int i=0; i<A[1]; ++i)
                    cout<<7;

                cout<<endl;
                return 0;
            }
        }

    }

    cout<<-1<<endl;

    return 0;
}


#include <iostream>
using namespace std;

int A[2]={1,0};

int main() {

    long long int sum=4, x, t=1;
    cin>>x;

    bool ok=true;

    while(sum<x+10&&ok){

            if(A[0]==0){
                t++;
                A[0]+=t;
                A[1]=0;
            }else{
                A[0]--;
                A[1]++;
            }

        sum=4*A[0]+7*A[1];

        if(sum==x){
            ok=false;
            break;
        }
    }

//  cout<<A[0]<<","<<A[1]<<endl;

    if(!ok){

    for(int i=0; i<A[0]; ++i){
        cout<<4;
    }

    for(int i=0; i<A[1]; ++i){
        cout<<7;
    }

    cout<<endl;

}
    else cout<<-1<<endl;
    return 0;
}


#include <iostream>
using namespace std;

int main(){

    long long int a=0, b=-1, n;
    cin>>n;

    if(n==0){
        cout<<-1<<endl;
        return 0;
    }

    bool ok=true;

    while(ok&&((b+1)*7<=n)){

        ++b;

        if((n-7*b)%4==0){
            a=(n-7*b)/4;
            ok=false;
            break;
        }
    }

    if(!ok){

    while(a>=7){
        b+=4;
        a-=7;
    }

    for(long long int i=0; i<a; ++i)
        cout<<4;
    for(long long int i=0; i<b; ++i)
        cout<<7;

    cout<<endl;

    return 0;
}
    cout<<-1<<endl;

    return 0;
}


#include <iostream>
using namespace std;

int main(){

    long long int x, A[2]={0,0};

    cin>>x;

    if(x==0){
        cout<<-1<<endl;
        return 0;
    }

    if(x%4==0&&x%7!=0){

    for(long long int i=0; i<x/4; ++i)
        cout<<4;

    cout<<endl;

    return 0;

    }else if(x%7==0&&x%4!=0){

    for(long long int i=0; i<x/7; ++i)
        cout<<7;

    cout<<endl;

    return 0;

    }else if((x%7)%4==0){
        A[0]=(x%7)/4;
        x-=4*A[0];
        A[1]=x/7;

        for(long long int i=0; i<A[0]; ++i)
            cout<<4;

        for(long long int i=0; i<A[1]; ++i)
            cout<<7;

        cout<<endl;

        return 0;

    }

    cout<<-1<<endl;

    return 0;
}


#include <iostream>
using namespace std;

int main(){

    long long int x, A[2]={0,0};

    cin>>x;

    if(x==0){
        cout<<-1<<endl;
        return 0;
    }

    if((x%7)%4==0){

//      cout<<1<<endl;

        A[1]=x/7;
        A[0]=(x%7)/4;

        for(long long int i=0; i<A[0]; ++i)
            cout<<4;

        for(long long int i=0; i<A[1]; ++i)
            cout<<7;

        cout<<endl;

        return 0;

    }else if(x%4==0&&x%7!=0){

//      cout<<2<<endl;

        A[0]=x/4;

        while(A[0]>=7){
            A[0]-=7;
            A[1]+=4;
        }

    for(long long int i=0; i<A[0]; ++i)
        cout<<4;
    for(long long int i=0; i<A[1]; ++i)
        cout<<7;

    cout<<endl;

    return 0;

    }else if(x%7==0&&x%4!=0){

//      cout<<3<<endl;

    for(long long int i=0; i<x/7; ++i)
        cout<<7;

    cout<<endl;

    return 0;

    }

    cout<<-1<<endl;

    return 0;
}


#include <iostream>
using namespace std;

int main(){

    long long int a=0, b=0, n;
    cin>>n;

    bool ok=true;

    while(ok&&((b+1)*7<=n)){

        ++b;

        if((n-7*b)%4==0){
            a=(n-7*b)/4;
            ok=false;
            break;
        }
    }

    if(!ok){

    while(a>=7){
        b+=4;
        a-=7;
    }

    for(long long int i=0; i<a; ++i)
        cout<<4;
    for(long long int i=0; i<b; ++i)
        cout<<7;

    cout<<endl;

    return 0;
}
    cout<<-1<<endl;

    return 0;
}


#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	long long n=0;
	string a;
	cin>>n;
	while (n>=0)
	{
		if (n%7==0)
		{
			a+='7';
			n-=7;
		}
		else
		{
			a+='4';
			n-=4;
		}
		if (n==0)
		{
			break;
		}
	}
	if(n<0)
	{
		cout<<-1;
	}
	else
	{
		cout<<a;
	}
	return 0;
}


#include<iostream>
using namespace std;
int a[100001];
int main(void) { int n;
	cin>>n;
	int x=0,y=0;
	while(1) {
		x++;
		if(x*4>n) {
			x--; break;
		}
	}
	while(1) {
		y++;
		if(y*7>n) {
			y--; break;
		}
	}
	for(int i=1;i<=x;i++) {
		for(int j=1;j<=y;j++) {
			if(i*4+j*7==n) {
				for(int l=1;l<=i;l++) {
					cout<<4;
				}
				for(int k=1;k<=j;k++) {
						cout<<7;
				}
				return 0;
			}
		}
	}
	cout<<"-1";
	return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <cmath>
using namespace std;
int n, ans,f,s,flag;
int main() {
	cin >> n;
	int maxf = n/4+1;
	int maxs = n/7+1;
	for (s = 1; s <= maxs; s++ ) {
		int k = s*7;
		int j = n-k;
		if(j % 4 == 0) {
			f = j / 4;
			flag = 1;
			break;
		}
	}
	if(flag != 1) {
		while(f--) {
			cout << "4";
		}
		while(s--) {
			cout << "7";
		}
	}else {
		cout<<"-1" << endl;
	}

	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n;
void put(int x,int y){
	for(int i=1;i<=y;i++) putchar('4');
	for(int i=1;i<=x;i++) putchar('7');
}
int main()
{
	cin>>n;
	for(int i=n/7;i>=0;i--){
		int j=n-i*7;
		if(j%4==0){
			put(i,j/4);
			return 0;
		}
	}
	cout<<"-1";
}


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

int main()
{
	int n,f=0,s=0;
	cin>>n;
	int ans[n]={100000000000000000};
	int count=0;
	for (int i=0;4*i<n;i++)
	{
		if ((n-4*i)%7==0)
		{
			s=(n-4*i)/7;
			f=i;
			ans[count]=0;
			for (int j=0;j<s+f;j++)
			{
				if (j<f) ans[count]=ans[count]*10+4;
				else ans[count]=ans[count]*10+7;
			}
			count++;
		}
	}
	if (f==0 && s==0)
	{
		cout<<-1<<endl;
		return 0;
	}
	sort (ans,ans+n);
	cout<<ans[0]<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int a;
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	cin>>a;
	for(int i=0;i<=a/4;i++)if((a-i*4)%7==0){
		for(int j=1;j<=i;j++)cout<<"4";
		for(int j=1;j<=(a-i*4)/7;j++)cout<<"7";
		return 0;
	}
	cout<<"-1";
	return 0;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;

int n,s;

int main()
{
	scanf("%d",&n);
	if(n%7==0)
		s=n/7;
	else s=n/7+1;
	if((7*s-n)%3!=0)
	{
		printf("-1\n");
		return 0;
	}
	else
	{
		int x=(7*s-n)/3;
		for(int i=1;i<=x;i++)
			printf("4");
		for(int i=x+1;i<=s;i++)
			printf("7");
		printf("\n");
	}
	return 0;
}


#include<iostream>
#include<algorithm>
using namespace std;
int h[100000],s=0;
int su(int x)
{
	int ans=0;
	while(x)
	{
		ans+=x%10;
		x/=10;
	}
	return ans;
}
void fun(int x)
{
	int a=x*10+4;
	int b=x*10+7;
	h[s++]=a;
	h[s++]=b;
	if(a<=10e+6)
	{
		fun(a);
		fun(b);
	}
}
int main(void)
{
	fun(0);
	int n,sum=0;
	cin>>n;
	sort(h,h+s);
	for(int i=0;h[i]!=0;i++)
	{
		sum=su(h[i]);
		if(sum==n)
		{
			cout<<h[i];
			return 0;
		}
	}
	cout<<"-1";
	return 0;
}


#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    int n;
    scanf("%d",&n);
    int four=n/4;
    n-=4*four;
    bool flag=true;
    while(n%7){
        if(!four){
            flag=false;
            break;
        }
        four--;
        n+=4;
    }
    if(!flag){
        printf("-1\n");
        return 0;
    }
    for(int i=0;i<four;i++)
        printf("4");
    for(int i=0;i<n/7;i++)
        printf("7");
    printf("\n");
    return 0;
}


#include<iostream>
using namespace std;
int main(){
    int n;
    cin>>n;
    if(n%4==0){
        for(int i=1;i<=n/4;i++)cout<<4;
        return 0;
    }
    int s=n/4;
    while(s>=0){
        if((n-s*4)%7==0)
		{
            for(int i=1;i<=s;i++)cout<<4;
            for(int i=1;i<=(n-s*4)/7;i++)cout<<7;
            return 0;
        }
        s--;
    }
    cout<<-1<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<=n/4;i++){
		if((n-i*4)%7==0){
			for(int j=0;j<i;j++)printf("4");
			for(int j=0;j<(n-i*4)/7;j++)printf("7");
			return 0;
		}
	}
	printf("-1\n");
}


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

int main()
{
	int n,f=0,s=0;
	cin>>n;
	long long ans[100000]={2147483640};
	int count=0;
	for (int i=0;4*i<n;i++)
	{
		if ((n-4*i)%7==0)
		{
			s=(n-4*i)/7;
			f=i;
			ans[count]=0;
			for (int j=0;j<s+f;j++)
			{
				if (j<f) ans[count]=(ans[count]*10)+4;
				if (j>=f) ans[count]=(ans[count]*10)+7;
			}
			//cout<<ans[count]<<endl; //Debug
			count++;
		}
	}
	//Debug
	long long res=-1;
	if (f==0 && s==0)
	{
		cout<<-1<<endl;
		return 0;
	}
	for (int i=0;i<n;i++)
	{
		if ((ans[i]>0 && ans[i]<res) || res==-1)
			res=ans[i];
	}
	cout<<res<<endl;
	return 0;
}


#include<iostream>
using namespace std;
int main()
{
    int x,y,i,n;
    cin>>n;
    for(y=n/7;y>=0;y--)
    {
        if((x-7*y)%4==0)
        {
            x=(x-7*y)/4;
            for(i=0;i<x;i++)
            {
                cout<<4;
            }
            for(i=0;i<x;i++)
            {
                cout<<7;
            }
            return 0;
        }
    }
    cout<<-1;
return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n;
string ans;
int main()
{
	cin>>n;
	while(n>7)
	{
		n-=7;
		ans+='7';
	}
	if(n==7)
	{
		cout<<ans<<7;
	}
	if(n==1)
	{
		if(ans.size()<1)cout<<-1;
		else cout<<44<<ans.substr(0,ans.size()-1);
	}
	if(n==2)
	{
		if(ans.size()<2)cout<<-1;
		else cout<<4444<<ans.substr(0,ans.size()-2);
	}
	if(n==3)
	{
		if(ans.size()<3)cout<<-1;
		else cout<<444444<<ans.substr(0,ans.size()-3);
	}
	if(n==4)
	{
		cout<<4<<ans;
	}
	if(n==5)
	{
		if(ans.size()<1)cout<<-1;
		else cout<<444<<ans.substr(0,ans.size()-1);
	}
	if(n==6)
	{
		if(ans.size()<2)cout<<-1;
		else cout<<44444<<ans.substr(0,ans.size()-2);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
using namespace std;

int main()
{
	int a, b, ok = 0, n;
	cin >> n;
	int t = n / 4;
	for (int i = n; i >= 0; --i) {
		if ((n - 4 * i) >= 0 && (n - 4 * i) % 7 == 0) {
			a = i;
			b = (n - 4 * i) / 7;
			ok = 1;
			break;
		}
	}
	if (!ok) printf("-1");
	else {
		for (int i = 0; i < a; ++i) putchar('4');
		for (int i = 0; i < b; ++i) putchar('7');
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
string s,mn="";
int main()
{
  int n;
  cin>>n;
  if(n%7==0)
  {
  for(int i=0;i<n/7;i++)
    cout<<"7";
  return 0;
  }
  for(int i=0;i<=6;i++)
    for(int j=0;j<=(n-i*4)/7;j++)
    {
    	if((i*4+j*7)==n)
    	{
    	  s="";
    	  for(int k=0;k<i;k++)
    	    s+='4';
    	  for(int k=0;k<j;k++)
    	    s+='7';
    	  if(mn=="")
    	    mn=s;
    	  else
    	  {
    	  	if(s.size()<mn.size())
    	  	  mn=s;
    	  	else
    	  	  if(s.size()==mn.size())
    	  	    mn=min(mn,s);
		  }
		}
	}
	if(mn=="")
	  cout<<-1;
	else
	  cout<<mn<<" ";
	return 0;
}


#include<cstdio>
int main(){
	long long int n;
	int x,y,x1,y1,sum=0,sum1=0;
	scanf("%d",&n);
	x=n%4;
	y=n%7;
	if(x==3){
		x1=n/4;
		for(int i=0;i<x1-1;i++){
			sum+=4;
			sum*=10;
		}
		x=x+4;
		sum+=x;
	//	printf("%d",sum);
	}
	else if(y==4){
		y1=n/7;
		for(int i=0;i<y1-1;i++){
			sum1+=7;
			sum1*=10;
		}
		sum1+=y;
	}
	else{
	printf("-1\n");
	return 0;
	}
	if(sum==0)
	printf("%d\n",sum1);
	else if(sum1==0)
	printf("%d\n",sum);
	else{
		if(sum<sum1)
	printf("%d\n",sum);
	else printf("%d\n",sum1);
	}

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
long long m,bo,s;
int main()
{
	cin>>m;
	for(int i=0;i<=m/4;i++)
	{
		s=m-i*4;
		if(s%7==0)
	    {
	    	for(int j=1;j<=i;j++) cout<<"4";
	    	for(int j=1;j<=s/7;j++) cout<<"7";
	    	cout<<"\n";
	    	return 0;
		}
	}
	cout<<"-1\n";
	return 0;
 }


#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
#include <sstream>
#include <set>
#include <queue>
#include <stack>
#include <cctype>
#include <map>
#include <climits>
#include <bitset>
using namespace std;
string strReverse(string strOrigin){
	if (strOrigin.length() == 0){
		return "";
	}
	long long i;
	string ans;
	for (i = strOrigin.length() - 1; i >= 0; --i) ans += strOrigin[i];
	return ans;
}
string CreateRequiedString(long long nCount, char chrChrarater){
	int i;
	string sAns;
	for (i = 1; i <= nCount; ++i)
		sAns += chrChrarater;
	return sAns;
}
int main(){
	ios::sync_with_stdio(false);
	int iSum, nSeven;
	cin >> iSum;
	nSeven = iSum / 7;
	iSum %= 7;
	if (iSum % 4 != 0){
		cout << -1;
		goto endapp;
	}
	cout << CreateRequiedString(iSum / 4, '4') << CreateRequiedString(nSeven, '7');
	endapp:
	//system("pause > nul");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n;
int main()
{
	scanf("%d",&n);
	for(int i=0;i<=n/4;i++)
		if((n-i*4)%7==0)
		{
			for(int j=1;j<=i;j++)
				printf("4");
			for(int j=1;j<=(n-i*4)/7;j++)
				printf("7");
			return 0;
		}
	printf("-1");
	return 0;
}


#include<iostream>
using namespace std;
int main(){
    int n;
    cin>>n;
    if(n%4==0){
        for(int i=1;i<=n/4;i++)cout<<4;
        return 0;
    }
    int s=n/4*4;
    while(s>=0){
        if((n-s)%7==0){
            for(int i=1;i<=s/4;i++)cout<<4;
            for(int i=1;i<=(n-s)/7;i++)cout<<7;
            return 0;
        }
        s-=4;
    }
    cout<<-1<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
const int MAXN=1007;
vector<int>g[MAXN];
bool used[MAXN];
int res=0;
void dfs(int v, int h= 0)
{
    used[v]=true;
    res=max(res, h);
    for (int i=0;i<(int)g[v].size();i++)
    {
        int to=g[v][i];
        if(!used[to])
        {
            dfs(to, h + 1);
        }
    }
}
int main()
{
   // freopen("input.txt", "r", stdin);
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i=1;i<=m;i++)
    {
        int u,v;
        scanf("%d%d", &u, &v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
        {
            used[j]=false;
        }
        dfs(i,0);
    }
    printf("%d\n", res);
}


#include <bits/stdc++.h>
#define F first
#define S second
#define Mp make_pair
using namespace std;
int n,m,A,B,a,d;
vector<long long>v[100002];
pair<int,int> go(int x,int y)
{
	d++;

	int M1=0;
	int M2=0;
	int Z=0;
	int ZZ=0;

	for (int i=0; i<v[x].size(); i++)
		if (y!=v[x][i])
		{
			pair<int,int> X=go(v[x][i],x);

			Z=max(Z,X.F);
			ZZ=max(ZZ,X.S);

			if (M1<X.F)
			{
				M2=M1;
				M1=X.F;
			}
				else
			if (M2<X.F) M2=X.F;
		}

	d--;

	return Mp(max(Z,d),max(M1+M2-d*2,ZZ));
}
main ()
{
	cin>>n>>m;

	for (int i=1; i<n; i++)
	{
		cin>>A>>B;

		v[A].push_back(B);
		v[B].push_back(A);
	}

	pair<int,int> X=go(1,1);

	cout<<max(X.F,X.S)<<endl;
}


#include <bits/stdc++.h>
#define F first
#define S second
#define Mp make_pair
using namespace std;
long long n,m,A,B,a,d,M1,M2;
vector<long long>v[10002];
int go(int x,int y)
{
	d++;

	int Z=-1;

	for (int i=0; i<v[x].size(); i++)
		if (y!=v[x][i]) Z=max(Z,go(v[x][i],x));

	if (Z==-1) Z=d;
	d--;

	return Z;
}
main ()
{
	cin>>n>>m;

	for (int i=1; i<n; i++)
	{
		cin>>A>>B;

		v[A].push_back(B);
		v[B].push_back(A);
	}

	for (int i=0; i<v[1].size(); i++)
	{
		d=0;

		int X=go(v[1][i],1);

		if (M1<X)
		{
			M2=M1;
			M1=X;
		}
			else
		if (M2<X) M2=X;
	}

	cout<<M1+M2<<endl;
}


#include <bits/stdc++.h>
#define F first
#define S second
#define Mp make_pair
using namespace std;
int n,m,A,B,a,d;
vector<long long>v[10002];
pair<int,int> go(int x,int y)
{
	d++;

	int M1=0;
	int M2=0;
	int Z=0;
	int ZZ=0;

	for (int i=0; i<v[x].size(); i++)
		if (y!=v[x][i])
		{
			pair<int,int> X=go(v[x][i],x);

			Z=max(Z,X.F);
			ZZ=max(ZZ,X.S);

			if (M1<X.F)
			{
				M2=M1;
				M1=X.F;
			}
				else
			if (M2<X.F) M2=X.F;
		}

	d--;

	return Mp(max(Z,d),max(M1+M2-d*2,ZZ));
}
main ()
{
	cin>>n>>m;

	for (int i=1; i<n; i++)
	{
		cin>>A>>B;

		v[A].push_back(B);
		v[B].push_back(A);
	}

	pair<int,int> X=go(1,1);

	cout<<max(X.F,X.S)<<endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <set>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::unordered_set<int> GraphEdges;
//typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::unordered_map<int, GraphEdges> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  if(iter == graph.end()) {
    graph.insert(std::pair<int,GraphEdges>(node,GraphEdges()));
    iter = graph.find(node);
  }
  GraphEdges &edges = iter->second;
  edges.insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges &edges = iter->second;
  for(auto eIter = edges.begin(); eIter != edges.end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}
int findMaxLatencyIterative(GraphMap_t &graph, int middle) {
  assert(middle > 0);
  std::unordered_set<int> visited;
  std::multiset<int> results;
  GraphEdges &edges = graph.find(middle)->second;

  visited.insert(middle);
  for(auto iter = edges.begin(); iter != edges.end(); iter++) {
    int depth = 1;
    std::queue<int> queue1;
    std::queue<int> queue2;
		std::queue<int> &toSearch = queue1;
    std::queue<int> &nextSearch = queue2;
    GraphEdges &childEdges = graph.find(*iter)->second;
    visited.insert(*iter);
    for(auto citer = childEdges.begin(); citer !=childEdges.end(); citer++) {
      if(visited.find(*citer) == visited.end())
        toSearch.push(*citer);
    }
    int q1Search = true;
    while(!toSearch.empty()) {
			depth++;
      while(!toSearch.empty()) {
        int node = toSearch.front(); toSearch.pop();
        visited.insert(node);
        GraphEdges &gcEdges = graph.find(node)->second;
        for(auto gcIter = gcEdges.begin(); gcIter != gcEdges.end(); gcIter++) {
          if(visited.find(*gcIter) == visited.end())
            nextSearch.push(*gcIter);
        }
      }
      q1Search = !q1Search;
      toSearch = (q1Search) ? queue1:queue2;
      nextSearch = (q1Search) ?queue2:queue1;
    }
    results.insert(depth);
  }
  int result = 0;
  while(results.size() > 2)
    results.erase(results.begin());
  while(!results.empty()) {
    result += *results.begin();
    results.erase(results.begin());
  }
  return result;
}
int findMiddleThroughInfection(GraphMap_t &graph) {
  std::unordered_set<int> dead;
  std::queue<int> willSpread;
  for(auto iter = graph.begin(); iter != graph.end(); iter++) {
    //if a leaf-node, add to infected.
    GraphEdges &edges = iter->second;
    if(edges.size() == 1) {
			willSpread.push(iter->first);
    }
  }
  int currentNode = -1;
  while(!willSpread.empty()) {
    currentNode = willSpread.front(); willSpread.pop();
    //If only one non-dead child exists, kill self and infect(wow this is dark)
    GraphEdges &edges = graph.find(currentNode)->second;
    int count = edges.size();
    int alive = 0;
    for(auto iter = edges.begin(); iter != edges.end() ; iter++) {
      if(dead.find(*iter) != dead.end())
				count--;
			else
				alive = *iter;
    }
    if(count == 1) {
      dead.insert(currentNode);
			assert(alive > 0);
      GraphEdges &aliveEdges = graph.find(alive)->second;
      count = aliveEdges.size();
      for(auto iter = aliveEdges.begin(); iter != aliveEdges.end(); iter++) {
        if(dead.find(*iter) != dead.end())
					count--;
      }
			if(count == 1)
        willSpread.push(alive);

    }
  }
  return currentNode;
}
int findMaxLatency(GraphMap_t &graph) {
/*  int result = 0;
  result = findMiddleThroughInfection(graph);
//  std::cerr << "middle: " << result << std::endl;
  auto gIter = graph.begin();
  result = findMaxLatencyIterative(graph, result);
  return result;*/
	 int result = 0;
		auto gIter = graph.begin();
		for(; gIter != graph.end(); gIter++) {
//		  int val = findMaxLatencyRecursive(graph, gIter->first, -1);
      int val = findMaxLatencyIterative(graph, gIter->first);
		  if(val > result)
				result = val;
		}
		return result;
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <memory>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::set<int> GraphEdges;
typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::map<int, GraphEdges_p> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  GraphEdges_p edges;
  if(iter == graph.end()) {
    edges = std::make_shared<GraphEdges>();
    graph.insert(std::pair<int, GraphEdges_p>(node, edges));
  } else {
    edges = iter->second;
  }
  edges->insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges_p edges = iter->second;
  for(auto eIter = edges->begin(); eIter != edges->end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}

int findMaxLatency(GraphMap_t &graph) {
  int result = 0;
  auto gIter = graph.begin();
  for(; gIter != graph.end(); gIter++) {
    int val = findMaxLatencyRecursive(graph, gIter->first, -1);
    if(val > result)
			result = val;
  }
  return result;
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatencyRecursive(graph, graph.begin()->first, -1);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <set>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::unordered_set<int> GraphEdges;
//typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::unordered_map<int, GraphEdges> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  if(iter == graph.end()) {
    graph.insert(std::pair<int,GraphEdges>(node,GraphEdges()));
    iter = graph.find(node);
  }
  GraphEdges &edges = iter->second;
  edges.insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges &edges = iter->second;
  for(auto eIter = edges.begin(); eIter != edges.end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}
int findMaxLatencyIterative(GraphMap_t &graph, int middle) {
  assert(middle > 0);
  std::unordered_set<int> visited;
  std::multiset<int> results;
  GraphEdges &edges = graph.find(middle)->second;

  visited.insert(middle);
  for(auto iter = edges.begin(); iter != edges.end(); iter++) {
    int depth = 1;
    std::queue<int> queue1;
    std::queue<int> queue2;
		std::queue<int>* toSearch = &queue1;
    std::queue<int>* nextSearch = &queue2;
    GraphEdges &childEdges = graph.find(*iter)->second;
    visited.insert(*iter);
    for(auto citer = childEdges.begin(); citer !=childEdges.end(); citer++) {
      if(visited.find(*citer) == visited.end())
        toSearch->push(*citer);
    }
    int q1Search = true;
    while(!queue1.empty() || !queue2.empty()) {
			depth++;
      while(!toSearch->empty()) {
        int node = toSearch->front(); toSearch->pop();
        visited.insert(node);
        GraphEdges &gcEdges = graph.find(node)->second;
        for(auto gcIter = gcEdges.begin(); gcIter != gcEdges.end(); gcIter++) {
          if(visited.find(*gcIter) == visited.end())
            nextSearch->push(*gcIter);
        }
      }
      q1Search = !q1Search;
      toSearch = (q1Search) ? &queue1:&queue2;
      nextSearch = (q1Search) ? &queue2:&queue1;
    }
    results.insert(depth);
  }
  int result = 0;
  while(results.size() > 2)
    results.erase(results.begin());
  while(!results.empty()) {
    result += *results.begin();
    results.erase(results.begin());
  }
  return result;
}
int findMiddleThroughInfection(GraphMap_t &graph) {
  std::unordered_set<int> dead;
  std::queue<int> willSpread;
  for(auto iter = graph.begin(); iter != graph.end(); iter++) {
    //if a leaf-node, add to infected.
    GraphEdges &edges = iter->second;
    if(edges.size() == 1) {
			willSpread.push(iter->first);
    }
  }
  int currentNode = -1;
  while(!willSpread.empty()) {
    currentNode = willSpread.front(); willSpread.pop();
    //If only one non-dead child exists, kill self and infect(wow this is dark)
    GraphEdges &edges = graph.find(currentNode)->second;
    int count = edges.size();
    int alive = 0;
    for(auto iter = edges.begin(); iter != edges.end() ; iter++) {
      if(dead.find(*iter) != dead.end())
				count--;
			else
				alive = *iter;
    }
    if(count == 1) {
      dead.insert(currentNode);
			assert(alive > 0);
      GraphEdges &aliveEdges = graph.find(alive)->second;
      count = aliveEdges.size();
      for(auto iter = aliveEdges.begin(); iter != aliveEdges.end(); iter++) {
        if(dead.find(*iter) != dead.end())
					count--;
      }
			if(count == 1)
        willSpread.push(alive);

    }
  }
  return currentNode;
}
int findMaxLatency(GraphMap_t &graph) {
  int result = 0;
  result = findMiddleThroughInfection(graph);
//  std::cerr << "middle: " << result << std::endl;
  auto gIter = graph.begin();
  result = findMaxLatencyIterative(graph, result);
  return result;
/*	 int result = 0;
		auto gIter = graph.begin();
		for(; gIter != graph.end(); gIter++) {
		  int val = findMaxLatencyRecursive(graph, gIter->first, -1);
//      int val = findMaxLatencyIterative(graph, gIter->first);
		  if(val > result)
				result = val;
		}
		return result;*/
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <set>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::unordered_set<int> GraphEdges;
//typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::unordered_map<int, GraphEdges> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  if(iter == graph.end()) {
    graph.insert(std::pair<int,GraphEdges>(node,GraphEdges()));
    iter = graph.find(node);
  }
  GraphEdges &edges = iter->second;
  edges.insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges &edges = iter->second;
  for(auto eIter = edges.begin(); eIter != edges.end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}
int findMaxLatencyIterative(GraphMap_t &graph, int middle) {
  assert(middle > 0);
  std::unordered_set<int> visited;
  std::multiset<int> results;
  GraphEdges &edges = graph.find(middle)->second;

  visited.insert(middle);
  for(auto iter = edges.begin(); iter != edges.end(); iter++) {
    int depth = 1;
    std::queue<int> queue1;
    std::queue<int> queue2;
		std::queue<int> &toSearch = queue1;
    std::queue<int> &nextSearch = queue2;
    GraphEdges &childEdges = graph.find(*iter)->second;
    visited.insert(*iter);
    for(auto citer = childEdges.begin(); citer !=childEdges.end(); citer++) {
      if(visited.find(*citer) == visited.end())
        toSearch.push(*citer);
    }
    int q1Search = true;
    while(!toSearch.empty()) {
			depth++;
      while(!toSearch.empty()) {
        int node = toSearch.front(); toSearch.pop();
        visited.insert(node);
        GraphEdges &gcEdges = graph.find(node)->second;
        for(auto gcIter = gcEdges.begin(); gcIter != gcEdges.end(); gcIter++) {
          if(visited.find(*gcIter) == visited.end())
            nextSearch.push(*gcIter);
        }
      }
      q1Search = !q1Search;
      toSearch = (q1Search) ? queue1:queue2;
      nextSearch = (q1Search) ?queue2:queue1;
    }
    results.insert(depth);
  }
  int result = 0;
  while(results.size() > 2)
    results.erase(results.begin());
  while(!results.empty()) {
    result += *results.begin();
    results.erase(results.begin());
  }
  return result;
}
int findMiddleThroughInfection(GraphMap_t &graph) {
  std::unordered_set<int> dead;
  std::queue<int> willSpread;
  for(auto iter = graph.begin(); iter != graph.end(); iter++) {
    //if a leaf-node, add to infected.
    GraphEdges &edges = iter->second;
    if(edges.size() == 1) {
			willSpread.push(iter->first);
    }
  }
  int currentNode = -1;
  while(!willSpread.empty()) {
    currentNode = willSpread.front(); willSpread.pop();
    //If only one non-dead child exists, kill self and infect(wow this is dark)
    GraphEdges &edges = graph.find(currentNode)->second;
    int count = edges.size();
    int alive = 0;
    for(auto iter = edges.begin(); iter != edges.end() ; iter++) {
      if(dead.find(*iter) != dead.end())
				count--;
			else
				alive = *iter;
    }
    if(count == 1) {
      dead.insert(currentNode);
			assert(alive > 0);
      GraphEdges &aliveEdges = graph.find(alive)->second;
      count = aliveEdges.size();
      for(auto iter = aliveEdges.begin(); iter != aliveEdges.end(); iter++) {
        if(dead.find(*iter) != dead.end())
					count--;
      }
			if(count == 1)
        willSpread.push(alive);

    }
  }
  return currentNode;
}
int findMaxLatency(GraphMap_t &graph) {
  int result = 0;
  result = findMiddleThroughInfection(graph);
//  std::cerr << "middle: " << result << std::endl;
  auto gIter = graph.begin();
  result = findMaxLatencyIterative(graph, result);
  return result;
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <set>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::unordered_set<int> GraphEdges;
//typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::unordered_map<int, GraphEdges> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  if(iter == graph.end()) {
    graph.insert(std::pair<int,GraphEdges>(node,GraphEdges()));
    iter = graph.find(node);
  }
  GraphEdges &edges = iter->second;
  edges.insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges &edges = iter->second;
  for(auto eIter = edges.begin(); eIter != edges.end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}
int findMaxLatencyIterative(GraphMap_t &graph, int middle) {
  assert(middle > 0);
  std::unordered_set<int> visited;
  std::multiset<int> results;
  GraphEdges &edges = graph.find(middle)->second;

  visited.insert(middle);
  for(auto iter = edges.begin(); iter != edges.end(); iter++) {
    int depth = 1;
    std::queue<int> queue1;
    std::queue<int> queue2;
		std::queue<int> &toSearch = queue1;
    std::queue<int> &nextSearch = queue2;
    GraphEdges &childEdges = graph.find(*iter)->second;
    visited.insert(*iter);
    for(auto citer = childEdges.begin(); citer !=childEdges.end(); citer++) {
      if(visited.find(*citer) == visited.end())
        toSearch.push(*citer);
    }
    int q1Search = true;
    while(!toSearch.empty()) {
			depth++;
      while(!toSearch.empty()) {
        int node = toSearch.front(); toSearch.pop();
        visited.insert(node);
        GraphEdges &gcEdges = graph.find(node)->second;
        for(auto gcIter = gcEdges.begin(); gcIter != gcEdges.end(); gcIter++) {
          if(visited.find(*gcIter) == visited.end())
            nextSearch.push(*gcIter);
        }
      }
      q1Search = !q1Search;
      toSearch = (q1Search) ? queue1:queue2;
      nextSearch = (q1Search) ?queue2:queue1;
    }
    results.insert(depth);
  }
  int result = 0;
  while(results.size() > 2)
    results.erase(results.begin());
  while(!results.empty()) {
    result += *results.begin();
    results.erase(results.begin());
  }
  return result;
}
int findMiddleThroughInfection(GraphMap_t &graph) {
  std::unordered_set<int> dead;
  std::queue<int> willSpread;
  for(auto iter = graph.begin(); iter != graph.end(); iter++) {
    //if a leaf-node, add to infected.
    GraphEdges &edges = iter->second;
    if(edges.size() == 1) {
			willSpread.push(iter->first);
    }
  }
  int currentNode = -1;
  while(!willSpread.empty()) {
    currentNode = willSpread.front(); willSpread.pop();
    //If only one non-dead child exists, kill self and infect(wow this is dark)
    GraphEdges &edges = graph.find(currentNode)->second;
    int count = edges.size();
    int alive = 0;
    for(auto iter = edges.begin(); iter != edges.end() ; iter++) {
      if(dead.find(*iter) != dead.end())
				count--;
			else
				alive = *iter;
    }
    if(count == 1) {
      dead.insert(currentNode);
			assert(alive > 0);
      GraphEdges &aliveEdges = graph.find(alive)->second;
      count = aliveEdges.size();
      for(auto iter = aliveEdges.begin(); iter != aliveEdges.end(); iter++) {
        if(dead.find(*iter) != dead.end())
					count--;
      }
			if(count == 1)
        willSpread.push(alive);

    }
  }
  return currentNode;
}
int findMaxLatency(GraphMap_t &graph) {
/*  int result = 0;
  result = findMiddleThroughInfection(graph);
//  std::cerr << "middle: " << result << std::endl;
  auto gIter = graph.begin();
  result = findMaxLatencyIterative(graph, result);
  return result;*/
	 int result = 0;
		auto gIter = graph.begin();
		for(; gIter != graph.end(); gIter++) {
		  int val = findMaxLatencyRecursive(graph, gIter->first, -1);
//      int val = findMaxLatencyIterative(graph, gIter->first);
		  if(val > result)
				result = val;
		}
		return result;
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <memory>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::set<int> GraphEdges;
typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::map<int, GraphEdges_p> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  GraphEdges_p edges;
  if(iter == graph.end()) {
    edges = std::make_shared<GraphEdges>();
    graph.insert(std::pair<int, GraphEdges_p>(node, edges));
  } else {
    edges = iter->second;
  }
  edges->insert(destNode);
}

int findMaxLength(GraphMap_t &graph, int startNode) {
  int max = 0;
  std::set<int> seen;
  std::vector<int> nextState;
  nextState.push_back(startNode);
  seen.insert(startNode);
  while(!nextState.empty()) {
    startNode = nextState.front();
    nextState.erase(nextState.begin());
    bool newState = false;
		auto gIter = graph.find(startNode);
		GraphEdges_p edges = gIter->second;

    for(auto eIter = edges->begin(); eIter != edges->end(); eIter++) {
      if(seen.find(*eIter) == seen.end()) {
		    newState = true;
		    seen.insert(*eIter);
		    nextState.push_back(*eIter);
			}
    }
   if(newState)
     max++;
  }
  return max;
}
int findMaxLatency(GraphMap_t &graph) {
  int maxLength = 0;
//  return findMaxLength(graph, graph.begin()->first);
  auto iter = graph.begin();
  for(; iter != graph.end(); iter++) {
    int val = findMaxLength(graph, iter->first);
    if(val > maxLength)
			maxLength = val;
  }
	return maxLength;
}

int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <memory>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::set<int> GraphEdges;
typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::map<int, GraphEdges_p> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  GraphEdges_p edges;
  if(iter == graph.end()) {
    edges = std::make_shared<GraphEdges>();
    graph.insert(std::pair<int, GraphEdges_p>(node, edges));
  } else {
    edges = iter->second;
  }
  edges->insert(destNode);
}

int findMaxLength(GraphMap_t &graph, int startNode) {
  int max = 0;
  std::set<int> seen;
  std::vector<int> nextState;
  nextState.push_back(startNode);
  seen.insert(startNode);
  while(!nextState.empty()) {
    startNode = nextState.front();
    nextState.erase(nextState.begin());
    bool newState = false;
		auto gIter = graph.find(startNode);
		GraphEdges_p edges = gIter->second;

    for(auto eIter = edges->begin(); eIter != edges->end(); eIter++) {
      if(seen.find(*eIter) == seen.end()) {
		    newState = true;
		    seen.insert(*eIter);
		    nextState.push_back(*eIter);
			}
    }
   if(newState)
     max++;
  }
  return max;
}
int findMaxLatency(GraphMap_t &graph) {
  return findMaxLength(graph, graph.begin()->first);
}

int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::unordered_set<int> GraphEdges;
typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::unordered_map<int, GraphEdges_p> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  GraphEdges_p edges;
  if(iter == graph.end()) {
    edges = std::make_shared<GraphEdges>();
    graph.insert(std::pair<int, GraphEdges_p>(node, edges));
  } else {
    edges = iter->second;
  }
  edges->insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges_p edges = iter->second;
  for(auto eIter = edges->begin(); eIter != edges->end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}

int findMaxLatency(GraphMap_t &graph) {
  int result = 0;
  auto gIter = graph.begin();
  for(; gIter != graph.end(); gIter++) {
    int val = findMaxLatencyRecursive(graph, gIter->first, -1);
    if(val > result)
			result = val;
  }
  return result;
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <memory>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::unordered_set<int> GraphEdges;
typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::unordered_map<int, GraphEdges_p> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  GraphEdges_p edges;
  if(iter == graph.end()) {
    edges = std::make_shared<GraphEdges>();
    graph.insert(std::pair<int, GraphEdges_p>(node, edges));
  } else {
    edges = iter->second;
  }
  edges->insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges_p edges = iter->second;
  for(auto eIter = edges->begin(); eIter != edges->end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}

int findMaxLatency(GraphMap_t &graph) {
  int result = 0;
  auto gIter = graph.begin();
  for(; gIter != graph.end(); gIter++) {
    int val = findMaxLatencyRecursive(graph, gIter->first, -1);
    if(val > result)
			result = val;
  }
  return result;
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <memory>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::set<int> GraphEdges;
typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::map<int, GraphEdges_p> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  GraphEdges_p edges;
  if(iter == graph.end()) {
    edges = std::make_shared<GraphEdges>();
    graph.insert(std::pair<int, GraphEdges_p>(node, edges));
  } else {
    edges = iter->second;
  }
  edges->insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges_p edges = iter->second;
  for(auto eIter = edges->begin(); eIter != edges->end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}

int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatencyRecursive(graph, graph.begin()->first, -1);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <set>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::unordered_set<int> GraphEdges;
//typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::unordered_map<int, GraphEdges> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  if(iter == graph.end()) {
    graph.insert(std::pair<int,GraphEdges>(node,GraphEdges()));
    iter = graph.find(node);
  }
  GraphEdges &edges = iter->second;
  edges.insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges &edges = iter->second;
  for(auto eIter = edges.begin(); eIter != edges.end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}
int findMaxLatencyIterative(GraphMap_t &graph, int middle) {
  assert(middle > 0);
  std::unordered_set<int> visited;
  std::multiset<int> results;
  GraphEdges &edges = graph.find(middle)->second;

  visited.insert(middle);
  for(auto iter = edges.begin(); iter != edges.end(); iter++) {
    int depth = 1;
    std::queue<int> queue1;
    std::queue<int> queue2;
		std::queue<int> &toSearch = queue1;
    std::queue<int> &nextSearch = queue2;
    GraphEdges &childEdges = graph.find(*iter)->second;
    visited.insert(*iter);
    for(auto citer = childEdges.begin(); citer !=childEdges.end(); citer++) {
      if(visited.find(*citer) == visited.end())
        toSearch.push(*citer);
    }
    int q1Search = true;
    while(!toSearch.empty()) {
			depth++;
      while(!toSearch.empty()) {
        int node = toSearch.front(); toSearch.pop();
        visited.insert(node);
        GraphEdges &gcEdges = graph.find(node)->second;
        for(auto gcIter = gcEdges.begin(); gcIter != gcEdges.end(); gcIter++) {
          if(visited.find(*gcIter) == visited.end())
            nextSearch.push(*gcIter);
        }
      }
      q1Search = !q1Search;
      toSearch = (q1Search) ? queue1:queue2;
      nextSearch = (q1Search) ?queue2:queue1;
    }
    results.insert(depth);
  }
  int result = 0;
  while(results.size() > 2)
    results.erase(results.begin());
  while(!results.empty()) {
    result += *results.begin();
    results.erase(results.begin());
  }
  return result;
}
int findMiddleThroughInfection(GraphMap_t &graph) {
  std::unordered_set<int> dead;
  std::queue<int> willSpread;
  for(auto iter = graph.begin(); iter != graph.end(); iter++) {
    //if a leaf-node, add to infected.
    GraphEdges &edges = iter->second;
    if(edges.size() == 1) {
			willSpread.push(iter->first);
    }
  }
  int currentNode = -1;
  while(!willSpread.empty()) {
    currentNode = willSpread.front(); willSpread.pop();
    //If only one non-dead child exists, kill self and infect(wow this is dark)
    GraphEdges &edges = graph.find(currentNode)->second;
    int count = edges.size();
    int alive = 0;
    for(auto iter = edges.begin(); iter != edges.end() ; iter++) {
      if(dead.find(*iter) != dead.end())
				count--;
			else
				alive = *iter;
    }
    if(count == 1) {
      dead.insert(currentNode);
			assert(alive > 0);
      GraphEdges &aliveEdges = graph.find(alive)->second;
      count = aliveEdges.size();
      for(auto iter = aliveEdges.begin(); iter != aliveEdges.end(); iter++) {
        if(dead.find(*iter) != dead.end())
					count--;
      }
			if(count == 1)
        willSpread.push(alive);

    }
  }
  return currentNode;
}
int findMaxLatency(GraphMap_t &graph) {
  int result = 0;
  result = findMiddleThroughInfection(graph);
  std::cerr << "middle: " << result << std::endl;
  auto gIter = graph.begin();
  result = findMaxLatencyIterative(graph, result);
  return result;
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <memory>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::unordered_set<int> GraphEdges;
//typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::unordered_map<int, GraphEdges> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  if(iter == graph.end()) {
    graph.insert(std::pair<int,GraphEdges>(node,GraphEdges()));
    iter = graph.find(node);
  }
  GraphEdges &edges = iter->second;
  edges.insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges &edges = iter->second;
  for(auto eIter = edges.begin(); eIter != edges.end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}

int findMaxLatency(GraphMap_t &graph) {
  int result = 0;
  auto gIter = graph.begin();
  for(; gIter != graph.end(); gIter++) {
    int val = findMaxLatencyRecursive(graph, gIter->first, -1);
    if(val > result)
			result = val;
  }
  return result;
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <memory>
#include <utility>
#include <vector>
#include <algorithm>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::set<int> GraphEdges;
typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::map<int, GraphEdges_p> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  GraphEdges_p edges;
  if(iter == graph.end()) {
    edges = std::make_shared<GraphEdges>();
    graph.insert(std::pair<int, GraphEdges_p>(node, edges));
  } else {
    edges = iter->second;
  }
  edges->insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges_p edges = iter->second;
  for(auto eIter = edges->begin(); eIter != edges->end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}

int findMiddleThroughInfection(GraphMap_t &graph) {
  //if we only have two or one nodes, stop and report either.
  //find all nodes with one edge, add to "infected".
  //  for each infected node's child
  //    infect if child has fewer than two healthy neighbors.
  //  remove node from infected and add to "dead"
  //repeat until we have two or fewer remaining.
  std::vector<int> infected;
  std::set<int> infectedSet;
  std::set<int> dead;
  auto infectNode = [&infected, &infectedSet] (int node) {
    if(infectedSet.find(node) == infectedSet.end()) {
      infected.push_back(node);
      infectedSet.insert(node);
    }
  };
  auto killTopInfected = [&infected, &infectedSet, &dead] () {
    int node = *infected.begin();
    dead.insert(node);
    infected.erase(infected.begin());
    infectedSet.erase(infectedSet.find(node));
  };
  for(auto iter = graph.begin(); iter != graph.end(); iter++) {
    int count = iter->second->size();
    if(count == 1)
			infectNode(iter->first);
  }
  while(graph.size() - (infected.size() + dead.size()) > 2) {
    int current = *infected.begin();
    killTopInfected();
		GraphEdges_p neighbors = graph.find(current)->second;
    for(auto it = neighbors->begin(); it != neighbors->end(); it++) {
      GraphEdges_p checkNeighbors = graph.find(*it)->second;
      if(checkNeighbors->size() < 3)
				infectNode(*it);
      else {
        int notHealthy = 0;
        for(auto hIter = checkNeighbors->begin(); hIter != checkNeighbors->end(); hIter++) {
          if(infectedSet.find(*hIter) != infectedSet.end())
						notHealthy++;
					else if(dead.find(*hIter) != dead.end())
						notHealthy++;
        }
				if(checkNeighbors->size() - notHealthy < 2)
					infectNode(*it);
      }
    }
  }
	return *(infected.begin());
}
int findMaxLatency(GraphMap_t &graph) {
  int result = 0;
  int node = findMiddleThroughInfection(graph);
  result = findMaxLatencyRecursive(graph, node, -1);
  return result;
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <memory>
#include <utility>
#include <vector>
#include <algorithm>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::set<int> GraphEdges;
typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::map<int, GraphEdges_p> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  GraphEdges_p edges;
  if(iter == graph.end()) {
    edges = std::make_shared<GraphEdges>();
    graph.insert(std::pair<int, GraphEdges_p>(node, edges));
  } else {
    edges = iter->second;
  }
  edges->insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges_p edges = iter->second;
  for(auto eIter = edges->begin(); eIter != edges->end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}

int findMiddleThroughInfection(GraphMap_t &graph) {
  //if we only have two or one nodes, stop and report either.
  //find all nodes with one edge, add to "infected".
  //  for each infected node's child
  //    infect if child has fewer than two healthy neighbors.
  //  remove node from infected and add to "dead"
  //repeat until we have two or fewer remaining.
  std::vector<int> infected;
  std::set<int> infectedSet;
  std::set<int> dead;
  std::map<int,int> infectedBy;

  auto infectNode = [&infected, &infectedSet, &infectedBy] (int node, int infector) {
    if(infectedSet.find(node) == infectedSet.end()) {
      if(infector != -1) {
				int infectedCount = infectedBy.find(infector)->second;
        infectedBy.insert(std::pair<int, int>(node,1+infectedCount));
      }
			else
				infectedBy.insert(std::pair<int,int>(node,0));

      infected.push_back(node);
      infectedSet.insert(node);
    }
  };
  auto killTopInfected = [&infected, &infectedSet, &dead] () {
    int node = *infected.begin();
    dead.insert(node);
    infected.erase(infected.begin());
    infectedSet.erase(infectedSet.find(node));
  };
  for(auto iter = graph.begin(); iter != graph.end(); iter++) {
    int count = iter->second->size();
    if(count == 1)
			infectNode(iter->first, -1);
  }
//  while(graph.size() - (infected.size() + dead.size()) > 2) {
  while(graph.size() - dead.size() > 2) {
    int current = *infected.begin();
    killTopInfected();
		GraphEdges_p neighbors = graph.find(current)->second;
    for(auto it = neighbors->begin(); it != neighbors->end(); it++) {
      GraphEdges_p checkNeighbors = graph.find(*it)->second;
      if(checkNeighbors->size() < 3)
				infectNode(*it, current);
      else {
        int notHealthy = 0;
        for(auto hIter = checkNeighbors->begin(); hIter != checkNeighbors->end(); hIter++) {
          if(infectedSet.find(*hIter) != infectedSet.end())
						notHealthy++;
					else if(dead.find(*hIter) != dead.end())
						notHealthy++;
        }
				if(checkNeighbors->size() - notHealthy < 2)
					infectNode(*it, current);
      }
    }
  }

	return *(infected.begin());
}

int findMaxLatency(GraphMap_t &graph) {
  int result = 0;

  int node = findMiddleThroughInfection(graph);
  result = findMaxLatencyRecursive(graph, node, -1);
  return result;
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <memory>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::set<int> GraphEdges;
typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::map<int, GraphEdges_p> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  GraphEdges_p edges;
  if(iter == graph.end()) {
    edges = std::make_shared<GraphEdges>();
    graph.insert(std::pair<int, GraphEdges_p>(node, edges));
  } else {
    edges = iter->second;
  }
  edges->insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges_p edges = iter->second;
  for(auto eIter = edges->begin(); eIter != edges->end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}

int findMaxLatency(GraphMap_t &graph) {
  int result = 0;
  auto gIter = graph.begin();
  for(; gIter != graph.end(); gIter++) {
    int val = findMaxLatencyRecursive(graph, gIter->first, -1);
    if(val > result)
			result = val;
  }
  return result;
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <set>
#include <utility>
#include <vector>

void getTwoNumbersSTDIN(int &v1, int &v2) {
  char buffer[25];
  std::cin.getline(buffer,25);
  char *parts = strtok(buffer, " ");
  v1 = atoi(parts);
  parts = strtok(NULL, " ");
  v2 = atoi(parts);
}

typedef std::unordered_set<int> GraphEdges;
//typedef std::shared_ptr<GraphEdges > GraphEdges_p;
typedef std::unordered_map<int, GraphEdges> GraphMap_t;

void insert(GraphMap_t &graph, int node, int destNode) {
  auto iter = graph.find(node);
  if(iter == graph.end()) {
    graph.insert(std::pair<int,GraphEdges>(node,GraphEdges()));
    iter = graph.find(node);
  }
  GraphEdges &edges = iter->second;
  edges.insert(destNode);
}

int findMaxLatencyRecursive(GraphMap_t &graph, int startNode, int lastNode) {
  std::set<int> childResults;
  auto iter = graph.find(startNode);
  GraphEdges &edges = iter->second;
  for(auto eIter = edges.begin(); eIter != edges.end(); eIter++) {
    if(*eIter != lastNode) {
      childResults.insert(1 + findMaxLatencyRecursive(graph, *eIter, startNode));
    }
  }
  int result = 0;

  if(!childResults.empty()) {
    result += *childResults.rbegin();
    auto it = childResults.end();
    it--;
    childResults.erase(it);
    if(!childResults.empty() && lastNode == -1) {
      result += *childResults.rbegin();
    }
  }
  return result;
}
int findMaxLatencyIterative(GraphMap_t &graph, int middle) {
  assert(middle > 0);
  std::unordered_set<int> visited;
  std::multiset<int> results;
  GraphEdges &edges = graph.find(middle)->second;

  visited.insert(middle);
  for(auto iter = edges.begin(); iter != edges.end(); iter++) {
    int depth = 1;
    std::queue<int> queue1;
    std::queue<int> queue2;
		std::queue<int> &toSearch = queue1;
    std::queue<int> &nextSearch = queue2;
    GraphEdges &childEdges = graph.find(*iter)->second;
    visited.insert(*iter);
    for(auto citer = childEdges.begin(); citer !=childEdges.end(); citer++) {
      if(visited.find(*citer) == visited.end())
        toSearch.push(*citer);
    }
    int q1Search = true;
    while(!queue1.empty() && !queue2.empty()) {
			depth++;
      while(!toSearch.empty()) {
        int node = toSearch.front(); toSearch.pop();
        visited.insert(node);
        GraphEdges &gcEdges = graph.find(node)->second;
        for(auto gcIter = gcEdges.begin(); gcIter != gcEdges.end(); gcIter++) {
          if(visited.find(*gcIter) == visited.end())
            nextSearch.push(*gcIter);
        }
      }
      q1Search = !q1Search;
      toSearch = (q1Search) ? queue1:queue2;
      nextSearch = (q1Search) ? queue2:queue1;
    }
    results.insert(depth);
  }
  int result = 0;
  while(results.size() > 2)
    results.erase(results.begin());
  while(!results.empty()) {
    result += *results.begin();
    results.erase(results.begin());
  }
  return result;
}
int findMiddleThroughInfection(GraphMap_t &graph) {
  std::unordered_set<int> dead;
  std::queue<int> willSpread;
  for(auto iter = graph.begin(); iter != graph.end(); iter++) {
    //if a leaf-node, add to infected.
    GraphEdges &edges = iter->second;
    if(edges.size() == 1) {
			willSpread.push(iter->first);
    }
  }
  int currentNode = -1;
  while(!willSpread.empty()) {
    currentNode = willSpread.front(); willSpread.pop();
    //If only one non-dead child exists, kill self and infect(wow this is dark)
    GraphEdges &edges = graph.find(currentNode)->second;
    int count = edges.size();
    int alive = 0;
    for(auto iter = edges.begin(); iter != edges.end() ; iter++) {
      if(dead.find(*iter) != dead.end())
				count--;
			else
				alive = *iter;
    }
    if(count == 1) {
      dead.insert(currentNode);
			assert(alive > 0);
      GraphEdges &aliveEdges = graph.find(alive)->second;
      count = aliveEdges.size();
      for(auto iter = aliveEdges.begin(); iter != aliveEdges.end(); iter++) {
        if(dead.find(*iter) != dead.end())
					count--;
      }
			if(count == 1)
        willSpread.push(alive);

    }
  }
  return currentNode;
}
int findMaxLatency(GraphMap_t &graph) {
  int result = 0;
  result = findMiddleThroughInfection(graph);
//  std::cerr << "middle: " << result << std::endl;
  auto gIter = graph.begin();
  result = findMaxLatencyIterative(graph, result);
  return result;
/*	 int result = 0;
		auto gIter = graph.begin();
		for(; gIter != graph.end(); gIter++) {
		  int val = findMaxLatencyRecursive(graph, gIter->first, -1);
//      int val = findMaxLatencyIterative(graph, gIter->first);
		  if(val > result)
				result = val;
		}
		return result;*/
}
int main() {
  int result = false;
  //get number of brains and connectors.
  int brains, connectors;
  getTwoNumbersSTDIN(brains,connectors);
  GraphMap_t graph;
  int node, dest;
  for(int i = 0; i < connectors; i++) {
    getTwoNumbersSTDIN(node, dest);
    insert(graph, node, dest);
    insert(graph, dest, node);
  }
  result = findMaxLatency(graph);

  std::cout << result << std::endl;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <string>
#include <queue>
#include <map>
#include <ctime>
#include <cstdio>
using namespace std;
#define ll long long
#define mp make_pair
#define f first
#define s second
int n,m,ans=0, p, q;
int ctr;
vector<vector<int> > gr;
bool mycomp(int a, int b){
	return(a>b);
}
int dfs(int now, int prev, int d){
    vector<int> gg(gr[now].size());
    ans = max(ans, d);
	for (int i=0; i<gr[now].size(); i++){
		if (gr[now][i]==prev)
			continue;
		gg[i] = dfs(gr[now][i], now, d+1);
	}
	if (gr[now].size() <= 2){
		if (gr[now].size() == 1)
		    return (d);
		else
			return (gg[0]);
	}
	else{
	    sort(gg.begin(), gg.end(), mycomp);
	    ans = max(ans, gg[0] + gg[1] - 2*d);
		return(gg[0]);
	}
}
int main() {
    scanf("%d%d",&n,&m);
    gr.resize(n);
    for (int i=0; i<n-1; ++i){
    	scanf("%d%d",&p,&q);
    	p--; q--;
    	gr[p].push_back(q);
    	gr[q].push_back(p);
    }
    dfs(0, -1, 0);
    cout<<ans;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <string>
#include <queue>
#include <map>
#include <ctime>
#include <cstdio>
using namespace std;
#define ll long long
#define mp make_pair
#define f first
#define s second
int n,m,ans=0, p, q;
int ctr;
vector<vector<int> > gr;
bool mycomp(int a, int b){
	return(a>b);
}
int dfs(int now, int prev, int d){
    vector<int> gg(gr[now].size()-1);
    ans = max(ans, d);
    int ss = 0;
	for (int i=0; i<gr[now].size(); i++){
		if (gr[now][i]==prev)
			continue;
		gg[ss] = dfs(gr[now][i], now, d+1);
		ss++;
	}
	if (gg.size() <= 1){
		if (gg.size() == 0)
		    return (d);
		else
			return (gg[0]);
	}
	else{
		//cout<<"hey"<<gg[0]<<gg[1];
	    sort(gg.begin(), gg.end(), mycomp);
	    ans = max(ans, gg[0] + gg[1] - 2*d);
		return(gg[0]);
	}
}
int main() {
    scanf("%d%d",&n,&m);
    gr.resize(n);
    for (int i=0; i<n-1; ++i){
    	scanf("%d%d",&p,&q);
    	p--; q--;
    	gr[p].push_back(q);
    	gr[q].push_back(p);
    }
    gr[0].push_back(-1);
    dfs(0, -1, 0);
    cout<<ans;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <string>
#include <queue>
#include <map>
#include <ctime>
#include <cstdio>
using namespace std;
#define ll long long
#define mp make_pair
#define f first
#define s second
int n,m,ans=0, p, q;
int ctr;
vector<vector<int> > gr;
bool mycomp(int a, int b){
	return(a>b);
}
int dfs(int now, int prev, int d){
    vector<int> gg(gr[now].size()-1);
    ans = max(ans, d);
	for (int i=0; i<gr[now].size(); i++){
		if (gr[now][i]==prev)
			continue;
		gg[i] = dfs(gr[now][i], now, d+1);
	}
	if (gg.size() <= 1){
		if (gg.size() == 0)
		    return (d);
		else
			return (gg[0]);
	}
	else{
		//cout<<"hey"<<gg[0]<<gg[1];
	    sort(gg.begin(), gg.end(), mycomp);
	    ans = max(ans, gg[0] + gg[1] - 2*d);
		return(gg[0]);
	}
}
int main() {
    scanf("%d%d",&n,&m);
    gr.resize(n);
    for (int i=0; i<n-1; ++i){
    	scanf("%d%d",&p,&q);
    	p--; q--;
    	gr[p].push_back(q);
    	gr[q].push_back(p);
    }
    gr[0].push_back(-1);
    dfs(0, -1, 0);
    cout<<ans;
}


import java.io.*;
import java.util.*;
public class TreeofLife
{
	public static void main(String args[])throws IOException
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int n = Integer.parseInt(st.nextToken());
		//int m = Integer.parseInt(st.nextToken());

			Graph nerve = new Graph(n);
			for(int i=0;i<n-1;i++)
			{
				st = new StringTokenizer(br.readLine());
				int v = Integer.parseInt(st.nextToken());
				int w = Integer.parseInt(st.nextToken());
				nerve.addEdge(v-1,w-1);
			}

			System.out.println(nerve.lifepath());

	}
}
class Graph
{
	ArrayList<Integer> adj[];
	public Graph(int v)
	{
		adj = (ArrayList<Integer>[])new ArrayList[v];
		for(int i=0;i<v;i++)
			adj[i] = new ArrayList<Integer>();

	}
	public void addEdge(int v, int w)
	{
		adj[w].add(v);
		adj[v].add(w);
	}
	public int V()
	{
		return adj.length;
	}
	public int lifepath()
	{
		int count=0;
		for(int i=0;i<adj.length;i++)
		{
			count+=((adj[i].size()-1)*adj[i].size())/2;
		}
		return count;
	}
}


import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int n=in.nextInt();
        Vector<Integer> graph[];
        graph = new Vector[110000];
        for(int i=0;i<110000;++i){
            graph[i]=new Vector<>();
        }
        boolean []visit=new boolean[110000];
        Arrays.fill(visit, false);

        for(int i=0;i<n-1;++i){
            int x=in.nextInt(), y=in.nextInt();
            graph[x].add(y);
            graph[y].add(x);
        }

        int ans = 0;
        for(int i=1;i<=n;++i){
            int deg = graph[i].size();
            ans += ((deg*(deg-1))/2);
        }

        System.out.println(ans);
    }
}


#include<bits/stdc++.h>
#pragma GCC optimize("O2")
#define S second
#define F first
#define PB push_back
#define sz(x) (int) x.size()
#define all(x) x.begin(),x.end()
#define L(x) 2*x
#define R(x) 2*x+1
#define M(x,y) (x+y)/2
using namespace std;
typedef long long ll;
const int N=1e5+1;
vector<int> co[N];
ll ans=0;
void dfs(int x,int p){
    for(auto y:co[x]){
        if(y==p)
            continue;
        dfs(y,x);
    }
    ans+=sz(co[x]);
    if(p!=0)
        ans--;
}
int main(){
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    int n;
    cin>>n;
    for(int i=0;i<n-1;i++){
        int a,b;
        cin>>a>>b;
        co[a].PB(b);
        co[b].PB(a);
    }
    dfs(1,0);
    cout<<ans;
}


#include<bits/stdc++.h>
#pragma GCC optimize("O2")
#define S second
#define F first
#define PB push_back
#define sz(x) (int) x.size()
#define all(x) x.begin(),x.end()
#define L(x) 2*x
#define R(x) 2*x+1
#define M(x,y) (x+y)/2
using namespace std;
typedef long long ll;
const int N=1e5+1;
vector<int> co[N];
ll ans=0;
void dfs(int x,int p){
    for(auto y:co[x]){
        if(y==p)
            continue;
        dfs(y,x);
    }
    if(sz(co[x])>2)
    ans+=sz(co[x]);
    if(p!=0)
        ans--;
}
int main(){
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    int n;
    cin>>n;
    for(int i=0;i<n-1;i++){
        int a,b;
        cin>>a>>b;
        co[a].PB(b);
        co[b].PB(a);
    }
    dfs(1,0);
    cout<<ans;
}


#include<bits/stdc++.h>
#pragma GCC optimize("O2")
#define S second
#define F first
#define PB push_back
#define sz(x) (int) x.size()
#define all(x) x.begin(),x.end()
#define L(x) 2*x
#define R(x) 2*x+1
#define M(x,y) (x+y)/2
using namespace std;
typedef long long ll;
const int N=1e5+1;
vector<int> co[N];
ll ans=0;
void dfs(int x,int p){
    for(auto y:co[x]){
        if(y==p)
            continue;
        dfs(y,x);
    }
    if(sz(co[x])>2)
    ans+=sz(co[x]);
    if(sz(co[x])>2)
    if(p!=0)
        ans--;
}
int main(){
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    int n;
    cin>>n;
    for(int i=0;i<n-1;i++){
        int a,b;
        cin>>a>>b;
        co[a].PB(b);
        co[b].PB(a);
    }
    dfs(1,0);
    cout<<ans;
}