// Slower C++ solution:
#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;                                        

}

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



using namespace std;



// Header files, namespaces,

// macros as defined above

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;



#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>





#define f first

#define s second

#define db long double

#define pb push_back

#define sz(c) (c).size()

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



typedef long long ll;

typedef pair <int , int> ii;

typedef pair <ii , int> iii;

typedef vector <int> vi;

typedef vector <ii> vii;

typedef vector <iii> viii;

typedef vector <vi> vvi;

typedef vector <vii> vvii;



const ll mod = 1e9+7;

const int MAX = 1e5+5;

const db eps = 1e-13;



int memo[MAX][2];

int n;

vvi g;



int dp( int node, int color , int p = -1 ) {



    if( memo[node][color] != -1 )

        return memo[node][color];



    int &res = memo[node][color];

    res = 1;

    if( sz(g[node]) == 1 && p != -1 ) {



        return res = res + (!color);



    }



    ll res1 = 1;

    ll res2 = 1;



    for( int nw: g[node] ) {

        if( nw==p )

            continue;



        if( !color )

            res1 = ( 1ll * res1 * dp( nw , color , node ) ) % mod;

        res2 = ( 1ll * res2 * dp( nw , color^1 , node ) ) % mod;

    }

    return res = ((!color)*res1+res2)%mod;

}





int main()

{

	ios_base::sync_with_stdio(0);

	cin.tie(0); cout.tie(0);

    cout<<setprecision(11)<<fixed;



    memset( memo , -1 , sizeof memo );

    cin>>n;

    if( n==1 ) {

        cout<<2<<"\n";

        return 0;

    }



    vi v;

    g = vvi(n+1,v);

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

        int a, b;

        cin>>a>>b;

        g[a].pb(b);

        g[b].pb(a);

    }

    cout<<dp( 1 , 0 )<<"\n";



}

/*

10

8 5

10 8

6 5

1 5

4 8

2 10

3 6

9 2

1 7

*/