stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

#define N 100500

#define pb push_back

#define mp make_pair

#define fi first

#define se second

typedef long long ll;

const ll m = 1e9 + 7;

int n;

ll memo[N][5];

vector <int> adj[N];



ll mul(ll a , ll b) {

    return ((a % m) * (b % m)) % m;

}



ll add(ll a , ll b) {

    return ((a % m) + (b % m)) % m;

}



ll dp(int u , int color , int par) {

    ll &sol = memo[u][color];

    if (sol != -1) return sol;

    ll product = 1;

    for (int v : adj[u]) {

        if (v == par) continue;

        if (color == 0) {

            product = mul(product , add(dp(v , 0 , u) , dp(v , 1 , u)));

        } else {

            product = mul(product , dp(v , 0 , u));

        }

    }

    return sol = product;

}



int main() {

    scanf("%d" , &n);

    for (int i = 1 ; i < n ; i++) {

        int u,v; scanf("%d%d" , &u , &v);

        adj[u].pb(v);

        adj[v].pb(u);

    }

    memset (memo , -1 , sizeof memo);

    printf("%lld\n" , add(dp(1 , 0 , 1) , dp(1 , 1 , 1)));

}


// Faster C++ solution for the same problem (measured speedup: 7.964812582963624x):
#include <iostream>

#include <vector>

#include <limits.h>

#include <algorithm>

#include <string>

#include <math.h>

#include <limits.h>

#include <queue>

#include <map>

#include <set>

#include <iomanip>

#include <bitset>

#include <cassert>

#include <random>

#include <functional>

#include <stack>

#include <iomanip>

using namespace std;

int MOD = 1e9 + 7;



int N;

typedef pair<int, int> pii;   //自分、親

vector<vector<int>> G;   //グラフ

vector<pii> order;



void setorder() {

	vector<bool> check;

	check.resize(N, false);   //来た->true

	queue<pii> st;

	st.push(pii(0,-1));

	while (!st.empty()) {

		pii cur = st.front();

		st.pop();

		check[cur.first] = true;

		order.push_back(cur);

		for (int next : G[cur.first]) {

			if (check[next])continue;

			st.push(pii(next, cur.first));

		}

	}

}



int main() {

	cin >> N;

	G.resize(N);

	for (int n = 0; n < N - 1; n++) {

		int u, v;

		cin >> u >> v;

		G[--u].push_back(--v);

		G[v].push_back(u);

	}

	setorder();

	vector<long long> DP[2];

	DP[0].resize(N, 1);

	DP[1].resize(N, 1);

	for (int ord = N - 1; ord >= 0; ord--) {

		pii cur = order[ord];

		//葉っぱの場合

		if (G[cur.first].size() == 1 && G[cur.first][0] == cur.second) {

			DP[0][cur.first] = 1;

			DP[1][cur.first] = 1;

		}

		if (cur.second == -1)continue;

		DP[0][cur.second] *= (DP[0][cur.first]+DP[1][cur.first]);

		DP[1][cur.second] *= (DP[0][cur.first]);

		DP[0][cur.second] %= MOD;

		DP[1][cur.second] %= MOD;

	}

	cout << (DP[0][0] + DP[1][0]) % MOD << endl;

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

#define N 100500

#define pb push_back

#define mp make_pair

#define fi first

#define se second

typedef long long ll;

const ll m = 1e9 + 7;

int n;

ll memo[N][5];

vector <int> adj[N];



ll mul(ll a , ll b) {

    return ((a % m) * (b % m)) % m;

}



ll add(ll a , ll b) {

    return ((a % m) + (b % m)) % m;

}



ll dp(int u , int color , int par) {

    ll &sol = memo[u][color];

    if (sol != -1) return sol;

    ll product = 1;

    for (int v : adj[u]) {

        if (v == par) continue;

        if (color == 0) {

            product = mul(product , add(dp(v , 0 , u) , dp(v , 1 , u)));

        } else {

            product = mul(product , dp(v , 0 , u));

        }

    }

    return sol = product;

}



int main() {

    scanf("%d" , &n);

    for (int i = 1 ; i < n ; i++) {

        int u,v; scanf("%d%d" , &u , &v);

        adj[u].pb(v);

        adj[v].pb(u);

    }

    memset (memo , -1 , sizeof memo);

    printf("%lld\n" , add(dp(1 , 0 , 1) , dp(1 , 1 , 1)));

}


// Faster C++ solution for the same problem (measured speedup: 2.2798350308499375x):
#include<bits/stdc++.h>

using namespace std;

#define all(v) ((v).begin()),((v).end())

#define ll long long

#define fastIO cout << fixed << setprecision(9), ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)

double const EPS = 1e-9, PI = acos(-1);

const int N = 1e5 + 9, M = 5e2 + 9, OO = 1e9 + 7, MOD = 1e9 + 7;

const ll inf = 1e18;



vector<int> adj[N];



ll mem[N][2];

ll add(ll a, ll b) {

  a += b;

  if(a >= MOD)

    a -= MOD;

  if(a < 0)

    a += MOD;

  return a;

}



ll mul(ll a, ll b) {

  return (a % MOD) * (b % MOD) % MOD;

}



void dfs(int node, int par) {

  mem[node][0] = 1, mem[node][1] = 1;

  for(int it: adj[node]) {

    if(it == par) continue;

    dfs(it, node);

    ll temp = mem[node][0];

    mem[node][0] = add( mul(temp, mem[it][0]), mul(temp, mem[it][1]));

    mem[node][1] = mul(mem[node][1], mem[it][0]);

  }

}



int main() {

  fastIO;

#ifdef LOCAL

  freopen("input.in", "rt", stdin);

#endif

  int n, u, v;

  cin >> n;

  for (int i = 1; i < n; ++i) {

    cin >> u >> v;

    adj[u].push_back(v);

    adj[v].push_back(u);

  }

  dfs(1, -1);

  cout << add(mem[1][0], mem[1][1]);

  return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

#define N 100500

#define pb push_back

#define mp make_pair

#define fi first

#define se second

typedef long long ll;

const ll m = 1e9 + 7;

int n;

ll memo[N][5];

vector <int> adj[N];



ll mul(ll a , ll b) {

    return ((a % m) * (b % m)) % m;

}



ll add(ll a , ll b) {

    return ((a % m) + (b % m)) % m;

}



ll dp(int u , int color , int par) {

    ll &sol = memo[u][color];

    if (sol != -1) return sol;

    ll product = 1;

    for (int v : adj[u]) {

        if (v == par) continue;

        if (color == 0) {

            product = mul(product , add(dp(v , 0 , u) , dp(v , 1 , u)));

        } else {

            product = mul(product , dp(v , 0 , u));

        }

    }

    return sol = product;

}



int main() {

    scanf("%d" , &n);

    for (int i = 1 ; i < n ; i++) {

        int u,v; scanf("%d%d" , &u , &v);

        adj[u].pb(v);

        adj[v].pb(u);

    }

    memset (memo , -1 , sizeof memo);

    printf("%lld\n" , add(dp(1 , 0 , 1) , dp(1 , 1 , 1)));

}


// Faster C++ solution for the same problem (measured speedup: 1.2771735263234516x):
#include <iostream>

#include <queue>

#define mod 1000000007



using namespace std;

int n,i,x,y;

struct nodS

{

    int parent=0;

    bool viz=false;

    long long dpa=1, dpb=1;

    vector <int> vecini;

} nod[100005];

struct poz

{

    int parent, id;

    poz(int id, int parent)

    {

        this->id=id;

        this->parent=parent;

    }

};

queue <poz> q;

void rezfunc(int poz)

{

    for(auto it : nod[poz].vecini)

    {

        if(it!=nod[poz].parent)

        {

            rezfunc(it);

            nod[poz].dpa*=(nod[it].dpa+nod[it].dpb);

            nod[poz].dpa%=mod;

            nod[poz].dpb*=nod[it].dpa;

            nod[poz].dpb%=mod;

        }

    }

}

int main()

{

    cin>>n;

    for(i=1;i<n;i++)

    {

        cin>>x>>y;

        nod[x].vecini.push_back(y);

        nod[y].vecini.push_back(x);

    }

    for(auto it : nod[1].vecini)

    {

        q.push(poz(it, 1));

    }





    while(!q.empty())

    {

        poz curr=q.front();

        nod[curr.id].parent=curr.parent;

        for(auto it : nod[curr.id].vecini)

            if(it!=curr.parent)

            {

                q.push(poz(it, curr.id));

            }



        q.pop();

    }



    /*

    for(i=1;i<=n;i++)

    {

        cout<<nod[i].parent<<' ';

    }

    */



    rezfunc(1);

    /*

    for(i=1;i<=n;i++)

    {

        cout<<nod[i].dpa<<' '<<nod[i].dpb<<'\n';

    }

    */



    cout<<(nod[1].dpa+nod[1].dpb)%mod;

    return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

#define N 100500

#define pb push_back

#define mp make_pair

#define fi first

#define se second

typedef long long ll;

const ll m = 1e9 + 7;

int n;

ll memo[N][5];

vector <int> adj[N];



ll mul(ll a , ll b) {

    return ((a % m) * (b % m)) % m;

}



ll add(ll a , ll b) {

    return ((a % m) + (b % m)) % m;

}



ll dp(int u , int color , int par) {

    ll &sol = memo[u][color];

    if (sol != -1) return sol;

    ll product = 1;

    for (int v : adj[u]) {

        if (v == par) continue;

        if (color == 0) {

            product = mul(product , add(dp(v , 0 , u) , dp(v , 1 , u)));

        } else {

            product = mul(product , dp(v , 0 , u));

        }

    }

    return sol = product;

}



int main() {

    scanf("%d" , &n);

    for (int i = 1 ; i < n ; i++) {

        int u,v; scanf("%d%d" , &u , &v);

        adj[u].pb(v);

        adj[v].pb(u);

    }

    memset (memo , -1 , sizeof memo);

    printf("%lld\n" , add(dp(1 , 0 , 1) , dp(1 , 1 , 1)));

}


// Faster C++ solution for the same problem (measured speedup: 1.8571943552885175x):
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#define fastio() ios_base::sync_with_stdio(false);

#define rmod(x, y) ((((x)%(y))+(y))%(y))

using namespace std;

using namespace __gnu_pbds;

typedef long long ll;

typedef long double ld;

template<typename T, typename R = null_type, typename C = less<T>>

tree<T, R, C, rb_tree_tag, tree_order_statistics_node_update> ordered_set(){

	return tree<T, R, C, rb_tree_tag, tree_order_statistics_node_update>();

}





const int maxn = 1e5+5, mod = 1e9+7;



int add(int a, int b){return (a+b)%mod;}

int mul(ll a, ll b){return (a*b)%ll(mod);}

int n, x, y, dp[maxn][2];

vector<int> vs[maxn];



int dfs(int v, int p, bool col){

	if (dp[v][col] != -1) return dp[v][col];

	int ret = dp[v][col];

	ret = 1;

	for(int e: vs[v]) if (e != p){

		int t = dfs(e, v, 1);

		if (col) t = add(t, dfs(e, v, 0));

		ret = mul(ret, t);

	}

	return dp[v][col] = ret;

}



int main(){

	memset(dp,-1, sizeof(dp));

	scanf("%d", &n);

	for(int i = 0; i<n-1; i++){

		scanf("%d %d", &x, &y);

		vs[--x].push_back(--y);

		vs[y].push_back(x);

	}

	dfs(0, -1, 1);

	dfs(0, -1, 0);

	printf("%d\n", add(dp[0][0], dp[0][1]));

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <queue>

#define mod 1000000007



using namespace std;

int n,i,x,y;

struct nodS

{

    int parent=0;

    bool viz=false;

    long long dpa=1, dpb=1;

    vector <int> vecini;

} nod[100005];

struct poz

{

    int parent, id;

    poz(int id, int parent)

    {

        this->id=id;

        this->parent=parent;

    }

};

queue <poz> q;

void rezfunc(int poz)

{

    for(auto it : nod[poz].vecini)

    {

        if(it!=nod[poz].parent)

        {

            rezfunc(it);

            nod[poz].dpa*=(nod[it].dpa+nod[it].dpb);

            nod[poz].dpa%=mod;

            nod[poz].dpb*=nod[it].dpa;

            nod[poz].dpb%=mod;

        }

    }

}

int main()

{

    cin>>n;

    for(i=1;i<n;i++)

    {

        cin>>x>>y;

        nod[x].vecini.push_back(y);

        nod[y].vecini.push_back(x);

    }

    for(auto it : nod[1].vecini)

    {

        q.push(poz(it, 1));

    }





    while(!q.empty())

    {

        poz curr=q.front();

        nod[curr.id].parent=curr.parent;

        for(auto it : nod[curr.id].vecini)

            if(it!=curr.parent)

            {

                q.push(poz(it, curr.id));

            }



        q.pop();

    }



    /*

    for(i=1;i<=n;i++)

    {

        cout<<nod[i].parent<<' ';

    }

    */



    rezfunc(1);

    /*

    for(i=1;i<=n;i++)

    {

        cout<<nod[i].dpa<<' '<<nod[i].dpb<<'\n';

    }

    */



    cout<<(nod[1].dpa+nod[1].dpb)%mod;

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.4541441057228524x):
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#define fastio() ios_base::sync_with_stdio(false);

#define rmod(x, y) ((((x)%(y))+(y))%(y))

using namespace std;

using namespace __gnu_pbds;

typedef long long ll;

typedef long double ld;

template<typename T, typename R = null_type, typename C = less<T>>

tree<T, R, C, rb_tree_tag, tree_order_statistics_node_update> ordered_set(){

	return tree<T, R, C, rb_tree_tag, tree_order_statistics_node_update>();

}





const int maxn = 1e5+5, mod = 1e9+7;



int add(int a, int b){return (a+b)%mod;}

int mul(ll a, ll b){return (a*b)%ll(mod);}

int n, x, y, dp[maxn][2];

vector<int> vs[maxn];



int dfs(int v, int p, bool col){

	if (dp[v][col] != -1) return dp[v][col];

	int ret = dp[v][col];

	ret = 1;

	for(int e: vs[v]) if (e != p){

		int t = dfs(e, v, 1);

		if (col) t = add(t, dfs(e, v, 0));

		ret = mul(ret, t);

	}

	return dp[v][col] = ret;

}



int main(){

	memset(dp,-1, sizeof(dp));

	scanf("%d", &n);

	for(int i = 0; i<n-1; i++){

		scanf("%d %d", &x, &y);

		vs[--x].push_back(--y);

		vs[y].push_back(x);

	}

	dfs(0, -1, 1);

	dfs(0, -1, 0);

	printf("%d\n", add(dp[0][0], dp[0][1]));

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

using namespace std;

using ll = long long;

#define in(v) v; cin >> v;

void ins() {}

template<class T,class... Rest>void ins(T& v,Rest&... rest){cin>>v;ins(rest...);}

#define rep(i,n) for(int i=0,_i=(n);i<_i;++i)



template<int MOD> struct MInt {

  long long val;

  MInt(long long val = 0) : val(val % MOD) { if (val < 0) val += MOD; }

  MInt operator+(const MInt& n) const { return MInt(val) += n; }

  MInt operator*(const MInt& n) const { return MInt(val) *= n; }

  MInt operator/(const MInt& n) const { return MInt(val) /= n; }

  MInt& operator+=(const MInt& n) { val = (val + n.val) % MOD; return *this; }

  MInt& operator*=(const MInt& n) { val = (val * n.val) % MOD; return *this; }

  friend ostream& operator<<(ostream& os, const MInt& n) { os<<n.val; return os; }

};

using mint = MInt<1000000007>;



struct Graph {

  vector<vector<int>> edge;

  Graph(int n = 0) { resize(n); }

  void resize(int n) {

    edge.resize(n, vector<int>());

  }

  void addEdge(int from, int to, bool directed = false) {

    edge[from].push_back(to);

    if (!directed)

      edge[to].push_back(from);

  }

};

Graph G;



constexpr int MAX_N = 1e5+1;

bool visited[MAX_N][2];

mint dp[MAX_N][2];

mint dfs(int cur, int parent, bool filled) {

  if (visited[cur][filled])

    return dp[cur][filled];

  mint ans = 1;

  for (const auto& to : G.edge[cur]) {

    if (to == parent)

      continue;

    ans *= filled ? dfs(to, cur, false)

      : dfs(to, cur, true) + dfs(to, cur, false);

  }

  visited[cur][filled] = true;

  return dp[cur][filled] = ans;

}



int main() {

  int in(N);

  G.resize(N);



  rep(i, N-1) {

    int x, y;

    ins(x, y);

    --x, --y;

    G.addEdge(x, y);

  }



  cout << dfs(0, -1, false) + dfs(0, -1, true) << endl;



  return 0;

}


// Faster C++ solution for the same problem (measured speedup: 2.581843271280402x):
#include <iostream>

#include <vector>

using namespace std;

#define in(v) v; cin >> v;

#define rep(i,n) for(int i=0,_i=(n);i<_i;++i)



struct Graph {

  vector<vector<int>> edge;

  Graph(int n = 0) { resize(n); }

  void resize(int n) { edge.resize(n, vector<int>()); }

  void addEdge(int from, int to) {

    edge[from].push_back(to); edge[to].push_back(from);

  }

  const vector<int>& operator[](int from) const { return edge[from]; }

};

constexpr int MOD = 1e9+7, MAX_N = 1e5;

long long dp[MAX_N][2];

long long dfs(const Graph &G, int cur, int prev, bool filled) {

  if (dp[cur][filled] != -1) return dp[cur][filled];

  long long ans = 1;

  for (const auto& to:G[cur]) {

    if (to == prev) continue;

    ans *= filled

      ? dfs(G, to, cur, false)

      : (dfs(G, to, cur, false) + dfs(G, to, cur, true)) % MOD;

    ans %= MOD;

  }

  return dp[cur][filled] = ans;

}

int main() {

  int in(N);



  Graph G(N);

  rep(i, N)

    dp[i][0] = dp[i][1] = -1;

  rep(i, N-1) {

    int in(x); int in(y);

    --x, --y;

    G.addEdge(x, y);

  }



  cout << (dfs(G, 0, -1, true) + dfs(G, 0, -1, false)) % MOD << endl;



  return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;



#define pb push_back

#define fi first

#define se second

#define ll long long

#define pq priority_queue

#define mp make_pair

#define pii pair<int,int>



const int mod=1e9+7;

int lowbit(int x) {return x&(-x);}



int n;

vector <int> edge[100010];

int f[100010][2];



int getf(int node,int c,int lst) {

	if (f[node][c]!=-1) return f[node][c];

	if (edge[node].size()==1&&edge[node][0]==lst) return 1;

	if (c==1) {

		ll res=1ll;

		for (int i=0;i<edge[node].size();i++) 

			if (edge[node][i]!=lst)

				res=getf(edge[node][i],0,node)*res%mod;

		return f[node][c]=res;

	}

	else {

		ll res=1ll;

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

			if (edge[node][i]==lst) continue;

			res*=(getf(edge[node][i],0,node)+getf(edge[node][i],1,node))%mod;

			res%=mod;

		}

		return f[node][c]=res;

	}

}



int main(){

	memset(f,-1,sizeof(f));

	scanf("%d",&n);

	for (int i=0;i<n-1;i++) {

		int x,y;

		scanf("%d%d",&x,&y);

		edge[x].pb(y);

		edge[y].pb(x);

	}

	cout<<(getf(1,0,-1)+getf(1,1,-1))%mod;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.244105441575191x):
#include<bits/stdc++.h>

using namespace std;



#define pb push_back

#define fi first

#define se second

#define ll long long

#define pq priority_queue

#define mp make_pair

#define pii pair<int,int>

#define mod 1000000007

#define debug(x) cerr<<#x<<"="<<x<<'\n'



pii f[100010];

vector <int> edge[100010];



pii getf(int node,int lst) {

	if (f[node].fi!=-1) return f[node];

	if (edge[node].size()==0||(node!=1&&edge[node].size()==1)) {

		f[node].fi=1;

		f[node].se=1;

		return f[node];

	}

	ll x=1,y=1;

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

		int v=edge[node][i];

		if (v==lst) continue;

		x*=(ll)getf(v,node).se;

		y*=(ll)((getf(v,node).se+getf(v,node).fi)%mod);

		x%=mod,y%=mod;

	}

	f[node].fi=x,f[node].se=y;

	return f[node];

}



int main(){

	int n;

	scanf("%d",&n);

	for (int i=1;i<n;i++) {

		int x,y;

		scanf("%d%d",&x,&y);

		edge[x].pb(y);

		edge[y].pb(x);

		f[i].fi=-1;

	}

	f[n].fi=-1;

	printf("%d",(getf(1,-1).fi+getf(1,-1).se)%mod);

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



typedef long long int ll;

const ll maxn = 100010;

const ll mod = 1000000007;

vector <ll> adj[maxn];

ll dp[maxn][3];



ll dfs(ll node, ll col, ll par){

    if(dp[node][col] != -1) return dp[node][col];

    ll ans = 1;

    for(auto x: adj[node]){

        if(x != par){

            if(col == 1){

                ans *= dfs(x,0,node);

                ans %= mod;

            }

            else{

                ans = ans * (dfs(x,0,node) + dfs(x,1,node));

                ans %= mod;

            }

        }

    }



    return dp[node][col] = ans;

}

int main(){

    memset(dp,-1,sizeof dp);

    ll n;

    scanf("%lld",&n);



    for(ll i = 1; i < n; i++){

        ll u,v;

        scanf("%lld %lld",&u,&v);

        adj[u].push_back(v);

        adj[v].push_back(u);

    }



    printf("%lld\n",(dfs(1,0,-1)+dfs(1,1,-1))%mod);

}


// Faster C++ solution for the same problem (measured speedup: 1.7716319431299776x):
#include <bits/stdc++.h>     



//#pragma GCC optimize("Ofast")

//#pragma comment(linker, "/stack:200000000")

//#pragma GCC target("sse,sse2,sse3,ssse3,sse4"



#define mp make_pair

#define pb push_back

#define f first

#define s second

#define ll long long

#define int ll

#define forn(i, a, b) for(int i = (a); i <= (b); ++i)

#define forev(i, b, a) for(int i = (b); i >= (a); --i)

#define VAR(v, i) __typeof( i) v=(i)

#define forit(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)

#define all(x) (x).begin(), (x).end()

#define sz(x) ((int)(x).size())

#define file(s) freopen(s".in","r",stdin); freopen(s".out","w",stdout);

 

using namespace std;

 

const int maxn = (int)1e5+100;

const int mod = (int)1e9 + 7;

 

#define inf mod

 

typedef long double ld;

typedef pair<int, int> pii;

typedef pair<ll, ll> pll;

typedef vector<int> vi;   

typedef vector<ll> Vll;               

typedef vector<pair<int, int> > vpii;

typedef vector<pair<ll, ll> > vpll;



int n, dp[maxn][2];

vi g[maxn];



void dfs(int v, int p = 0){

  dp[v][0]=dp[v][1]=1;

  for(auto to:g[v])

    if(to!=p){

      dfs(to,v);

      dp[v][0]=dp[v][0]*((dp[to][0]+dp[to][1])%mod)%mod;

      dp[v][1]=dp[v][1]*dp[to][0]%mod;

    }

}

main () {

  cin>>n;

  forn(i,1,n-1){

    int u, v;

    cin>>u>>v;

    g[u].pb(v);

    g[v].pb(u);

  }

  dfs(1);

  cout<<(dp[1][0]+dp[1][1])%mod;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



typedef long long int ll;

const ll maxn = 100010;

const ll mod = 1000000007;

vector <ll> adj[maxn];

ll dp[maxn][3];



ll dfs(ll node, ll col, ll par){

    if(dp[node][col] != -1) return dp[node][col];

    ll ans = 1;

    for(auto x: adj[node]){

        if(x != par){

            if(col == 1){

                ans *= dfs(x,0,node);

                ans %= mod;

            }

            else{

                ans = ans * (dfs(x,0,node) + dfs(x,1,node));

                ans %= mod;

            }

        }

    }



    return dp[node][col] = ans;

}

int main(){

    memset(dp,-1,sizeof dp);

    ll n;

    scanf("%lld",&n);



    for(ll i = 1; i < n; i++){

        ll u,v;

        scanf("%lld %lld",&u,&v);

        adj[u].push_back(v);

        adj[v].push_back(u);

    }



    printf("%lld\n",(dfs(1,0,-1)+dfs(1,1,-1))%mod);

}


// Faster C++ solution for the same problem (measured speedup: 1.7760781443640288x):
#include <bits/stdc++.h> 



using namespace std;

 

typedef long long ll;

typedef long double ld;

typedef unsigned long long ull;

 

#define nl '\n'

 

#define y1 aza_ibagaliev

 

#define f first

#define s second

	

#define ed end()

#define bg begin()

#define rbg rbegin()

 

#define rv reverse

#define mp make_pair

#define pb push_back

#define ppb pop_back

#define ppf pop_front

 

#define sz size()

#define all(x) x.bg, x.ed

 

#define pll pair < ll, ll >

#define pii pair < int, int >

 

#define sqr(x) ((x) * 1ll * (x))

#define sqrd(x) ((x) * 1.0 * (x))

 

#define speed ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)

 

#define rnl cout << "----------------------------------------" << nl

 

#define bit __builtin_popcount

 

inline ll bip(ll x, ll n, ll mod){ll res=1;while(n){if(n & 1){res=(res*x)%mod;}x=(x*x)%mod;n>>=1;}return res;}

        	

const int ppr = 257;

const ll INF = 2e18;

const int inf = 2e9;

const int mod = 1e9 + 7;

const int N = 1e5 + 123;

const ld pi = 3.1741592653589793238462643;

 

const int dx[] = {1, 0, -1, 0};

const int dy[] = {0, 1, 0, -1};



ll n, dp[3][N];

vector<int>g[N];



void dfs(int v, int pr=0) {

	dp[0][v] = dp[1][v] = 1;



	for(int to : g[v]) {

		if(to == pr) continue;

		dfs(to, v);	

		dp[0][v] = (dp[0][v] * (dp[0][to] + dp[1][to])) % mod;

		dp[1][v] = (dp[1][v] * dp[0][to]) % mod;

	}

}



main() {             	

//  freopen(".in", "r", stdin);

//  freopen(".out", "w", stdout);



//	srand(time(NULL));



	scanf("%d", &n);



	for(int i = 1; i < n; i++) {

		int x, y;

		scanf("%d%d", &x, &y);

		g[x].pb(y);

		g[y].pb(x);

	}



	dfs(1);



	cout << (dp[0][1] + dp[1][1]) % mod;

    

    return 0;                                        

}