#include <bits/stdc++.h>   using namespace std;   const int N = 100000 + 77, Mod = 1000000007;   struct SegmentTree {     int nn;     vector<int> LC, RC, S, lz;     int cur = 0;     inline void __init() { AddNode(); }     inline void AddNode() {       ++cur;       LC.push_back(-1);       RC.push_back(-1);       S.push_back(0);       lz.push_back(0);     }     inline void Clear() {       LC.clear();       LC.shrink_to_fit();       RC.clear();       RC.shrink_to_fit();       S.clear();       S.shrink_to_fit();       lz.clear();       lz.shrink_to_fit();     }     inline void AddLeft(int id) {       if (LC[id] != -1) return;       LC[id] = cur;       AddNode();     }     inline void AddRight(int id) {       if (RC[id] != -1) return;       RC[id] = cur;       AddNode();     }     inline void Shift(int l, int r, int id) {       int x = lz[id];       lz[id] = 0;       S[id] = (S[id] + (r - l) * 1ll * x) % Mod;       if (r - l > 1)         AddRight(id), AddLeft(id), lz[LC[id]] = (lz[LC[id]] + x) % Mod,                                    lz[RC[id]] = (lz[RC[id]] + x) % Mod;     }     void Add(int ql, int qr, int x, int l, int r, int id) {       Shift(l, r, id);       if (qr <= l || r <= ql) return;       if (ql <= l && r <= qr) {         lz[id] = (lz[id] + x) % Mod;         Shift(l, r, id);         return;       }       int mid = ((l + r) >> 1);       assert(LC[id] != -1);       assert(RC[id] != -1);       Add(ql, qr, x, l, mid, LC[id]);       Add(ql, qr, x, mid, r, RC[id]);       S[id] = (S[LC[id]] + S[RC[id]]) % Mod;     }     int Get(int ql, int qr, int l, int r, int id) {       Shift(l, r, id);       if (qr <= l || r <= ql) return 0;       if (ql <= l && r <= qr) return S[id];       int mid = ((l + r) >> 1);       return (Get(ql, qr, l, mid, LC[id]) + Get(ql, qr, mid, r, RC[id])) % Mod;     }     inline void Add(int ql, int qr, int x) { Add(ql, qr, x, 1, nn + 1, 0); }     inline int Get(int ql, int qr) { return Get(ql, qr, 1, nn + 1, 0); }   };   int n, A, L[N], R[N], a[N], d[N], XX = 1;   vector<int> adj[N], V[N];   SegmentTree Sv;   SegmentTree S[N];   inline int Pow(int x, long long y) {     int r = 1;     for (; y; y >>= 1, x = x * 1ll * x % Mod)       if (y & 1) r = r * 1ll * x % Mod;     return r;   }   void dfs(int v, int prev = -1) {     for (int u : adj[v])       if (u != prev) d[u] = d[v] + 1, dfs(u, v);   }   void dfs2(int v, int prev = -1) {     S[v].Add(L[v], R[v] + 1, a[v]);     V[v].push_back(v);     for (int u : adj[v]) {       if (u == prev) continue;       dfs2(u, v);       if ((int)V[u].size() > (int)V[v].size()) swap(V[v], V[u]), swap(S[v], S[u]);       for (int x : V[u]) {         int val = S[v].Get(L[x], R[x] + 1) * 1ll * a[x] % Mod;         val = val * 2ll * d[v] % Mod;         A = (A - val + Mod) % Mod;       }       for (int x : V[u]) {         V[v].push_back(x);         S[v].Add(L[x], R[x] + 1, a[x]);       }       V[u].clear();       V[u].shrink_to_fit();       S[u].Clear();     }   }   int main() {     scanf( %d , &n);     for (int i = 1; i <= n; ++i)       scanf( %d %d , L + i, R + i), XX = XX * 1ll * (R[i] - L[i] + 1) % Mod,                                     a[i] = Pow(R[i] - L[i] + 1, Mod - 2);     for (int u, v, i = 1; i < n; ++i)       scanf( %d %d , &v, &u), adj[v].push_back(u), adj[u].push_back(v);     dfs(1);     Sv.nn = N - 2;     Sv.__init();     for (int i = 1; i <= n; ++i) S[i].nn = N - 2, S[i].__init();     for (int i = 1; i <= n; ++i) Sv.Add(L[i], R[i] + 1, a[i]);     for (int i = 1; i <= n; ++i) {       int val = Sv.Get(L[i], R[i] + 1);       val = (val - a[i] * 1ll * (R[i] - L[i] + 1)) % Mod;       if (val < 0) val += Mod;       A = (A + d[i] * 1ll * a[i] % Mod * 1ll * val) % Mod;     }     dfs2(1);     A = ((A % Mod) + Mod) % Mod;     A = A * 1ll * XX % Mod;     printf( %d n , A);     return 0;   }