#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());


#define BOOST        ios::sync_with_stdio(false);  cin.tie(NULL); cout.tie(NULL);
#define AZ(x)        x.begin(),x.end()
#define fi           first
#define se           second
#define pb           push_back
#define emp          emplace_back
#define mp           make_pair
#define mt           make_tuple 
#define debug(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); degub(_it, args); }
#define For(i,a,n)   for(auto i = a; i < n; i++)
#define int          long long

template<typename T> using V = vector<T>;
template<typename T, typename U> using P = pair<T,U>;

typedef long long ll;
typedef long double ld;


template<typename T>
// for super_map add a parameter Y above and replace "null_type" with "Y"

// set with two additional super powers
    // find_by_order(int k) - returns k'th smallest element (0-indexed)
    // order_of_key(int k) - returns number of elements strictly smaller than k.
using super_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;


void degub(istream_iterator<string> it) {cerr << endl;}
template<typename T, typename... Args>
void degub(istream_iterator<string> it, T a, Args... args) {
    cerr << "[" << *it << " : " << a << "] ";
    degub(++it, args...);
}


ll power(ll a,ll b)
{
    // a = a;
    ll result = 1;

    while(b)
    {
        if(b&1)
            result = (result*a);
        b >>= 1, a = (a*a);
    }
    return result;
}

ll super_rand(ll n) // Random number from set [0,n-1]
{
    uniform_int_distribution<ll> uid(0, n - 1);
    return uid(rng);
}



/*


1. Make sure you're taking all the inputs.
2. In case of nested loops, remember to use different variables.
3. If in doubt, do int -> ll
4. Don't fight the question, try solving the next one.
5. ffs (positon of first set bit), clz (leading 0s, max->32), ctz (trailing 0s), popcount (set bits). Don't use any of these on 0;


*/



// Don't code anything above this //






const int mod = 1e9+7, N = 1e5 + 5;
const ll INF = 1000000000000000107;

V<int> tre[N];
int dp[N][2];
bool vis[N];
int par[N];
void dfs(int node)
{
    vis[node] = 1;
    bool isleaf = 1;
    for(auto i : tre[node])
    {
        if(!vis[i])
        {
            isleaf = 0;
            par[i] = node;
            dfs(i);
        }
    }
    if(isleaf)
    {
        dp[node][0] = 1, dp[node][1] = 1; 
        return;
    }
    int val1 = 1, val2 = 1;
    for(auto i : tre[node])
    {
        if(i == par[node])
            continue;
        val1 = (val1 * ((dp[i][0] + dp[i][1]) % mod)) % mod;
        val2 = (val2 * dp[i][0]) % mod;
    }
    dp[node][0] = val1;
    dp[node][1] = val2;
}

int32_t main()
{
    BOOST
    

    int n;
    cin >> n;

    int u, v;
    for(int i = 0; i < n - 1; i++)
    {
        cin >> u >> v;
        tre[u].pb(v);
        tre[v].pb(u);
    }
    dfs(1);
    int ans = (dp[1][0] + dp[1][1]) % mod;
    cout << ans << "\n";
    return 0;
}


Measured memory_bytes: 12416