#include <iostream>
#include <iomanip>
#include <string>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <vector>
#include <cassert>
#include <fstream>
#include <algorithm>
#include <list>
#include <random>
#include <ctime>
#include <cmath>
#include <random>
#include <bitset>
#include <complex>
#include <functional>
#include <numeric>

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
#define int ll
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector< vi > vvi;
typedef vector< vvi > vvvi;
typedef vector<short> vs;
typedef vector<vs> vvs;
typedef vector<vvs> vvvs;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
typedef pair<ld, ld> pld;
typedef complex<double> base;

#define mmin(a, b) a = min(a, (b))
#define mmax(a, b) a = max(a, (b))
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define ALL(a) a.begin(),a.end()
#define sqr(x) (x) * (x)
#define fori(i, n) for(int i = 0; i < int(n); ++i)
#define cint const int & 
#define SZ(a) ((int)(a.size()))
#define watch(x) cout << (#x) << " = " << x << endl;

const double PI = 2 * acos(0.0);

template<class T>
void show(const vector<T> &a) {
	for (T x : a)
		cout << x << " ";
	cout << endl;
}

const int N = 1e5 + 9;
const ll oo = 1e15;
int parent[N];
int is_free[N];
ll bsum[N];
vi g[N];
int n, m;
ll a[N], b[N];

set<int> inside[N];
set<pair<ll, int>> neibs[N];
ll gw, gb;
set<pair<ll, int>> fre;
int counter = 0;

void make_set(int v) {
	++counter;
	inside[v].insert(v);
	parent[v] = v;
	bsum[v] = b[v];
	for (int to : g[v])
		neibs[v].insert(mp(a[to] - b[to], to));
}

int find_set(int v) {
	if (parent[v] == v) return v;
	return parent[v] = find_set(parent[v]);
}

void union_sets(int u, int v) {
	u = find_set(u);
	v = find_set(v);
	if (u == v) return;
	--counter;
	is_free[v] = 1;
	if (SZ(inside[u]) < SZ(inside[v]))
		swap(v, u);
	inside[u].insert(ALL(inside[v]));
	bsum[u] += bsum[v];
	parent[v] = u;
	neibs[u].insert(ALL(neibs[v]));
}

void add_to_free(int u) {
	while (!neibs[u].empty()) {
		bool ok = 0;
		if (inside[u].count((*neibs[u].begin()).second)) {
			ok = 1;
			neibs[u].erase(neibs[u].begin());
		}
		if (!ok) break;
	}
	if (neibs[u].empty()) {
		assert(counter == 1);
		return;
	}
	int superv = (*neibs[u].begin()).second;
	fre.insert(mp(a[superv] - b[superv] - bsum[u], u));
}

void add_to_cool(int v) {
	v = find_set(v);
	is_free[v] = 1;
	while (!neibs[v].empty() && (*neibs[v].begin()).first + gb - bsum[v] <= gw) {
		int u = (*neibs[v].begin()).second;
		neibs[v].erase(neibs[v].begin());
		union_sets(v, u);
		v = find_set(v);
	}
	add_to_free(v);
}



ll solve() {
	if (n == 1) {
		return a[1];
	}
	gb = accumulate(b + 1, b + n + 1, 0LL);
	fori(i, n) {
		make_set(i + 1);
		fre.insert(mp(a[i + 1] - b[i + 1], i + 1));
	}
	while (counter > 1) {
		ll minim = (*fre.begin()).first;
		// minim + gb <= gw
		//watch(minim);
		gw = minim + gb;
		while (!fre.empty() && (*fre.begin()).first + gb == gw) {
			int v = find_set((*fre.begin()).second);
			fre.erase(fre.begin());
			add_to_cool(v);
		}
	}
	return gw;
}

signed main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	cin >> n >> m;
	for (int i = 1; i <= n; ++i) {
		cin >> a[i] >> b[i];
		mmax(a[i], b[i]);
	}
	fori(iter, m) {
		int u, v;
		cin >> u >> v;
		g[u].pb(v);
		g[v].pb(u);
	}

	cout << solve() << endl;
	return 0;

}

Measured memory_bytes: 47992