Problem: A maze is represented by a tree (an undirected graph, where exactly one way exists between each pair of vertices). In the maze the entrance vertex and the exit vertex are chosen with some probability. The exit from the maze is sought by Deep First Search. If there are several possible ways to move, the move is chosen equiprobably. Consider the following pseudo-code:
    
    
      
    DFS(x)  
        if x == exit vertex then  
            finish search  
        flag[x] <- TRUE  
        random shuffle the vertices' order in V(x) // here all permutations have equal probability to be chosen  
        for i <- 1 to length[V] do  
            if flag[V[i]] = FALSE then  
                count++;  
                DFS(y);  
        count++;  
    

V(x) is the list vertices adjacent to x. The flag array is initially filled as FALSE. DFS initially starts with a parameter of an entrance vertex. When the search is finished, variable count will contain the number of moves.

Your task is to count the mathematical expectation of the number of moves one has to do to exit the maze.

Input

The first line determines the number of vertices in the graph n (1 ≤ n ≤ 105). The next n - 1 lines contain pairs of integers ai and bi, which show the existence of an edge between ai and bi vertices (1 ≤ ai, bi ≤ n). It is guaranteed that the given graph is a tree.

Next n lines contain pairs of non-negative numbers xi and yi, which represent the probability of choosing the i-th vertex as an entrance and exit correspondingly. The probabilities to choose vertex i as an entrance and an exit equal <image> and <image> correspondingly. The sum of all xi and the sum of all yi are positive and do not exceed 106.

Output

Print the expectation of the number of moves. The absolute or relative error should not exceed 10 - 9.

Examples

Input

2
1 2
0 1
1 0


Output

1.00000000000000000000


Input

3
1 2
1 3
1 0
0 2
0 3


Output

2.00000000000000000000


Input

7
1 2
1 3
2 4
2 5
3 6
3 7
1 1
1 1
1 1
1 1
1 1
1 1
1 1


Output

4.04081632653

Note

In the first sample the entrance vertex is always 1 and the exit vertex is always 2.

In the second sample the entrance vertex is always 1 and the exit vertex with the probability of 2/5 will be 2 of with the probability if 3/5 will be 3. The mathematical expectations for the exit vertices 2 and 3 will be equal (symmetrical cases). During the first move one can go to the exit vertex with the probability of 0.5 or to go to a vertex that's not the exit vertex with the probability of 0.5. In the first case the number of moves equals 1, in the second one it equals 3. The total mathematical expectation is counted as 2 / 5 × (1 × 0.5 + 3 × 0.5) + 3 / 5 × (1 × 0.5 + 3 × 0.5)

Solution (in JAVA):

Solution:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Labyrinth implements Runnable {
    int[] src;
    int[] dst;
    int[] first;
    int[] next;
    int[] sumEnterProb;
    long[] sumPairProb;
    int[] x;
    int[] y;
    int sumx;
    int sumy;

    private void solve() throws IOException {
        int n = nextInt();
        src = new int[2 * (n - 1)];
        dst = new int[2 * (n - 1)];
        first = new int[n];
        Arrays.fill(first, -1);
        next = new int[2 * (n - 1)];
        x = new int[n];
        y = new int[n];
        for (int i = 0; i < n - 1; ++i) {
            int a = nextInt() - 1;
            int b = nextInt() - 1;
            src[2 * i] = a;
            dst[2 * i] = b;
            next[2 * i] = first[a];
            first[a] = 2 * i;
            src[2 * i + 1] = b;
            dst[2 * i + 1] = a;
            next[2 * i + 1] = first[b];
            first[b] = 2 * i + 1;
        }
        sumx = 0;
        sumy = 0;
        for (int i = 0; i < n; ++i) {
            x[i] = nextInt();
            y[i] = nextInt();
            sumx += x[i];
            sumy += y[i];
        }
        sumEnterProb = new int[2 * (n - 1)];
        rec1(0, -1);
        sumPairProb = new long[2 * (n - 1)];
        rec2(0, -1);
        rec3(0, -1, 0);
        long total = (n - 1) * (long) sumx * sumy;
        for (int i = 0; i < (2 * (n - 1)); ++i)
            total -= sumPairProb[i];
        writer.println(total / (double) (sumx * (long) sumy));
    }

    private void rec3(int root, int parent, long sum) {
        long s = 0;
        int edge = first[root];
        while (edge >= 0) {
            if (dst[edge] != parent) {
                s += sumPairProb[edge];
            }
            edge = next[edge];
        }
        edge = first[root];
        while (edge >= 0) {
            if (dst[edge] != parent) {
                sumPairProb[edge ^ 1] = sum + y[root] * (long) sumEnterProb[edge ^ 1] + s - sumPairProb[edge];
                rec3(dst[edge], root, sumPairProb[edge ^ 1]);
            }
            edge = next[edge];
        }
    }

    private long rec2(int root, int parent) {
        int edge = first[root];
        long s = 0;
        while (edge >= 0) {
            if (dst[edge] != parent) {
                long r = rec2(dst[edge], root) + y[dst[edge]] * (long) sumEnterProb[edge];
                sumPairProb[edge] = r;
                s += r;
            }
            edge = next[edge];
        }
        return s;
    }

    private int rec1(int root, int parent) {
        int edge = first[root];
        int s = x[root];
        while (edge >= 0) {
            if (dst[edge] != parent) {
                int r = rec1(dst[edge], root);
                sumEnterProb[edge] = r;
                sumEnterProb[edge ^ 1] = sumx - r;
                s += r;
            }
            edge = next[edge];
        }
        return s;
    }

    public static void main(String[] args) {
        new Labyrinth().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}