import java.io.*;
import java.math.*;
import java.security.KeyStore.Entry;
import java.util.*;
/*
                                                                yash jobanputra
                                                                    DA-IICT
*/
public class yash {
    private static InputStream stream;
    private static byte[] buf = new byte[1024];
    private static int curChar;
    private static int numChars;
    private static SpaceCharFilter filter;
    private static PrintWriter pw;
    private static long mod = 1000000000 + 7;
    private static long mod1 = 1000000000 + 9;
    private static int MAX=1000001;
    private static int block;
    private static int[] par;
    private static long[] cost;
    private static long[] costm;
    private static int times;
    private static long ans;
    private static int max=51;
    private static boolean[] vis;
    private static boolean[] vis2;
    private static boolean[] vis3;
    private static long[] sa;
    private static long count;
    private static boolean ff;
    private static ArrayList<Integer>[] ggc;
    private static long[] arra;
    private static long[] a;
    private static int[] dp;
   // private static int[] ind;
    //private static long[] dist;
    public static void soln()
    {
    	int n=ni();
    	HashSet<Integer>[] g=new HashSet[n+1];
    	ArrayList<Integer>[] gl=new ArrayList[n+1];
    	for(int i=1;i<=n;i++)
    	{
    		g[i]=new HashSet<>();gl[i]=new ArrayList<>();
    	}
    	for(int i=0;i<n-1;i++)
    	{
    		int a=ni();int b=ni();
    		g[a].add(b);
    		gl[b].add(a);gl[a].add(b);
    	}
    	vis=new boolean[n+1];
    	dp=new int[n+1];
    	dfs(gl,g,1);
    	//pa(dp);
    	Arrays.fill(vis,false);
    	dfs2(gl,g,1);
    	//pa(dp);
    	int min=Integer.MAX_VALUE;
    	for(int i=1;i<=n;i++)
    	{
    		if(dp[i]<min)	min=dp[i];
    	}
    	pl(min);
    	for(int i=1;i<=n;i++)
    	{
    		if(dp[i]==min)
    			p(i);
    	}
    }
    public static void dfs(ArrayList<Integer>[] gr,HashSet<Integer>[] g,int v)
    {
        vis[v]=true;
        ArrayList<Integer> arr=gr[v];
        for(int i=0;i<arr.size();i++)
        {
            if(!vis[arr.get(i)])
            {
           		dfs(gr,g,arr.get(i));
           		if(g[v].contains(arr.get(i)))
           		{
           			//pw.print("PO");
           			dp[v]+=dp[arr.get(i)];
           		}
           		else
           		{
           			//pw.println(v+" "+arr.get(i));
           			dp[v]+=(dp[arr.get(i)])+1;
           		}
            }
        }
    }
    public static void dfs2(ArrayList<Integer>[] gr,HashSet<Integer>[] g,int v)
    {
        vis[v]=true;
        ArrayList<Integer> arr=gr[v];
        int ind=0;
        for(int i=0;i<arr.size();i++)
        {
            if(!vis[arr.get(i)])
            {
            	if(g[v].contains(arr.get(i)))
           		{
           			dp[arr.get(i)]=(dp[v]+1);
           		}
           		else
           			dp[arr.get(i)]=(dp[v]-1);
           		dfs2(gr,g,arr.get(i));
            }
        }
    }
    public static class lca{
    	int[] e;
    	int[] l;
    	int[] h;
    	int[] level;
    	boolean[] vis;
    	int time;
    	int[] tree=new int[10000000];
        int[] lazy=new int[10000000];
        int n;
    	public lca(ArrayList<Integer>[] g)
    	{
    		n=g.length-1;
    		pw.println(n);
    		e=new int[2*n];
    		l=new int[2*n];
    		h=new int[n+1];
    		vis=new boolean[n+1];
    		level=new int[n+1];
    		level[1]=0;
    		dfs(g,1);
    		Arrays.fill(lazy, 0);
    		build(l,0,0,2*n-1);
    	}
    	public int lf(int u,int v)
    	{
    		int a=h[u];int b=h[v];
    		if(h[u]>h[v])
    			{a=h[v];b=h[u];}
    		int p=query(l,0,0,2*n-1,a,b);
    		return e[p];
    	}
    	public void dfs(ArrayList<Integer>[] gr,int v)
        {
             vis[v]=true;
             time++;
             e[time]=v;
             l[time]=level[v];
             h[v]=time;
             ArrayList<Integer> arr=gr[v];
             for(int i=0;i<arr.size();i++)
             {
                 if(!vis[arr.get(i)])
                 {
                	 level[arr.get(i)]=level[v]+1;
                	 dfs(gr,arr.get(i));
                	 time++;e[time]=v;l[time]=level[v];
                 }
             }
         }
    	 public void build(int[] arr,int node,int l,int r)
         {
             if(l==r)
             {
                 tree[node]=l;
             }
             else
             {
                 int m=(l+r)/2;
                 build(arr,(2*node)+1,l,m);
                 build(arr,(2*node)+2,m+1,r);
                 if(arr[tree[2*node+1]]<arr[tree[2*node+2]])
                	 tree[node]=tree[2*node+1];
                 else
                	 tree[node]=tree[2*node+2];
             }
         }
    	 public int query(int[] arr,int node,int l,int r,int s,int e)
         {
             if(e<l || r<s)
                 return -1;
             if(s<=l && e>=r)
                 return tree[node];
             int m=(l+r)/2;
             int p1=query(arr,(2*node+1),l,m,s,e);
             int p2=query(arr,(2*node+2),m+1,r,s,e);
             if(p1==-1)
            	 return p2;
             else if(p2==-1)
            	 return p1;
             else
             {
            	 if(arr[p1]<arr[p2])
            		 return p1;
            	 else
            		 return p2;
             }
         }
    }
    public static long[] reverse(long[] arr, int l, int r)
      {
          int d = (r-l+1)/2;
          for(int i=0;i<d;i++)
          {
             long t = arr[l+i];
             arr[l+i] = arr[r-i];
             arr[r-i] = t;
          }
          return arr;
      }
    private static class graph{
        public static void arti(boolean[] ap,int[] parent,int[] disc,int[] low,ArrayList<Integer>[] gr,boolean[] vis,int ver)
        {
            int child=0;
            vis[ver]=true;
            ArrayList<Integer> arr=gr[ver];
            times++;
            disc[ver]=low[ver]=times;
            for(int i=0;i<arr.size();i++)
            {
                if(!vis[arr.get(i)])
                {
                    child++;
                    parent[arr.get(i)]=ver;
                    arti(ap,parent,disc,low,gr,vis,arr.get(i));
                    low[ver]=Math.min(low[ver], low[arr.get(i)]);
                    if(parent[ver]!=0 && low[arr.get(i)]>=disc[ver])
                        ap[ver]=true;
                    if(parent[ver]==0 && child>1)
                        ap[ver]=true;
                }
                else if(parent[ver]!=arr.get(i))
                    low[ver]=Math.min(low[ver], disc[arr.get(i)]);
            }
        }
        public static void floyd(Pair[] arr,int n,int m,int[][] dist)
        {
            for(int i=0;i<=n;i++)
            {
                Arrays.fill(dist[i], Integer.MAX_VALUE);
            }
            for(int c=0;c<m;c++)
            {
                int w=arr[c].v;
                int a=arr[c].j.v;
                int b=arr[c].j.i;
                dist[a][b]=w;
            }
            for(int i=0;i<=n;i++)
                dist[i][i]=0;
            for(int k=1;k<=n;k++)
            {
                for(int i=1;i<=n;i++)
                {
                    for(int j=1;j<=n;j++)
                    {
                        if(dist[i][k]!=Integer.MAX_VALUE && dist[k][j]!=Integer.MAX_VALUE)
                        dist[i][j]=Math.min(dist[i][j], dist[i][k]+dist[k][j]);
                    }
                }
            }
        }
        public static boolean bfs(ArrayList<Integer>[] gr,int v,int n)
        {

            boolean[] vis=new boolean[n+1];
            int c2=0;
            Queue<Integer> q=new LinkedList<>();
            q.add(v);
            while(!q.isEmpty())
            {
                int x=q.poll();
                Iterator<Integer> it=gr[x].iterator();
                while(it.hasNext())
                {
                    int p=it.next();
                    if(!vis[p])
                    {
                        q.add(p);
                        c2++;
                        vis[p]=true;
                    }
                }
            }
            return c2==n;
        }
        public static ArrayList<Pair> MSTP(int n,int m,ArrayList<Pair>[] arr,int[][] arr2)
        {
            ArrayList<Pair> pp=new ArrayList<>();
            int[] par=new int[n+1];
            int[] key=new int[n+1];
            vis=new boolean[n+1];
            Arrays.fill(key, Integer.MAX_VALUE);
            key[1]=0;
            PriorityQueue<Integer> dis=new PriorityQueue<>(n+1,
                    new Comparator<Integer>()
                    {
                        public int compare(Integer p,Integer q)
                        {
                        return key[p]-key[q];
                        }
                    }
                    );
            dis.add(1);
            vis[1]=true;
            while(!dis.isEmpty())
            {
                //pw.println(dis);
                int u=dis.poll();
                    ArrayList<Pair> p=arr[u];
                    for(int i=0;i<p.size();i++)
                    {
                        if(key[u]+p.get(i).i<key[p.get(i).v])
                        {
                            key[p.get(i).v]=key[u]+p.get(i).i;
                            par[p.get(i).v]=u;
                            if(!vis[p.get(i).v])
                            {
                                dis.add(p.get(i).v);
                                vis[p.get(i).v]=true;
                            }
                        }
                    }
            }
            for(int i=1;i<=n;i++)
                pp.add(new Pair(i,par[i]));
            return pp;
        }
        public static ArrayList<Pair> MSTK(int n,int m,Pair[] arr)
        {
            ArrayList<Pair> pp=new ArrayList<>();
            long sum=0;
            Arrays.sort(arr);
            DSU x=new DSU(n+1);
            for(int c=0;(c<m);c++)
            {
                Pair p=arr[c];
                //int a=p.v;
                //int b=p.i;
                int a=p.j.v;
                int b=p.j.i;
                int w=p.v;
                if(x.find(a)!=x.find(b))
                {
                    pp.add(new Pair(w,new Pair(a,b)));
                    x.Union(a, b);
                }
            }
            return pp;
        }
        public static int[] dijkstras(ArrayList<Pair>[] gr)
        {
            int n=gr.length-1;
            int[] dist=new int[n+1];
            Arrays.fill(dist, Integer.MAX_VALUE);

            PriorityQueue<Integer> dis=new PriorityQueue<>(n+1,
                    new Comparator<Integer>()
                    {
                        public int compare(Integer p,Integer q)
                        {
                        return dist[p]-dist[q];
                        }
                    }
                    );
            boolean[] vis=new boolean[n+1];
            Arrays.fill(vis, false);

            int s=1;
            dist[s]=0;
            dis.add(s);
            vis[s]=true;
            while(!dis.isEmpty())
            {
                int p=dis.poll();
                for(int i=0;i<gr[p].size();i++)
                {
                    int y=gr[p].get(i).v;
                    int w=gr[p].get(i).i;
                    if(!vis[y])
                    {
                        dist[y]=dist[p]+w;
                        dis.add(y);
                        vis[y]=true;
                    }
                    else
                    {
                        if(dist[p]+w<dist[y])
                        {
                            dist[y]=dist[p]+w;
                        }
                    }
                }
            }
            return dist;
        }
    }

    public static class sieve{
        public static ArrayList<Integer> sieves(int n)
        {
            ArrayList<Integer> arr=new ArrayList<>();
            boolean[] bol=new boolean[n+1];
            Arrays.fill(bol, true);
            //arr.add(1);
            for(int i=2;i<=n;i++)
            {
                if(bol[i])
                {
                    arr.add(i);
                    for(int j=2;j*i<=n;j++)
                    {
                        bol[i*j]=false;
                    }
                }
            }
            return arr;
        }
    }
    public static class isprime{
        public static boolean check(int n)
        {
            if(n==2)
                return true;
            else if(n==3)
                return true;
            else if(n%2==0)
                return false;
            else if(n%3==0)
                return false;
            else
            {
                for(int i=6;;i+=6)
                {
                    if(i>Math.sqrt(n))
                        break;
                    if(n%(i-1)==0)
                    {
                        return false;
                    }
                    else if(n%(i+1)==0)
                        return false;
                                    }
                return true;
            }
        }
    }
    private static class DSU{
        int[] parent;
        int[] rank;
        int cnt;
        public DSU(int n){
            parent=new int[n];
            rank=new int[n];
            for(int i=0;i<n;i++){
                parent[i]=i;
                rank[i]=1;
            }
            cnt=n;
        }
        int find(int i){
            while(parent[i] !=i){
                parent[i]=parent[parent[i]];
                i=parent[i];
            }
            return i;
        }
        int Union(int x, int y){
            int xset = find(x);
            int yset = find(y);
            if(xset!=yset)
                cnt--;
            if(rank[xset]<rank[yset]){
                parent[xset] = yset;
                rank[yset]+=rank[xset];
                rank[xset]=0;
                return yset;
            }else{
                parent[yset]=xset;
                rank[xset]+=rank[yset];
                rank[yset]=0;
                return xset;
            }
        }
    }
    private static class Pair implements Comparable<Pair>{
        int v,i;Pair j;
        public Pair(int a,int b){
            v=a;
            i=b;
        }
        public Pair(int a,Pair b)
        {
            v=a;
            j=b;
        }
        @Override
        public int compareTo(Pair arg0) {
            {
                return this.v-arg0.v;
            }
        }
    }
    private static class Pairl implements Comparable<Pairl>{
        long v,i;Pairl j;
        public Pairl(long a,long b){
            v=a;
            i=b;
        }
        public Pairl(long a,Pairl b)
        {
            v=a;
            j=b;
        }
        @Override
        public int compareTo(Pairl arg0) {
            {
                if(this.v>arg0.v)
                    return 1;
                else
                    return -1;
            }
        }
    }
    public static long f(long number,long m) {
          if (number <= 1) return 1;
          else return (number * f(number - 1,m))%m;
       }
    public static long mmi(long a, long m)
    {
        long m0 = m;
        long y = 0, x = 1;

        if (m == 1)
          return 0;

        while (a > 1)
        {
            // q is quotient
            long q = a / m;
            long t = m;

            // m is remainder now, process same as
            // Euclid's algo
            m = a % m; a = t;
            t = y;

            // Update y and x
            y = x - q * y;
            x = t;
        }

        // Make x positive
        if (x < 0)
           x += m0;

        return x;
    }
    public static class segtree{
        static int[] tree=new int[10000000];
        static int[] lazy=new int[10000000];
        public static void initial()
        {
            Arrays.fill(lazy, 0);
        }
        public static void build(int[] arr,int node,int l,int r)
        {
            if(l==r)
            {
                tree[node]=arr[l];
            }
            else
            {
                int m=(l+r)/2;
                build(arr,(2*node)+1,l,m);
                build(arr,(2*node)+2,m+1,r);
                tree[node]=tree[2*node+1]+tree[(2*node)+2];
            }
        }
        public static void updater(int[] arr,int node,int l,int r,int s,int e,int val)
        {
            if(lazy[node]!=0)
            {
                tree[node]+=(r-l+1)*lazy[node];
                if(l!=r)
                {
                    lazy[2*node+1]+=lazy[node];
                    lazy[2*node+2]+=lazy[node];
                }
                lazy[node]=0;
            }
            if(s<=l && e>=r)
            {
                tree[node]+=(r-l+1)*val;
                if(l!=r)
                {
                    lazy[2*node+1]+=val;
                    lazy[2*node+2]+=val;
                }
            }
            else if(!(e<l || r<s))
            {
                int m=(l+r)/2;
                updater(arr,2*node+1,l,m,s,e,val);
                updater(arr,2*node+2,m+1,r,s,e,val);
                tree[node]=tree[2*node+1]+tree[2*node+2];
            }
        }
        public static void update(int[] arr,int node,int l,int r,int ind,int val)
        {
            if(l==r)
            {
                arr[ind]+=val;
                tree[node]+=val;
            }
            else
            {
                int m=(l+r)/2;
                if(l<=ind && ind<=m)
                {
                    update(arr,(2*node+1),l,m,ind,val);
                }
                else
                {
                    update(arr,(2*node+2),m+1,r,ind,val);
                }
                tree[node]=tree[2*node+1]+tree[2*node+2];
            }
        }
        public static int query(int node,int l,int r,int s,int e)
        {
            if(lazy[node]!=0)
            {
                tree[node]+=(r-l+1)*lazy[node];
                if(l!=r)
                {
                    lazy[2*node+1]+=lazy[node];
                    lazy[2*node+2]+=lazy[node];
                }
                lazy[node]=0;
            }
            if(e<l || r<s)
                return 0;
            if(s<=l && e>=r)
                return tree[node];
            int m=(l+r)/2;
            int p1=query((2*node+1),l,m,s,e);
            int p2=query((2*node+2),m+1,r,s,e);
            return (p1+p2);
        }
    }

    private static long pow(long a, long b, long c) {
        if (b == 0)
            return 1;
        long p = pow(a, b / 2, c);
        p = (p * p) % c;
        return (b % 2 == 0) ? p : (a * p) % c;
    }
    private static long gcd(long n, long l) {
        if (l == 0)
            return n;
        return gcd(l, n % l);
    }
    private static int gcd(int n, int l) {
        if (l == 0)
            return n;
        return gcd(l, n % l);
    }
    private static long max(long a, long b) {
        if (a > b)
            return a;
        return b;
    }
    private static long min(long a, long b) {
        if (a < b)
            return a;
        return b;
    }
    public static void merge(int arr[], int l, int m, int r)
    {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        /* Create temp arrays */
        int L[] = new int [n1];
        int R[] = new int [n2];

        /*Copy data to temp arrays*/
        for (int i=0; i<n1; ++i)
            L[i] = arr[l + i];
        for (int j=0; j<n2; ++j)
            R[j] = arr[m + 1+ j];

        /* Merge the temp arrays */

        // Initial indexes of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarry array
        int k = l;
        while (i < n1 && j < n2)
        {
            if (L[i] <= R[j])
            {
                arr[k] = L[i];
                i++;
            }
            else
            {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        /* Copy remaining elements of L[] if any */
        while (i < n1)
        {
            arr[k] = L[i];
            i++;
            k++;
        }

        /* Copy remaining elements of R[] if any */
        while (j < n2)
        {
            arr[k] = R[j];
            j++;
            k++;
        }
    }
    public static void merge(long arr[], int l, int m, int r)
    {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        /* Create temp arrays */
        long L[] = new long [n1];
        long R[] = new long [n2];

        /*Copy data to temp arrays*/
        for (int i=0; i<n1; ++i)
            L[i] = arr[l + i];
        for (int j=0; j<n2; ++j)
            R[j] = arr[m + 1+ j];

        /* Merge the temp arrays */

        // Initial indexes of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarry array
        int k = l;
        while (i < n1 && j < n2)
        {
            if (L[i] <= R[j])
            {
                arr[k] = L[i];
                i++;
            }
            else
            {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        /* Copy remaining elements of L[] if any */
        while (i < n1)
        {
            arr[k] = L[i];
            i++;
            k++;
        }

        /* Copy remaining elements of R[] if any */
        while (j < n2)
        {
            arr[k] = R[j];
            j++;
            k++;
        }
    }
    public static void sort(long arr[])
    {
    	sort(arr,0,arr.length-1);
    }
    public static void sort(int arr[])
    {
    	sort(arr,0,arr.length-1);
    }
    public static void sort(int arr[], int l, int r)
    {
        if (l < r)
        {
            // Find the middle point
            int m = (l+r)/2;

            // Sort first and second halves
            sort(arr, l, m);
            sort(arr , m+1, r);

            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }
    public static void sort(long arr[], int l, int r)
    {
        if (l < r)
        {
            // Find the middle point
            int m = (l+r)/2;

            // Sort first and second halves
            sort(arr, l, m);
            sort(arr , m+1, r);

            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }
    public static void main(String[] args) throws Exception {
        new Thread(null,new Runnable(){
            @Override
            public void run() {
               /* try {
                    InputReader(new FileInputStream("input.txt"));
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }*/
                InputReader(System.in);
                pw = new PrintWriter(System.out);
                /*try {
                    pw=new PrintWriter(new FileOutputStream("output.txt"));
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }*/
                soln();
                pw.close();
            }
        },"1",1<<26).start();
    }

    public static void InputReader(InputStream stream1) {
        stream = stream1;
    }

    private static boolean isWhitespace(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    private static boolean isEndOfLine(int c) {
        return c == '\n' || c == '\r' || c == -1;
    }

    private static int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    private static int ni() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    private static long nl() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        long res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }
    private static double nd()
    {
        double ret = 0, div = 1;
        int c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();

        do {
            ret = ret * 10 + c - '0';
        }
        while ((c = read()) >= '0' && c <= '9');

        if (c == '.')
        {
            while ((c = read()) >= '0' && c <= '9')
            {
                ret += (c - '0') / (div *= 10);
            }
        }

        if (neg)
            return -ret;
        return ret;
    }
    private static String nextToken() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }

    private static String nli() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isEndOfLine(c));
        return res.toString();
    }

    private static int[] nia(int n) {
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = ni();
        }
        return arr;
    }

    private static long[] nla(int n) {
        long[] arr = new long[n];
        for (int i = 0; i < n; i++) {
            arr[i] = nl();
        }
        return arr;
    }

    private static void pa(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            pw.print(arr[i] + " ");
        }
        pw.println();
        return;
    }

    private static void pa(long[] arr) {
        for (int i = 0; i < arr.length; i++) {
            pw.print(arr[i] + " ");
        }
        pw.println();
        return;
    }
    private static void pl(int a)
    {
    	pw.println(a);
    }
    private static void pl(long a)
    {
    	pw.println(a);
    }
    private static void p(int a)
    {
    	pw.print(a+" ");
    }
    private static void p(long a)
    {
    	pw.print(a+" ");
    }
    private static boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return isWhitespace(c);
    }
    private static char nc() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        char c1=(char)c;
        while(!isSpaceChar(c))
            c=read();
        return c1;
    }
    public String ns() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }
    private interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.StringTokenizer;

public class D {
    static int n;
    static ArrayList<E> adj[];

    static class E {
        int to;
        boolean ok;

        public E(int to, boolean ok) {
            this.to = to;
            this.ok = ok;
        }
    }

    public static void main(String[] args) throws IOException {
        InputReader in = new InputReader();
        n = in.nextInt();
        adj = new ArrayList[n];
        for (int i = 0; i < n; i++)
            adj[i] = new ArrayList<E>();
        for (int i = 0; i < n - 1; i++) {
            int a = in.nextInt() - 1;
            int b = in.nextInt() - 1;
            adj[a].add(new E(b, true));
            adj[b].add(new E(a, false));
        }
        cnt = dfs1(0, -1);
        dfs2(0, -1, cnt);
        Iterator<Integer> it = res.iterator();
        StringBuilder sb = new StringBuilder();
        while (it.hasNext())
            sb.append(it.next() + " ");
        System.out.println(cnt);
        System.out.println(sb);
    }

    public static int dfs1(int cur, int p) {
        int cnt = 0, size = adj[cur].size();
        for (int i = 0; i < size; i++) {
            E e = adj[cur].get(i);
            if (e.to != p)
                cnt += dfs1(e.to, cur) + (e.ok ? 1 : 0);
        }
        return cnt;
    }

    static int cnt;
    static LinkedList<Integer> res = new LinkedList<Integer>();

    public static void dfs2(int cur, int p, int total) {
        if (cnt > total) {
            res.clear();
            res.add(cur);
            cnt = total;
        } else if (total == cnt) {
            res.add(cur);
        }
        int size = adj[cur].size();
        for (int i = 0; i < size; i++) {
            E e = adj[cur].get(i);
            if (e.to != p) {
                dfs2(e.to, cur, total - (e.ok ? 1 : 0));
            }
        }
    }

    static class InputReader {
        BufferedReader in;
        StringTokenizer st;

        public InputReader() throws IOException {
            in = new BufferedReader(new InputStreamReader(System.in));
            st = new StringTokenizer(in.readLine());
        }

        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        public String next() throws IOException {
            while (!st.hasMoreElements())
                st = new StringTokenizer(in.readLine());
            return st.nextToken();
        }

        public int nextInt() throws NumberFormatException, IOException {
            return Integer.parseInt(next());
        }

        public long nextLong() throws NumberFormatException, IOException {
            return Long.parseLong(next());
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.StringTokenizer;

public class D {
    static int n;
    static ArrayList<E> adj[];

    static class E {
        int to;
        boolean ok;

        public E(int to, boolean ok) {
            this.to = to;
            this.ok = ok;
        }
    }

    public static void main(String[] args) throws IOException {
        InputReader in = new InputReader();
        n = in.nextInt();
        adj = new ArrayList[n];
        for (int i = 0; i < n; i++)
            adj[i] = new ArrayList<E>();
        for (int i = 0; i < n - 1; i++) {
            int a = in.nextInt() - 1;
            int b = in.nextInt() - 1;
            adj[a].add(new E(b, true));
            adj[b].add(new E(a, false));
        }
        cnt = dfs1(0, -1);
        dfs2(0, -1, cnt);
        Collections.sort(res);
        Iterator<Integer> it = res.iterator();
        StringBuilder sb = new StringBuilder();
        while (it.hasNext())
            sb.append(it.next() + " ");
        System.out.println(cnt);
        System.out.println(sb);
    }

    public static int dfs1(int cur, int p) {
        int cnt = 0, size = adj[cur].size();
        for (int i = 0; i < size; i++) {
            E e = adj[cur].get(i);
            if (e.to != p)
                cnt += dfs1(e.to, cur) + (e.ok ? 1 : 0);
        }
        return cnt;
    }

    static int cnt;
    static LinkedList<Integer> res = new LinkedList<Integer>();

    public static void dfs2(int cur, int p, int total) {
        if (cnt > total) {
            res.clear();
            res.add(cur);
            cnt = total;
        } else if (total == cnt) {
            res.add(cur);
        }
        int size = adj[cur].size();
        for (int i = 0; i < size; i++) {
            E e = adj[cur].get(i);
            if (e.to != p) {
                dfs2(e.to, cur, total - (e.ok ? 1 : 0));
            }
        }
    }

    static class InputReader {
        BufferedReader in;
        StringTokenizer st;

        public InputReader() throws IOException {
            in = new BufferedReader(new InputStreamReader(System.in));
            st = new StringTokenizer(in.readLine());
        }

        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        public String next() throws IOException {
            while (!st.hasMoreElements())
                st = new StringTokenizer(in.readLine());
            return st.nextToken();
        }

        public int nextInt() throws NumberFormatException, IOException {
            return Integer.parseInt(next());
        }

        public long nextLong() throws NumberFormatException, IOException {
            return Long.parseLong(next());
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.StringTokenizer;

public class D {
    static int n;
    static ArrayList<E> adj[];

    static class E {
        int to;
        boolean ok;

        public E(int to, boolean ok) {
            this.to = to;
            this.ok = ok;
        }
    }

    public static void main(String[] args) throws IOException {
        InputReader in = new InputReader();
        n = in.nextInt();
        adj = new ArrayList[n];
        for (int i = 0; i < n; i++)
            adj[i] = new ArrayList<E>();
        for (int i = 0; i < n - 1; i++) {
            int a = in.nextInt() - 1;
            int b = in.nextInt() - 1;
            adj[a].add(new E(b, true));
            adj[b].add(new E(a, false));
        }
        cnt = dfs1(0, -1);
        dfs2(0, -1, cnt);
        Collections.sort(res);
        Iterator<Integer> it = res.iterator();
        StringBuilder sb = new StringBuilder();
        while (it.hasNext())
            sb.append(it.next() + " ");
        System.out.println(cnt);
        System.out.println(sb);
    }

    public static int dfs1(int cur, int p) {
        int cnt = 0, size = adj[cur].size();
        for (int i = 0; i < size; i++) {
            E e = adj[cur].get(i);
            if (e.to != p)
                cnt += dfs1(e.to, cur) + (!e.ok ? 1 : 0);
        }
        return cnt;
    }

    static int cnt;
    static LinkedList<Integer> res = new LinkedList<Integer>();

    public static void dfs2(int cur, int p, int total) {
        if (cnt > total) {
            res.clear();
            res.add(cur+1);
            cnt = total;
        } else if (total == cnt) {
            res.add(cur+1);
        }
        int size = adj[cur].size();
        for (int i = 0; i < size; i++) {
            E e = adj[cur].get(i);
            if (e.to != p) {
                dfs2(e.to, cur, total + (e.ok ? 1 : -1));
            }
        }
    }

    static class InputReader {
        BufferedReader in;
        StringTokenizer st;

        public InputReader() throws IOException {
            in = new BufferedReader(new InputStreamReader(System.in));
            st = new StringTokenizer(in.readLine());
        }

        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        public String next() throws IOException {
            while (!st.hasMoreElements())
                st = new StringTokenizer(in.readLine());
            return st.nextToken();
        }

        public int nextInt() throws NumberFormatException, IOException {
            return Integer.parseInt(next());
        }

        public long nextLong() throws NumberFormatException, IOException {
            return Long.parseLong(next());
        }
    }
}


import java.io.*;
import java.util.*;

public class Cbr {

    public static void main(String[] args) throws IOException {
        Cbr cbr = new Cbr();
        cbr.run();
        cbr.out.flush();
    }

    private void run() throws IOException {
        int n = nextInt();
        d = new ArrayList<List<Integer>>(n);
        dr = new ArrayList<List<Integer>>(n);
        for (int i = 0; i < n; i++) {
            d.add(new ArrayList<Integer>());
            dr.add(new ArrayList<Integer>());
        }
        for (int i = 0; i < n - 1; i++) {
            int v = nextInt() - 1, u = nextInt() - 1;
            d.get(v).add(u);
            dr.get(u).add(v);
        }
        a = new int[n];
        used = new boolean[n];
        Arrays.fill(used, false);
        a[0] = dfs(0);
        m = a[0];
        Arrays.fill(used, false);
        dfs1(0);
        out.println(m);
        for (int i = 0; i < n; i++)
            if (a[i] == m) {
                out.print(i + 1);
                out.print(' ');
            }
    }

    private List<List<Integer>> d;
    private List<List<Integer>> dr;
    private boolean[] used;
    private int[] a;
    private int m;

    private int dfs(int v) {
        int k = 0;
        used[v] = true;
        for (Integer u : d.get(v))
            if (!used[u])
                k += dfs(u);
        for (Integer u : dr.get(v))
            if (!used[u])
                k += dfs(u) + 1;
        return k;
    }

    private void dfs1(int v) {
        used[v] = true;
        for (Integer u: d.get(v))
            if (!used[u]) {
                a[u] = a[v] + 1;
                dfs1(u);
            }
        for (Integer u : dr.get(v))
            if (!used[u]) {
                a[u] = a[v] - 1;
                m = Math.min(m, a[u]);
                dfs1(u);
            }
    }

    private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private PrintWriter out = new PrintWriter(System.out);

    private StringTokenizer st;

    private String nextToken() throws IOException {
        while (st == null || !st.hasMoreTokens())
            st = new StringTokenizer(br.readLine());
        return st.nextToken();
    }

    private int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

}


import java.io.*;
import java.util.*;

public class Cbr {

    private List<Set<Integer>> d;
    private List<Set<Integer>> dr;

    public static void main(String[] args) throws IOException {
        Cbr cbr = new Cbr();
        cbr.run();
        cbr.out.flush();
    }

    private void run() throws IOException {
        int n = nextInt();
        d = new ArrayList<Set<Integer>>(n);
        dr = new ArrayList<Set<Integer>>(n);
        for (int i = 0; i < n; i++) {
            d.add(new LinkedHashSet<Integer>());
            dr.add(new LinkedHashSet<Integer>());
        }
        for (int i = 0; i < n - 1; i++) {
            int v = nextInt() - 1, u = nextInt() - 1;
            d.get(v).add(u);
            dr.get(u).add(v);
        }
        answer = new int[n];
        use = new boolean[n];
        Arrays.fill(use, false);
        answer[0] = dfs(0);
        minimum = answer[0];
        Arrays.fill(use, false);
        dfs1(0);
        out.println(minimum);
        for (int i = 0; i < n; i++)
            if (answer[i] == minimum) {
                out.print(i + 1);
                out.print(' ');
            }
    }

    private boolean[] use;
    private int[] answer;
    private int minimum;

    private int dfs(int v) {
        int k = 0;
        use[v] = true;
        for (Integer u : d.get(v))
            if (!use[u])
                k += dfs(u);
        for (Integer u : dr.get(v))
            if (!use[u])
                k += dfs(u) + 1;
        return k;
    }

    private void dfs1(int v) {
        use[v] = true;
        for (Integer u: d.get(v))
            if (!use[u]) {
                answer[u] = answer[v] + 1;
                dfs1(u);
            }
        for (Integer u : dr.get(v))
            if (!use[u]) {
                answer[u] = answer[v] - 1;
                minimum = Math.min(minimum, answer[u]);
                dfs1(u);
            }
    }

    private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private PrintWriter out = new PrintWriter(System.out);

    private StringTokenizer st;

    private String nextToken() throws IOException {
        while (st == null || !st.hasMoreTokens())
            st = new StringTokenizer(br.readLine());
        return st.nextToken();
    }

    private int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

}


import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Deque;
import java.util.ArrayDeque;

public class ProblemD
{
	public static void main(String[] args)
	{
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		Map<Integer, List<Integer>> parents = new HashMap<Integer, List<Integer>>();
		Map<Integer, List<Integer>> children = new HashMap<Integer, List<Integer>>();
		for (int i = 0; i < n; i++)
		{
			parents.put(i, new ArrayList<Integer>());
			children.put(i, new ArrayList<Integer>());
		}
		int[] cap = new int[n];
		for (int i = 1; i < n; i++)
		{
			int from = in.nextInt() - 1;
			int to = in.nextInt() - 1;
			parents.get(to).add(from);
			children.get(from).add(to);
			cap[i] = -1;
		}
		// Compute cap[0]
		Deque<Integer> stack = new ArrayDeque<Integer>();
		boolean[] check = new boolean[n];
		stack.addFirst(0);
		check[0] = true;
		while (stack.size() > 0)
		{
			int current = stack.removeFirst();
			for (int i : parents.get(current))
			{
				if (!check[i])
				{
					stack.addFirst(i);
					check[i] = true;
					cap[0]++;
				}
			}
			for (int i : children.get(current))
			{
				if (!check[i])
				{
					stack.addFirst(i);
					check[i] = true;
				}
			}
		}
		// Compute cap[i] generally
		stack = new ArrayDeque<Integer>();
		check = new boolean[n];
		stack.addFirst(0);
		check[0] = true;
		int mincap = cap[0];
		while (stack.size() > 0)
		{
			int current = stack.removeFirst();
			for (int i : parents.get(current))
			{
				if (!check[i])
				{
					stack.addFirst(i);
					check[i] = true;
					cap[i] = cap[current] - 1;
					mincap = (cap[i] < mincap) ? cap[i] : mincap;
				}
			}
			for (int i : children.get(current))
			{
				if (!check[i])
				{
					stack.addFirst(i);
					check[i] = true;
					cap[i] = cap[current] + 1;
				}
			}
		}
		System.out.println(mincap);
		boolean first = true;
		for (int i = 0; i < n; i++)
		{
			if (mincap == cap[i])
			{
				if (!first)
				{
					System.out.print(" ");
				}
				first = false;
				System.out.print(i + 1);
			}
		}
		System.out.println();
	}
}


/**
 * User: wbh023
 * Date: 12-8-28
 * To change this template use File | Settings | File Templates.
 */

import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class ChoosingCapital implements Runnable {

  int[] dist;
  int[] red;
  ArrayList[] roads;
  int redAll = 0;

  class Edge {
    Edge(int x, int y, int from){
      this.x = x; this.y = y; this.from = from;
    }
    int x, y, from;
  }

  public void solve() throws IOException {
    int cityCount = nextInt();
    // [1, cityCount]
    dist = new int[cityCount + 1];
    red =  new int[cityCount + 1];

    roads = new ArrayList[cityCount + 1];
    for(int i = 0; i <= cityCount; ++i) {
      roads[i] = new ArrayList<Edge>();
    }

    for(int i = 0; i < cityCount - 1; ++i) {
      int from = nextInt();
      int to = nextInt();
      Edge pt =new Edge(from, to, from);
      roads[from].add(pt);
      pt = new Edge(to, from, from);
      roads[to].add(pt);
    }

    dist[0] = 0;
    red[0] = 0;

    explore(1, 0, 0);

    ArrayList<Integer> result = new ArrayList<Integer>();
    int minReverse = Integer.MAX_VALUE;

    for(int i = 1; i <= cityCount; ++i ) {
      int val = redAll -  2 * red[i] + dist[i];
      if( val < minReverse) {
        minReverse = val;
        result.clear();
        result.add( i );
      }
      else if( val == minReverse ) {
        result.add( i );
      }
    }

    stdout.println(minReverse);
    for(int i = 0; i < result.size() - 1; ++i)
      stdout.print(result.get(i) + " ");
    stdout.println( result.get( result.size()-1 )) ;
  }

  // parent
  private void explore(int no, int parent, int len) {
    dist[no] = len;

    for (Object p : roads[no]) {
      Edge pt = (Edge) p;
      if (pt.y == parent) continue;

      red[pt.y] = red[no];
      if (pt.from == pt.y) {
        red[pt.y]++;
        redAll++;
      }
      explore(pt.y, no, len + 1);
    }

  }

  public static void main(String args[]) throws IOException {
    new ChoosingCapital().run();
  }

  PrintWriter stdout;
  StringTokenizer tokenizer;
  BufferedReader stdin;

  public void run() {
    try {
      stdin = new BufferedReader(new InputStreamReader(System.in));
      stdout = new PrintWriter(System.out);
      tokenizer = null;
      solve();
      stdin.close();
      stdout.close();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  String nextToken() throws IOException {
    while (tokenizer == null || !tokenizer.hasMoreTokens()) {
      tokenizer = new StringTokenizer(stdin.readLine());
    }
    return tokenizer.nextToken();
  }

  double nextDouble() throws IOException {
    return Double.parseDouble(nextToken());
  }

  int nextInt() throws IOException {
    return Integer.parseInt(nextToken());
  }

}


/**
 * User: wbh023
 * Date: 12-8-28
 * To change this template use File | Settings | File Templates.
 */

import java.awt.datatransfer.StringSelection;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class ChoosingCapital implements Runnable {

  int[] dist;
  int[] red;
  ArrayList[] roads;
  int redAll = 0;

  class Point {
    int y, from;
  }

  public void solve() throws IOException {
    int cityCount = nextInt();
    // [1, cityCount]
    dist = new int[cityCount + 1];
    red =  new int[cityCount + 1];
    // -1 means not dfs
    Arrays.fill(dist, -1);

    roads = new ArrayList[cityCount + 1];
    for(int i = 0; i <= cityCount; ++i) {
      roads[i] = new ArrayList<Point>();
    }

    for(int i = 0; i < cityCount - 1; ++i) {
      int from = nextInt();
      int to = nextInt();
      Point pt =new Point();
      pt.from = from;
      pt.y = to;
      roads[from].add(pt);
      pt = new Point();
      pt.from = from;
      pt.y = from;
      roads[to].add(pt);
    }

    dist[0] = 0;
    red[0] = 0;

    explore(1, 0, 0);

    ArrayList<Integer> result = new ArrayList<Integer>();
    int minReverse = Integer.MAX_VALUE;

    for(int i = 1; i <= cityCount; ++i ) {
      int val = redAll -  2 * red[i] + dist[i];
      if( val < minReverse) {
        minReverse = val;
        result.clear();
        result.add( i );
      }
      else if( val == minReverse ) {
        result.add( i );
      }
    }

    stdout.println(minReverse);
    for(int i = 0; i < result.size() - 1; ++i)
      stdout.print(result.get(i) + " ");
    stdout.println( result.get( result.size()-1 )) ;
  }

  private void explore(int no, int parent, int len) {
    dist[no] = len;

    for(Object p : roads[no]) {
      Point pt = (Point)p;
      if( pt.y == parent )continue;
      if( dist[pt.y] == -1 ) {
        red[pt.y] = red[no];
        if( pt.from == pt.y ) {
          red[pt.y]++;
          redAll++;
        }
        explore(pt.y, no, len + 1);
      }
    }
  }

  public static void main(String args[]) throws IOException {
    new ChoosingCapital().run();
  }

  PrintWriter stdout;
  StringTokenizer tokenizer;
  BufferedReader stdin;

  public void run() {
    try {
      stdin = new BufferedReader(new InputStreamReader(System.in));
      stdout = new PrintWriter(System.out);
      tokenizer = null;
      solve();
      stdin.close();
      stdout.close();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  String nextToken() throws IOException {
    while (tokenizer == null || !tokenizer.hasMoreTokens()) {
      tokenizer = new StringTokenizer(stdin.readLine());
    }
    return tokenizer.nextToken();
  }

  double nextDouble() throws IOException {
    return Double.parseDouble(nextToken());
  }

  int nextInt() throws IOException {
    return Integer.parseInt(nextToken());
  }

}


/**
 * User: wbh023
 * Date: 12-8-28
 * To change this template use File | Settings | File Templates.
 */

import java.awt.datatransfer.StringSelection;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class ChoosingCapital implements Runnable {

  int[] ways;
  ArrayList[] roads;

  public void solve() throws IOException {
    int cityCount = nextInt();
    // [1, cityCount]
    ways = new int[cityCount + 1];
    // -1 means not dfs
    Arrays.fill(ways, -1);

    roads = new ArrayList[100];
    for(int i = 0; i <= cityCount; ++i) {
      roads[i] = new ArrayList<Integer>();
    }

    for(int i = 0; i < cityCount - 1; ++i) {
      int from = nextInt();
      int to = nextInt();
      roads[from].add( to );
    }

    for(int i = 1; i <= cityCount; ++i) {
      if(ways[i] == -1) {
        explore(i);
      }
    }

    ArrayList<Integer> result = new ArrayList<Integer>();
    int minReverse = Integer.MAX_VALUE;
    for(int i = 1; i <= cityCount; ++i) {
      if( cityCount - ways[i] - 1 < minReverse ) {
        minReverse = cityCount - ways[i] - 1;
        result.clear();
        result.add(i);
      }
      else if( cityCount - ways[i] - 1 == minReverse) {
        result.add(i);
      }
    }

    stdout.println(minReverse);
    for(int i = 0; i < result.size() - 1; ++i)
      stdout.print(result.get(i) + " ");
    stdout.println( result.get( result.size()-1 )) ;
  }

  private int explore(int i) {
    int citi = 0;
    for( Object x : roads[i]) {
      int a = (Integer)x;
      if( ways[a] == -1 )
        explore(a);
      citi += (ways[a] + 1);
    }
    ways[i] = citi;
    return citi;
  }

  public static void main(String args[]) throws IOException {
    new ChoosingCapital().run();
  }

  PrintWriter stdout;
  StringTokenizer tokenizer;
  BufferedReader stdin;

  public void run() {
    try {
      stdin = new BufferedReader(new InputStreamReader(System.in));
      stdout = new PrintWriter(System.out);
      tokenizer = null;
      solve();
      stdin.close();
      stdout.close();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  String nextToken() throws IOException {
    while (tokenizer == null || !tokenizer.hasMoreTokens()) {
      tokenizer = new StringTokenizer(stdin.readLine());
    }
    return tokenizer.nextToken();
  }

  double nextDouble() throws IOException {
    return Double.parseDouble(nextToken());
  }

  int nextInt() throws IOException {
    return Integer.parseInt(nextToken());
  }

}


/**
 * User: wbh023
 * Date: 12-8-28
 * To change this template use File | Settings | File Templates.
 */

import java.awt.datatransfer.StringSelection;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class ChoosingCapital implements Runnable {

  int[] dist;
  int[] red;
  ArrayList[] roads;
  int redAll = 0;

  class Point {
    int y, from;
  }

  public void solve() throws IOException {
    int cityCount = nextInt();
    // [1, cityCount]
    dist = new int[cityCount + 1];
    red =  new int[cityCount + 1];
    // -1 means not dfs
    Arrays.fill(dist, -1);

    roads = new ArrayList[cityCount + 1];
    for(int i = 0; i <= cityCount; ++i) {
      roads[i] = new ArrayList<Point>();
    }

    for(int i = 0; i < cityCount - 1; ++i) {
      int from = nextInt();
      int to = nextInt();
      Point pt =new Point();
      pt.from = from;
      pt.y = to;
      roads[from].add(pt);
      pt = new Point();
      pt.from = from;
      pt.y = from;
      roads[to].add(pt);
    }

    dist[0] = 0;
    red[0] = 0;

    explore(1, 0, 0);

    ArrayList<Integer> result = new ArrayList<Integer>();
    int minReverse = Integer.MAX_VALUE;

    for(int i = 1; i <= cityCount; ++i ) {
      int val = redAll -  2 * red[i] + dist[i];
      if( val < minReverse) {
        minReverse = val;
        result.clear();
        result.add( i );
      }
      else if( val == minReverse ) {
        result.add( i );
      }
    }

    stdout.println(minReverse);
    for(int i = 0; i < result.size() - 1; ++i)
      stdout.print(result.get(i) + " ");
    stdout.println( result.get( result.size()-1 )) ;
  }

  private void explore(int no, int parent, int len) {
    dist[no] = len;

    for(Object p : roads[no]) {
      Point pt = (Point)p;
      if( pt.y == parent )continue;
      if( dist[pt.y] == -1 ) {
        red[pt.y] = red[parent];
        if( pt.from == pt.y ) {
          red[pt.y]++;
          redAll++;
        }
        explore(pt.y, no, len + 1);
      }
    }
  }

  public static void main(String args[]) throws IOException {
    new ChoosingCapital().run();
  }

  PrintWriter stdout;
  StringTokenizer tokenizer;
  BufferedReader stdin;

  public void run() {
    try {
      stdin = new BufferedReader(new InputStreamReader(System.in));
      stdout = new PrintWriter(System.out);
      tokenizer = null;
      solve();
      stdin.close();
      stdout.close();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  String nextToken() throws IOException {
    while (tokenizer == null || !tokenizer.hasMoreTokens()) {
      tokenizer = new StringTokenizer(stdin.readLine());
    }
    return tokenizer.nextToken();
  }

  double nextDouble() throws IOException {
    return Double.parseDouble(nextToken());
  }

  int nextInt() throws IOException {
    return Integer.parseInt(nextToken());
  }

}


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.StringTokenizer;
public class cf219d {
  static int n;
  static ArrayList<Integer>[] gg;
  static HashSet<Integer>[] g;
  static int[] dp, dp2;
  public static void main(String[] args) {
    FastScanner in = new FastScanner(System.in);
    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    n = in.nextInt();
    g = new HashSet[n];
    for(int i=0; i<n; i++) g[i] = new HashSet<Integer>();
    gg = new ArrayList[n];
    for(int i=0; i<n; i++) gg[i] = new ArrayList<Integer>();
    for(int i=0; i<n-1; i++) {
      int a = in.nextInt()-1;
      int b = in.nextInt()-1;
      g[a].add(b);
      gg[a].add(b);
      gg[b].add(a);
    }
    dp = new int[n];
    dp2 = new int[n];
    go(0,0);
    go2(0,0);
    int min = 987654321;
    for(int i=0; i<n; i++)
      if(dp[i]+dp2[i] < min)
        min = dp[i]+dp2[i];
    out.println(min);
    for(int i=0; i<n; i++)
      if(dp[i]+dp2[i] == min)
        out.print((i+1)+" ");
    out.close();
  }
  static int go(int x, int p) {
    for(int z : gg[x])
      if(z != p) {
        dp[x] += go(z,x);
        if(!g[x].contains(z)) dp[x]++;
      }
    return dp[x];
  }
  static void go2(int x, int p) {
    if(x != p) {
      dp2[x] = dp2[p]+dp[p]-dp[x];
      if(g[p].contains(x)) dp2[x]++;
      else dp2[x]--;
    }
    for(int z : gg[x])
      if(z != p)
        go2(z,x);
  }
  static class FastScanner {
    BufferedReader br;
    StringTokenizer st;

    public FastScanner(InputStream in) {
      br = new BufferedReader(new InputStreamReader(in));
      scanLine();
    }
    public void scanLine() {
      try {
        st = new StringTokenizer(br.readLine().trim());
      } catch(Exception e) {
        throw new RuntimeException(e.getMessage());
      }
    }
    public int numTokens() {
      if(!st.hasMoreTokens()) {
        scanLine();
        return numTokens();
      }
      return st.countTokens();
    }
    public String next() {
      if(!st.hasMoreTokens()) {
        scanLine();
        return next();
      }
      return st.nextToken();
    }
    public double nextDouble() {
      return Double.parseDouble(next());
    }
    public long nextLong() {
      return Long.parseLong(next());
    }
    public int nextInt() {
      return Integer.parseInt(next());
    }
  }
}


import java.awt.*;
import java.awt.geom.*;
import java.io.*;
import java.math.*;
import java.text.*;
import java.util.*;

/*
br = new BufferedReader(new FileReader("input.txt"));
pw = new PrintWriter(new BufferedWriter(new FileWriter("output.txt")));
br = new BufferedReader(new InputStreamReader(System.in));
pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
 */

public class Main {
	private static BufferedReader br;
	private static StringTokenizer st;
	private static PrintWriter pw;

	public static void main(String[] args) throws IOException	{
		br = new BufferedReader(new InputStreamReader(System.in));
		pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		int n = readInt();
		LinkedList<Edge>[] edges = new LinkedList[n];
		for(int i = 0; i < n; i++)	{
			edges[i] = new LinkedList<Edge>();
		}
		for(int k = 1; k < n; k++)	{
			int a = readInt();
			int b = readInt();
			a--;
			b--;
			edges[a].add(new Edge(b, true));
			edges[b].add(new Edge(a, false));
		}
		int[] dist = new int[n];
		Arrays.fill(dist, 1 << 25);
		dist[0] = 0;
		LinkedList<Integer> q = new LinkedList<Integer>();
		q.add(0);
		LinkedList<Integer> order = new LinkedList<Integer>();
		while(!q.isEmpty())	{
			int curr = q.removeFirst();
			order.addLast(curr);
			for(Edge out: edges[curr])	{
				if(dist[out.d] > 1 + dist[curr])	{
					q.addLast(out.d);
					dist[out.d] = 1 + dist[curr];
				}
			}
		}
		int[] cost = new int[n];
		for(int i = 0; i < n; i++)	{
			for(Edge out: edges[i])	{
				if(dist[out.d] > dist[i] && !out.is)
					cost[0]++;
			}
		}
		while(!order.isEmpty()){
			int i = order.removeFirst();
			for(Edge out: edges[i])	{
				if(dist[out.d] > dist[i])	{
					if(out.is)	{
						cost[out.d] = 1 + cost[i];
					}
					else	{
						cost[out.d] = -1 + cost[i];
					}
				}
			}
		}
		int min = Integer.MAX_VALUE;
		for(int out: cost)	{
			min = Math.min(min, out);
		}
		pw.println(min);
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < n; i++)	{
			if(cost[i] == min)	{
				sb.append((i+1) + " ");
			}
		}
		pw.println(sb.toString().trim());
		pw.close();
	}

	static class Edge	{
		public int d;
		public boolean is;
		public Edge(int a, boolean b)	{
			d=a;
			is=b;
		}
	}

	/* NOTEBOOK CODE */

	public static void loadArray(int[][] grid) throws IOException {
		for(int[] a: grid)
			loadArray(a);
	}

	public static void loadArray(int[] in) throws IOException {
		for(int i = 0; i < in.length; i++)
			in[i] = readInt();
	}

	public static void loadArray(long[] in) throws IOException {
		for(int i = 0; i < in.length; i++)
			in[i] = readLong();
	}

	private static long readLong() throws IOException	{
		return Long.parseLong(nextToken());
	}

	private static double readDouble() throws IOException	{
		return Double.parseDouble(nextToken());
	}

	private static int readInt() throws IOException	{
		return Integer.parseInt(nextToken());
	}

	private static String nextToken() throws IOException	{
		while(st == null || !st.hasMoreTokens())	{
			if(!br.ready())	{
				pw.close();
				System.exit(0);
			}
			st = new StringTokenizer(br.readLine().trim());
		}
		return st.nextToken();
	}
}


import java.util.*;
import java.io.*;

public class Main{

  BufferedReader in;
  StringTokenizer str = null;

  private String next() throws Exception{
    if(str == null || !str.hasMoreElements())
      str = new StringTokenizer(in.readLine());
    return str.nextToken();
  }

  private int nextInt() throws Exception{
    return Integer.parseInt(next());
  }

  int n;
  List<Integer> g[];
  int mem[];
  Set<Integer> ans;

  public void run() throws Exception{
    in = new BufferedReader(new InputStreamReader(System.in));
    n = nextInt();
    g = new LinkedList[n];
    for(int i=0;i<n;i++){
      g[i] = new LinkedList<Integer>();
    }
    mem = new int[n];
    Arrays.fill(mem, -1);

    for(int i=0;i<n-1;i++){
      int a = nextInt()-1;
      int b = nextInt()-1;
      g[a].add(b);
    }

    int min = Integer.MAX_VALUE;
    ans = new HashSet<Integer>();

    for(int i=0;i<n;i++){
      if (mem[i] == -1){
        dfs(i);
      }
      int roads = n - 1 - mem[i];
      if (roads < min){
        min = roads;
        ans.clear();ans.add(i + 1);
      }else if (roads == min){
        ans.add(i + 1);
      }
    }

    PrintWriter out = new PrintWriter(System.out);

    //out.println(Arrays.toString(mem));

    out.println(min);
    for(int i : ans)
      out.print(i + " ");

    out.println();
    out.close();
  }

  private int dfs(int x){
    if(mem[x] != -1)
      return mem[x];
    int ret = 0;
    for(int i : g[x]){
      ret+=dfs(i)+1;
    }
    return mem[x] = ret;
  }

  public static void main(String args[]) throws Exception{
    new Main().run();
  }
}


import java.util.*;
import java.io.*;

public class Main{

  BufferedReader in;
  StringTokenizer str = null;

  private String next() throws Exception{
    if(str == null || !str.hasMoreElements())
      str = new StringTokenizer(in.readLine());
    return str.nextToken();
  }

  private int nextInt() throws Exception{
    return Integer.parseInt(next());
  }

  int n;
  Set<Integer> []g, gt;
  int []mem;
  List<Integer> ans;

  public void run() throws Exception{
    in = new BufferedReader(new InputStreamReader(System.in));
    n = nextInt();
    g = new HashSet[n];
    gt = new HashSet[n];
    for(int i=0;i<n;i++){
      g[i] = new HashSet<Integer>();
      gt[i] = new HashSet<Integer>();
    }
    mem = new int[n];
    Arrays.fill(mem, -1);
    for(int i=0;i<n-1;i++){
      int a = nextInt()-1;
      int b = nextInt()-1;
      g[a].add(b);
      gt[b].add(a);
    }

    mem[0] = dfs(0, -1);
    for(int i : g[0])
      dfs1(i, 0, 1);
    for(int i : gt[0])
      dfs1(i, 0, -1);
    //System.out.println(Arrays.toString(mem));

    int min = Integer.MAX_VALUE;
    ans = new ArrayList<Integer>();
    PrintWriter out = new PrintWriter(System.out);

    for(int i=0;i<n;i++){
      if (mem[i] < min){
        min = mem[i];
        ans.clear();
        ans.add(i+1);
      }else if (mem[i] == min){
        ans.add(i + 1);
      }
    }
    out.println(min);
    for(int i : ans)
      out.print(i + " ");
    out.println();
    out.close();
  }

  private void dfs1(int x, int prev, int v){
    if (mem[x]!=-1) return;
    mem[x] = mem[prev] + v;
    for(int i : g[x]){
      dfs1(i, x, 1);
    }
    for(int i : gt[x]){
      dfs1(i, x, -1);
    }
  }

  private int dfs(int x, int prev){
    int ret = 0;
    for(int i : g[x]){
      if (i == prev) continue;
      ret+=dfs(i, x);
    }
    for(int i : gt[x]){
      if (i == prev) continue;
      ret+=dfs(i, x)+1;
    }
    return ret;
  }

  public static void main(String args[]) throws Exception{
    new Main().run();
  }
}


import java.util.*;
import java.io.*;

public class Main{

  BufferedReader in;
  StringTokenizer str = null;

  private String next() throws Exception{
    if(str == null || !str.hasMoreElements())
      str = new StringTokenizer(in.readLine());
    return str.nextToken();
  }

  private int nextInt() throws Exception{
    return Integer.parseInt(next());
  }

  int n;
  Set<Integer> []g, gt;
  int []mem;
  Set<Integer> ans;

  public void run() throws Exception{
    in = new BufferedReader(new InputStreamReader(System.in));
    n = nextInt();
    g = new HashSet[n];
    gt = new HashSet[n];
    for(int i=0;i<n;i++){
      g[i] = new HashSet<Integer>();
      gt[i] = new HashSet<Integer>();
    }
    mem = new int[n];
    Arrays.fill(mem, -1);
    for(int i=0;i<n-1;i++){
      int a = nextInt()-1;
      int b = nextInt()-1;
      g[a].add(b);
      gt[b].add(a);
    }

    mem[0] = dfs(0, -1);
    for(int i : g[0])
      dfs1(i, 0, 1);
    for(int i : gt[0])
      dfs1(i, 0, -1);
    //System.out.println(Arrays.toString(mem));

    int min = Integer.MAX_VALUE;
    ans = new HashSet<Integer>();
    PrintWriter out = new PrintWriter(System.out);

    for(int i=0;i<n;i++){
      if (mem[i] < min){
        min = mem[i];
        ans.clear();
        ans.add(i+1);
      }else if (mem[i] == min){
        ans.add(i + 1);
      }
    }
    out.println(min);
    for(int i : ans)
      out.print(i + " ");
    out.println();
    out.close();
  }

  private void dfs1(int x, int prev, int v){
    if (mem[x]!=-1) return;
    mem[x] = mem[prev] + v;
    for(int i : g[x]){
      dfs1(i, x, 1);
    }
    for(int i : gt[x]){
      dfs1(i, x, -1);
    }
  }

  private int dfs(int x, int prev){
    int ret = 0;
    for(int i : g[x]){
      if (i == prev) continue;
      ret+=dfs(i, x);
    }
    for(int i : gt[x]){
      if (i == prev) continue;
      ret+=dfs(i, x)+1;
    }
    return ret;
  }

  public static void main(String args[]) throws Exception{
    new Main().run();
  }
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.*;

public class D
{
	BufferedReader in;
	PrintStream out;
	StringTokenizer tok;
	public D() throws NumberFormatException, IOException
	{
		in = new BufferedReader(new InputStreamReader(System.in));
		//in = new BufferedReader(new FileReader("in.txt"));
		out = System.out;
		run();
	}
	List<Integer>[] G;
	List<Integer>[] G1;
	int[] sol;
	int count;
	boolean[] mark;
	void DFS(int s)
	{
		mark[s] = true;
		for(int i: G[s])
		{
			if(!mark[i])
			DFS(i);
		}
		for(int i:G1[s])
		{
			if(!mark[i])
			{
				count++;
				DFS(i);
			}
		}
	}
	void DFS1(int s)
	{
		mark[s] = true;
		for(int i: G[s])
		{
			if(!mark[i])
			{
				sol[i] = sol[s]+1;
				DFS1(i);
			}
		}
		for(int i:G1[s])
		{
			if(!mark[i])
			{
				sol[i] = sol[s]-1;
				DFS1(i);
			}
		}
	}
	void solve()
	{
		mark = new boolean[G.length];
		count = 0;
		DFS(0);
		mark = new boolean[G.length];
		sol[0] = count;
		DFS1(0);
	}
	void run() throws NumberFormatException, IOException
	{
		int n = nextInt();
		G = new ArrayList[n];
		G1 = new ArrayList[n];
		sol = new int[n];
		for(int i = 0; i < n; i++)
		{
			G[i] = new ArrayList<Integer>();
			G1[i] = new ArrayList<Integer>();
		}
		for(int i = 0; i < n-1; i++)
		{
			int a = nextInt()-1;
			int b = nextInt()-1;
			G[a].add(b);
			G1[b].add(a);
		}
		solve();
		int min = Integer.MAX_VALUE;
		for(int i  = 0;i < n; i++)
			min = Math.min(min, sol[i]);
		out.println(min);
		for(int i = 0; i < n; i++)
			if(sol[i]==min)out.print((i+1)+" ");
		out.println();
	}
	public static void main(String[] args) throws NumberFormatException, IOException
	{
		new D();
	}
	String nextToken() throws IOException
	{
		if(tok ==null || !tok.hasMoreTokens()) tok = new StringTokenizer(in.readLine());
		return tok.nextToken();
	}
	int nextInt() throws NumberFormatException, IOException
	{
		return Integer.parseInt(nextToken());
	}
	long nextLong() throws NumberFormatException, IOException
	{
		return Long.parseLong(nextToken());
	}
	double nextDouble() throws NumberFormatException, IOException
	{
		return Double.parseDouble(nextToken());
	}
}


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.TreeMap;

public class D {

	static StreamTokenizer st;
	static ArrayList<Integer>[]ages;
	static TreeMap<Long, Boolean> used;
	static int[]cnt;
	static int n;
	public static void main(String[] args) throws IOException{
		st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		n = nextInt();
		ages = new ArrayList[n+1];
		for (int i = 1; i <= n; i++) {
			ages[i] = new ArrayList<Integer>();
		}
		used = new TreeMap<Long, Boolean>();
		for (int i = 1; i < n; i++) {
			int v1 = nextInt();
			int v2 = nextInt();
			ages[v1].add(v2);
			ages[v2].add(v1);
			long hash = (long)v1*(n+1)+v2;
			used.put(hash, true);
		}
		cnt = new int[n+1];
		dfs(1, 0);
		dfs2(1, 0);
		int min = (int) 1e9;
		for (int i = 1; i <= n; i++) {
			if (cnt[i] < min)
				min = cnt[i];
		}
		pw.println(min);
		for (int i = 1; i <= n; i++) {
			if (cnt[i]==min)
				pw.print(i+" ");
		}
		pw.close();
	}

	private static void dfs2(int v, int p) {
		for (int to : ages[v]) {
			if (to==p)
				continue;
			cnt[to] += cnt[v]-cnt[to];
			if (!used.containsKey((long)to*(n+1)+v))
				cnt[to]++;
			else
				cnt[to]--;
			dfs2(to, v);
		}
	}

	private static void dfs(int v, int p) {
		for (int to : ages[v]) {
			if (to==p)
				continue;
			dfs(to, v);
			cnt[v] += cnt[to];
			if (!used.containsKey((long)v*(n+1)+to))
				cnt[v]++;
		}
	}

	private static int nextInt() throws IOException{
		st.nextToken();
		return (int) st.nval;
	}

}


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class Solution implements Runnable {

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st;

	String nextToken() throws Exception {
		while (st == null || !st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}

	int nextInt() throws Exception {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws Exception {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws Exception {
		return Double.parseDouble(nextToken());
	}

	class Edge {
		int b, e;
		int o;
		Edge next;
		Edge(int q, int w, int oo, Edge n) {
			b = q; e = w; o = oo; next = n;
		}
	}

	Edge[] v;
	int ans = 0;
	int[] res;
	int tm = 0;

	void dfs1(int q, int w) {
		for (Edge r = v[q]; r != null; r = r.next) {
			if (r.e != w) {
				ans += r.o;
				dfs1(r.e, q);
			}
		}
	}

	void dfs2(int q, int w) {
		res[q] = ans + tm;
		for (Edge r = v[q]; r != null; r = r.next) {
			if (r.e != w) {
				tm += r.o == 0? 1 : -1;
				dfs2(r.e, q);
				tm -= r.o == 0? 1 : -1;
			}
		}
	}

	void solve() throws Exception {
		int n = nextInt();
		v = new Edge[n];
		res = new int[n];
		for (int i = 0; i < n - 1; i++) {
			int a = nextInt() - 1;
			int b = nextInt() - 1;
			v[a] = new Edge(a, b, 0, v[a]);
			v[b] = new Edge(b, a, 1, v[b]);
		}
		dfs1(0, -1);
		dfs2(0, -1);
		int aa = res[0];
		for (int i = 1; i < n; i++) if (res[i] < aa) aa = res[i];
		out.println(aa);
		for (int i = 0; i < n; i++) if (res[i] == aa) out.print((i + 1) + " ");
	}

	public void run() {
		try {
//			Locale.setDefault(Locale.UK);
			in = new BufferedReader(new InputStreamReader(System.in));
			//in = new BufferedReader(new FileReader("input.txt"));
			out = new PrintWriter(System.out);
			//out = new PrintWriter("output.txt");
			solve();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		} finally {
			out.close();
		}
	}

	public static void main(String[] args) {
		//new Thread(null, new Solution(), "1", 1 << 28).start();
		(new Solution()).run();
	}

}


import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;// 6/30/12 11:56 AM
// by Abrackadabra

public class Sol {
    public static void main(String[] args) throws IOException {
        //if (args.length > 0 && args[0].equals("Abra")||true ) debugMode = true;
        new Sol().run();
        /*new Thread(null, new Runnable() {
            public void run() {
                try {
                    new H().run();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }, "1", 1 << 24).start();*/
    }

    int IOMode = 0; //0 - consoleIO, 1 - <taskName>.in/out, 2 - input.txt/output.txt, 3 - test case generator
    String taskName = "";
    boolean testBasedProblem = false;

    public class Pair<F,S> implements Comparable<Pair<F,S>> {

        public F first;
        public S second;

        public Pair(F first, S second) {
            this.first = first;
            this.second = second;
        }

        @Override
        @SuppressWarnings(value = "unchecked")
        public int compareTo(Pair<F, S> other) {
            int res = ((Comparable<F>)first).compareTo(other.first);
            if(res != 0)
                return res;
            return ((Comparable<S>)second).compareTo(other.second);
        }
    }

    int n;
    ArrayList<Pair<Integer, Integer>>[] g;
    int how[];
    int INF=1000000000;

    int dfs1 (int v, int p){
         int curr=0;
         for (int i=0; i<g[v].size(); ++i){
             Pair<Integer, Integer> now = g[v].get(i);
             int nex=now.first;
             if (nex == v)
                 nex=now.second;
             if (nex == p)
                 continue;
             if (nex==now.first)
                 ++curr;
             curr+=dfs1(nex, v);
         }
         return curr;
    }

    void dfs (int v, int p, int cur){
        how[v]=cur;
        for (int i=0; i<g[v].size(); ++i){
            Pair<Integer, Integer> now = g[v].get(i);
            int nex=now.first;
            if (nex == v)
                nex=now.second;
            if (nex == p)
                continue;
            if (nex==now.second)
                dfs(nex, v, cur+1);
            else
                dfs(nex, v, cur-1);
        }
    }
    void solve() throws IOException {
        n=nextInt();
        g=new ArrayList[n];
        for (int i=0; i<n; ++i)
            g[i]=new ArrayList();
        how=new int[n];
        for (int i=0; i<n-1; ++i){
            int q=nextInt();
            int w=nextInt();
            --q; --w;
            g[q].add(new Pair(q,w));
            g[w].add(new Pair(q,w));
        }
        int cur=dfs1(0, -1);
        dfs(0, -1, cur);
        int mn=INF;
        for (int i=0; i<n; ++i)
            mn=Math.min(mn, how[i]);
        out.println(mn);
        for (int i=0; i<n; ++i)
            if (how[i]==mn)
                out.print((i+1) + " ");
    }

    long startTime = System.nanoTime(), tempTime = startTime, finishTime = startTime;
    long startMem = Runtime.getRuntime().totalMemory(), finishMem = startMem;
    int testIndex;

    void run() throws IOException {
        init();
        if (debugMode) {
            con.println("Start");
            con.println("Console:");
        }

        int tests = testBasedProblem ? nextInt() : 1;
        for (testIndex = 1; testIndex <= tests; testIndex++)
            solve();

        finishTime = System.nanoTime();
        finishMem = Runtime.getRuntime().totalMemory();
        out.flush();
        if (debugMode) {
            int maxSymbols = 1000;
            BufferedReader tbr = new BufferedReader(new FileReader("input.txt"));
            char[] a = new char[maxSymbols];
            tbr.read(a);
            if (a[0] != 0) {
                con.println("File input:");
                con.println(a);
                if (a[maxSymbols - 1] != 0) con.println("...");
            }
            tbr = new BufferedReader(new FileReader("output.txt"));
            a = new char[maxSymbols];
            tbr.read(a);
            if (a[0] != 0) {
                con.println("File output:");
                con.println(a);
                if (a[maxSymbols - 1] != 0) con.println("...");
            }
            con.println("Execution time: " + (finishTime - startTime) / 1000000000.0 + " sec");
            con.println("Used memory:    " + (finishMem - startMem) + " bytes");
            con.println("Total memory:   " + Runtime.getRuntime().totalMemory() + " bytes");
        }
    }

    boolean tick(double x) {
        if (System.nanoTime() - tempTime > x * 1e9) {
            tempTime = System.nanoTime();
            con.println("Tick at " + (tempTime - startTime) / 1000000000 + " sec");
            con.print("   ");
            return true;
        }
        return false;
    }

    static boolean debugMode = false;
    PrintStream con = System.out;

    void init() throws IOException {
        if (debugMode && IOMode != 3) {
            br = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter(new FileWriter("output.txt"));
        } else
            switch (IOMode) {
                case 0:
                    br = new BufferedReader(new InputStreamReader(System.in));
                    out = new PrintWriter(System.out);
                    break;
                case 1:
                    br = new BufferedReader(new FileReader(taskName + ".in"));
                    out = new PrintWriter(new FileWriter(taskName + ".out"));
                    break;
                case 2:
                    br = new BufferedReader(new FileReader("input.txt"));
                    out = new PrintWriter(new FileWriter("output.txt"));
                    break;
                case 3:
                    out = new PrintWriter(new FileWriter("input.txt"));
                    break;
            }
        if (!debugMode)
            con = new PrintStream(new OutputStream() {
                public void write(int b) throws IOException {
                } // to /dev/null
            });
        if ((IOMode == 1 && taskName.length() == 0) || (IOMode != 1 && taskName.length() != 0)) {
            System.err.println("Leha, check IO settings");
            System.err.flush();
            System.exit(0);
        }
    }

    BufferedReader br;
    PrintWriter out;
    StringTokenizer in;

    boolean hasMoreTokens() throws IOException {
        while (in == null || !in.hasMoreTokens()) {
            String line = br.readLine();
            if (line == null) return false;
            in = new StringTokenizer(line);
        }
        return true;
    }

    String nextString() throws IOException {
        return hasMoreTokens() ? in.nextToken() : null;
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextString());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextString());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextString());
    }
}


import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;

public class Main {

    private static ArrayList <ArrayList <Integer>> graph = new ArrayList <ArrayList <Integer>> ();
    private static ArrayList <ArrayList <Integer>> graphActual = new ArrayList <ArrayList <Integer>> ();
    private static HashSet <Integer> visited = new HashSet <Integer> ();
    private static int[] ans;
    private static int curAns = 0;
    private static int n;

    public static void main(String[] args) {
        Scanner sc = new Scanner (System.in);
        n = sc.nextInt();

        for (int i = 0; i < n; ++i)
        {
            graph.add(new ArrayList<Integer>());
            graphActual.add(new ArrayList <Integer>());
        }

        for (int i = 0; i < n-1; ++i)
        {
            int a = sc.nextInt() - 1;
            int b = sc.nextInt() - 1;

            graph.get(a).add(b);
            graph.get(b).add(a);

            graphActual.get(a).add(b);
        }

        dfs(0);

        ans = new int[n];
        ans[0] = curAns;

        visited = new HashSet <Integer> ();
        dfs2(0);

        int temp = Integer.MAX_VALUE;
        for (int i = 0; i < n; ++i)
            if (ans[i]<temp)
                temp = ans[i];

        System.out.println(temp);

        for (int i = 0; i < n; ++i)
            if (ans[i]==temp)
                System.out.print((i+1) + " ");
    }

    private static void dfs(int a) {
        visited.add(a);
        for (int i = 0; i < graph.get(a).size(); ++i)
            if (!visited.contains(graph.get(a).get(i)))
            {
                if (!check(a, graph.get(a).get(i)))
                    curAns++;

                dfs(graph.get(a).get(i));
            }

    }

    private static void dfs2(int a) {
        visited.add(a);
        for (int i = 0; i < graph.get(a).size(); ++i)
            if (!visited.contains(graph.get(a).get(i)))
            {
                if (!check(a, graph.get(a).get(i)))
                    ans[ graph.get(a).get(i) ] = ans[a] - 1;
                else
                    ans[ graph.get(a).get(i) ] = ans[a] + 1;

                dfs2(graph.get(a).get(i));
            }
    }

    private static boolean check(int a, int b) {
        for (int i = 0; i < graphActual.get(a).size(); ++i)
            if (graphActual.get(a).get(i) == b)
                return true;
        return false;
    }
}


import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;

public class Main {

    private static ArrayList <ArrayList <Integer>> graph = new ArrayList <ArrayList <Integer>> ();
    private static ArrayList <HashSet <Integer>> graphActual = new ArrayList <HashSet <Integer>> ();
    private static HashSet <Integer> visited = new HashSet <Integer> ();
    private static int[] ans;
    private static int curAns = 0;
    private static int n;

    public static void main(String[] args) {
        Scanner sc = new Scanner (System.in);
        n = sc.nextInt();

        for (int i = 0; i < n; ++i)
        {
            graph.add(new ArrayList<Integer>());
            graphActual.add(new HashSet <Integer>());
        }

        for (int i = 0; i < n-1; ++i)
        {
            int a = sc.nextInt() - 1;
            int b = sc.nextInt() - 1;

            graph.get(a).add(b);
            graph.get(b).add(a);

            graphActual.get(a).add(b);
        }

        dfs(0);

        ans = new int[n];
        ans[0] = curAns;

        visited = new HashSet <Integer> ();
        dfs2(0);

        int temp = Integer.MAX_VALUE;
        for (int i = 0; i < n; ++i)
            if (ans[i]<temp)
                temp = ans[i];

        System.out.println(temp);

        for (int i = 0; i < n; ++i)
            if (ans[i]==temp)
                System.out.print((i+1) + " ");
    }

    private static void dfs(int a) {
        visited.add(a);
        for (int i = 0; i < graph.get(a).size(); ++i)
            if (!visited.contains(graph.get(a).get(i)))
            {
                if (!check(a, graph.get(a).get(i)))
                    curAns++;

                dfs(graph.get(a).get(i));
            }

    }

    private static void dfs2(int a) {
        visited.add(a);
        for (int i = 0; i < graph.get(a).size(); ++i)
            if (!visited.contains(graph.get(a).get(i)))
            {
                if (!check(a, graph.get(a).get(i)))
                    ans[ graph.get(a).get(i) ] = ans[a] - 1;
                else
                    ans[ graph.get(a).get(i) ] = ans[a] + 1;

                dfs2(graph.get(a).get(i));
            }
    }

    private static boolean check(int a, int b) {
        return (graphActual.get(a).contains(b));
    }
}


package pkg219d;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;

public class Main {

    private static ArrayList <ArrayList <Integer>> graph = new ArrayList <ArrayList <Integer>> ();
    private static ArrayList <ArrayList <Integer>> graphActual = new ArrayList <ArrayList <Integer>> ();
    private static HashSet <Integer> visited = new HashSet <Integer> ();
    private static int[] ans;
    private static int curAns = 0;
    private static int n;

    public static void main(String[] args) {
        Scanner sc = new Scanner (System.in);
        n = sc.nextInt();

        for (int i = 0; i < n; ++i)
        {
            graph.add(new ArrayList<Integer>());
            graphActual.add(new ArrayList <Integer>());
        }

        for (int i = 0; i < n-1; ++i)
        {
            int a = sc.nextInt() - 1;
            int b = sc.nextInt() - 1;

            graph.get(a).add(b);
            graph.get(b).add(a);

            graphActual.get(a).add(b);
        }

        dfs(0);

        ans = new int[n];
        ans[0] = curAns;

        visited = new HashSet <Integer> ();
        dfs2(0);

        int temp = Integer.MAX_VALUE;
        for (int i = 0; i < n; ++i)
            if (ans[i]<temp)
                temp = ans[i];

        System.out.println(temp);

        for (int i = 0; i < n; ++i)
            if (ans[i]==temp)
                System.out.print((i+1) + " ");
    }

    private static void dfs(int a) {
        visited.add(a);
        for (int i = 0; i < graph.get(a).size(); ++i)
            if (!visited.contains(graph.get(a).get(i)))
            {
                if (!check(a, graph.get(a).get(i)))
                    curAns++;

                dfs(graph.get(a).get(i));
            }

    }

    private static void dfs2(int a) {
        visited.add(a);
        for (int i = 0; i < graph.get(a).size(); ++i)
            if (!visited.contains(graph.get(a).get(i)))
            {
                if (!check(a, graph.get(a).get(i)))
                    ans[ graph.get(a).get(i) ] = ans[a] - 1;
                else
                    ans[ graph.get(a).get(i) ] = ans[a] + 1;

                dfs2(graph.get(a).get(i));
            }
    }

    private static boolean check(int a, int b) {
        for (int i = 0; i < graphActual.get(a).size(); ++i)
            if (graphActual.get(a).get(i) == b)
                return true;
        return false;
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;

public class Main {
    int maxn = 201100;
    class node {
        int ne, be;
        boolean ava;
        node(int b, int e, boolean v) {
            this.be = b;
            this.ne = e;
            ava = v;
        }
    }

    node buf[] = new node[maxn * 2];
    int E[] = new int[maxn], len;

    void add(int a, int b) {
        buf[len] = new node(b, E[a], true);
        E[a] = len++;
        buf[len] = new node(a, E[b], false);
        E[b] = len++;
    }

    int dp[] = new int[maxn];
    boolean vis[] = new boolean[maxn];

    void init() {
        len = 0;
        Arrays.fill(E, -1);
        Arrays.fill(dp,0);
    }

    void dfs1(int a) {
        vis[a] = true;
        for (int i = E[a]; i != -1; i = buf[i].ne) {
            int b = buf[i].be;
            if (vis[b])
                continue;
            dfs1(b);
            dp[a] += dp[b];
            if (!buf[i].ava)
                dp[a]++;
        }
    }

    void dfs2(int a) {
        vis[a] = true;
        for (int i = E[a]; i != -1; i = buf[i].ne) {
            int b = buf[i].be;
            if (vis[b])
                continue;
            if (buf[i].ava)
                dp[b] = dp[a] + 1;
            else
                dp[b] = dp[a] - 1;
            dfs2(b);
        }
    }
    StreamTokenizer in = new StreamTokenizer(new BufferedReader(
            new InputStreamReader(System.in)));
    int nextInt() throws IOException {
        in.nextToken();
        return (int) in.nval;
    }
    void run() throws IOException {
        int n=nextInt();
        init();
        for(int i=1;i<n;i++)
            add(nextInt(),nextInt());
        Arrays.fill(vis,false);
        dfs1(1);
        Arrays.fill(vis,false);
        dfs2(1);
        int ans=n;
        for(int i=1;i<=n;i++)
            if(dp[i]<ans)
                ans=dp[i];
        System.out.println(ans);
        for(int i=1;i<=n;i++)
            if(dp[i]==ans)
                System.out.print(i+" ");
        System.out.println();
    }

    public static void main(String[] args) throws IOException {
        new Main().run();
    }

}


import java.util.*;
import java.io.*;
public class a {
  static long mod = 1000000007;
  static int[] depth, goods;
  static ArrayList<Edge>[] tree;
public static void main(String[] args) throws IOException
{
  input.init(System.in);
  PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

  int n = input.nextInt();
  ArrayList<Edge>[] adj = new ArrayList[n];
  for(int i = 0; i<n; i++) adj[i] = new ArrayList<Edge>();
  for(int i = 0; i<n-1; i++)
  {
    int a = input.nextInt()-1, b = input.nextInt()-1;
    adj[a].add(new Edge(b, true));
    adj[b].add(new Edge(a, false));
  }
  tree = new ArrayList[n];
  for(int i = 0; i<n; i++) tree[i] = new ArrayList<Edge>();
  Queue<Integer> q = new LinkedList<Integer>();
  boolean[] visited = new boolean[n];
  q.add(0);
  visited[0] = true;
  int numGood = 0;
  while(!q.isEmpty())
  {
    int at = q.poll();
    //System.out.println(adj[at].size());
    for(Edge e: adj[at])
    {
      //System.out.println(e.to);
      if(!visited[e.to])
      {
        visited[e.to] = true;
        q.add(e.to);
        if(e.good) numGood++;
        tree[e.to].add(new Edge(at, e.good));
      }
    }
  }
  //for(boolean b: visited) System.out.println(b);
  depth = new int[n];
  goods = new int[n];
  Arrays.fill(depth, -1);
  depth[0]=0;
  for(int i = 0; i<n; i++) calcDepth(i);
  int min = n;
  for(int i = 0; i<n; i++) min = Math.min(min, n-1-numGood+goods[i]-(depth[i]-goods[i]));
  out.println(min);
  for(int i = 0; i<n; i++)
  {
    int x = n-1-numGood+goods[i]-(depth[i]-goods[i]);
    if(x==min) out.print((i+1)+" ");
  }

  out.close();

}
static int calcDepth(int at)
{
  //System.out.println(at);
  if(at==0) return 0;
  if(depth[at] != -1) return depth[at];
  Edge go = tree[at].get(0);
  int parentDepth = calcDepth(go.to);
  if(go.good) goods[at] = goods[go.to] +1;
  else goods[at] = goods[go.to];
  return depth[at] = 1+parentDepth;

}
static class Edge{
  int to;
  boolean good;
  public Edge(int tt, boolean gg)
  {
    to = tt;
    good = gg;
  }
}
static class input {
  static BufferedReader reader;
  static StringTokenizer tokenizer;

  /** call this method to initialize reader for InputStream */
  static void init(InputStream input) {
      reader = new BufferedReader(
                   new InputStreamReader(input) );
      tokenizer = new StringTokenizer("");
  }

  /** get next word */
  static String next() throws IOException {
      while ( ! tokenizer.hasMoreTokens() ) {
          //TODO add check for eof if necessary
          tokenizer = new StringTokenizer(
                 reader.readLine() );
      }
      return tokenizer.nextToken();
  }

  static int nextInt() throws IOException {
      return Integer.parseInt( next() );
  }
  static long nextLong() throws IOException {
    return Long.parseLong( next() );
}

  static double nextDouble() throws IOException {
      return Double.parseDouble( next() );
  }
  static String nextLine() throws IOException {
    return reader.readLine();
  }
}
}


import java.util.*;
import java.io.*;
import java.math.*;

public class D {
	public static class Edge{
		int from;
		int to;

		public Edge(int from, int to){
			this.from = from;
			this.to = to;
		}
	}

	public static void main(String[] args) throws Exception{
		Scanner sc = new Scanner(System.in);
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		int n = Integer.valueOf(br.readLine());

		ArrayList[] al = new ArrayList[n];
		ArrayList[] reverse = new ArrayList[n];

		for(int i=0; i<n; i++){
			al[i] = new ArrayList<Edge>();
			reverse[i] = new ArrayList<Edge>();
		}

		for(int i=0; i<n-1; i++){
			String[] s = br.readLine().split("\\s+");
			int from = Integer.valueOf(s[0])-1;
			int to = Integer.valueOf(s[1])-1;

			al[from].add(new Edge(from, to));
			reverse[to].add(new Edge(to, from));
		}

		ArrayList<Integer> min = new ArrayList<Integer>();
		int minimum = Integer.MAX_VALUE;

		int[] minarr = new int[n];

		for(int i=0; i<1; i++){
			boolean[] marked = new boolean[n];
			marked[i] = true;
			int inverted = 0;

			LinkedList<Edge> queue = new LinkedList<Edge>();

			queue.add(new Edge(0, 0));
			marked[0] = true;

			while(!queue.isEmpty()){
				Edge curr = queue.poll();

				for(int j=0; j<al[curr.to].size(); j++){
					Edge e = (Edge) al[curr.to].get(j);

					if(marked[e.to]){
						continue;
					}

					marked[e.to] = true;
					queue.add(e);
					minarr[e.to] = minarr[e.from] + 1;
				}

				for(int j=0; j<reverse[curr.to].size(); j++){
					Edge e = (Edge) reverse[curr.to].get(j);

					if(marked[e.to]){
						continue;
					}

					marked[e.to] = true;
					queue.add(e);
					minarr[e.to] = minarr[e.from]-1;
					inverted++;
				}
			}

			for(int j=0; j<n; j++){
				minarr[j] += inverted;
				minimum = Math.min(minarr[j], minimum);
			}
		}

		for(int i=0; i<n; i++){
			if(minarr[i] == minimum){
				min.add(i);
			}
		}

		System.out.println(minimum);
		System.out.printf("%d", min.get(0)+1);

		for(int i=1; i<min.size(); i++){
			System.out.printf(" %d", min.get(i)+1);
		}

		System.out.println();
	}
}


import java.util.*;
import java.math.*;

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

		int n = sc.nextInt();

		ArrayList[] al = new ArrayList[n];
		ArrayList[] reverse = new ArrayList[n];

		for(int i=0; i<n; i++){
			al[i] = new ArrayList<Integer>();
			reverse[i] = new ArrayList<Integer>();
		}

		for(int i=0; i<n-1; i++){
			int from = sc.nextInt()-1;
			int to = sc.nextInt()-1;

			al[from].add(to);
			reverse[to].add(from);
		}

		ArrayList<Integer> min = new ArrayList<Integer>();
		int minimum = Integer.MAX_VALUE;

		for(int i=0; i<n; i++){
			boolean[] marked = new boolean[n];
			marked[i] = true;
			int count = 1;
			int inverted = 0;

			LinkedList<Integer> queue = new LinkedList<Integer>();

			queue.add(i);

			while(!queue.isEmpty()){
				int curr = queue.poll();

				for(int j=0; j<al[curr].size(); j++){
					int next = Integer.valueOf(al[curr].get(j).toString());

					if(marked[next]){
						continue;
					}

					marked[next] = true;
					count++;
					queue.add(next);
				}

				for(int j=0; j<reverse[curr].size(); j++){
					int next = Integer.valueOf(reverse[curr].get(j).toString());

					if(marked[next]){
						continue;
					}

					marked[next] = true;
					count++;
					inverted++;
					queue.add(next);
				}
			}

			if(inverted < minimum){
				min = new ArrayList<Integer>();
				min.add(i);
				minimum = inverted;
			}else if(inverted == minimum){
				min.add(i);
			}
		}

		System.out.println(minimum);
		System.out.printf("%d", min.get(0)+1);

		for(int i=1; i<min.size(); i++){
			System.out.printf(" %d", min.get(i)+1);
		}

		System.out.println();
	}
}


import java.util.*;
import java.math.*;

public class D {
	public static class Edge{
		int from;
		int to;

		public Edge(int from, int to){
			this.from = from;
			this.to = to;
		}
	}

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

		int n = sc.nextInt();

		ArrayList[] al = new ArrayList[n];
		ArrayList[] reverse = new ArrayList[n];

		for(int i=0; i<n; i++){
			al[i] = new ArrayList<Edge>();
			reverse[i] = new ArrayList<Edge>();
		}

		for(int i=0; i<n-1; i++){
			int from = sc.nextInt()-1;
			int to = sc.nextInt()-1;

			al[from].add(new Edge(from, to));
			reverse[to].add(new Edge(to, from));
		}

		ArrayList<Integer> min = new ArrayList<Integer>();
		int minimum = Integer.MAX_VALUE;

		int[] minarr = new int[n];

		for(int i=0; i<1; i++){
			boolean[] marked = new boolean[n];
			marked[i] = true;
			int inverted = 0;

			LinkedList<Edge> queue = new LinkedList<Edge>();

			queue.add(new Edge(0, 0));
			marked[0] = true;

			while(!queue.isEmpty()){
				Edge curr = queue.poll();

				for(int j=0; j<al[curr.to].size(); j++){
					Edge e = (Edge) al[curr.to].get(j);

					if(marked[e.to]){
						continue;
					}

					marked[e.to] = true;
					queue.add(e);
					minarr[e.to] = minarr[e.from] + 1;
				}

				for(int j=0; j<reverse[curr.to].size(); j++){
					Edge e = (Edge) reverse[curr.to].get(j);

					if(marked[e.to]){
						continue;
					}

					marked[e.to] = true;
					queue.add(e);
					minarr[e.to] = minarr[e.from]-1;
					inverted++;
				}
			}

			for(int j=0; j<n; j++){
				minarr[j] += inverted;
				minimum = Math.min(minarr[j], minimum);
			}
		}

		for(int i=0; i<n; i++){
			if(minarr[i] == minimum){
				min.add(i);
			}
		}

		System.out.println(minimum);
		System.out.printf("%d", min.get(0)+1);

		for(int i=1; i<min.size(); i++){
			System.out.printf(" %d", min.get(i)+1);
		}

		System.out.println();
	}
}