// Original C++ solution (slower):
#include <iostream>

#include <vector>

#include <cstring>



using namespace std;



const int MAX_N = 1e5 + 5, BLACK = 0, WHITE = 1, MOD = 1e9 + 7;

vector <int> tree[MAX_N];

long long no_of_ways[MAX_N][2];



long long dfs_count(int parent, int v, int colour)

{

    if(no_of_ways[v][colour] != -1)

    {

        return no_of_ways[v][colour];

    }



    no_of_ways[v][colour] = 1;



    for(int i = 0; i < tree[v].size(); i++)

    {

        int child = tree[v][i];



        if(child == parent) continue;



        long long no_of_subtrees = 1;



        if(colour == BLACK)

        {

            no_of_subtrees = dfs_count(v, child, WHITE);

        }

        else if(colour == WHITE)

        {

            no_of_subtrees = (dfs_count(v, child, BLACK) + dfs_count(v, child, WHITE))%MOD;

        }



        no_of_ways[v][colour] = (no_of_ways[v][colour]*no_of_subtrees)%MOD;

    }



    return no_of_ways[v][colour];

}



int main()

{

    int no_of_vertices;

    cin >> no_of_vertices;



    for(int i = 1; i <= no_of_vertices - 1; i++)

    {

        int x, y;

        cin >> x >> y;



        tree[x].push_back(y);

        tree[y].push_back(x);

    }



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



    long long answer = (dfs_count(0, 1, BLACK) + dfs_count(0, 1, WHITE))%MOD;



    cout << answer;

    return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

#include <ext/pb_ds/trie_policy.hpp>

using namespace std;

using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

typedef trie<string, null_type, trie_string_access_traits<>, pat_trie_tag, trie_prefix_search_node_update> pref_trie;

typedef unsigned long long BITMASK; typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<double, double> pdd; typedef pair<long long, long long> pll;

#define has_bit(bit_mask, x) ((bit_mask) & (1ULL << (x)))

#define turn_on_bit(bit_mask, x) (bit_mask |= (1ULL << (x)))

#define turn_off_bit(bit_mask, x) (bit_mask &= (~(1ULL << (x))))

#define smallest_on_bit(bit_mask) (__builtin_ctzint((bit_mask) & (-(bit_mask))))

#define CLOCK_START clock_t chrono_clk_beg = clock()

#define CLOCK_END clock_t chrono_clk_end = clock(); cerr << (double(chrono_clk_end - chrono_clk_beg) / CLOCKS_PER_SEC) << " sec"

#define bug(args ...) cerr << __LINE__ << ">> ", err(new istringstream(string(#args)), args), cerr << '\n'

#define decToBin(name, num) string name = bitset<8>(num).to_string();

#define binToDec(name, binary) unsigned long name = bitset<8>(binary).to_ulong();

#define radToDeg(name, radians) double name = radians * 180 / M_PI;

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

#define mapfind(mp, x) (mp.find(x) != mp.end())

#define arrfind(arr, x) (find(all(arr), x) != arr.end())

#define removeDuplicates(vec) sort(vec.begin(), vec.end()); vec.erase(unique(vec.begin(), vec.end()), vec.end())

#define printMat(mat) for (auto &x : mat) { for (auto &y : x) cout << y << " "; cout << '\n'; }

#define printArr(arr) for (auto &x : arr) cout << x << " "; cout << '\n';

#define ceil(a, b) ((a+b-1)/b)

#define INF (1LL<<30)

#define INF32 (1LL<<62)

#define F first

#define S second

#define M_PI 3.14159265358979323846

void err(istringstream *iss) {} template<typename T, typename ... Args> void err(istringstream *iss, const T &_val, const Args & ... args) { string _name; *iss >> _name; if (_name.back()==',') _name.pop_back(); cerr << _name << " = " << _val << "; ", err(iss, args ...); }

void str_replaceAll(string& str, const string& from, const string& to) { if(from.empty()) return; size_t start_pos = 0; while((start_pos = str.find(from, start_pos)) != std::string::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); } }

#define MOD 1000000007



const int BLACK = 0, WHITE = 1;

int dp[100005][2];

int solve(vector<int> adj[], int cur, int par, int color)

{

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

    ll res = 1;

    for (auto &x : adj[cur])

    {

        if (x == par) continue;

        ll val = 1;

        if (color == BLACK) val = solve(adj, x, cur, WHITE);

        else val = (solve(adj, x, cur, WHITE) + solve(adj, x, cur, BLACK)) % MOD;

        res = (res * val) % MOD;

    }

    return dp[cur][color] = res;

}

signed main()

{

    ios_base::sync_with_stdio(false); cin.tie(NULL);

    int n;

    cin >> n;

    vector<int> adj[n+1];

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

    {

        int u, v;

        cin >> u >> v;

        adj[u].push_back(v);

        adj[v].push_back(u);

    }

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

    ll ans = (solve(adj, 1, -1, BLACK) + solve(adj, 1, -1, WHITE)) % MOD;

    cout << ans << '\n';

    return 0;

}


// Fastest known solution for this problem: