#include<bits/stdc++.h>
#define X first
#define Y second
#define pb emplace_back
#define FOR(i,a,b) for(int (i)=(a);i<(b);++(i))
#define EFOR(i,a,b) for(int (i)=(a);i<=(b);++(i))
#define rep(X,Y) for (int (X) = 0;(X) < (Y);++(X))
#define reps(X,S,Y) for (int (X) = S;(X) < (Y);++(X))
#define rrep(X,Y) for (int (X) = (Y)-1;(X) >=0;--(X))
#define rreps(X,S,Y) for (int (X) = (Y)-1;(X) >= (S);--(X))
#define all(X) (X).begin(),(X).end()
#define rall(X) (X).rbegin(),(X).rend()
#define eb emplace_back
#define UNIQUE(X) (X).erase(unique(all(X)),(X).end())

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef ll LL;
typedef pii PII;
typedef pll PLL;
template<class T> using vv=vector<vector<T>>;
template<class T> inline bool MX(T &l,const T &r){return l<r?l=r,1:0;}
template<class T> inline bool MN(T &l,const T &r){return l>r?l=r,1:0;}
const ll MOD=1e9+7;

int N;
int M;
LL ans;
LL A[114514];
LL B[114514];
LL C[114514];
bool used[114514];
vector<int> es[114514];
priority_queue<pll, vector<pll>, greater<pll>> order;

struct UfData {
  int parsz;
  LL exc;
  LL bsum;
  LL W;

  UfData() : parsz(-1) {
    W = 0;
    bsum = 0;
    exc = 0;
  }

  void Merge(const UfData &d, int u, int v) {
    parsz += d.parsz;
    
    LL a = exc + max(C[v] - W, 0LL);
    LL b = d.exc + max(C[u] - d.W, 0LL);
    if (a < b) {
      W = max(W, C[v]) + d.bsum;
    } else if (a > b) {
      W = max(d.W, C[u]) + bsum;
    } else {
      LL f = max(W, C[v]) + d.bsum;
      LL g = max(d.W, C[u]) + bsum;
      W = max(f, g);
    }

    exc = min(a, b);
    bsum += d.bsum;
    // w += d.w;
  }
};

struct UnionFind {
  vector<UfData> dat;

  UnionFind() {}
  UnionFind(int n) {
    Init(n);
  }

  void Init(int n) {
    dat.assign(n, UfData());
  }

  int Root(int v) {
    if (dat[v].parsz < 0) return v;
    return dat[v].parsz=Root(dat[v].parsz);
  }

  bool Unite(int u, int v) {
    int p = Root(u); 
    int q = Root(v);
    if (p == q) return false;
    //printf("unite %d %d from %d %d\n", p, q, u, v);

    if (dat[p].parsz > dat[q].parsz) {
      swap(p, q);
      swap(u, v);
    }

    dat[p].Merge(dat[q], u, v);
    dat[q].parsz = p;

    return true;
  }
  
  bool Same(int u, int v) {
    return Root(u) == Root(v);
  }

  int Size(int v) {
    return -dat[Root(v)].parsz;
  }

  UfData& Data(int v) {
    return dat[Root(v)];
  }
};

int main() {
  scanf("%d%d", &N, &M);
  rep(i, N) {
    scanf("%lld%lld", &A[i], &B[i]);
    C[i] = max(A[i]-B[i], 0LL);
    order.push(pll(C[i], i));
    ans += B[i];
  }

  rep(i, M) { 
    int u, v;
    scanf("%d%d", &u, &v);
    --u;
    --v;
    es[u].emplace_back(v);
    es[v].emplace_back(u);
  }

  UnionFind uf(N);
  rep(v, N) {
    auto &d = uf.Data(v);
    d.bsum = B[v];
    if (A[v] > B[v]) {
      d.exc = A[v] - B[v];
      d.W = A[v];
    } else {
      d.exc = 0;
      d.W = B[v];
    }
  }

  while (!order.empty()) {
    auto p = order.top(); order.pop();
    int v = p.Y;
    //printf("p: %lld %d\n", p.X, v);
    used[v] = true;
    for (int u : es[v]) {
      if (!used[u]) continue;
      //printf("uniting %d, %d\n", u, v);

      uf.Unite(u, v);
    }
  }

  auto &d = uf.Data(0);
  assert(d.bsum == ans);
  printf("%lld\n", d.bsum + d.exc);
}


Measured memory_bytes: 13552