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

const long long MOD = 1000000007;

typedef long long ll; // -9,223,372,036,854,775,808 から 9,223,372,036,854,775,807

template <class T> using vec = std::vector<T>;
template <class T> using vec2 = vec<vec<T>>;
template <class T> using vec3 = vec<vec<vec<T>>>;

// #define DEBUG

struct GCDResult{long long x; long long y; long long res;};
GCDResult gcd(long long a, long long b){
    if(a < 0){
        auto sub = gcd(-a, b);
        return GCDResult{-sub.x, sub.y, sub.res};
    }
    if(b < 0){
        auto sub = gcd(a, -b);
        return GCDResult{sub.x, -sub.y, sub.res};
    }
    if(a < b){
        auto sub = gcd(b, a);
        return GCDResult{sub.y, sub.x, sub.res};
    }
    // a >= b AND a >= 0 AND b >= 0
    if(b == 0){
        return GCDResult{1LL, 0LL, a};
    }
    // a >= b AND a > 0 AND b > 0
    auto sub = gcd(b, a % b);
    return GCDResult{sub.y, sub.x - sub.y*(a/b), sub.res};
}

// Requires ATC_GCD
const int COM_MAX = 510000;
template <long long p>
class Zp{
    long long content;

    // for comb()
    static array<long long, COM_MAX> fac;
    static array<long long, COM_MAX> finv;
    static array<long long, COM_MAX> inv_;
    static bool is_initialized_com_table;

    // By rng_2 (See https://drken1215.hatenablog.com/entry/2018/06/08/210000)
    // テーブルを作る前処理
    static void COMinit() {
        auto MOD = p;
        auto MAX = COM_MAX;
        fac[0] = fac[1] = 1;
        finv[0] = finv[1] = 1;
        inv_[1] = 1;
        for (int i = 2; i < MAX; i++){
            fac[i] = fac[i - 1] * i % MOD;
            inv_[i] = MOD - inv_[MOD%i] * (MOD / i) % MOD;
            finv[i] = finv[i - 1] * inv_[i] % MOD;
        }
        is_initialized_com_table = true;
    }

    // 二項係数計算
    static long long COM(int n, int k){
        auto MOD = p;
        auto MAX = COM_MAX;
        if(!is_initialized_com_table){
            assert(false);
        }
        if (n < k) return 0;
        if (n < 0 || k < 0) return 0;
        return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
    }



    public:
    Zp(long long content_){
        if(content_ >= 0){
            content = content_ % p;
        }else{
            long long temp = p;
            while(temp < -content_){
                temp *= p;
            }
            content = (temp + content_) % p;
        }
    }

    bool operator==(const Zp<p>& rhs) const{
        return this->content == rhs.content;
    }

    bool operator!=(const Zp<p>& rhs) const{
        return !(*this == rhs);
    }

    Zp<p> operator+(const Zp<p>& rhs) const{
        return Zp<p>(this->content + rhs.content);
    }

    Zp<p> operator-() const{
        return Zp<p>(p - this->content);
    }

    Zp<p> operator-(const Zp<p>& rhs) const{
        return Zp<p>(this->content - rhs.content + p);
    }

    Zp<p> operator*(const Zp<p>& rhs) const{
        return Zp<p>(this->content * rhs.content);
    }

    Zp<p> inv() const{
        if(this->content == 0){
            assert(false);
        }

        auto res = gcd(this->content, p);
        return Zp<p>(res.x);
    }

    Zp<p> operator/(const Zp<p>& rhs) const{
        if(rhs.content == 0){
            assert(false);
        }
        
        return (*this)*rhs.inv();
    }

    Zp<p> pow(int n){
        auto res = Zp<p>(1);
        Zp<p> mult = (*this);
        while(n > 0){
            if(n & 1 == 1){
                res = res*mult;
            }
            n >>= 1;
            mult = mult*mult;
        }
        return res;
    }

    long long raw(){
        return this->content;
    }

    static void initializeCom(){
        COMinit();
    }

    static Zp<p> com(int n, int k){
        return Zp<p>(COM(n, k));
    }

};

template <long long p>
bool Zp<p>::is_initialized_com_table = false;
template <long long p>
array<long long, COM_MAX> Zp<p>::fac;
template <long long p>
array<long long, COM_MAX> Zp<p>::finv;
template <long long p>
array<long long, COM_MAX> Zp<p>::inv_;


struct Edge{
    int to;
};

struct Node{
    Zp<MOD> sumPow;
    ll num;
};


class RerootingSum{
    vec2<int> edges;
    vec<Node> partials;  // partials[i]はiからEdge.to向きの部分木の部分解
    vec<set<int>> edgeMap;

    // upを上方として、downにNode情報をとる。
    Node fillFirst(int up, int down){
        if(edges.at(down).empty()){
            // 末尾
            partials.at(down) = Node{Zp<MOD>(0), 0};
            return partials.at(down);
        }

        Zp<MOD> resPow(0);
        ll resNum = 0;
        for(auto iter: edges.at(down)){
            if(iter == up){
                continue;
            }



            auto pRes = fillFirst(down, iter);
            resPow = resPow + Zp<MOD>(2).pow(pRes.num + 1);  // numは自信を含まない積算なので
            resNum += pRes.num + 1;
        }

        // partials.at(down)にこの部分での結果を保存
        partials.at(down) = Node{resPow, resNum};

        return partials.at(down);
    }

    // fillFirstだと子どもから親への部分木の情報がないのでそれを埋める
    void fillHoles(int up, int down){
        // downからupへの距離を追加する
        if(up != -1){
            // upでの(down向きを除いた)部分木たちの和をもとめる。
            auto res = partials.at(up);

            // resにはupからdownにいった分が余計に含まれているのでこれを削る。
            auto subRes = partials.at(down);
            
            auto resUp = Node{res.sumPow - Zp<MOD>(2).pow(subRes.num + 1), res.num - (subRes.num + 1)};


            // downのうちupむきの分がなかったのを足しこむ
            partials.at(down).sumPow = partials.at(down).sumPow + Zp<MOD>(2).pow(resUp.num + 1);
            partials.at(down).num += resUp.num + 1;
        }

        // 下に伝播
        for(auto iter: edges.at(down)){
            if(iter == up){
                continue;
            }
            fillHoles(down, iter);
        }
    }

    public:
    RerootingSum(vec2<int> edges){
        this->edges = edges;
        partials = vec<Node>(edges.size(), Node{Zp<MOD>(0), 0});
        fillFirst(-1, 0);
        fillHoles(-1, 0);
    }

    Zp<MOD> getResult(int pos){
        #ifdef DEBUG
        printf("*START: result\n");
        cout << pos << endl;
        for(auto iter: partials.at(pos)){
            cout << iter << ",";
        }
        cout << endl;
        printf("*END: result\n");
        #endif
        if(edges.at(pos).size() <= 1){
            return Zp<MOD>(0);
        }
        
        return Zp<MOD>(2).pow(partials.at(pos).num) - (partials.at(pos).sumPow - Zp<MOD>(edges.at(pos).size()) + Zp<MOD>(1));
    }
};


void solve(long long N, std::vector<long long> A, std::vector<long long> B){
    for(int i=0; i < N-1; i++){
        A.at(i)--;
        B.at(i)--;
    }

    vec2<int> edges(N);
    for(int i=0; i < N-1; i++){
        edges.at(A.at(i)).push_back(B.at(i));
        edges.at(B.at(i)).push_back(A.at(i));
    }

    RerootingSum rs(edges);

    auto res = Zp<MOD>(0);
    for(int i=0; i < N; i++){
        res = res + rs.getResult(i);
    }
    #ifdef DEBUG
    printf("*START: numbers\n");
    cout << res.raw() << endl;
    printf("*END: numbers\n");
    #endif
    res = res / Zp<MOD>(2).pow(N);

    cout << res.raw() << endl;
}

// Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
int main(){
    long long N;
    scanf("%lld",&N);
    std::vector<long long> A(N-1);
    std::vector<long long> B(N-1);
    for(int i = 0 ; i < N-1 ; i++){
        scanf("%lld",&A[i]);
        scanf("%lld",&B[i]);
    }
    solve(N, std::move(A), std::move(B));
    return 0;
}


Measured memory_bytes: 47488