#include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define int ll
#define FOR(i,a,b) for(int i=int(a);i<int(b);i++)
#define REP(i,b) FOR(i,0,b)
int read(){
	int i;
	scanf("%lld",&i);
	return i;
}
using vi=vector<int>;
#define PB push_back
#define ALL(x) x.begin(),x.end()
using pi=pair<int,int>;

struct UnionFind{
	vi rank,par;
	void Init(int n){
		rank.assign(n,0);
		par.assign(n,-1);
	}
	int Find(int a){
		return par[a]==-1?a:(par[a]=Find(par[a]));
	}
	bool Same(int a,int b){
		return Find(a)==Find(b);
	}
	void Unite(int a,int b){
		a=Find(a),b=Find(b);
		if(a==b)return;
		if(rank[a]<rank[b])swap(a,b);
		par[b]=a;
		if(rank[a]==rank[b])rank[a]++;
	}
};

const int mod=1000000009;

pi Merge(pi a,pi b){
	return pi(a.first+b.first,a.second*b.second%mod);
}

signed main(){
	int n=read(),m=read();
	vector<vi> g(n);
	vi deg(n,0);
	REP(_,m){
		int a=read()-1,b=read()-1;
		g[a].PB(b);
		g[b].PB(a);
		deg[a]++;
		deg[b]++;
	}
	priority_queue<pi> pq;
	REP(i,n)pq.push(pi(deg[i],i));
	vi used(n,0),ord;
	while(!pq.empty()){
		int v=pq.top().first,i=pq.top().second;
		pq.pop();
		if(deg[i]!=v)continue;
		ord.PB(i);
		for(auto j:g[i])if(!used[j])
			pq.push(pi(--deg[j],j));
		used[i]=1;
	}
	reverse(ALL(ord));
	vector<pi> ans(n);
	UnionFind uf;uf.Init(n);
	used.assign(n,0);
	for(auto i:ord){
		pi w(0,1);
		for(auto j:g[i])if(used[j])
			if(!uf.Same(i,j)){
				w=Merge(w,ans[uf.Find(j)]);
				uf.Unite(i,j);
			}
		if(w.first==0)
			w.first=1;
		else if(w.first==1)
			w.second=(w.second+1)%mod;
		ans[uf.Find(i)]=w;
		used[i]=1;
	}
	pi w=ans[uf.Find(0)];
	REP(i,n)if(!uf.Same(0,i)){
		w=Merge(w,ans[uf.Find(i)]);
		uf.Unite(0,i);
	}
	cout<<w.first<<endl<<w.second<<endl;
}
### Prompt

Develop a solution in cpp to the problem described below:

Training is indispensable for achieving good results at ICPC. Rabbit wants to win at ICPC, so he decided to practice today as well.

Today's training is to train your eyesight and concentration by observing many stars shining in the night sky. Rabbits can record the characteristics of stars with their own sense.

Rabbit decided to add the characteristics of the stars recorded as "Star Observation Diary" to his notebook. Here, we want to avoid recording two "similar" stars together. Whether or not the two stars are "similar" is all determined by the rabbit's judgment. The relationship of "similarity" is not so complicated and satisfies the following conditions.

> Condition: There are four different stars A, B, C, D, and A and B, B and C, and C and D are "similar" respectively. At this time, A and C are "similar", B and D are "similar", or both.

Rabbits want to record as many stars as possible without recording two "similar" stars. I also want to know how many ways to do that.



Input


N M
X1 Y1
...
XM YM


N is the number of stars and M is the number of pairs of two "similar" stars. A star is represented by an integer number greater than or equal to 1 and less than or equal to N, and Xi, Yi (1 ≤ i ≤ M) indicates that the star Xi and the star Yi are "similar".

Satisfy 1 ≤ N ≤ 100,000, 0 ≤ M ≤ 200,000, 1 ≤ Xi <Yi ≤ N. The same set as (Xi, Yi) does not appear multiple times. The relationship of "similarity" satisfies the condition specified in the problem statement.

Output

The first line shows the maximum number of stars that can be recorded so that two "similar" stars are not recorded, and the second line shows the number of star combinations that can achieve that maximum (only the order in which they are recorded). Divide the changed one by 1,000,000,009 and output the remainder.

Examples

Input

4 3
1 2
1 3
1 4


Output

3
1


Input

11 5
1 2
3 4
5 6
7 8
9 10


Output

6
32


Input

9 14
1 2
1 3
2 3
3 4
3 5
3 6
3 7
3 8
3 9
4 5
4 6
5 6
7 8
8 9


Output

4
6

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define int ll
#define FOR(i,a,b) for(int i=int(a);i<int(b);i++)
#define REP(i,b) FOR(i,0,b)
int read(){
	int i;
	scanf("%lld",&i);
	return i;
}
using vi=vector<int>;
#define PB push_back
#define ALL(x) x.begin(),x.end()
using pi=pair<int,int>;

struct UnionFind{
	vi rank,par;
	void Init(int n){
		rank.assign(n,0);
		par.assign(n,-1);
	}
	int Find(int a){
		return par[a]==-1?a:(par[a]=Find(par[a]));
	}
	bool Same(int a,int b){
		return Find(a)==Find(b);
	}
	void Unite(int a,int b){
		a=Find(a),b=Find(b);
		if(a==b)return;
		if(rank[a]<rank[b])swap(a,b);
		par[b]=a;
		if(rank[a]==rank[b])rank[a]++;
	}
};

const int mod=1000000009;

pi Merge(pi a,pi b){
	return pi(a.first+b.first,a.second*b.second%mod);
}

signed main(){
	int n=read(),m=read();
	vector<vi> g(n);
	vi deg(n,0);
	REP(_,m){
		int a=read()-1,b=read()-1;
		g[a].PB(b);
		g[b].PB(a);
		deg[a]++;
		deg[b]++;
	}
	priority_queue<pi> pq;
	REP(i,n)pq.push(pi(deg[i],i));
	vi used(n,0),ord;
	while(!pq.empty()){
		int v=pq.top().first,i=pq.top().second;
		pq.pop();
		if(deg[i]!=v)continue;
		ord.PB(i);
		for(auto j:g[i])if(!used[j])
			pq.push(pi(--deg[j],j));
		used[i]=1;
	}
	reverse(ALL(ord));
	vector<pi> ans(n);
	UnionFind uf;uf.Init(n);
	used.assign(n,0);
	for(auto i:ord){
		pi w(0,1);
		for(auto j:g[i])if(used[j])
			if(!uf.Same(i,j)){
				w=Merge(w,ans[uf.Find(j)]);
				uf.Unite(i,j);
			}
		if(w.first==0)
			w.first=1;
		else if(w.first==1)
			w.second=(w.second+1)%mod;
		ans[uf.Find(i)]=w;
		used[i]=1;
	}
	pi w=ans[uf.Find(0)];
	REP(i,n)if(!uf.Same(0,i)){
		w=Merge(w,ans[uf.Find(i)]);
		uf.Unite(0,i);
	}
	cout<<w.first<<endl<<w.second<<endl;
}
```