Problem:
Score : 1000 points

Problem Statement

There is a simple undirected graph with N vertices and M edges.
The vertices are numbered 1 through N, and the edges are numbered 1 through M.
Edge i connects Vertex U_i and V_i.
Also, Vertex i has two predetermined integers A_i and B_i.
You will play the following game on this graph.

First, choose one vertex and stand on it, with W yen (the currency of Japan) in your pocket.
Here, A_s \leq W must hold, where s is the vertex you choose.
Then, perform the following two kinds of operations any number of times in any order:

Choose one vertex v that is directly connected by an edge to the vertex you are standing on, and move to vertex v. Here, you need to have at least A_v yen in your pocket when you perform this move.

Donate B_v yen to the vertex v you are standing on. Here, the amount of money in your pocket must not become less than 0 yen.

You win the game when you donate once to every vertex.
Find the smallest initial amount of money W that enables you to win the game.

Constraints

1 \leq N \leq 10^5

N-1 \leq M \leq 10^5

1 \leq A_i,B_i \leq 10^9

1 \leq U_i < V_i \leq N

The given graph is connected and simple (there is at most one edge between any pair of vertices).

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
A_2 B_2
:
A_N B_N
U_1 V_1
U_2 V_2
:
U_M V_M

Output

Print the smallest initial amount of money W that enables you to win the game.

Sample Input 1

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

Sample Output 1

6

If you have 6 yen initially, you can win the game as follows:

Stand on Vertex 4. This is possible since you have not less than 6 yen.

Donate 2 yen to Vertex 4. Now you have 4 yen.

Move to Vertex 3. This is possible since you have not less than 4 yen.

Donate 1 yen to Vertex 3. Now you have 3 yen.

Move to Vertex 2. This is possible since you have not less than 1 yen.

Move to Vertex 1. This is possible since you have not less than 3 yen.

Donate 1 yen to Vertex 1. Now you have 2 yen.

Move to Vertex 2. This is possible since you have not less than 1 yen.

Donate 2 yen to Vertex 2. Now you have 0 yen.

If you have less than 6 yen initially, you cannot win the game. Thus, the answer is 6.

Sample Input 2

5 8
6 4
15 13
15 19
15 1
20 7
1 3
1 4
1 5
2 3
2 4
2 5
3 5
4 5

Sample Output 2

44

Sample Input 3

9 10
131 2
98 79
242 32
231 38
382 82
224 22
140 88
209 70
164 64
6 8
1 6
1 4
1 3
4 7
4 9
3 7
3 9
5 9
2 5

Sample Output 3

582

Solution in Rust (1.42.0) (judge verdict: Accepted)

use proconio::{input, marker::Usize1};

#[allow(dead_code)]
#[derive(Clone, Copy, Debug)]
enum ParentOrSize {
    Parent(usize),
    Size(usize),
}

#[allow(dead_code)]
#[derive(Clone, Debug)]
struct UnionFind(Vec<ParentOrSize>);

#[allow(dead_code)]
impl UnionFind {
    pub fn new(len: usize) -> Self {
        Self(vec![ParentOrSize::Size(1); len])
    }

    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }

    pub fn len(&self) -> usize {
        self.0.len()
    }

    pub fn find(&mut self, i: usize) -> usize {
        self.find_and_size(i).0
    }

    fn find_and_size(&mut self, i: usize) -> (usize, usize) {
        assert!(i < self.len());
        match self.0[i] {
            ParentOrSize::Parent(p) => {
                let ret = self.find_and_size(p);
                self.0[i] = ParentOrSize::Parent(ret.0);
                ret
            }
            ParentOrSize::Size(si) => (i, si),
        }
    }

    pub fn unite(&mut self, u: usize, v: usize) {
        let (mut u, su) = self.find_and_size(u);
        let (mut v, sv) = self.find_and_size(v);
        if u == v {
            return;
        }
        if su > sv {
            std::mem::swap(&mut u, &mut v);
            std::mem::swap(&mut v, &mut u);
        }
        self.0[v] = ParentOrSize::Size(su + sv);
        self.0[u] = ParentOrSize::Parent(v);
    }

    pub fn same(&mut self, u: usize, v: usize) -> bool {
        self.find(u) == self.find(v)
    }
}

fn main() {
    input!(
        n: usize,
        m: usize,
        ab: [(i64, i64); n],
        uv: [(Usize1, Usize1); m]
    );
    let mut g = vec![vec![]; n];
    for (u, v) in uv {
        g[u].push(v);
        g[v].push(u);
    }
    let b: Vec<_> = ab.iter().map(|(_, b)| b).collect();
    let c: Vec<_> = ab.iter().map(|(a, b)| a - b).collect();

    let mut ord: Vec<_> = (0..n).collect();
    ord.sort_by_key(|&i| c[i]);

    let mut ckd = vec![false; n];
    let mut dp = vec![0; n];
    let mut sum_b_of_cmp = vec![0; n];
    let mut uf = UnionFind::new(n);
    for x in ord {
        let mut adj: Vec<_> = g[x]
            .iter()
            .copied()
            .map(|y| uf.find(y))
            .filter(|&y| ckd[y])
            .collect();
        adj.sort();
        adj.dedup();
        let sum_b_of_cmp_x = b[x] + adj.iter().map(|&y| sum_b_of_cmp[y]).sum::<i64>();
        let mut ans = c[x].max(0) + sum_b_of_cmp_x;
        for &y in &adj {
            let now = dp[y].max(c[x]) + sum_b_of_cmp_x - sum_b_of_cmp[y];
            if now < ans {
                ans = now;
            }
        }
        for y in adj {
            uf.unite(x, y);
        }
        let x = uf.find(x);
        sum_b_of_cmp[x] = sum_b_of_cmp_x;
        ckd[x] = true;
        dp[x] = ans;
    }
    println!("{}", dp[uf.find(0)]);
}