Problem:
Score : 100 points

Problem Statement

There is a tree with N vertices, numbered 1, 2, \ldots, N.
For each i (1 \leq i \leq N - 1), the i-th edge connects Vertex x_i and y_i.

Taro has decided to paint each vertex in white or black.
Here, it is not allowed to paint two adjacent vertices both in black.

Find the number of ways in which the vertices can be painted, modulo 10^9 + 7.

Constraints

All values in input are integers.

1 \leq N \leq 10^5

1 \leq x_i, y_i \leq N

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
x_2 y_2
:
x_{N - 1} y_{N - 1}

Output

Print the number of ways in which the vertices can be painted, modulo 10^9 + 7.

Sample Input 1

3
1 2
2 3

Sample Output 1

5

There are five ways to paint the vertices, as follows:

Sample Input 2

4
1 2
1 3
1 4

Sample Output 2

9

There are nine ways to paint the vertices, as follows:

Sample Input 3

1

Sample Output 3

2

Sample Input 4

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

Sample Output 4

157

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		
		if(N == 1){
			Console.WriteLine(2);
			return;
		}
		
		List<int>[] E = new List<int>[N];
		for(int i=0;i<N;i++){
			E[i] = new List<int>();
		}
		
		for(int i=0;i<N-1;i++){
			E[X[i]].Add(Y[i]);
			E[Y[i]].Add(X[i]);
		}
		
		int[] depth = new int[N];
		int[] parent = new int[N];
		parent[0] = -1;
		depth[0] = 0;
		
		var q = new Queue<int>();
		q.Enqueue(0);
		while(q.Count > 0){
			var now = q.Dequeue();
			foreach(var nxt in E[now]){
				if(nxt == parent[now]) continue;
				depth[nxt] = depth[now] + 1;
				parent[nxt] = now;
				q.Enqueue(nxt);
			}
		}
		
		Pair[] P = new Pair[N];
		for(int i=0;i<N;i++){
			P[i] = new Pair(i, depth[i]);
		}
		
		Array.Sort(P, (p1, p2) => -1 * (p1.Depth.CompareTo(p2.Depth)));
		mlong[][] dp = new mlong[2][];
		for(int i=0;i<2;i++){
			dp[i] = new mlong[N];
		}
//Console.WriteLine("ok");		
		
		for(int i=0;i<N;i++){
			int now = P[i].Idx;
			if(now != 0 && E[now].Count == 1){
				dp[0][now] = 1;
				dp[1][now] = 1;
				continue;
			}
			
			mlong tot = 1;
			mlong p0 = 1;
			foreach(var nxt in E[now]){
				if(nxt == parent[now]) continue;
				tot *= (dp[0][nxt] + dp[1][nxt]);
				p0 *= (dp[0][nxt]);
			}
			
			dp[0][now] = tot;
			dp[1][now] = p0;
		}
		
		Console.WriteLine(dp[0][0] + dp[1][0]);
		
		
	}
	
	class Pair{
		public int Idx,Depth;
		public Pair(int idx, int depth){
			Idx = idx; Depth = depth;
		}
	}
	
	int N;
	int[] X,Y;
	public Sol(){
		N = ri();
		X = new int[N - 1];
		Y = new int[N - 1];
		for(int i=0;i<N-1;i++) {
			var d = ria();
			X[i] = d[0] - 1;
			Y[i] = d[1] - 1;
		}
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


struct mlong {
	
	const long mod = (long) 1e9 + 7;
	long V;
	
	public mlong(long _v = 0){
		V = _v;
	}
	
	public static mlong operator+(mlong a, mlong b){
		var v0 = a.V + b.V; if(v0 >= mod) v0 -= mod;
		return new mlong(v0);
	}
	public static mlong operator-(mlong a, mlong b){
		var v0 = mod + a.V - b.V; if(v0 >= mod) v0 -= mod;
		return new mlong(v0);
	}
	public static mlong operator*(mlong a, mlong b){
		var v0 = a.V * b.V; if(v0 >= mod) v0 %= mod;
		return new mlong(v0);
	}
	public static mlong operator/(mlong a, mlong b){
		var v0 = a.V * inv(b.V).V; if(v0 >= mod) v0 %= mod;
		return new mlong(v0);
	}
	
	
	public static mlong inv(long x){
		long a = 0, b = 0, c = 0;
		ExtGCD(x, mod, ref a, ref b, ref c);
		return (mlong)((a + mod) % mod);
	}
	
	public static void ExtGCD(long x, long y, ref long a, ref long b, ref long c){
		long r0 = x; long r1 = y;
		long a0 = 1; long a1 = 0;
		long b0 = 0; long b1 = 1;
		long q1, r2, a2, b2;
		while(r1 > 0){
			q1 = r0 / r1;
			r2 = r0 % r1;
			a2 = a0 - q1 * a1;
			b2 = b0 - q1 * b1;
			r0 = r1; r1 = r2;
			a0 = a1; a1 = a2;
			b0 = b1; b1 = b2;
		}
		c = r0;
		a = a0;
		b = b0;
	}
	
	public static mlong ModPow(mlong a, long k){
		if(k == 0) return (mlong) 1;
		if(a == 0) return (mlong) 0;
		mlong x = a;
		mlong ret = 1;
		while(k > 0){
			if(k % 2 == 1) ret *= x;
			x *= x;
			k >>= 1;
		}
		return ret;
	}
	
	
	public static bool operator == (mlong a, mlong b){
		 return a.Equals(b);
	}
	public static bool operator != (mlong a, mlong b){
		 return !(a == b);
	}
	
	public override bool Equals(System.Object obj){
		if(obj  ==  null) return false;
		mlong p  =  (mlong) obj;
		if((System.Object) p  ==  null) return false;
		return p.V  ==  V;
	}
	public override int GetHashCode(){
		return V.GetHashCode();
	}
	
	public static implicit operator mlong(long n){
		return new mlong(n);
	}
	public static implicit operator mlong(int n){
		return new mlong(n);
	}
	public static explicit operator long(mlong n){
		return n.V;
	}
	
	public override String ToString(){
		return V.ToString();
	}
	
	
}