#include <bits/stdc++.h>
#include <iostream>
#include <string>
#include <cstdlib>
#include <string.h>
#include <vector>
#include <cstdio>
#include <iomanip>
#include <stack>
#include <set>
#include <map>
#include <list>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <utility>
#define PI 3.1415926535897932384626433832795l
#define IOS ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define deci(n) cout<<fixed<<setprecision(n);
#define F first
#define S second
#define mk make_pair
#define pb push_back
#define ALPHA 27
#define ll long long int
#define ld long double
#define mmset(arr, n) memset(arr, n, sizeof arr)
#define debug(x) cerr << '#' << ' ' << x << '\n'
#define len(s) s.length()
#define ForA(i,a,b) for(int i = a; i < b; i++)
#define ForA1(i,a,b) for(int i = b - 1; i >= a; i--)
#define ForB1(i,a,b) for(int i = b; i > a; i--)
#define ForB(i,a,b) for(int i = a; i <= b; i++)
#define INT_SIZE 18
#define maxn 1010

using namespace std;

const ll INF = (ll)(8e18);
const ll MOD = 1000000007;

vector <int> G[maxn];
bool vis[maxn],Flag = false,color[maxn];
vector < pair <int,int> > V;
vector <int> d,e;

void dfs(int v, int par){
    vis[v] = true;
    for(int i = 0; i < (int)G[v].size(); i++){
        if(vis[G[v][i]] == false) dfs(G[v][i], v);
        else if(G[v][i] != par && par != -1 && color[G[v][i]] == false){
            V.pb(mk(v, G[v][i]));
            Flag = true;
        }
    }
    color[v] = true;
}

int main()
{
    IOS;
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    #endif
    int n; cin >> n;
    ForB(i,1,n - 1){
        int u,v; cin >> u >> v;
        G[u].pb(v);
        G[v].pb(u);
    }
    ForB(i,1,n){
        Flag = false;
      if(vis[i] == false){
          dfs(i, -1);
          if(Flag == false){
             d.pb(i);
          }else e.pb(i);
      }
    }
    for(int i = 0; i < (int)e.size(); i++) d.pb(e[i]);
    cout << (int)V.size() << '\n';
    for(int i = 0; i < (int)V.size(); i++){
        cout << V[i].F << ' ' << V[i].S << ' ' << V[i].F << ' ' << d[i] << '\n';
    }
    #ifdef LOCAL_DEFINE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
    #endif
    return 0 ;
}


#include <bits/stdc++.h>
#include <iostream>
#include <string>
#include <cstdlib>
#include <string.h>
#include <vector>
#include <cstdio>
#include <iomanip>
#include <stack>
#include <set>
#include <map>
#include <list>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <utility>
#define PI 3.1415926535897932384626433832795l
#define IOS ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define deci(n) cout<<fixed<<setprecision(n);
#define F first
#define S second
#define mk make_pair
#define pb push_back
#define ALPHA 27
#define ll long long int
#define ld long double
#define mmset(arr, n) memset(arr, n, sizeof arr)
#define debug(x) cerr << '#' << ' ' << x << '\n'
#define len(s) s.length()
#define ForA(i,a,b) for(int i = a; i < b; i++)
#define ForA1(i,a,b) for(int i = b - 1; i >= a; i--)
#define ForB1(i,a,b) for(int i = b; i > a; i--)
#define ForB(i,a,b) for(int i = a; i <= b; i++)
#define INT_SIZE 18
#define maxn 1010

using namespace std;

const ll INF = (ll)(8e18);
const ll MOD = 1000000007;

vector <int> G[maxn];
bool vis[maxn],Flag = false,color[maxn];
vector < pair <int,int> > V;
vector <int> d;

void dfs(int v, int par){
    vis[v] = true;
    for(int i = 0; i < (int)G[v].size(); i++){
        if(vis[G[v][i]] == false) dfs(G[v][i], v);
        else if(G[v][i] != par && par != -1 && color[G[v][i]] == false){
            V.pb(mk(v, G[v][i]));
            Flag = true;
        }
    }
    color[v] = true;
}

int main()
{
    IOS;
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    #endif
    int n; cin >> n;
    ForB(i,1,n - 1){
        int u,v; cin >> u >> v;
        G[u].pb(v);
        G[v].pb(u);
    }
    ForB(i,1,n){
        Flag = false;
      if(vis[i] == false){
          dfs(i, -1);
          if(Flag == false){
             d.pb(i);
          }
      }
    }
    if((int)d.size() != (int)V.size()) {cout << 0 << '\n'; return 0;}
    cout << (int)V.size() << '\n';
    for(int i = 0; i < (int)V.size(); i++){
        cout << V[i].F << ' ' << V[i].S << ' ' << V[i].F << ' ' << d[i] << '\n';
    }
    #ifdef LOCAL_DEFINE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
    #endif
    return 0 ;
}


#include <bits/stdc++.h>
#include <iostream>
#include <string>
#include <cstdlib>
#include <string.h>
#include <vector>
#include <cstdio>
#include <iomanip>
#include <stack>
#include <set>
#include <map>
#include <list>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <utility>
#define PI 3.1415926535897932384626433832795l
#define IOS ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define deci(n) cout<<fixed<<setprecision(n);
#define F first
#define S second
#define mk make_pair
#define pb push_back
#define ALPHA 27
#define ll long long int
#define ld long double
#define mmset(arr, n) memset(arr, n, sizeof arr)
#define debug(x) cerr << '#' << ' ' << x << '\n'
#define len(s) s.length()
#define ForA(i,a,b) for(int i = a; i < b; i++)
#define ForA1(i,a,b) for(int i = b - 1; i >= a; i--)
#define ForB1(i,a,b) for(int i = b; i > a; i--)
#define ForB(i,a,b) for(int i = a; i <= b; i++)
#define INT_SIZE 18
#define maxn 1010

using namespace std;

const ll INF = (ll)(8e18);
const ll MOD = 1000000007;

vector <int> G[maxn];
bool vis[maxn],Flag = false;
vector < pair <int,int> > V;
vector <int> d;

void dfs(int v, int par){
    vis[v] = true;
    for(int i = 0; i < (int)G[v].size(); i++){
        if(vis[G[v][i]] == false) dfs(G[v][i], v);
        else if(G[v][i] != par && par != -1){
            V.pb(mk(par, G[v][i]));
            Flag = true;
        }
    }
}

int main()
{
    IOS;
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    #endif
    int n; cin >> n;
    ForB(i,1,n - 1){
        int u,v; cin >> u >> v;
        G[u].pb(v);
        G[v].pb(u);
    }
    ForB(i,1,n){
        Flag = false;
      if(vis[i] == false){
          dfs(i, -1);
          if(Flag == false){
             d.pb(i);
          }
      }
    }
    cout << (int)V.size() << '\n';
    for(int i = 0; i < (int)V.size(); i++){
        cout << V[i].F << ' ' << V[i].S << ' ' << V[i].F << ' ' << d[i] << '\n';
    }
    #ifdef LOCAL_DEFINE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
    #endif
    return 0 ;
}


#include <bits/stdc++.h>
#include <iostream>
#include <string>
#include <cstdlib>
#include <string.h>
#include <vector>
#include <cstdio>
#include <iomanip>
#include <stack>
#include <set>
#include <map>
#include <list>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <utility>
#define PI 3.1415926535897932384626433832795l
#define IOS ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define deci(n) cout<<fixed<<setprecision(n);
#define F first
#define S second
#define mk make_pair
#define pb push_back
#define ALPHA 27
#define ll long long int
#define ld long double
#define mmset(arr, n) memset(arr, n, sizeof arr)
#define debug(x) cerr << '#' << ' ' << x << '\n'
#define len(s) s.length()
#define ForA(i,a,b) for(int i = a; i < b; i++)
#define ForA1(i,a,b) for(int i = b - 1; i >= a; i--)
#define ForB1(i,a,b) for(int i = b; i > a; i--)
#define ForB(i,a,b) for(int i = a; i <= b; i++)
#define INT_SIZE 18
#define maxn 1010

using namespace std;

const ll INF = (ll)(8e18);
const ll MOD = 1000000007;

vector <int> G[maxn];
bool vis[maxn],Flag = false,color[maxn];
vector < pair <int,int> > V;
vector <int> d;

void dfs(int v, int par){
    vis[v] = true;
    for(int i = 0; i < (int)G[v].size(); i++){
        if(vis[G[v][i]] == false) dfs(G[v][i], v);
        else if(G[v][i] != par && par != -1 && color[G[v][i]] == false){
            V.pb(mk(v, G[v][i]));
            Flag = true;
        }
    }
    color[v] = true;
}

int main()
{
    IOS;
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    #endif
    int n; cin >> n;
    ForB(i,1,n - 1){
        int u,v; cin >> u >> v;
        G[u].pb(v);
        G[v].pb(u);
    }
    ForB(i,1,n){
        Flag = false;
      if(vis[i] == false){
          dfs(i, -1);
          if(Flag == false){
             d.pb(i);
          }
      }
    }
    if(n == 100) cerr << (int)d.size() << '\n';
    cout << (int)V.size() << '\n';
    for(int i = 0; i < (int)V.size(); i++){
        cout << V[i].F << ' ' << V[i].S << ' ' << V[i].F << ' ' << d[i] << '\n';
    }
    #ifdef LOCAL_DEFINE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
    #endif
    return 0 ;
}


#include<bits/stdc++.h>
using namespace std;
int par[100002],sz[100002];
vector<pair<int,int> >ao;
vector<pair<int,int> >at;
int find(int x)
{
 if(par[x]==x)
 return x;
 else
 {
  par[x]=find(par[x]);
 }
 return par[x];
}
int unio(int a ,int b)
{
 int c=find(a),d=find(b);
 if(c==d)
 return 1;
 else
 {
  par[c]=d;
 }
 return 0;
}
int main()
	{
 	int n,a,b,i;
 	cin >> n;
 	for(i=0;i<=n;i++)
 	{
  		par[i]=i;
  		sz[i]=1;
 	}
 	for(i=0;i<n-1;i++){
  	cin >> a >> b;
  		if(unio(a,b)==1)
  		{
   		ao.push_back(make_pair(a,b));
  		}
 	}
 	for (i=2;i<=n;i++)
 	{
  		if(unio(1,i)==0)
  		{
   		at.push_back(make_pair(1,i));
  		}
 	}
 cout << ao.size() << endl;
 for(i=0;i<ao.size();i++)
 {
  cout << ao[i].first << " " << ao[i].second << " " << at[i].first << " " << at[i].second << endl;
 }
 return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
int par[100002];
vector<pair<int,int> >city;
vector<pair<int,int> >atpool;
int find(int x){
 	if(par[x]==x)
 		return x;
 	else
  		par[x]=find(par[x]);
 return par[x];
}
int unione(int a ,int b){
 	int c=find(a),d=find(b);
 	if(c==d)
 		return 1;
 	else
  		par[c]=d;
 return 0;
}
int main(){
 	int n,a,b,i;
 	cin >> n;
 	for(i=0;i<=n;i++){
  		par[i]=i;
 	}
 	for(i=0;i<n-1;i++){
  	cin >> a >> b;
  		if(unione(a,b)==1)
   			city.pb(mp(a,b));
 	}
 	for (i=2;i<=n;i++){
  		if(unione(1,i)==0)
   			atpool.pb(mp(1,i));
 	}
 cout << city.size() << endl;
 for(i=0;i<city.size();i++)
  	cout << city[i].first << " " << city[i].second << " " << atpool[i].first << " " << atpool[i].second << endl;
 return 0;
}


#include<bits/stdc++.h>
using namespace std;
int par[100002],sz[100002];
vector<pair<int,int> >ao;
vector<pair<int,int> >at;
int find(int x){
 	if(par[x]==x)
 		return x;
 	else
  		par[x]=find(par[x]);
 return par[x];
}
int unio(int a ,int b){
 	int c=find(a),d=find(b);
 	if(c==d)
 		return 1;
 	else
  		par[c]=d;
 return 0;
}
int main(){
 	int n,a,b,i;
 	cin >> n;
 	for(i=0;i<=n;i++){
  		par[i]=i;
  		sz[i]=1;
 	}
 	for(i=0;i<n-1;i++){
  	cin >> a >> b;
  		if(unio(a,b)==1)
   			ao.push_back(make_pair(a,b));
 	}
 	for (i=2;i<=n;i++){
  		if(unio(1,i)==0)
   			at.push_back(make_pair(1,i));
 	}
 cout << ao.size() << endl;
 for(i=0;i<ao.size();i++)
  	cout << ao[i].first << " " << ao[i].second << " " << at[i].first << " " << at[i].second << endl;
 return 0;
}


#include<bits/stdc++.h>
using namespace std;
long long int par[100002],sz[100002];
vector<pair<long long int,long long int> >ao;
vector<pair<long long int,long long int> >at;
long long int find(long long int x)
{
 if(par[x]==x)
 return x;
 else
 {
  par[x]=find(par[x]);
 }
 return par[x];
}
int unio(long long int a , long long int b)
{
 long long int c=find(a),d=find(b);
 if(c==d)
 return 1;
 else
 {
  par[c]=d;
  sz[d]+=sz[c];
 }
 return 0;
}
int main()
	{
 	long long int n,a,b,i;
 	cin >> n;
 	for(i=0;i<=n;i++)
 	{
  		par[i]=i;
  		sz[i]=1;
 	}
 	for(i=0;i<n-1;i++){
  	cin >> a >> b;
  		if(unio(a,b)==1)
  		{
   		ao.push_back(make_pair(a,b));
  		}
 	}
 	for (i=2;i<=n;i++)
 	{
  		if(unio(2,i)==0)
  		{
   		at.push_back(make_pair(2,i));
  		}
 	}
 cout << ao.size() << endl;
 for(i=0;i<ao.size();i++)
 {
  cout << ao[i].first << " " << ao[i].second << " " << at[i].first << " " << at[i].second << endl;
 }
 return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
int par[100002],sz[100002];
vector<pair<int,int> >ao;
vector<pair<int,int> >at;
int find(int x){
 	if(par[x]==x)
 		return x;
 	else
  		par[x]=find(par[x]);
 return par[x];
}
int unio(int a ,int b){
 	int c=find(a),d=find(b);
 	if(c==d)
 		return 1;
 	else
  		par[c]=d;
 return 0;
}
int main(){
 	int n,a,b,i;
 	cin >> n;
 	for(i=0;i<=n;i++){
  		par[i]=i;
  		sz[i]=1;
 	}
 	for(i=0;i<n-1;i++){
  	cin >> a >> b;
  		if(unio(a,b)==1)
   			ao.pb(make_pair(a,b));
 	}
 	for (i=2;i<=n;i++){
  		if(unio(1,i)==0)
   			at.pb(make_pair(1,i));
 	}
 cout << ao.size() << endl;
 for(i=0;i<ao.size();i++)
  	cout << ao[i].first << " " << ao[i].second << " " << at[i].first << " " << at[i].second << endl;
 return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
int par[100002];
vector<pair<int,int> >ao;
vector<pair<int,int> >at;
int find(int x){
 	if(par[x]==x)
 		return x;
 	else
  		par[x]=find(par[x]);
 return par[x];
}
int unio(int a ,int b){
 	int c=find(a),d=find(b);
 	if(c==d)
 		return 1;
 	else
  		par[c]=d;
 return 0;
}
int main(){
 	int n,a,b,i;
 	cin >> n;
 	for(i=0;i<=n;i++){
  		par[i]=i;
 	}
 	for(i=0;i<n-1;i++){
  	cin >> a >> b;
  		if(unio(a,b)==1)
   			ao.pb(mp(a,b));
 	}
 	for (i=2;i<=n;i++){
  		if(unio(1,i)==0)
   			at.pb(mp(1,i));
 	}
 cout << ao.size() << endl;
 for(i=0;i<ao.size();i++)
  	cout << ao[i].first << " " << ao[i].second << " " << at[i].first << " " << at[i].second << endl;
 return 0;
}


#include<bits/stdc++.h>
using namespace std;
long long int par[100002],sz[100002];
vector<pair<long long int,long long int> >ao;
vector<pair<long long int,long long int> >at;
long long int find(long long int x)
{
 if(par[x]==x)
 return x;
 else
 {
  par[x]=find(par[x]);
 }
 return par[x];
}
int unio(long long int a , long long int b)
{
 long long int c=find(a),d=find(b);
 if(c==d)
 return 1;
 else
 {
  par[c]=d;
 }
 return 0;
}
int main()
	{
 	long long int n,a,b,i;
 	cin >> n;
 	for(i=0;i<=n;i++)
 	{
  		par[i]=i;
  		sz[i]=1;
 	}
 	for(i=0;i<n-1;i++){
  	cin >> a >> b;
  		if(unio(a,b)==1)
  		{
   		ao.push_back(make_pair(a,b));
  		}
 	}
 	for (i=2;i<=n;i++)
 	{
  		if(unio(1,i)==0)
  		{
   		at.push_back(make_pair(1,i));
  		}
 	}
 cout << ao.size() << endl;
 for(i=0;i<ao.size();i++)
 {
  cout << ao[i].first << " " << ao[i].second << " " << at[i].first << " " << at[i].second << endl;
 }
 return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
int par[100002];
vector<pair<int,int> >city;
vector<pair<int,int> >atpool;
int find(int x){
 	if(par[x]==x)
 		return x;
 	else
  		par[x]=find(par[x]);
 return par[x];
}
int unione(int a ,int b){
 	int c=find(a),d=find(b);
 	if(c==d)
 		return 1;
 	else
  		par[c]=d;
 return 0;
}
int main(){
 	int n,a,b,i;
 	cin >> n;
 	for(i=0;i<=n;i++){
  		par[i]=i;
 	}
 	for(i=0;i<n-1;i++){
  	cin >> a >> b;
  		if(unione(a,b)==1)
   			city.pb(mp(a,b));
 	}
 	for (i=2;i<=n;i++){
  		if(unio(1,i)==0)
   			atpool.pb(mp(1,i));
 	}
 cout << city.size() << endl;
 for(i=0;i<city.size();i++)
  	cout << city[i].first << " " << city[i].second << " " << atpool[i].first << " " << atpool[i].second << endl;
 return 0;
}


#include <bits/stdc++.h>

using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)

#define ordered_set tree<int , null_type,less<int >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const int mod = inf + 7;
const int N = 1e6 + 555; // TL MB
const double PI = acos(-1.0);

bool used[40];
int p[40];
map<int, int> cnt;
int get(int v){
	return v == p[v] ? v : p[v] = get(p[v]);
}
bool merge(int a, int b){
	a = get(a), b = get(b);
	if(a != b){
		p[b] = a;
		return 1;
	}
	return 0;
}
vector<pair<int, int> > q;
void solve()
{
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i) p[i] = i;
	for(int i = 0; i < n - 1; ++i){
		int u, v;
		cin >> u >> v;
		if(!merge(u, v)) q.pb({u, v});
	}
	set<int> st;
	for(int i = 1; i <= n; ++i){
			st.insert(get(i));
	}
	vector<int> qq;
	for(auto it : st) qq.pb(it);
	cout << sz(qq) - 1 << endl;
	for(int i = 1; i < qq.size(); ++i){
		cout << q.back().F << " " << q.back().S << " "  << qq[i - 1] << " " << qq[i] ;
		q.pop_back();
	}

}

int main()
{
    Red;
    // int T; cin >> T; while(T--)
    solve();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)

#define ordered_set tree<int , null_type,less<int >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const int mod = inf + 7;
const int N = 1e6 + 555; // TL MB
const double PI = acos(-1.0);

bool used[40];
int p[40];
map<int, int> cnt;
int get(int v){
	return v == p[v] ? v : p[v] = get(p[v]);
}
bool merge(int a, int b){
	a = get(a), b = get(b);
	if(a != b){
		p[b] = a;
		return 1;
	}
	return 0;
}
vector<pair<int, int> > q;
void solve()
{
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i) p[i] = i;
	for(int i = 0; i < n - 1; ++i){
		int u, v;
		cin >> u >> v;
		if(!merge(u, v)) q.pb({u, v});
	}
	set<int> st;
	for(int i = 1; i <= n; ++i){
			st.insert(get(i));
	}
	vector<int> qq;
	for(auto it : st) qq.pb(it);
	cout << sz(qq) - 1 << endl;
	for(int i = 1; i < qq.size(); ++i){
		cout << q.back().F << " " << q.back().S << " "  << qq[i - 1] << " " << qq[i] << endl ;
		q.pop_back();
	}

}

int main()
{
    Red;
    // int T; cin >> T; while(T--)
    solve();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)

#define ordered_set tree<int , null_type,less<int >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const int mod = inf + 7;
const int N = 1e6 + 555; // TL MB
const double PI = acos(-1.0);

bool used[N];
int p[N];
map<int, int> cnt;
int get(int v){
	return v == p[v] ? v : p[v] = get(p[v]);
}
bool merge(int a, int b){
	a = get(a), b = get(b);
	if(a != b){
		p[b] = a;
		return 1;
	}
	return 0;
}
vector<pair<int, int> > q;
void solve()
{
	int n;
	cin >> n;
	for(int i = 0; i < n - 1; ++i){
		int u, v;
		cin >> u >> v;
		if(!merge(u, v)) q.pb({u, v}});
	}
	set<int> st;
	for(int i = 1; i <= n; ++i){
			st.insert(get(i));
	}
	vector<int> qq;
	for(auto it : st) qq.pb(it);
	cout << sz(qq) - 1 << endl;
	for(int i = 1; i < qq.size(); ++i){
		cout << q.back().F << " " << q.back().S << " "  << qq[i - 1] << " " << qq[i] << endl;
		q.pop_back();
	}

}

int main()
{
    Red;
    // int T; cin >> T; while(T--)
    solve();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)

#define ordered_set tree<int , null_type,less<int >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const int mod = inf + 7;
const int N = 1e6 + 555; // TL MB
const double PI = acos(-1.0);

bool used[40];
int p[40];
map<int, int> cnt;
int get(int v){
	return v == p[v] ? v : p[v] = get(p[v]);
}
bool merge(int a, int b){
	a = get(a), b = get(b);
	if(a != b){
		p[b] = a;
		return 1;
	}
	return 0;
}
vector<pair<int, int> > q;
void solve()
{
	int n;
	cin >> n;
	for(int i = 0; i < n - 1; ++i){
		int u, v;
		cin >> u >> v;
		if(!merge(u, v)) q.pb({u, v}});
	}
	set<int> st;
	for(int i = 1; i <= n; ++i){
			st.insert(get(i));
	}
	vector<int> qq;
	for(auto it : st) qq.pb(it);
	cout << sz(qq) - 1 << endl;
	for(int i = 1; i < qq.size(); ++i){
		cout << q.back().F << " " << q.back().S << " "  << qq[i - 1] << " " << qq[i] << endl;
		q.pop_back();
	}

}

int main()
{
    Red;
    // int T; cin >> T; while(T--)
    solve();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)

#define ordered_set tree<int , null_type,less<int >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const int mod = inf + 7;
const int N = 1e6 + 555; // TL MB
const double PI = acos(-1.0);

bool used[40];
int p[40];
map<int, int> cnt;
int get(int v){
	return v == p[v] ? v : p[v] = get(p[v]);
}
bool merge(int a, int b){
	a = get(a), b = get(b);
	if(a != b){
		p[b] = a;
		return 1;
	}
	return 0;
}
vector<pair<int, int> > q;
void solve()
{
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i) p[i] = i;
	for(int i = 0; i < n - 1; ++i){
		int u, v;
		cin >> u >> v;
		if(!merge(u, v)) q.pb({u, v});
	}
	set<int> st;
	for(int i = 1; i <= n; ++i){
			st.insert(get(i));
	}
	vector<int> qq;
	for(auto it : st) qq.pb(it);
	cout << sz(qq) - 1 << endl;
	for(int i = 1; i < qq.size(); ++i){
		cout << qq[i - 1] << " " << qq[i] << " " << q.back().F << " " << q.back().S;
		q.pop_back();
	}

}

int main()
{
    Red;
    // int T; cin >> T; while(T--)
    solve();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

#define pb push_back
#define mp make_pair
#define cotu cout
#define itn int
#define Red ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define F first
#define S second
#define sz(x) (int)x.size()
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int i = 0; i < n; ++i)
#define repr(i,n) for(int i = n - 1; i >= 0; --i)
#define Rep(i, a, n) for(int i = (a); i <=(n); ++i)
#define repst(i, n) for(auto it = n.begin(); it != n.end(); ++it)
#define Repr(i, a, n) for(int i = (n); i >= (a); --i)

#define ordered_set tree<int , null_type,less<int >, rb_tree_tag,tree_order_statistics_node_update>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;

const int inf = int(1e9);
const int mod = inf + 7;
const int N = 1e6 + 555; // TL MB
const double PI = acos(-1.0);

bool used[40];
int p[N];
map<int, int> cnt;
int get(int v){
	return v == p[v] ? v : p[v] = get(p[v]);
}
bool merge(int a, int b){
	a = get(a), b = get(b);
	if(a != b){
		p[b] = a;
		return 1;
	}
	return 0;
}
vector<pair<int, int> > q;
void solve()
{
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i) p[i] = i;
	for(int i = 0; i < n - 1; ++i){
		int u, v;
		cin >> u >> v;
		if(!merge(u, v)) q.pb({u, v});
	}
	set<int> st;
	for(int i = 1; i <= n; ++i){
			st.insert(get(i));
	}
	vector<int> qq;
	for(auto it : st) qq.pb(it);
	cout << sz(qq) - 1 << endl;
	for(int i = 1; i < qq.size(); ++i){
		cout << q.back().F << " " << q.back().S << " "  << qq[i - 1] << " " << qq[i] << endl ;
		q.pop_back();
	}

}

int main()
{
    Red;
    // int T; cin >> T; while(T--)
    solve();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
const int LIM = 5e5+5, MOD = 1e9+7;
int t,n,m,k,x,y;
int size[(const int)1e5];
int parent[(const int)1e5];
int findparent(int x){
	if(x == parent[x]) return x;
	else parent[x] = findparent(parent[x]);
	return parent[x];
}
int myunion(int a,int b){
	a = findparent(a);
	b = findparent(b);
	if(a != b){
		if(size[a] < size[b])
			swap(a,b);
		parent[b] = a;
		size[a] += size[b];
		return 1;
	}
	else return 0;
}
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n;
	vp32 v1,v2;
	set<int> v3;
	forn(i,n+1) parent[i] = i;
	forn(i,n-1){
		cin >> x >> y;
		// if(x > y) swap(x,y);
		v1.pb(mp(x,y));
	}
	// sort(v1.begin(),v1.end());
	forn(i,n-1){
		x = v1[i].fi;
		y = v1[i].se;
		t = myunion(x,y);
		t = findparent(x);
		t = findparent(y);
		if(t == 0) v2.pb(mp(x,y));
	}
	queue<int> q3;
	forsn(i,1,n+1){
		if(v3.find(parent[i]) == v3.end())
			q3.push(parent[i]);
		v3.insert(parent[i]);
	}
	// forn(i,n+1){/
	// cout << v2.size() << " " << q3.size()<<endl;
	if(!q3.empty()){
		x = q3.front();
		q3.pop();
	}
	// cout << "G";
	cout << v2.size()<<endl; y = 0;
	while(!q3.empty()){
		cout << v2[y].fi << " " << v2[y].se << " ";
		cout << x << " " << q3.front() <<endl;
		q3.pop();
		y++;
	}
	// cout << v3.size();
	// cout << v2.size() << endl;
	// forsn(i,1,n+1) cout << parent[i] << " ";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
const int LIM = 5e5+5, MOD = 1e9+7;
int t,n,m,k,x,y;
int size[(const int)1e5];
int parent[(const int)1e5];
int findparent(int a){
	if(a == parent[a])
		return a;
	else{
		parent[a] = findparent(parent[a]);
		return parent[a];
	}
}
int myunion(int a,int b){
	a = findparent(a);
	b = findparent(b);
	if(a == b) return 0;
	else {
		if(size[a] < size[b])
			swap(a,b);
		size[a] += size[b];
		parent[b] = a;
		return 1;
	}
}
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n;
	vp32 v1,v2;
	set<int> v3;
	forn(i,n+1) parent[i] = i;
	forn(i,n-1){
		cin >> x >> y;
		if(x > y) swap(x,y);
		v1.pb(mp(x,y));
	}
	sort(v1.begin(),v1.end());
	forn(i,n-1){
		x = v1[i].fi;
		y = v1[i].se;
		t = myunion(x,y);
		if(t == 0) v2.pb(mp(x,y));
	}
	queue<int> q3;
	forsn(i,1,n+1){
		if(v3.find(parent[i]) == v3.end())
			q3.push(parent[i]);
		v3.insert(parent[i]);
	}
	// forn(i,n+1){/
	// cout << v2.size() << " " << q3.size()<<endl;
	if(!q3.empty()){
		x = q3.front();
		q3.pop();
	}
	// cout << "G";
	cout << v2.size()<<endl; y = 0;
	while(!q3.empty()){
		cout << v2[y].fi << " " << v2[y].se << " ";
		cout << x << " " << q3.front() <<endl;
		q3.pop();
		y++;
	}
	// cout << v3.size();
	// cout << v2.size() << endl;
	// forsn(i,1,n+1) cout << parent[i] << " ";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
const int LIM = 5e5+5, MOD = 1e9+7;
int t,n,m,k,x,y;
int size[(const int)1e5];
int parent[(const int)1e5];
int findparent(int x){
	if(x == parent[x]) return x;
	else parent[x] = findparent(parent[x]);
	return parent[x];
}
int myunion(int a,int b){
	a = findparent(a);
	b = findparent(b);
	if(a != b){
		if(size[a] < size[b])
			swap(a,b);
		parent[b] = a;
		// cout << "out " <<  a << " " << b <<endl;
		size[a] += size[b];
		return 1;
	}
	else return 0;
}
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n;
	vp32 v1,v2;
	set<int> v3;
	forn(i,n+1) {size[i] = 1; parent[i] = i;}
	forn(i,n-1){
		cin >> x >> y;
		// if(x > y) swap(x,y);
		v1.pb(mp(x,y));
	}
	forn(i,n-1){
		x = v1[i].fi;
		y = v1[i].se;
		t = myunion(x,y);
		if(t == 0) v2.pb(mp(x,y));
	}
	forn(i,n+1){
		t = findparent(i);
	}
	queue<int> q3;
	forsn(i,1,n+1){
		if(v3.find(parent[i]) == v3.end())
			q3.push(parent[i]);
		v3.insert(parent[i]);
	}
	// forn(i,n+1){/
	// cout << v2.size() << " " << q3.size()<<endl;
	if(!q3.empty()){
		x = q3.front();
		q3.pop();
	}
	// cout << "G";
	cout << v2.size()<<endl; y = 0;
	while(!q3.empty() and y < v2.size()){
		cout << v2[y].fi << " " << v2[y].se << " ";
		cout << x << " " << q3.front() <<endl;
		x = q3.front();
		q3.pop();
		y++;
	}
	// cout << v3.size();
	// cout << v2.size() << endl;
	// forsn(i,1,n+1) cout << parent[i] << " ";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
const int LIM = 5e5+5, MOD = 1e9+7;
int t,n,m,k,x,y;
int size[(const int)1e5];
int parent[(const int)1e5];
int findparent(int x){
	if(x == parent[x]) return x;
	else parent[x] = findparent(parent[x]);
	return parent[x];
}
int myunion(int a,int b){
	a = findparent(a);
	b = findparent(b);
	if(a != b){
		if(size[a] < size[b])
			swap(a,b);
		parent[b] = a;
		size[a] += size[b];
		return 1;
	}
	else return 0;
}
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n;
	vp32 v1,v2;
	set<int> v3;
	forn(i,n+1) parent[i] = i;
	forn(i,n-1){
		cin >> x >> y;
		// if(x > y) swap(x,y);
		v1.pb(mp(x,y));
	}
	// sort(v1.begin(),v1.end());
	forn(i,n-1){
		x = v1[i].fi;
		y = v1[i].se;
		t = myunion(x,y);
		t = findparent(x);
		t = findparent(y);
		if(t == 0) v2.pb(mp(x,y));
	}
	queue<int> q3;
	forsn(i,1,n+1){
		if(v3.find(parent[i]) == v3.end())
			q3.push(parent[i]);
		v3.insert(parent[i]);
	}
	// forn(i,n+1){/
	cout << v2.size() << " " << q3.size()<<endl;
	if(!q3.empty()){
		x = q3.front();
		q3.pop();
	}
	// cout << "G";
	cout << v2.size()<<endl; y = 0;
	while(!q3.empty()){
		cout << v2[y].fi << " " << v2[y].se << " ";
		cout << x << " " << q3.front() <<endl;
		q3.pop();
		y++;
	}
	// cout << v3.size();
	// cout << v2.size() << endl;
	// forsn(i,1,n+1) cout << parent[i] << " ";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
const int LIM = 5e5+5, MOD = 1e9+7;
int t,n,m,k,x,y;
int size[(const int)1e5];
int parent[(const int)1e5];
int findparent(int x){
	if(x == parent[x]) return x;
	else parent[x] = findparent(parent[x]);
	return parent[x];
}
int myunion(int a,int b){
	a = findparent(a);
	b = findparent(b);
	if(a != b){
		if(size[a] < size[b])
			swap(a,b);
		parent[b] = a;
		size[a] += size[b];
		return 1;
	}
	else return 0;
}
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n;
	vp32 v1,v2;
	set<int> v3;
	forn(i,n+1) {size[i] = 1; parent[i] = i;}
	forn(i,n-1){
		cin >> x >> y;
		// if(x > y) swap(x,y);
		v1.pb(mp(x,y));
	}
	forn(i,n-1){
		x = v1[i].fi;
		y = v1[i].se;
		t = myunion(x,y);
		if(t == 0) v2.pb(mp(x,y));
	}
	queue<int> q3;
	forsn(i,1,n+1){
		if(v3.find(parent[i]) == v3.end())
			q3.push(parent[i]);
		v3.insert(parent[i]);
	}
	// forn(i,n+1){/
	// cout << v2.size() << " " << q3.size()<<endl;
	if(!q3.empty()){
		x = q3.front();
		q3.pop();
	}
	// cout << "G";
	cout << v2.size()<<endl; y = 0;
	while(!q3.empty()){
		cout << v2[y].fi << " " << v2[y].se << " ";
		cout << x << " " << q3.front() <<endl;
		q3.pop();
		y++;
	}
	// cout << v3.size();
	// cout << v2.size() << endl;
	// forsn(i,1,n+1) cout << parent[i] << " ";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
const int LIM = 5e5+5, MOD = 1e9+7;
int t,n,m,k,x,y;
int size[(const int)1e5];
int parent[(const int)1e5];
int findparent(int x){
	if(x == parent[x]) return x;
	else parent[x] = findparent(parent[x]);
	return parent[x];
}
int myunion(int a,int b){
	a = findparent(a);
	b = findparent(b);
	if(a != b){
		if(size[a] < size[b])
			swap(a,b);
		parent[b] = a;
		// cout << "out " <<  a << " " << b <<endl;
		size[a] += size[b];
		return 1;
	}
	else return 0;
}
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n;
	vp32 v1,v2;
	set<int> v3;
	forn(i,n+1) {size[i] = 1; parent[i] = i;}
	forn(i,n-1){
		cin >> x >> y;
		// if(x > y) swap(x,y);
		v1.pb(mp(x,y));
	}
	forn(i,n-1){
		x = v1[i].fi;
		y = v1[i].se;
		t = myunion(x,y);
		if(t == 0) v2.pb(mp(x,y));
	}
	queue<int> q3;
	forsn(i,1,n+1){
		if(v3.find(parent[i]) == v3.end())
			q3.push(parent[i]);
		v3.insert(parent[i]);
	}
	// forn(i,n+1){/
	// cout << v2.size() << " " << q3.size()<<endl;
	if(!q3.empty()){
		x = q3.front();
		q3.pop();
	}
	// cout << "G";
	cout << v2.size()<<endl; y = 0;
	while(!q3.empty() and y < v2.size()){
		cout << v2[y].fi << " " << v2[y].se << " ";
		cout << x << " " << q3.front() <<endl;
		q3.pop();
		y++;
	}
	// cout << v3.size();
	// cout << v2.size() << endl;
	// forsn(i,1,n+1) cout << parent[i] << " ";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
const int LIM = 5e5+5, MOD = 1e9+7;
int t,n,m,k,x,y;
int size[(const int)1e5];
int parent[(const int)1e5];
int findparent(int x){
	if(x == parent[x]) return x;
	else parent[x] = findparent(parent[x]);
	return parent[x];
}
int myunion(int a,int b){
	a = findparent(a);
	b = findparent(b);
	if(a != b){
		if(size[a] < size[b])
			swap(a,b);
		parent[b] = a;
		// cout << "out " <<  a << " " << b <<endl;
		size[a] += size[b];
		return 1;
	}
	else return 0;
}
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n;
	vp32 v1,v2;
	set<int> v3;
	forn(i,n+1) {size[i] = 1; parent[i] = i;}
	forn(i,n-1){
		cin >> x >> y;
		// if(x > y) swap(x,y);
		v1.pb(mp(x,y));
	}
	forn(i,n-1){
		x = v1[i].fi;
		y = v1[i].se;
		t = myunion(x,y);
		if(t == 0) v2.pb(mp(x,y));
	}
	queue<int> q3;
	forsn(i,1,n+1){
		if(v3.find(parent[i]) == v3.end())
			q3.push(parent[i]);
		v3.insert(parent[i]);
	}
	// forn(i,n+1){/
	// cout << v2.size() << " " << q3.size()<<endl;
	if(!q3.empty()){
		x = q3.front();
		q3.pop();
	}
	// cout << "G";
	cout << v2.size()<<endl; y = 0;
	while(!q3.empty() and y < v2.size()){
		cout << v2[y].fi << " " << v2[y].se << " ";
		cout << x << " " << q3.front() <<endl;
		x = q3.front();
		q3.pop();
		y++;
	}
	// cout << v3.size();
	// cout << v2.size() << endl;
	// forsn(i,1,n+1) cout << parent[i] << " ";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
const int LIM = 5e5+5, MOD = 1e9+7;
int t,n,m,k,x,y;
int size[(const int)1e5];
int parent[(const int)1e5];
int findparent(int x){
	if(x == parent[x]) return x;
	else parent[x] = findparent(parent[x]);
	return parent[x];
}
int myunion(int a,int b){
	a = findparent(a);
	b = findparent(b);
	if(a != b){
		if(size[a] < size[b])
			swap(a,b);
		parent[b] = a;
		// cout << "out " <<  a << " " << b <<endl;
		size[a] += size[b];
		return 1;
	}
	else return 0;
}
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n;
	vp32 v1,v2;
	set<int> v3;
	forn(i,n+1) {size[i] = 1; parent[i] = i;}
	forn(i,n-1){
		cin >> x >> y;
		if(x > y) swap(x,y);
		v1.pb(mp(x,y));
	}
	forn(i,n-1){
		x = v1[i].fi;
		y = v1[i].se;
		t = myunion(x,y);
		if(t == 0) v2.pb(mp(x,y));
	}
	queue<int> q3;
	forsn(i,1,n+1){
		if(v3.find(parent[i]) == v3.end())
			q3.push(parent[i]);
		v3.insert(parent[i]);
	}
	// forn(i,n+1){/
	// cout << v2.size() << " " << q3.size()<<endl;
	if(!q3.empty()){
		x = q3.front();
		q3.pop();
	}
	// cout << "G";
	cout << v2.size()<<endl; y = 0;
	while(!q3.empty() and y < v2.size()){
		cout << v2[y].fi << " " << v2[y].se << " ";
		cout << x << " " << q3.front() <<endl;
		q3.pop();
		y++;
	}
	// cout << v3.size();
	// cout << v2.size() << endl;
	// forsn(i,1,n+1) cout << parent[i] << " ";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define forstl(i,v) for(auto &i: v)
#define forn(i,e) for(int i = 0; i < e; i++)
#define forsn(i,s,e) for(int i = s; i < e; i++)
#define rforn(i,s) for(int i = s; i >= 0; i--)
#define rforsn(i,s,e) for(int i = s; i >= e; i--)
#define ln "\n"
#define dbg(x) cout<<#x<<" = "<<x<<ln
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> p32;
typedef pair<ll,ll> p64;
typedef pair<double,double> pdd;
typedef vector<ll> v64;
typedef vector<int> v32;
typedef vector<vector<int> > vv32;
typedef vector<p64> vp64;
typedef vector<p32> vp32;
typedef map<int,int> m32;
#pragma GCC optimize ("-O2")
const int LIM = 5e5+5, MOD = 1e9+7;
int t,n,m,k,x,y;
int size[(const int)1e5];
int parent[(const int)1e5];
int findparent(int a){
	if(a == parent[a])
		return a;
	else{
		parent[a] = findparent(parent[a]);
		return parent[a];
	}
}
int myunion(int a,int b){
	a = findparent(a);
	b = findparent(b);
	if(a == b) return 0;
	else {
		if(size[a] < size[b])
			swap(a,b);
		size[a] += size[b];
		parent[b] = a;
		return 1;
	}
}
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n;
	vp32 v1,v2;
	set<int> v3;
	forn(i,n+1) parent[i] = i;
	forn(i,n-1){
		cin >> x >> y;
		v1.pb(mp(x,y));
	}
	forn(i,n-1){
		x = v1[i].fi;
		y = v1[i].se;
		t = myunion(x,y);
		if(t == 0) v2.pb(mp(x,y));
	}
	queue<int> q3;
	forsn(i,1,n+1){
		if(v3.find(parent[i]) == v3.end())
			q3.push(parent[i]);
		v3.insert(parent[i]);
	}
	x = q3.front();
	q3.pop();
	cout << v2.size()<<endl; y = 0;
	while(!q3.empty()){
		cout << v2[y].fi << " " << v2[y].se << " ";
		cout << x << " " << q3.front() <<endl;
		q3.pop();
	}
	// cout << v3.size();
	// cout << v2.size() << endl;
	// forsn(i,1,n+1) cout << parent[i] << " ";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e3+1;
vector<int>a[N],vis(N),p(N),size(N),components;
vector<pair<int,int> >useless;
int find_set(int v)
{
	if (p[v]==v)return v;
	else return p[v]=find_set(p[v]);
}
void union_sets(int a,int b)
{
	a=find_set(a);
	b=find_set(b);
	if (a!=b)
	{
		if (size[a]<size[b])swap(a,b);
		p[b]=a;
		size[a]+=size[b];
	}
}
void dfs(int u)
{
	vis[u]=1;
	for (int i=0;i<a[u].size();i++)
	{
		if (!vis[a[u][i]])
		{
			union_sets(u,a[u][i]);
			vis[a[u][i]]=1;
			dfs(a[u][i]);
		}else if (vis[a[u][i]]==1)useless.push_back({a[u][i],u});
	}
	vis[u]=2;
}
int main()
{
	int n,u,v,k=0;
	cin >>n;
	for (int i=1;i<=1000;i++)
	{
		size[i]=1;
		p[i]=i;
	}
	for (int i=0;i<n-1;i++)
	{
		cin >>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);

	}
	for (int i=1;i<=1000;i++)
	{
		if (!vis[i])
		{
			dfs(i);
			components.push_back(find_set(i));
			k++;
		}
	}
//	cout <<components[0]<<" "<<components[1]<<endl;
	cout <<k-1<<endl;
	for (int i=0;i<k-1;i++)
	{
		cout <<useless[i].first<<" "<<useless[i].second<<" "<<components[i]<<" "<<components[i+1]<<endl;
		union_sets(components[i],components[i+1]);
	}
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e3+1;
vector<int>a[N],vis(N),p(N),size(N),components;
vector<pair<int,int> >useless;
int find_set(int v)
{
	if (p[v]==v)return v;
	else return p[v]=find_set(p[v]);
}
void union_sets(int a,int b)
{
	a=find_set(a);
	b=find_set(b);
	if (a!=b)
	{
		if (size[a]<size[b])swap(a,b);
		p[b]=a;
		size[a]+=size[b];
	}
}
void dfs(int u)
{
	vis[u]=1;
	for (int i=0;i<a[u].size();i++)
	{
		if (!vis[a[u][i]])
		{
			union_sets(u,a[u][i]);
			vis[a[u][i]]=1;
			dfs(a[u][i]);
		}else if (vis[a[u][i]]==1)useless.push_back({a[u][i],u});
	}
	vis[u]=2;
}
int main()
{
	int n,u,v,k=0;
	cin >>n;
	for (int i=1;i<=1000;i++)
	{
		size[i]=1;
		p[i]=i;
	}
	for (int i=0;i<n-1;i++)
	{
		cin >>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);

	}
	for (int i=1;i<=n;i++)
	{
		if (!vis[i])
		{
			dfs(i);
			components.push_back(find_set(i));
			k++;
		}
	}
//	cout <<components[0]<<" "<<components[1]<<endl;
	cout <<k-1<<endl;
	for (int i=0;i<k-1;i++)
	{
		cout <<useless[i].first<<" "<<useless[i].second<<" "<<components[i]<<" "<<components[i+1]<<endl;
		union_sets(components[i],components[i+1]);
	}
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e3+1;
vector<int>a[N],vis(N),p(N),size(N),components;
vector<pair<int,int> >useless;
int find_set(int v)
{
	if (p[v]==v)return v;
	else return p[v]=find_set(p[v]);
}
void union_sets(int a,int b)
{
	a=find_set(a);
	b=find_set(b);
	if (a!=b)
	{
		if (size[a]<size[b])swap(a,b);
		p[b]=a;
		size[a]+=size[b];
	}
}
void dfs(int u)
{
	vis[u]=1;
	for (int i=0;i<a[u].size();i++)
	{
		if (!vis[a[u][i]])
		{
			union_sets(u,a[u][i]);
			vis[a[u][i]]=1;
			dfs(a[u][i]);
		}else if (vis[a[u][i]]==1)useless.push_back({a[u][i],u});
	}
	vis[u]=2;
}
int main()
{
	int n,u,v,k=0;
	cin >>n;
	for (int i=0;i<n-1;i++)
	{
		cin >>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);
		size[i+1]=1;
		p[i+1]=i;
	}
	for (int i=1;i<=n;i++)
	{
		if (!vis[i])
		{
			dfs(i);
			components.push_back(i);
			k++;
		}
	}
//	cout <<components[0]<<" "<<components[1]<<endl;
	cout <<k-1<<endl;
	for (int i=0;i<k-1;i++)
	{
		cout <<useless[i].first<<" "<<useless[i].second<<" "<<components[i]<<" "<<components[i+1]<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e3+1;
vector<int>a[N],vis(N),p(N),size(N),components;
vector<pair<int,int> >useless;
int find_set(int v)
{
	if (p[v]==v)return v;
	else return p[v]=find_set(p[v]);
}
void union_sets(int a,int b)
{
	a=find_set(a);
	b=find_set(b);
	if (a!=b)
	{
		if (size[a]<size[b])swap(a,b);
		p[b]=a;
		size[a]+=size[b];
	}
}
void dfs(int u,int parent)
{
	vis[u]=1;
	for (int i=0;i<a[u].size();i++)
	{
		if (!vis[a[u][i]])
		{
			union_sets(u,a[u][i]);
			vis[a[u][i]]=1;
			dfs(a[u][i],u);
		}else if (vis[a[u][i]]==1 and a[u][i]!=parent)useless.push_back({a[u][i],u});
	}
	vis[u]=2;
}
int main()
{
	int n,u,v,k=0;
	cin >>n;
	for (int i=1;i<=1000;i++)
	{
		size[i]=1;
		p[i]=i;
	}
	for (int i=0;i<n-1;i++)
	{
		cin >>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);

	}
	for (int i=1;i<=n;i++)
	{
		if (!vis[i])
		{
			dfs(i,i);
			components.push_back(find_set(i));
			k++;
		}
	}
//	cout <<components[0]<<" "<<components[1]<<endl;
	cout <<k-1<<endl;
	for (int i=0;i<k-1;i++)
	{
		cout <<useless[i].first<<" "<<useless[i].second<<" "<<1<<" "<<components[i+1] <<endl;

	}
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e3+1;
vector<int>a[N],vis(N),p(N),size(N),components;
vector<pair<int,int> >useless;
int find_set(int v)
{
	if (p[v]==v)return v;
	else return p[v]=find_set(p[v]);
}
void union_sets(int a,int b)
{
	a=find_set(a);
	b=find_set(b);
	if (a!=b)
	{
		if (size[a]<size[b])swap(a,b);
		p[b]=a;
		size[a]+=size[b];
	}
}
void dfs(int u)
{
	vis[u]=1;
	for (int i=0;i<a[u].size();i++)
	{
		if (!vis[a[u][i]])
		{
			union_sets(u,a[u][i]);
			vis[a[u][i]]=1;
			dfs(a[u][i]);
		}else if (vis[a[u][i]]==1)useless.push_back({a[u][i],u});
	}
	vis[u]=2;
}
int main()
{
	int n,u,v,k=0;
	cin >>n;
	for (int i=1;i<=1000;i++)
	{
		size[i]=1;
		p[i]=i;
	}
	for (int i=0;i<n-1;i++)
	{
		cin >>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);

	}
	for (int i=1;i<=n;i++)
	{
		if (!vis[i])
		{
			dfs(i);
			components.push_back(find_set(i));
			k++;
		}
	}
//	cout <<components[0]<<" "<<components[1]<<endl;
	cout <<k-1<<endl;
	for (int i=0;i<k-1;i++)
	{
		cout <<useless[i].first<<" "<<useless[i].second<<" "<<1<<" "<<components[i+1] <<endl;

	}
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e3+1;
vector<int>a[N],vis(N),p(N),size(N),components;
vector<pair<int,int> >useless;
int find_set(int v)
{
	if (p[v]==v)return v;
	else return p[v]=find_set(p[v]);
}
void union_sets(int a,int b)
{
	a=find_set(a);
	b=find_set(b);
	if (a!=b)
	{
		if (size[a]<size[b])swap(a,b);
		p[b]=a;
		size[a]+=size[b];
	}
}
void dfs(int u)
{
	vis[u]=1;
	for (int i=0;i<a[u].size();i++)
	{
		if (!vis[a[u][i]])
		{
			union_sets(u,a[u][i]);
			vis[a[u][i]]=1;
			dfs(a[u][i]);
		}else if (vis[a[u][i]]==1)useless.push_back({a[u][i],u});
	}
	vis[u]=2;
}
int main()
{
	int n,u,v,k=0;
	cin >>n;
	for (int i=0;i<n-1;i++)
	{
		cin >>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);
		size[i+1]=1;
		p[i+1]=i+1;
	}
	for (int i=1;i<=n;i++)
	{
		if (!vis[i])
		{
			dfs(i);
			components.push_back(find_set(i));
			k++;
		}
	}
//	cout <<components[0]<<" "<<components[1]<<endl;
	cout <<k-1<<endl;
	for (int i=0;i<k-1;i++)
	{
		cout <<useless[i].first<<" "<<useless[i].second<<" "<<components[i]<<" "<<components[i+1]<<endl;
		union_sets(components[i],components[i+1]);
	}
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e3+1;
vector<int>a[N],vis(N),p(N),size(N),components;
vector<pair<int,int> >useless;
int find_set(int v)
{
	if (p[v]==v)return v;
	else return p[v]=find_set(p[v]);
}
void union_sets(int a,int b)
{
	a=find_set(a);
	b=find_set(b);
	if (a!=b)
	{
		if (size[a]<size[b])swap(a,b);
		p[b]=a;
		size[a]+=size[b];
	}
}
void dfs(int u)
{
	vis[u]=1;
	for (int i=0;i<a[u].size();i++)
	{
		if (!vis[a[u][i]])
		{
			union_sets(u,a[u][i]);
			vis[a[u][i]]=1;
			dfs(a[u][i]);
		}else if (vis[a[u][i]]==1)useless.push_back({a[u][i],u});
	}
	vis[u]=2;
}
int main()
{
	int n,u,v,k=0;
	cin >>n;
	for (int i=1;i<=1000;i++)
	{
		size[i]=1;
		p[i]=i;
	}
	for (int i=0;i<n-1;i++)
	{
		cin >>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);

	}
	for (int i=1;i<=n;i++)
	{
		if (!vis[i])
		{
			dfs(i);
			components.push_back(find_set(i));
			k++;
		}
	}
//	cout <<components[0]<<" "<<components[1]<<endl;
	cout <<k-1<<endl;
	for (int i=0;i<k-1;i++)
	{
		cout <<useless[i].first<<" "<<useless[i].second<<" "<<find_set(components[i])<<" "<<find_set(components[i+1])<<endl;
		union_sets(components[i],components[i+1]);
	}
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e3+1;
vector<int>a[N],vis(N),p(N),size(N),components;
vector<pair<int,int> >useless;

void dfs(int u,int parent)
{
	vis[u]=1;
	for (int i=0;i<a[u].size();i++)
	{
		if (!vis[a[u][i]])
		{

			vis[a[u][i]]=1;
			dfs(a[u][i],u);
		}else if (vis[a[u][i]]==1 and a[u][i]!=parent)useless.push_back({a[u][i],u});
	}
	vis[u]=2;
}
int main()
{
	int n,u,v,k=0;
	cin >>n;
	for (int i=0;i<n-1;i++)
	{
		cin >>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);

	}
	for (int i=1;i<=n;i++)
	{
		if (!vis[i])
		{
			dfs(i,i);
			components.push_back((i));
			k++;
		}
	}
//	cout <<components[0]<<" "<<components[1]<<endl;
	cout <<k-1<<endl;
	for (int i=0;i<k-1;i++)
	{
		cout <<useless[i].first<<" "<<useless[i].second<<" "<<1<<" "<<components[i+1] <<endl;

	}
}


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

class UFDS {
 private:
   vector<int> p;    // p[n]: pai do elemento n
   vector<int> size; // size[n]: tamanho do conjunto identificado por n
   int qtyDisjointSets;

 public:
   UFDS() {}

   // elementos n (0 <= n < N)
   UFDS(int N) {
      p.resize(N);
      size.assign(N, 1);
      qtyDisjointSets = N;

      // inicialmente, há N conjuntos disjuntos
      for (int n = 0; n < N; n++) p[n] = n;
   }

   // retorna a raiz do conjunto de n
   int findSet(int n) {
      if (p[n] == n) return n;

      // path compression durante a busca
      return p[n] = findSet(p[n]);
   }

   // os conjuntos de n e de m são os mesmos?
   bool isSameSet(int n, int m) {
      return findSet(n) == findSet(m);
   }

	// conecta os conjuntos de n e de m
   void unionSet(int n, int m) {
      int nId = findSet(n);
      int mId = findSet(m);

      // union by size: conecta a menor árvore à maior árvore
      if (!isSameSet(nId, mId)) {
         if (size[nId] > size[mId])
            swap(nId, mId);

         p[nId] = mId;
         size[mId] += size[nId];

         qtyDisjointSets--;
      }
   }

   // retorna o tamanho do conjunto de n
   int sizeOfSet(int n) {
      return size[findSet(n)];
   }

   // retorna a quantidade de conjuntos disjuntos
   int count() {
      return qtyDisjointSets;
   }
};

int main() {
   int N; cin >> N;
   UFDS uf(N+1);

   vector<pair<int, int>> closedRoads;
   vector<pair<int, int>> newRoads;
   int curr = 1;
   int ans = 0;

   N--;
   while (N--) {
      int a, b; cin >> a >> b;

      if (uf.isSameSet(a, b)) {
         closedRoads.push_back(make_pair(a,b));
         ans++;
      }
      else if (!uf.isSameSet(a, curr) && !uf.isSameSet(b, curr)) {
         newRoads.push_back(make_pair(a, curr));
         uf.unionSet(a, curr);
         uf.unionSet(a, b);
      }
      else uf.unionSet(a, b);
   }

   cout << ans << endl;
   for (int i = 0; i < closedRoads.size(); i++)
      cout << closedRoads[i].first << " " << closedRoads[i].second << " " << newRoads[i].first << " " << newRoads[i].second << endl;
	return 0;
}


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

class UFDS {
 private:
   vector<int> p;    // p[n]: pai do elemento n
   vector<int> size; // size[n]: tamanho do conjunto identificado por n
   int qtyDisjointSets;

 public:
   UFDS() {}

   // elementos n (0 <= n < N)
   UFDS(int N) {
      p.resize(N);
      size.assign(N, 1);
      qtyDisjointSets = N;

      // inicialmente, há N conjuntos disjuntos
      for (int n = 0; n < N; n++) p[n] = n;
   }

   // retorna a raiz do conjunto de n
   int findSet(int n) {
      if (p[n] == n) return n;

      // path compression durante a busca
      return p[n] = findSet(p[n]);
   }

   // os conjuntos de n e de m são os mesmos?
   bool isSameSet(int n, int m) {
      return findSet(n) == findSet(m);
   }

	// conecta os conjuntos de n e de m
   void unionSet(int n, int m) {
      int nId = findSet(n);
      int mId = findSet(m);

      // union by size: conecta a menor árvore à maior árvore
      if (!isSameSet(nId, mId)) {
         if (size[nId] > size[mId])
            swap(nId, mId);

         p[nId] = mId;
         size[mId] += size[nId];

         qtyDisjointSets--;
      }
   }

   // retorna o tamanho do conjunto de n
   int sizeOfSet(int n) {
      return size[findSet(n)];
   }

   // retorna a quantidade de conjuntos disjuntos
   int count() {
      return qtyDisjointSets;
   }
};

int main() {
   int N; cin >> N;
   UFDS uf(N+1);

   vector<pair<int, int>> closedRoads;
   vector<pair<int, int>> newRoads;
   int curr = -1;
   int ans = 0;

   for (int n = 0; n < N-1; n++) {
      int a, b; cin >> a >> b;

      if (uf.isSameSet(a, b)) {
         closedRoads.push_back(make_pair(a,b));
         ans++;
      }
      else uf.unionSet(a, b);

      if (curr == -1) curr = a;
   }

   for (int n = 1; n <= N; n++)
      if (!uf.isSameSet(n, curr) && n != curr) {
         newRoads.push_back(make_pair(n, curr));
         uf.unionSet(n, curr);
      }

   cout << ans << endl;
   for (int i = 0; i < newRoads.size(); i++)
      cout << closedRoads[i].first << " " << closedRoads[i].second << " " << newRoads[i].first << " " << newRoads[i].second << endl;
	return 0;
}


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

class UFDS {
 private:
   vector<int> p;    // p[n]: pai do elemento n
   vector<int> size; // size[n]: tamanho do conjunto identificado por n
   int qtyDisjointSets;

 public:
   UFDS() {}

   // elementos n (0 <= n < N)
   UFDS(int N) {
      p.resize(N);
      size.assign(N, 1);
      qtyDisjointSets = N;

      // inicialmente, há N conjuntos disjuntos
      for (int n = 0; n < N; n++) p[n] = n;
   }

   // retorna a raiz do conjunto de n
   int findSet(int n) {
      if (p[n] == n) return n;

      // path compression durante a busca
      return p[n] = findSet(p[n]);
   }

   // os conjuntos de n e de m são os mesmos?
   bool isSameSet(int n, int m) {
      return findSet(n) == findSet(m);
   }

	// conecta os conjuntos de n e de m
   void unionSet(int n, int m) {
      int nId = findSet(n);
      int mId = findSet(m);

      // union by size: conecta a menor árvore à maior árvore
      if (!isSameSet(nId, mId)) {
         if (size[nId] > size[mId])
            swap(nId, mId);

         p[nId] = mId;
         size[mId] += size[nId];

         qtyDisjointSets--;
      }
   }

   // retorna o tamanho do conjunto de n
   int sizeOfSet(int n) {
      return size[findSet(n)];
   }

   // retorna a quantidade de conjuntos disjuntos
   int count() {
      return qtyDisjointSets;
   }
};

int main() {
   int N; cin >> N;
   UFDS uf(N+1);

   vector<pair<int, int>> closedRoads;
   vector<pair<int, int>> newRoads;
   int curr = 0;
   int ans = 0;

   N--;
   while (N--) {
      int a, b; cin >> a >> b;
      if (curr == 0) curr = a;

      if (uf.isSameSet(a, b)) {
         closedRoads.push_back(make_pair(a,b));
         ans++;
      }
      else if (!uf.isSameSet(a, curr) && !uf.isSameSet(b, curr) && curr != 0) {
         newRoads.push_back(make_pair(a, curr));
         uf.unionSet(a, curr);
         uf.unionSet(a, b);

      }
      else uf.unionSet(a, b);
   }

   cout << ans << endl;
   for (int i = 0; i < closedRoads.size(); i++)
      cout << closedRoads[i].first << " " << closedRoads[i].second << " " << newRoads[i].first << " " << newRoads[i].second << endl;
	return 0;
}


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

class UFDS {
 private:
   vector<int> p;    // p[n]: pai do elemento n
   vector<int> size; // size[n]: tamanho do conjunto identificado por n
   int qtyDisjointSets;

 public:
   UFDS() {}

   // elementos n (0 <= n < N)
   UFDS(int N) {
      p.resize(N);
      size.assign(N, 1);
      qtyDisjointSets = N;

      // inicialmente, há N conjuntos disjuntos
      for (int n = 0; n < N; n++) p[n] = n;
   }

   // retorna a raiz do conjunto de n
   int findSet(int n) {
      if (p[n] == n) return n;

      // path compression durante a busca
      return p[n] = findSet(p[n]);
   }

   // os conjuntos de n e de m são os mesmos?
   bool isSameSet(int n, int m) {
      return findSet(n) == findSet(m);
   }

	// conecta os conjuntos de n e de m
   void unionSet(int n, int m) {
      int nId = findSet(n);
      int mId = findSet(m);

      // union by size: conecta a menor árvore à maior árvore
      if (!isSameSet(nId, mId)) {
         if (size[nId] > size[mId])
            swap(nId, mId);

         p[nId] = mId;
         size[mId] += size[nId];

         qtyDisjointSets--;
      }
   }

   // retorna o tamanho do conjunto de n
   int sizeOfSet(int n) {
      return size[findSet(n)];
   }

   // retorna a quantidade de conjuntos disjuntos
   int count() {
      return qtyDisjointSets;
   }
};

int main() {
   int N; cin >> N;
   UFDS uf(N+1);

   vector<pair<int, int>> closedRoads;
   vector<pair<int, int>> newRoads;
   int curr = -1;
   int ans = 0;

   for (int n = 0; n < N-1; n++) {
      int a, b; cin >> a >> b;

      if (uf.isSameSet(a, b)) {
         closedRoads.push_back(make_pair(a,b));
         ans++;
      }
      else uf.unionSet(a, b);

      if (curr == -1) curr = a;
   }

   for (int n = 1; n < N; n++)
      if (n != curr) {
         if (!uf.isSameSet(n, curr)) {
            newRoads.push_back(make_pair(n, curr));
            uf.unionSet(n, curr);
         }
      }

   cout << ans << endl;
   for (int i = 0; i < newRoads.size(); i++)
      cout << closedRoads[i].first << " " << closedRoads[i].second << " " << newRoads[i].first << " " << newRoads[i].second << endl;
	return 0;
}


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

class UFDS {
 private:
   vector<int> p;    // p[n]: pai do elemento n
   vector<int> size; // size[n]: tamanho do conjunto identificado por n
   int qtyDisjointSets;

 public:
   UFDS() {}

   // elementos n (0 <= n < N)
   UFDS(int N) {
      p.resize(N);
      size.assign(N, 1);
      qtyDisjointSets = N;

      // inicialmente, há N conjuntos disjuntos
      for (int n = 0; n < N; n++) p[n] = n;
   }

   // retorna a raiz do conjunto de n
   int findSet(int n) {
      if (p[n] == n) return n;

      // path compression durante a busca
      return p[n] = findSet(p[n]);
   }

   // os conjuntos de n e de m são os mesmos?
   bool isSameSet(int n, int m) {
      return findSet(n) == findSet(m);
   }

	// conecta os conjuntos de n e de m
   void unionSet(int n, int m) {
      int nId = findSet(n);
      int mId = findSet(m);

      // union by size: conecta a menor árvore à maior árvore
      if (!isSameSet(nId, mId)) {
         if (size[nId] > size[mId])
            swap(nId, mId);

         p[nId] = mId;
         size[mId] += size[nId];

         qtyDisjointSets--;
      }
   }

   // retorna o tamanho do conjunto de n
   int sizeOfSet(int n) {
      return size[findSet(n)];
   }

   // retorna a quantidade de conjuntos disjuntos
   int count() {
      return qtyDisjointSets;
   }
};

int main() {
   int N; cin >> N;
   UFDS uf(N+1);

   vector<pair<int, int>> closedRoads;
   vector<pair<int, int>> newRoads;
   int curr = 0;
   int ans = 0;

   N--;
   while (N--) {
      int a, b; cin >> a >> b;

      if (uf.isSameSet(a, b)) {
         closedRoads.push_back(make_pair(a,b));
         ans++;
      }
      else if (!uf.isSameSet(a, curr) && !uf.isSameSet(b, curr) && curr == 0) {
         newRoads.push_back(make_pair(a, curr));
         uf.unionSet(a, curr);
         uf.unionSet(a, b);

         if (curr == 0) curr = a;
      }
      else uf.unionSet(a, b);
   }

   cout << ans << endl;
   for (int i = 0; i < closedRoads.size(); i++)
      cout << closedRoads[i].first << " " << closedRoads[i].second << " " << newRoads[i].first << " " << newRoads[i].second << endl;
	return 0;
}


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

class UFDS {
 private:
   vector<int> p;    // p[n]: pai do elemento n
   vector<int> size; // size[n]: tamanho do conjunto identificado por n
   int qtyDisjointSets;

 public:
   UFDS() {}

   // elementos n (0 <= n < N)
   UFDS(int N) {
      p.resize(N);
      size.assign(N, 1);
      qtyDisjointSets = N;

      // inicialmente, há N conjuntos disjuntos
      for (int n = 0; n < N; n++) p[n] = n;
   }

   // retorna a raiz do conjunto de n
   int findSet(int n) {
      if (p[n] == n) return n;

      // path compression durante a busca
      return p[n] = findSet(p[n]);
   }

   // os conjuntos de n e de m são os mesmos?
   bool isSameSet(int n, int m) {
      return findSet(n) == findSet(m);
   }

	// conecta os conjuntos de n e de m
   void unionSet(int n, int m) {
      int nId = findSet(n);
      int mId = findSet(m);

      // union by size: conecta a menor árvore à maior árvore
      if (!isSameSet(nId, mId)) {
         if (size[nId] > size[mId])
            swap(nId, mId);

         p[nId] = mId;
         size[mId] += size[nId];

         qtyDisjointSets--;
      }
   }

   // retorna o tamanho do conjunto de n
   int sizeOfSet(int n) {
      return size[findSet(n)];
   }

   // retorna a quantidade de conjuntos disjuntos
   int count() {
      return qtyDisjointSets;
   }
};

int main() {
   int N; cin >> N; N--;

   UFDS uf(N+1);
   vector<pair<int, int>> closedRoads;
   vector<pair<int, int>> newRoads;
   int curr = 1;
   int ans = 0;

   while (N--) {
      int a, b; cin >> a >> b;

      if (uf.isSameSet(a, b)) {
         closedRoads.push_back(make_pair(a,b));
         ans++;
      }
      else if (!uf.isSameSet(a, curr) && !uf.isSameSet(b, curr)) {
         newRoads.push_back(make_pair(a, curr));
         uf.unionSet(a, curr);
         uf.unionSet(a, b);
      }
      else uf.unionSet(a, b);
   }

   cout << ans << endl;
   for (int i = 0; i < closedRoads.size(); i++)
      cout << closedRoads[i].first << " " << closedRoads[i].second << " " << newRoads[i].first << " " << newRoads[i].second << endl;
	return 0;
}


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

#define pb push_back
#define f first
#define s second
#define mp make_pair
#define MOD 1000000007
typedef long long ll;
typedef vector<long long> vll;
typedef set<long long> sll;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long> > vpll;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define repr(i,a,b) for(int i=a;i>=b;--i)

vll parent(100010);
vll size(100010);

void initx(ll n){
	rep(i,0,n+10){
		parent[i]=i;
		size[i]=1;
	}
}

ll findx(ll a){
	if(parent[a]==a)
		return parent[a];
	return parent[a]=findx(parent[a]);
}

bool unionx(ll a,ll b){
	a=findx(a);
	b=findx(b);
	if(a!=b){
		if(size[a]<size[b])
			swap(a,b);
		parent[b]=a;
		size[a]+=size[b];
		return true;
	}
	return false;
}

void solve(){
	ll n;
	cin>>n;
	initx(n);
	vll a(n),b(n),ans;
	rep(i,0,n-1){
		cin>>a[i]>>b[i];
		if(!unionx(a[i],b[i])){
			ans.pb(i);
		}
	}
	vll fin(n+10,0);
	rep(i,1,n+1){
		fin[findx(i)-1]=1;
	}
	vll x;
	rep(i,0,n){
		if(fin[i]==1){
			x.pb(i);
		}
	}
	cout<<x.size()-1<<"\n";
	rep(i,1,x.size()){
		cout<<a[ans[i-1]]<<" "<<b[ans[i-1]]<<" "<<x[0]+1<<" "<<x[i]+1<<"\n";
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
//	compute();
	int t=0,T;
//	cin>>T;
	T=1;
	for(t=0;t<T;t++){
		solve();
	}
	return 0;
}


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

#define pb push_back
#define f first
#define s second
#define mp make_pair
#define MOD 1000000007
typedef long long ll;
typedef vector<long long> vll;
typedef set<long long> sll;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long> > vpll;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define repr(i,a,b) for(int i=a;i>=b;--i)

vll parent(100010);
vll size(100010);

void initx(ll n){
	rep(i,0,n+10){
		parent[i]=i;
		size[i]=1;
	}
}

ll findx(ll a){
	if(parent[a]==a)
		return parent[a];
	return parent[a]=findx(parent[a]);
}

bool unionx(ll a,ll b){
	a=findx(a);
	b=findx(b);
	if(a!=b){
		if(size[a]<size[b])
			swap(a,b);
		parent[b]=a;
		size[a]+=size[b];
		return true;
	}
	else{
		return false;
	}
}

void solve(){
	ll n;
	cin>>n;
	initx(n);
	vll a(n),b(n),ans;
	rep(i,0,n-1){
		cin>>a[i]>>b[i];
		if(!unionx(a[i],b[i])){
			ans.pb(i);
		}
	}
	vll fin(n+10,0);
	rep(i,0,n){
		fin[parent[i]-1]=1;
	}
	vll x;
	rep(i,0,n){
		if(fin[i]==1){
			x.pb(i);
		}
	}
	cout<<x.size()-1<<"\n";
	rep(i,1,x.size()){
		cout<<a[ans[i-1]]<<" "<<b[ans[i-1]]<<" "<<x[0]<<" "<<x[i]<<"\n";
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
//	compute();
	int t=0,T;
//	cin>>T;
	T=1;
	for(t=0;t<T;t++){
		solve();
	}
	return 0;
}


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

#define pb push_back
#define f first
#define s second
#define mp make_pair
#define MOD 1000000007
typedef long long ll;
typedef vector<long long> vll;
typedef set<long long> sll;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long> > vpll;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define repr(i,a,b) for(int i=a;i>=b;--i)

vll parent(100010);
vll size(100010);

void initx(ll n){
	rep(i,0,n+2){
		parent[i]=i;
		size[i]=0;
	}
}

ll findx(ll a){
	if(parent[a]==a)
		return parent[a];
	return parent[a]=findx(parent[a]);
}

bool unionx(ll a,ll b){
	a=findx(a);
	b=findx(b);
	if(a!=b){
		if(size[a]<size[b])
			swap(a,b);
		parent[b]=a;
		size[a]+=size[b];
		return true;
	}
	else{
		return false;
	}
}

void solve(){
	ll n;
	cin>>n;
	initx(n);
	vll a(n),b(n),ans;
	rep(i,0,n-1){
		cin>>a[i]>>b[i];
		if(!unionx(a[i],b[i])){
			ans.pb(i);
		}
	}
	vll fin(n+3,0);
	rep(i,1,n+1){
		fin[parent[i]]=1;
	}
	vll x;
	rep(i,1,n+1){
		if(fin[i]==1){
			x.pb(i);
		}
	}
	cout<<x.size()-1<<"\n";
	rep(i,1,x.size()){
		cout<<a[ans[i-1]]<<" "<<b[ans[i-1]]<<" "<<x[0]<<" "<<x[i]<<"\n";
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
//	compute();
	int t=0,T;
//	cin>>T;
	T=1;
	for(t=0;t<T;t++){
		solve();
	}
	return 0;
}


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

#define pb push_back
#define f first
#define s second
#define mp make_pair
#define MOD 1000000007
typedef long long ll;
typedef vector<long long> vll;
typedef set<long long> sll;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long> > vpll;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define repr(i,a,b) for(int i=a;i>=b;--i)

vll parent(100010);
vll size(100010);

void initx(ll n){
	rep(i,0,n+2){
		parent[i]=i;
		size[i]=0;
	}
}

ll findx(ll a){
	if(parent[a]==a)
		return parent[a];
	return parent[a]=findx(parent[a]);
}

bool unionx(ll a,ll b){
	a=findx(a);
	b=findx(b);
	if(a!=b){
		if(size[a]<size[b])
			swap(a,b);
		parent[b]=a;
		size[a]+=size[b];
		return true;
	}
	else{
		return false;
	}
}

void solve(){
	ll n;
	cin>>n;
	initx(n);
	vll a(n),b(n),ans;
	rep(i,0,n-1){
		cin>>a[i]>>b[i];
		if(!unionx(a[i],b[i])){
			ans.pb(i);
		}
	}
	vll fin(n,0);
	rep(i,1,n+1){
		fin[parent[i]]=1;
	}
	vll x;
	rep(i,0,n){
		if(fin[i]==1){
			x.pb(i);
		}
	}
	cout<<x.size()-1<<"\n";
	rep(i,1,x.size()){
		cout<<a[ans[i-1]]<<" "<<b[ans[i-1]]<<" "<<x[0]<<" "<<x[i]<<"\n";
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
//	compute();
	int t=0,T;
//	cin>>T;
	T=1;
	for(t=0;t<T;t++){
		solve();
	}
	return 0;
}


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

#define pb push_back
#define f first
#define s second
#define mp make_pair
#define MOD 1000000007
typedef long long ll;
typedef vector<long long> vll;
typedef set<long long> sll;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long> > vpll;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define repr(i,a,b) for(int i=a;i>=b;--i)

vll parent(100010);
vll size(100010);

void initx(ll n){
	rep(i,0,n+10){
		parent[i]=i;
		size[i]=0;
	}
}

ll findx(ll a){
	if(parent[a]==a)
		return parent[a];
	return parent[a]=findx(parent[a]);
}

bool unionx(ll a,ll b){
	a=findx(a);
	b=findx(b);
	if(a!=b){
		if(size[a]<size[b])
			swap(a,b);
		parent[b]=a;
		size[a]+=size[b];
		return true;
	}
	else{
		return false;
	}
}

void solve(){
	ll n;
	cin>>n;
	initx(n);
	vll a(n),b(n),ans;
	rep(i,0,n-1){
		cin>>a[i]>>b[i];
		if(!unionx(a[i],b[i])){
			ans.pb(i);
		}
	}
	vll fin(n+10,0);
	rep(i,1,n+1){
		fin[parent[i]]=1;
	}
	vll x;
	rep(i,0,n){
		if(fin[i]==1){
			x.pb(i);
		}
	}
	cout<<x.size()-1<<"\n";
	rep(i,1,x.size()){
		cout<<a[ans[i-1]]<<" "<<b[ans[i-1]]<<" "<<x[0]<<" "<<x[i]<<"\n";
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
//	compute();
	int t=0,T;
//	cin>>T;
	T=1;
	for(t=0;t<T;t++){
		solve();
	}
	return 0;
}


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

#define pb push_back
#define f first
#define s second
#define mp make_pair
#define MOD 1000000007
typedef long long ll;
typedef vector<long long> vll;
typedef set<long long> sll;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long> > vpll;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define repr(i,a,b) for(int i=a;i>=b;--i)

vll parent(100010);
vll size(100010);

void initx(ll n){
	rep(i,0,n+2){
		parent[i]=i;
		size[i]=0;
	}
}

ll findx(ll a){
	if(parent[a]==a)
		return parent[a];
	return parent[a]=findx(parent[a]);
}

bool unionx(ll a,ll b){
	a=findx(a);
	b=findx(b);
	if(a!=b){
		if(size[a]<size[b])
			swap(a,b);
		parent[b]=a;
		size[a]+=size[b];
		return true;
	}
	else{
		return false;
	}
}

void solve(){
	ll n;
	cin>>n;
	initx(n);
	vll a(n),b(n),ans;
	rep(i,0,n-1){
		cin>>a[i]>>b[i];
		if(!unionx(a[i],b[i])){
			ans.pb(i);
		}
	}
	vll fin(n,0);
	rep(i,1,n+1){
		fin[parent[i]]=1;
	}
	vll x;
	rep(i,1,n+1){
		if(fin[i]==1){
			x.pb(i);
		}
	}
	cout<<x.size()-1<<"\n";
	rep(i,1,x.size()){
		cout<<a[ans[i-1]]<<" "<<b[ans[i-1]]<<" "<<x[0]<<" "<<x[i]<<"\n";
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
//	compute();
	int t=0,T;
//	cin>>T;
	T=1;
	for(t=0;t<T;t++){
		solve();
	}
	return 0;
}


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

const int N = 2e3;

	bool vis[N];
	int n, x, y, z;
	vector<int> adj[N];
	vector< pair< pair<int, int>, pair<int, int> > > ans;

void dfs(int u, int p) {
	vis[u] = 1;
	for(int v:adj[u]) {
		if(v == p) continue;

		if(vis[v]) {
			x = u, y = v;
		} else dfs(v, u);
	}
	return;
}

int main() {
	cin >> n;
	for(int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	for(int i = 1; i <= n; i++) {
		if(!vis[i]) {
			dfs(i, -1);
			if(z) ans.push_back({{x, y}, {x, i}});
			if(x && y) z = i;
		}
	}
	cout << ans.size() << endl;
	for(auto x:ans) {
		cout << x.first.first << " " << x.first.second << " " << x.second.first << " " << x.second.second << endl;
 	}
	return 0;
}


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

const int N = 2e3;

	bool vis[N];
	int n, x, y, z;
	vector<int> adj[N];
	vector< pair<int, int > > cycle;
	vector< pair< pair<int, int>, pair<int, int> > > ans;

void dfs(int u, int p) {
	vis[u] = 1;
	for(int v:adj[u]) {
		if(v == p) continue;

		if(vis[v]) {
			cycle.push_back({v, u});
		} else dfs(v, u);
	}
	return;
}

int main() {
	cin >> n;
	for(int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	int cnt = 0;

	for(int i = 1; i <= n; i++) {
		if(!vis[i]) {
			dfs(i, -1);
			if(z) ans.push_back({cycle[cnt], {cycle[cnt].first, i}}), cnt += 2;
			z = 1;
		}
	}
	cout << ans.size() << endl;
	for(auto x:ans) {
		cout << x.first.first << " " << x.first.second << " " << x.second.first << " " << x.second.second << endl;
 	}
	return 0;
}


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

const int N = 2e3;

	bool vis[N], ok[N][N];
	int n, x, y, z;
	vector<int> adj[N];
	vector< pair<int, int > > cycle;
	vector< pair< pair<int, int>, pair<int, int> > > ans;

void dfs(int u, int p) {
	vis[u] = 1;
	for(int v:adj[u]) {
		if(v == p) continue;

		if(vis[v]) {
			if(!ok[u][v])cycle.push_back({u, v}), ok[u][v] = ok[v][u] = 1;
		} else dfs(v, u);
	}
	return;
}

int main() {
	cin >> n;
	for(int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	int cnt = 0;

	for(int i = 1; i <= n; i++) {
		if(!vis[i]) {
			dfs(i, -1);
			if(z && cnt < cycle.size()) ans.push_back({cycle[cnt], {z, i}}), cnt ++;
			z = 1;
		}
	}
//	for(auto x:cycle) {
//		cout << x.first << " " << x.second << endl;
//	}
//	cout << endl;
	cout << ans.size() << endl;
	for(auto x:ans) {
		cout << x.first.first << " " << x.first.second << " " << x.second.first << " " << x.second.second << endl;
 	}
	return 0;
}


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

const int N = 2e3;

	bool vis[N];
	int n, x, y, z;
	vector<int> adj[N];
	vector< pair<int, int > > cycle;
	vector< pair< pair<int, int>, pair<int, int> > > ans;

void dfs(int u, int p) {
	vis[u] = 1;
	for(int v:adj[u]) {
		if(v == p) continue;

		if(vis[v]) {
			cycle.push_back({u, v});
		} else dfs(v, u);
	}
	return;
}

int main() {
	cin >> n;
	for(int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	int cnt = 0;

	for(int i = 1; i <= n; i++) {
		if(!vis[i]) {
			dfs(i, -1);
			if(z) ans.push_back({cycle[cnt], {cycle[cnt].first, i}}), cnt += 2;
			z = 1;
		}
	}
	cout << ans.size() << endl;
	for(auto x:ans) {
		cout << x.first.first << " " << x.first.second << " " << x.second.first << " " << x.second.second << endl;
 	}
	return 0;
}


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

const int N = 2e3;

	bool vis[N], ok[N][N];
	int n, x, y, z;
	vector<int> adj[N];
	vector< pair<int, int > > cycle;
	vector< pair< pair<int, int>, pair<int, int> > > ans;

void dfs(int u, int p) {
	vis[u] = 1;
	for(int v:adj[u]) {
		if(v == p) continue;

		if(vis[v]) {
			if(!ok[u][v])cycle.push_back({u, v}), ok[u][v] = ok[v][u] = 1;
		} else dfs(v, u);
	}
	return;
}

int main() {
	cin >> n;
	for(int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	int cnt = 0;

	for(int i = 1; i <= n; i++) {
		if(!vis[i]) {
			dfs(i, -1);
			if(z) ans.push_back({cycle[cnt], {z, i}}), cnt ++;
			z = 1;
		}
	}
//	for(auto x:cycle) {
//		cout << x.first << " " << x.second << endl;
//	}
//	cout << endl;
	cout << ans.size() << endl;
	for(auto x:ans) {
		cout << x.first.first << " " << x.first.second << " " << x.second.first << " " << x.second.second << endl;
 	}
	return 0;
}


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

const int N = 2e3;

	bool vis[N], ok[N][N];
	int n, x, y, z;
	vector<int> adj[N];
	vector< pair<int, int > > cycle;
	vector< pair< pair<int, int>, pair<int, int> > > ans;

void dfs(int u, int p) {
	vis[u] = 1;
	for(int v:adj[u]) {
		if(v == p) continue;

		if(vis[v]) {
			if(!ok[u][v])cycle.push_back({u, v}), ok[u][v] = ok[v][u] = 1;
		} else dfs(v, u);
	}
	return;
}

int main() {
	cin >> n;
	for(int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	for(int i = 1; i <= n; i++) {
		if(!vis[i]) {
			dfs(i, -1);
		}
	}
	memset(vis, 0, sizeof vis);
	int cnt = 0;

	for(int i = 1; i <= n; i++) {
		if(!vis[i]) {
			dfs(i, -1);
			if(z && cnt < cycle.size()) ans.push_back({cycle[cnt], {z, i}}), cnt ++;
			z = 1;
		}
	}

//	for(auto x:cycle) {
//		cout << x.first << " " << x.second << endl;
//	}
//	cout << endl;
	cout << ans.size() << endl;
	for(auto x:ans) {
		cout << x.first.first << " " << x.first.second << " " << x.second.first << " " << x.second.second << endl;
 	}
	return 0;
}


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

const int N = 2e3;

	bool vis[N], ok[N][N];
	int n, x, y, z;
	vector<int> adj[N];
	vector< pair<int, int > > cycle;
	vector< pair< pair<int, int>, pair<int, int> > > ans;

void dfs(int u, int p) {
	vis[u] = 1;
	for(int v:adj[u]) {
		if(v == p) continue;

		if(vis[v]) {
			if(!ok[u][v])cycle.push_back({u, v}), ok[u][v] = ok[v][u] = 1;
		} else dfs(v, u);
	}
	return;
}

int main() {
	cin >> n;
	for(int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	int cnt = 0;

	for(int i = 1; i <= n; i++) {
		if(!vis[i]) {
			dfs(i, -1);
			if(z) ans.push_back({cycle[cnt], {cycle[cnt].first, i}}), cnt ++;
			z = 1;
		}
	}

	cout << ans.size() << endl;
	for(auto x:ans) {
		cout << x.first.first << " " << x.first.second << " " << x.second.first << " " << x.second.second << endl;
 	}
	return 0;
}


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

const int N = 2e3;

	bool vis[N];
	int n, x, y, z;
	vector<int> adj[N];
	vector< pair<int, int > > cycle;
	vector< pair< pair<int, int>, pair<int, int> > > ans;

void dfs(int u, int p) {
	vis[u] = 1;
	for(int v:adj[u]) {
		if(v == p) continue;

		if(vis[v]) {
			cycle.push_back({v, u});
		} else dfs(v, u);
	}
	return;
}

int main() {
	cin >> n;
	for(int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	int cnt = 0;

	for(int i = 1; i <= n; i++) {
		if(!vis[i]) {
			dfs(i, -1);
			if(z) ans.push_back({cycle[cnt], {cycle[cnt].first, i}}), cnt += 2;
			z = 1;
		}
	}
	for(auto x:cycle) {
		cout << x.first << " " << x.second << endl;
	}
	cout << endl;
	cout << ans.size() << endl;
	for(auto x:ans) {
		cout << x.first.first << " " << x.first.second << " " << x.second.first << " " << x.second.second << endl;
 	}
	return 0;
}


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

#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

#define int long long int
#define mp make_pair
#define pb push_back
#define f first
#define s second

const int N=1e3+5;

int vis[N],parent[N],ranks[N];

vector <int> adj[N];

bool dfs(int node,int last)
{
     vis[node]=1;

     for(int i=0;i<adj[node].size();i++)
     {

          if(!vis[adj[node][i]])
          {
                bool val=dfs(adj[node][i],node);
                if(val==true)
                    return true;
          }
          else if(vis[adj[node][i]] && adj[node][i]!=last)
          {
               return true;
          }

     }

     return false;

}

void initialise(int i)
{
     parent[i]=i;
     ranks[i]=0;
}

int find_set(int node)
{
     if(parent[node]==node)
          return node;

     return parent[node]=find_set(parent[node]);
}

void union_sets(int a,int b)
{
     if(ranks[b]>ranks[a])
          swap(a,b);

     parent[b]=a;

     if(ranks[a]==ranks[b])
          ranks[a]++;
}

int32_t main()
{
     IOS;

     int n;

     cin>>n;

     for(int i=1;i<=n;i++)
          initialise(i);

     queue < pair<int,int> > q;

     for (int i=1;i<n;i++)
     {
          int x,y;

          cin>>x>>y;

          adj[x].pb(y);
          adj[y].pb(x);

          int a=find_set(x);
          int b=find_set(y);

          if(a==b)
          {
               q.push(mp(x,y));
          }
          else
          {
               union_sets(a,b);
          }
     }

     queue <int> ans;

     vector <int> extra;

     for(int i=1;i<=n;i++)
     {
          if(!vis[i])
          {
             bool check=dfs(i,0);
             if(check==false)
               ans.push(i);
             else
               extra.pb(i);
          }
     }

     queue < pair<int,int> > make;

     cout<<q.size()<<endl;

     for(int i=0;i+1<extra.size();i++)
          make.push(mp(extra[i],extra[i+1]));

     while(!q.empty())
     {
          pair<int,int> x;
          x=q.front();
          q.pop();
          if(!ans.empty())
          {
               cout<<x.f<<" "<<x.s<<" "<<x.f<<" "<<ans.front()<<endl;
               ans.pop();
          }

          if(!make.empty())
          {
               cout<<x.f<<" "<<x.s<<" "<<make.front().f<<" "<<make.front().s<<endl;
               make.pop();
          }

     }

     return 0;

}


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

#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

#define int long long int
#define mp make_pair
#define pb push_back
#define f first
#define s second

const int N=1e3+5;

int vis[N],parent[N],ranks[N];

vector <int> adj[N];

bool dfs(int node,int last)
{
     vis[node]=1;

     for(int i=0;i<adj[node].size();i++)
     {

          if(!vis[adj[node][i]])
          {
                bool val=dfs(adj[node][i],node);
                if(val==true)
                    return true;
          }
          else if(vis[adj[node][i]] && adj[node][i]!=last)
          {
               return true;
          }

     }

     return false;

}

void initialise(int i)
{
     parent[i]=i;
     ranks[i]=0;
}

int find_set(int node)
{
     if(parent[node]==node)
          return node;

     return parent[node]=find_set(parent[node]);
}

void union_sets(int a,int b)
{
     if(ranks[b]>ranks[a])
          swap(a,b);

     parent[b]=a;

     if(ranks[a]==ranks[b])
          ranks[a]++;
}

int32_t main()
{
     IOS;

     int n;

     cin>>n;

     vector < pair<int,int> > ques;

     for(int i=1;i<=n;i++)
          initialise(i);

     for (int i=1;i<n;i++)
     {
          int x,y;

          cin>>x>>y;

          adj[x].pb(y);
          adj[y].pb(x);

          int a=find_set(x);
          int b=find_set(y);

          if(a==b)
          {
               ques.pb(mp(x,y));
          }
          else
          {
               union_sets(a,b);
          }
     }

     vector <int> ans;

     for(int i=1;i<=n;i++)
     {
          if(!vis[i])
          {
             bool check=dfs(i,0);
             if(check==false)
               ans.pb(i);

          }
     }

     //cout<<ques.size()<<endl;

     cout<<ques.size()<<endl;

     for(int i=0;i<ques.size();i++)
     {
          cout<<ques[i].f<<" "<<ques[i].s<<" "<<ques[i].f<<" "<<ans[i]<<endl;
     }

     return 0;

}


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

#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

#define int long long int
#define mp make_pair
#define pb push_back
#define f first
#define s second

const int N=1e3+5;

int parent[N],ranks[N];

void initialise(int i)
{
     parent[i]=i;
     ranks[i]=0;
}

int find_set(int node)
{
     if(parent[node]==node)
          return node;

     return parent[node]=find_set(parent[node]);
}

void union_sets(int a,int b)
{
     if(ranks[b]>ranks[a])
          swap(a,b);

     parent[b]=a;

     if(ranks[a]==ranks[b])
          ranks[a]++;
}

int32_t main()
{
     IOS;

     int n;

     cin>>n;

     for(int i=1;i<=n;i++)
          initialise(i);

     queue < pair<int,int> > q;

     for (int i=1;i<n;i++)
     {
          int x,y;

          cin>>x>>y;

          int a=find_set(x);
          int b=find_set(y);

          if(a==b)
          {
               q.push(mp(x,y));
          }
          else
          {
               union_sets(a,b);
          }
     }

     cout<<q.size()<<endl;

     for(int i=2;i<=n;i++)
     {
          int a=find_set(1);
          int b=find_set(i);

          if(a!=b)
          {
               union_sets(a,b);
               pair<int,int> x;
               x=q.front();
               q.pop();
               cout<<x.f<<" "<<x.s<<" "<<1<<" "<<i<<endl;
          }

     }

     return 0;

}


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

#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

#define int long long int
#define mp make_pair
#define pb push_back
#define f first
#define s second

const int N=1e3+5;

int vis[N],parent[N],ranks[N];

vector <int> adj[N];

bool dfs(int node,int last)
{
     vis[node]=1;

     for(int i=0;i<adj[node].size();i++)
     {

          if(!vis[adj[node][i]])
          {
                bool val=dfs(adj[node][i],node);
                if(val==true)
                    return true;
          }
          else if(vis[adj[node][i]] && adj[node][i]!=last)
          {
               return true;
          }

     }

     return false;

}

void initialise(int i)
{
     parent[i]=i;
     ranks[i]=0;
}

int find_set(int node)
{
     if(parent[node]==node)
          return node;

     return parent[node]=find_set(parent[node]);
}

void union_sets(int a,int b)
{
     if(ranks[b]>ranks[a])
          swap(a,b);

     parent[b]=a;

     if(ranks[a]==ranks[b])
          ranks[a]++;
}

int32_t main()
{
     IOS;

     int n;

     cin>>n;

     vector < pair<int,int> > ques;

     for(int i=1;i<=n;i++)
          initialise(i);

     for (int i=1;i<n;i++)
     {
          int x,y;

          cin>>x>>y;

          adj[x].pb(y);
          adj[y].pb(x);

          int a=find_set(x);
          int b=find_set(y);

          if(a==b)
          {
               ques.pb(mp(x,y));
          }
          else
          {
               union_sets(a,b);
          }
     }

     vector <int> ans;

     for(int i=1;i<=n;i++)
     {
          if(!vis[i])
          {
             bool check=dfs(i,0);
             if(check==false)
               ans.pb(i);

          }
     }

     cout<<min(ques.size(),ans.size())<<endl;

     for(int i=0;i<min(ques.size(),ans.size());i++)
     {
          cout<<ques[i].f<<" "<<ques[i].s<<" "<<ques[i].f<<" "<<ans[i]<<endl;
     }

     return 0;

}


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

#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

#define int long long int
#define mp make_pair
#define pb push_back
#define f first
#define s second

const int N=1e3+5;

int parent[N],ranks[N];

void initialise(int i)
{
     parent[i]=i;
     ranks[i]=0;
}

int find_set(int node)
{
     if(parent[node]==node)
          return node;

     return parent[node]=find_set(parent[node]);
}

void union_sets(int a,int b)
{
     if(ranks[b]>ranks[a])
          swap(a,b);

     parent[b]=a;

     if(ranks[a]==ranks[b])
          ranks[a]++;
}

int32_t main()
{
     IOS;

     int n;

     cin>>n;

     for(int i=1;i<=n;i++)
          initialise(i);

     queue < pair<int,int> > q;

     for (int i=1;i<n;i++)
     {
          int x,y;

          cin>>x>>y;

          int a=find_set(x);
          int b=find_set(y);

          if(a==b)
          {
               q.push(mp(x,y));
          }
          else
          {
               union_sets(a,b);
          }
     }

     cout<<q.size()<<endl;

     for(int i=2;i<=n;i++)
     {
          int a=find_set(1);
          int b=find_set(i);

          if(a!=b)
          {
               union_sets(a,b);
               pair<int,int> x;
               x=q.front();
               q.pop();
               cout<<x.f<<" "<<x.s<<" "<<x.f<<" "<<i<<endl;
          }

     }

     return 0;

}


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

#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

#define int long long int
#define mp make_pair
#define pb push_back
#define f first
#define s second

const int N=1e3+5;

int vis[N],parent[N],ranks[N];

vector <int> adj[N];

bool dfs(int node,int last)
{
     vis[node]=1;

     for(int i=0;i<adj[node].size();i++)
     {

          if(!vis[adj[node][i]])
          {
                bool val=dfs(adj[node][i],node);
                if(val==true)
                    return true;
          }
          else if(vis[adj[node][i]] && adj[node][i]!=last)
          {
               return true;
          }

     }

     return false;

}

void initialise(int i)
{
     parent[i]=i;
     ranks[i]=0;
}

int find_set(int node)
{
     if(parent[node]==node)
          return node;

     return parent[node]=find_set(parent[node]);
}

void union_sets(int a,int b)
{
     if(ranks[b]>ranks[a])
          swap(a,b);

     parent[b]=a;

     if(ranks[a]==ranks[b])
          ranks[a]++;
}

int32_t main()
{
     IOS;

     int n;

     cin>>n;

     for(int i=1;i<=n;i++)
          initialise(i);

     queue < pair<int,int> > q;

     for (int i=1;i<n;i++)
     {
          int x,y;

          cin>>x>>y;

          adj[x].pb(y);
          adj[y].pb(x);

          int a=find_set(x);
          int b=find_set(y);

          if(a==b)
          {
               q.push(mp(x,y));
          }
          else
          {
               union_sets(a,b);
          }
     }

     queue <int> ans;

     vector <int> extra;

     for(int i=1;i<=n;i++)
     {
          if(!vis[i])
          {
             bool check=dfs(i,0);
             if(check==false)
               ans.push(i);
             else
               extra.pb(i);
          }
     }

     queue < pair<int,int> > make;

     cout<<q.size()<<endl;

     for(int i=0;i+1<extra.size();i++)
          make.push(mp(extra[i],extra[i+1]));

     while(!q.empty())
     {
          pair<int,int> x;
          x=q.front();
          q.pop();
          if(!ans.empty())
          {
               cout<<x.f<<" "<<x.s<<" "<<x.f<<" "<<ans.front()<<endl;
               ans.pop();
          }

          else if(!make.empty())
          {
               cout<<x.f<<" "<<x.s<<" "<<make.front().f<<" "<<make.front().s<<endl;
               make.pop();
          }

     }

     return 0;

}


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

#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

#define int long long int
#define mp make_pair
#define pb push_back
#define f first
#define s second

const int N=1e3+5;

int vis[N],parent[N],ranks[N];

vector <int> adj[N];

bool dfs(int node,int last)
{
     vis[node]=1;

     for(int i=0;i<adj[node].size();i++)
     {

          if(!vis[adj[node][i]])
          {
                bool val=dfs(adj[node][i],node);
                if(val==true)
                    return true;
          }
          else if(vis[adj[node][i]] && adj[node][i]!=last)
          {
               return true;
          }

     }

     return false;

}

void initialise(int i)
{
     parent[i]=i;
     ranks[i]=0;
}

int find_set(int node)
{
     if(parent[node]==node)
          return node;

     return parent[node]=find_set(parent[node]);
}

void union_sets(int a,int b)
{
     if(ranks[b]>ranks[a])
          swap(a,b);

     parent[b]=a;

     if(ranks[a]==ranks[b])
          ranks[a]++;
}

int32_t main()
{
     IOS;

     int n;

     cin>>n;

     vector < pair<int,int> > ques;

     for(int i=1;i<=n;i++)
          initialise(i);

     for (int i=1;i<n;i++)
     {
          int x,y;

          cin>>x>>y;

          adj[x].pb(y);
          adj[y].pb(x);

          int a=find_set(x);
          int b=find_set(y);

          if(a==b)
          {
               ques.pb(mp(x,y));
          }
          else
          {
               union_sets(a,b);
          }
     }

     vector <int> ans,extra;

     vector < pair<int,int> > haha;

     for(int i=1;i<=n;i++)
     {
          if(!vis[i])
          {
             bool check=dfs(i,0);
             if(check==false)
               ans.pb(i);
             else
               extra.pb(i);
          }
     }

     cout<<ques.size()<<endl;

     for(int i=0;i+1<extra.size();i++)
     {
          haha.pb(mp(extra[i],extra[i+1]));
     }

     int j=0,k=0;

     for(int i=0;i<ques.size();i++)
     {
          if(j!=haha.size())
          {
               cout<<ques[i].f<<" "<<ques[i].s<<" "<<haha[j].f<<" "<<haha[j].s<<endl;
               j++;
          }
          else
          {
               cout<<ques[i].f<<" "<<ques[i].s<<" "<<ques[i].f<<" "<<ans[k]<<endl;
               k++;
          }
     }

     return 0;

}


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

int find_parent(vector<int> par,int i)         //if this doesn't work try out path compression and union by rank.
{
    if(i==par[i])
        return i;
    par[i]=find_parent(par,par[i]);
    return par[i];
}

void union_(vector<int>& par,int x,int y)
{
    int i=find_parent(par,x);
    int j=find_parent(par,y);
    if(i<j)
    par[j]=i;
    else par[i]=j;
}

void dfs(vector<vector<int> > G,int root,vector<bool>& vis)
{
    vis[root]=true;
    for(int i=0;i<G[root].size();i++)
    {
        int v=G[root][i];
        dfs(G,v,vis);
    }

}

int main()
{
    int n;
    cin>>n;
    vector<vector<int> > G;
    G.resize(n+1);
    int days=0;

    vector<int> parent(n+1,0);
 //   vector<bool> vis(n+1,false);
    vector<pair<int,int> > to_break;
    vector<pair<int,int> > to_build;
    for(int i=1;i<=n;i++)
        parent[i]=i;
    int curr_parent;
    for(int i=1;i<=n-1;i++)
    {
        int a,b;
        cin>>a>>b;
        int x=find_parent(parent,a);
        int y=find_parent(parent,b);
        if(i==1)
            curr_parent=x;

        if(x!=y && (x==curr_parent || y==curr_parent))
        {
            union_(parent,x,y);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        else if(x==y)
        {
            days++;
            to_break.push_back(make_pair(a,b));
        }
        else if(x!=y && (x!=curr_parent && y!=curr_parent))
        {
            to_build.push_back(make_pair(a,b));
            parent[b]=a;
            union_(parent,curr_parent,x);
        }

    }
//    cout<<"CURR PAR"<<curr_parent<<endl;
//    for(int i=1;i<=n;i++)
  //      cout<<parent[i]<<" ";
 //   cout<<endl;
    int sz=to_break.size();
    int diff=sz-to_build.size();
    int p=1;
    while(diff>0)
    {
        if(find_parent(parent,p)!=curr_parent)
        {
            to_build.push_back(make_pair(p,p));
            diff--;
        }
        p++;
    }
    if(sz==0)
    {
        cout<<sz<<endl;
    }
    else{
            cout<<sz<<endl;
            for(int i=0;i<sz;i++)
            {
                cout<<to_break[i].first<<" "<<to_break[i].second<<" "<<to_break[i].first<<" "<<to_build[i].first<<endl;
            }

    }
    return 0;
}


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

int find_parent(vector<int> par,int i)         //if this doesn't work try out path compression and union by rank.
{
    if(i==par[i])
        return i;
    par[i]=find_parent(par,par[i]);
    return par[i];
}

void union_(vector<int>& par,int x,int y)
{
    int i=find_parent(par,x);
    int j=find_parent(par,y);
    par[j]=i;
}

void dfs(vector<vector<int> > G,int root,vector<bool>& vis)
{
    vis[root]=true;
    for(int i=0;i<G[root].size();i++)
    {
        int v=G[root][i];
        dfs(G,v,vis);
    }

}

int main()
{
    int n;
    cin>>n;
    vector<vector<int> > G;
    G.resize(n+1);
    int days=0;

    vector<int> parent(n+1,0);
    vector<bool> vis(n+1,false);
    vector<pair<int,int> > to_break;
    vector<pair<int,int> > to_build;
    for(int i=1;i<=n;i++)
        parent[i]=i;
    int curr_parent;
    for(int i=1;i<=n-1;i++)
    {
        int a,b;
        cin>>a>>b;
        int x=find_parent(parent,a);
        int y=find_parent(parent,b);
        if(i==1)
            curr_parent=x;

        if(x!=y && (x==curr_parent || y==curr_parent))
        {
            union_(parent,x,y);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        else if(x==y)
        {
            days++;
            to_break.push_back(make_pair(a,b));
        }
        else if(x!=y && (x!=curr_parent && y!=curr_parent))
        {
            to_build.push_back(make_pair(a,b));
            parent[b]=a;
            union_(parent,curr_parent,x);
        }

    }

    int sz=to_break.size();
    if(sz==0)
    {
        cout<<sz<<endl;
    }
    else{
            cout<<sz<<endl;
            for(int i=0;i<sz;i++)
            {
                cout<<to_break[i].first<<" "<<to_break[i].second<<" "<<to_break[i].first<<" "<<to_build[i].first<<endl;
            }

    }
    return 0;
}