//  DO NOT USE:  A   N (segtree)

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

//														MACROS
#define ll long long
#define pii pair<ll,ll>
#define f(a,b,c) for(ll a=b;a<c;a++)
#define read(t) ll t; cin>>t;
#define readarr(arr,n) ll arr[n]; f(i,0,n) cin>>arr[i];
#define deb(x)  cout<<x<<"         KAMEHAMEHA"<<endl;

//														OBJECTS
struct obj
{
    ll x,y;
};

//														USEFUL FUNCTIONS
ll powm(ll , ll ) ;

//          											SEGMENT TREE(!N)

const int N=3e0+5;
ll tree[4*N+1];
ll A[N];
ll lazy[4*N+1]={0};

void build(ll,ll,ll);
void update(ll,ll,ll,ll,ll);
ll query(ll,ll,ll,ll,ll);
void updateRange(ll,ll,ll,ll,ll,ll);
ll queryRange(ll,ll,ll,ll,ll);

//														GLOBAL VARS
ll INF =LLONG_MAX;
const ll M= 1000000007;
ll dp[100005][2]={0};
bool vis[100005]={0};

pii dfs(vector <ll> pos[],ll n, ll ind)
{
    // deb(ind)
    vis[ind]=true;
    ll a=1,b=1;
    for(auto x:pos[ind])
    {
        if(!vis[x])
        {
            pii xx;
            xx=dfs(pos,n,x);
            a*=(xx.first+xx.second);
            a%=M;
            b*=xx.first;        
            b%=M;
        }
    }
    // deb(a)
    // deb(h)
    // cout<<ind<<" "<<a<<" "<<b<<" "<<endl;
    return make_pair(a,b);
}


// 														MAIN
int main()
{ 
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);
	cout.tie(NULL);
    read(n)
    vector <ll> pos[n+1];
    f(i,0,n-1)
    {
        ll x,y;
        cin>>x>>y;
        pos[x].push_back(y);
        pos[y].push_back(x);
    }
    // deb(dfs(pos,n,1,1,1).second)
    ll lv=1;
    f(i,1,n+1) if(pos[i].size()==1) {lv=i;break;}
    pii z=dfs(pos,n,lv);
    cout<<(z.first+z.second)%M;

}










//													FUNCTIONS DECLARATIONS
ll powm(ll a, ll b) {
	ll res=1;
	while(b) {
		if(b&1)
			res=(res*a)%M;
		a=(a*a)%M;
		b>>=1;
	}
	return res;
}

void build(ll node, ll start, ll end)
{
    if(start == end)
    {
        // Leaf node will have a single element
        tree[node] = A[start];
    }
    else
    {
        ll mid = (start + end) / 2;
        // Recurse on the left child
        build(2*node, start, mid);
        // Recurse on the right child
        build(2*node+1, mid+1, end);
        // llernal node will have the sum of both of its children
        tree[node] = tree[2*node] + tree[2*node+1];
    }
}
void update(ll node, ll start, ll end, ll idx, ll val)
{
    if(start == end)
    {
        // Leaf node
        A[idx] += val;
        tree[node] += val;
    }
    else
    {
        ll mid = (start + end) / 2;
        if(start <= idx and idx <= mid)
        {
            // If idx is in the left child, recurse on the left child
            update(2*node, start, mid, idx, val);
        }
        else
        {
            // if idx is in the right child, recurse on the right child
            update(2*node+1, mid+1, end, idx, val);
        }
        // llernal node will have the sum of both of its children
        tree[node] = tree[2*node] + tree[2*node+1];
    }
}

ll query(ll node, ll start, ll end, ll l, ll r)
{
    if(r < start or end < l)
    {
        // range represented by a node is completely outside the given range
        return 0;
    }
    if(l <= start and end <= r)
    {
        // range represented by a node is completely inside the given range
        return tree[node];
    }
    // range represented by a node is partially inside and partially outside the given range
    ll mid = (start + end) / 2;
    ll p1 = query(2*node, start, mid, l, r);
    ll p2 = query(2*node+1, mid+1, end, l, r);
    return (p1 + p2);
}

void updateRange(ll node, ll start, ll end, ll l, ll r, ll val)
{
    if(lazy[node] != 0)
    { 
        // This node needs to be updated
        tree[node] += (end - start + 1) * lazy[node];    // Update it
        if(start != end)
        {
            lazy[node*2] += lazy[node];                  // Mark child as lazy
            lazy[node*2+1] += lazy[node];                // Mark child as lazy
        }
        lazy[node] = 0;                                  // Reset it
    }
    if(start > end or start > r or end < l)              // Current segment is not within range [l, r]
        return;
    if(start >= l and end <= r)
    {
        // Segment is fully within range
        tree[node] += (end - start + 1) * val;
        if(start != end)
        {
            // Not leaf node
            lazy[node*2] += val;
            lazy[node*2+1] += val;
        }
        return;
    }
    ll mid = (start + end) / 2;
    updateRange(node*2, start, mid, l, r, val);        // Updating left child
    updateRange(node*2 + 1, mid + 1, end, l, r, val);   // Updating right child
    tree[node] = tree[node*2] + tree[node*2+1];        // Updating root with max value 
}

ll queryRange(ll node, ll start, ll end, ll l, ll r)
{
    if(start > end or start > r or end < l)
        return 0;         // Out of range
    if(lazy[node] != 0)
    {
        // This node needs to be updated
        tree[node] += (end - start + 1) * lazy[node];            // Update it
        if(start != end)
        {
            lazy[node*2] += lazy[node];         // Mark child as lazy
            lazy[node*2+1] += lazy[node];    // Mark child as lazy
        }
        lazy[node] = 0;                 // Reset it
    }
    if(start >= l and end <= r)             // Current segment is totally within range [l, r]
        return tree[node];
    ll mid = (start + end) / 2;
    ll p1 = queryRange(node*2, start, mid, l, r);         // Query left child
    ll p2 = queryRange(node*2 + 1, mid + 1, end, l, r); // Query right child
    return (p1 + p2);
}


Measured memory_bytes: 13696