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.

Examples

Input

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


Output

6


Input

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


Output

44


Input

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


Output

582
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Scanner;

@SuppressWarnings("unchecked")
class Main{

    static class Node{
        int v;
        long A,B;
        Node(int v,long a,long b){this.v=v;A=a;B=b;}
    }

    static long[] w0;
    static long[] w;

    static int[] pare;
    static int root(int v){
        if(pare[v]<0)return v;
        return pare[v] = root(pare[v]);
    }
    static void unite(int p,int c){
        p=root(p);c=root(c);
        if(p==c)return;
        pare[p]+=pare[c];
        pare[c]=p;
    }
    static boolean same(int u,int v){
        return root(u)==root(v);
    }
    static class Edge{
        int from,to;
        long cost;
        Edge(int from,int to,long cost){this.from=from;this.to=to;this.cost=cost;}
    }
    

    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int M = scan.nextInt();
        long[] A = new long[N];
        long[] B = new long[N];
        w0 = new long[N];
        w = new long[N];
        pare=new int[N];
        for(int i=0;i<N;++i){
            A[i]=scan.nextLong();
            B[i]=scan.nextLong();
            w0[i] = Math.max(0, A[i]-B[i]);
            w[i] = B[i];
        }
        Arrays.fill(pare, -1);

        PriorityQueue<Node> nodeQue[] = new PriorityQueue[N];
        for(int i=0;i<N;++i)nodeQue[i]=new PriorityQueue<>((a,b)->(int)(((a.A-a.B)-(b.A-b.B))));
        while(M-->0){
            int u = scan.nextInt()-1;
            int v = scan.nextInt()-1;
            nodeQue[u].add(new Node(v, A[v],B[v]));
            nodeQue[v].add(new Node(u, A[u],B[u]));
        }
        if(N==1){
            System.out.println(Math.max(A[0], B[0]));
            return;
        }
        PriorityQueue<Edge> que = new PriorityQueue<>((a,b)->a.cost-b.cost==0 ? a.from-b.from : a.cost-b.cost<0 ? -1 : 1);
        for(int i=0;i<N;++i){
            Node n = nodeQue[i].peek();
            // System.out.println(i+" "+n.v+" "+Math.max(w0[i], w0[i] + n.A-w[i]));
            que.add(new Edge(i, n.v, Math.max(w0[i], (n.A-n.B)-w[i])));
        }


        while(!que.isEmpty()){
            Edge e = que.poll();
            //System.out.println(e.from+" <<< "+e.to);
            if(same(e.from, e.to) || e.cost != Math.max(w0[root(e.from)], A[e.to]-B[e.to]-w[root(e.from)]))continue;
            // System.out.println("success");
            w0[root(e.from)] = e.cost;
            w[root(e.from)] += w[root(e.to)];
            while(!nodeQue[root(e.to)].isEmpty())nodeQue[root(e.from)].add(nodeQue[root(e.to)].poll());
            unite(e.from, e.to);
            // System.out.println(w0[root(e.from)]+" "+w[root(e.from)]);
            while(!nodeQue[root(e.from)].isEmpty() && same(e.from, nodeQue[root(e.from)].peek().v))nodeQue[root(e.from)].poll();
            if(nodeQue[root(e.from)].isEmpty())break;
            Node next = nodeQue[root(e.from)].peek();
            // System.out.println("add : "+ root(e.from)+" <<< "+next.v);
            que.add(new Edge(root(e.from), next.v, Math.max(w0[root(e.from)], next.A-next.B-w[root(e.from)])));
        }
        long sum = 0;
        for(int i=0;i<N;++i)sum+=B[i];
        // System.out.println();
        // for(int i=0;i<N;++i)System.out.println(root(i));
        System.out.println(w0[root(0)]+sum);
    }
}