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 C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>

using namespace std;

typedef long long lint;

struct unionfind_t {
  int n;
  vector<int> parent, rank;
  unionfind_t(int _n): n(_n), parent(n), rank(n, 0) {
    iota(parent.begin(), parent.end(), 0);
  }
  int find(int v) {
    if (v == parent[v]) return v;
    return parent[v] = find(parent[v]);
  }
  int join(int a, int b) {
    a = find(a);
    b = find(b);
    if (a == b) return a;
    if (rank[a] > rank[b]) swap(a, b);
    parent[a] = b;
    if (rank[a] == rank[b]) ++rank[b];
    return b;
  }
};

int main() {
  int n, m;
  scanf("%d %d", &n, &m);

  struct node_t {
    lint min_stand, cost;
  };
  lint cost_sum = 0LL;
  vector<node_t> nodes(n);
  for (int i = 0; i < n; ++i) {
    scanf("%lld %lld", &nodes[i].min_stand, &nodes[i].cost);
    cost_sum += nodes[i].cost;
  }

  vector<vector<int>> adj(n);
  for (int i = 0; i < m; ++i) {
    int a, b;
    scanf("%d %d", &a, &b), --a, --b;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }

  struct dp_t {
    lint total;
    lint worst_state;
  };

  vector<dp_t> dp(n);
  unionfind_t uf(n);

  vector<int> sorted_by_min_stand(n);
  iota(sorted_by_min_stand.begin(), sorted_by_min_stand.end(), 0);
  sort(sorted_by_min_stand.begin(), sorted_by_min_stand.end(),
       [&nodes](int a, int b) {
         return nodes[a].min_stand < nodes[b].min_stand;
       });
  vector<bool> mark(n, false);
  for (int v : sorted_by_min_stand) {
    static vector<int> cnts; cnts.clear();
    mark[v] = true;
    for (int u : adj[v])
      if (mark[u]) {
        cnts.push_back(uf.find(u));
      }
    sort(cnts.begin(), cnts.end());
    cnts.resize(unique(cnts.begin(), cnts.end()) - cnts.begin());

    lint cnts_total = 0LL;
    for (int cnt : cnts)
      cnts_total += dp[cnt].total;

    dp_t result;
    result.total = cnts_total + nodes[v].cost;
    result.worst_state = -cnts_total - nodes[v].min_stand;

    for (int cnt : cnts) {
      lint others_total = cnts_total - dp[cnt].total;

      result.worst_state =
        max(result.worst_state,
            min({-others_total - nodes[v].cost + dp[cnt].worst_state,
                 -others_total - nodes[v].min_stand}));
    }

    int joined_cnt = v;
    for (int cnt : cnts) joined_cnt = uf.join(joined_cnt, cnt);
    dp[joined_cnt] = result;
  }
  printf("%lld\n", max(cost_sum, -dp[uf.find(0)].worst_state));
  return 0;
}