#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 10005

enum Type{
	NONE,
	START,
	FINISH,
};

struct Heap{
	Heap(){
		left = NULL;
		right = NULL;
		diff = 0;
		cost = 0;
		edge_id = 0;
	}

	Heap(int arg_cost,int arg_edge_id){
		left = NULL;
		right = NULL;
		diff = 0;
		cost = arg_cost;
		edge_id = arg_edge_id;
	}
	Heap *left,*right;
	int diff,cost,edge_id;
};

struct Edge{
	Edge(int arg_from,int arg_to,int arg_cost){
		from = arg_from;
		to = arg_to;
		cost = arg_cost;
	}
	int from,to,cost;
};

int V,E;
int boss[NUM];
int table_index;
int in_num[NUM];
int from_cost[NUM],FROM[NUM];
vector<Edge> edge;
Heap heap_table[1000005];
Heap* HEAP[NUM];
Type type[NUM];


void lazy(Heap* A){

	if(A->left){
		A->left->diff += A->diff;
	}
	if(A->right){
		A->right->diff += A->diff;
	}
	A->cost += A->diff;
	A->diff = 0;
}


Heap* meld(Heap* A,Heap* B){

	if(!A){
		return B;
	}
	if(!B){
		return A;
	}

	if((A->cost+A->diff) > (B->cost+B->diff)){
		swap(A,B);
	}

	lazy(A);

	A->right = meld(A->right,B);
	swap(A->left,A->right);

	return A;
}

Heap* pop(Heap *A){
	lazy(A);
	return meld(A->left,A->right);
}



int get_boss(int id){
	if(boss[id] == id)return id;
	else{
		return boss[id] = get_boss(boss[id]);
	}
}

int is_same(int x,int y){
	return get_boss(x) == get_boss(y);
}

void unite(int x,int y){
	int boss_x = get_boss(x);
	int boss_y = get_boss(y);

	if(boss_x == boss_y)return;

	boss[boss_x] = boss_y;
}

void init(){

	for(int i = 0; i < V; i++){
		boss[i] = i;
	}
}

int MCA(int root){

	init();
	table_index = 0;

	for(int i = 0; i < V; i++){
		type[i] = NONE;
		HEAP[i] = NULL;
	}
	type[root] = FINISH;

	for(int i = 0; i < edge.size(); i++){

		heap_table[table_index] = Heap(edge[i].cost,i);
		HEAP[edge[i].to] = meld(HEAP[edge[i].to],&heap_table[table_index++]);
	}

	int ret = 0;

	for(int start = 0; start < V; start++){

		if(type[start] != NONE)continue;

		int current = start;
		vector<int> USED;

		while(type[current] != FINISH){

			type[current] = START;
			USED.push_back(current);

			if(!HEAP[current]){
				return BIG_NUM;
			}

			FROM[current] = get_boss(edge[HEAP[current]->edge_id].from);

			from_cost[current] = HEAP[current]->cost+HEAP[current]->diff;

			HEAP[current] = pop(HEAP[current]);

			if(FROM[current] == current)continue;

			ret += from_cost[current];

			if(type[FROM[current]] == START){

				int tmp = current;
				int debug = 0;

				do{
					if(HEAP[tmp]){
						HEAP[tmp]->diff -= from_cost[tmp];
					}

					if(tmp != current){
						unite(tmp,current);
						HEAP[current] = meld(HEAP[current],HEAP[tmp]);
					}

					tmp = get_boss(FROM[tmp]);

				}while(tmp != current);


			}else{
				current = FROM[current];
			}
		}

		for(int k = 0; k < USED.size(); k++){
			type[USED[k]] = FINISH;
		}
	}
	return ret;
}

int main(){

	scanf("%d %d",&V,&E);

	for(int i = 0; i < V; i++){

		in_num[i] = 0;
	}

	int from,to;

	for(int loop = 0; loop < E; loop++){

		scanf("%d %d",&from,&to);
		in_num[to]++;

		edge.push_back(Edge(from,to,0));
		edge.push_back(Edge(to,from,1));
	}

	vector<int> ANS;
	int min_cost = BIG_NUM,tmp;

	for(int i = 0; i < V; i++){

		if(in_num[i] > 0)continue;

		tmp = MCA(i);

		if(min_cost > tmp){

			min_cost = tmp;
			ANS.clear();
			ANS.push_back(i);

		}else if(min_cost == tmp){

			ANS.push_back(i);
		}
	}

	printf("%lld %d\n",ANS.size(),min_cost);

	printf("%d",ANS[0]);
	for(int i = 1; i < ANS.size(); i++){
		printf(" %d",ANS[i]);
	}
	printf("\n");

	return 0;
}



Measured memory_bytes: 37252