Problem:
B: Brilliant Stars

ICPC で良い成績を収めるには修行が欠かせない．うさぎは ICPC で勝ちたいので，今日も修行をすることにした．

今日の修行は，夜空に輝くたくさんの星たちを観測して，視力と集中力を鍛えようというものである．うさぎは独自のセンスで星の特徴を記録していくことができる．

うさぎは「星の観測日記」として記録した星の特徴をノートにつけていくことにした．ここで，「似ている」 2 つの星をともに記録することは避けたい．2 つの星が「似ている」かどうかは，すべてうさぎの判断で決まっている．「似ている」かどうかの関係はあまり複雑ではなく，以下の条件を満たす．

条件： 異なる 4 つの星 A, B, C, D があり，A と B，B と C，C と D がそれぞれ「似ている」とする．このとき，A と C が「似ている」か，B と D が「似ている」か，あるいはその両方が成り立つ．

うさぎは「似ている」 2 つの星を記録しないようになるべくたくさんの星を記録したい．また，そのようにする方法が何通りあるかも知りたい．

Input

N M
X1 Y1
...
XM YM

N は星の個数，M は「似ている」 2 つの星の組の個数である．星は 1 以上 N 以下の整数の番号により表され，Xi, Yi (1 ≤ i ≤ M) は星 Xi と星 Yi が「似ている」ことを表す．

1 ≤ N ≤ 100,000，0 ≤ M ≤ 200,000，1 ≤ Xi < Yi ≤ N を満たす．(Xi, Yi) として同一の組は複数回現れない．「似ている」かどうかの関係は，問題文で指定された条件を満たす．

Output

1 行目に，「似ている」 2 つの星を記録しないように記録できる星の個数の最大値を，2 行目に，その最大値を実現できる星の組み合わせの個数 (記録する順番のみを変えたものは同じと考える) を 1,000,000,009 で割った余りを出力せよ．

Sample Input 1

4 3
1 2
1 3
1 4

Sample Output 1

3
1

Sample Input 2

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

Sample Output 2

6
32

Sample Input 3

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

Sample Output 3

4
6

Solution in C++11 (judge verdict: Runtime Error)

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

#define int long long
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define pb push_back
#define fi first
#define se second
template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

const int mod=1000000009;

pint op(const pint &a,const pint &b){
    return {a.fi+b.fi,a.se*b.se%mod};
}

vint G[100000];
int deg[100000];
int mark[100000];
int sizev[100000];
int sizee[200000];
pint ans;
int que[100000],tail;

int vs_[100000];pint es_[200000];

void solve2(int N,int *vs,int M,pint *es);

void solve(int N,int *vs,int M,pint *es){
    rep(i,N)deg[vs[i]]=0,mark[vs[i]]=-1;

    for(int i=0;i<M;i++){
        G[es[i].fi][deg[es[i].fi]++]=es[i].se;
        G[es[i].se][deg[es[i].se]++]=es[i].fi;
    }

    int cnt=0;
    for(int i=0;i<N;i++){
        if(mark[vs[i]]!=-1)continue;
        sizev[cnt]=sizee[cnt]=0;
        int c=cnt++;
        sizev[c]++;
        mark[vs[i]]=c;
        tail=1;
        que[0]=vs[i];
        for(int j=0;j<tail;j++){
            int v=que[j];
            for(int k=0;k<deg[v];k++){
                int u=G[v][k];
                if(mark[u]!=-1)continue;
                mark[u]=c;
                sizev[c]++;
                que[tail++]=u;
            }
        }
    }

    for(int i=0;i<M;i++)sizee[mark[es[i].fi]]++;
    rep(i,N)vs_[i]=vs[i];
    rep(i,M)es_[i]=es[i];

    int c=0;
    for(int i=0;i<cnt;i++){
        int nc=sizev[i]+c;
        sizev[i]=c;
        c=nc;
    }

    c=0;
    for(int i=0;i<cnt;i++){
        int nc=sizee[i]+c;
        sizee[i]=c;
        c=nc;
    }

    rep(i,N){
        int tmp=sizev[mark[vs_[i]]]++;
        vs[tmp]=vs_[i];
    }

    rep(i,M){
        int tmp=sizee[mark[es_[i].fi]]++;
        es[tmp]=es_[i];
    }

    rep(i,cnt){
        int t=i?sizev[i-1]:0;
        int s=i?sizee[i-1]:0;
        solve2(sizev[i]-t,vs+t,sizee[i]-s,es+s);
    }
}

void solve2(int N,int *vs,int M,pint *es){
    if(N*(N-1)/2==M){
        ans=op(ans,{1,N});
        return;
    }

    rep(i,N)deg[vs[i]]=0;

    for(int i=0;i<M;i++)deg[es[i].fi]++,deg[es[i].se]++;
    int cent=-1;
    rep(i,N){
        if(deg[vs[i]]==N-1)cent=vs[i];
    }

    int t=0;
    rep(i,N){
        if(vs[i]==cent)continue;
        vs[t++]=vs[i];
    }

    int s=0;
    rep(i,M){
        if(es[i].fi==cent||es[i].se==cent)continue;
        es[s++]=es[i];
    }
    solve(t,vs,s,es);
}

signed main(){
    int N,M;
    scanf("%lld%lld",&N,&M);


    static int vs[100000];
    static pint es[200000];
    rep(i,N)vs[i]=i;
    rep(i,M){
        int a,b;
        scanf("%lld%lld",&a,&b);
        a--;b--;
        es[i]={a,b};
        G[a].pb(b);G[b].pb(a);
    }
    ans={0,1};
    solve(N,vs,M,es);
    printf("%lld\n%lld\n",ans.fi,ans.se);
    return 0;
}