#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define pll pair<ll,ll>
#define pii pair<int,int>
#define rep(i,n) for(ll i=0;i<n;i++)
#define For(i,a,b) for(int i=a;i<b;i++)
#define sz(x) ((ll)(x).size())
#define pb push_back
#define mp make_pair
#define bit(n) (1LL<<(n))
#define F first
#define S second
#define debug(x) cerr << x << endl
#define Complex complex<double>
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
const ll INF = 1LL<<60;
const ll mod = (int)1e9 + 7;

class UnionFind {
public:
    vector <ll> par; // 各元の親を表す配列
    vector <ll> siz; // 素集合のサイズを表す配列(1 で初期化)

    // Constructor
    UnionFind(ll sz_): par(sz_), siz(sz_, 1LL) {
        for (ll i = 0; i < sz_; ++i) par[i] = i; // 初期では親は自分自身
    }
    void init(ll sz_) {
        siz.assign(sz_, 1LL);  // assign: 再代入
        par.resize(sz_);  // resize: 再確保
        for (ll i = 0; i < sz_; ++i) par[i] = i; // 初期では親は自分自身
    }

    // Member Function
    // Find
    ll root(ll x) { // 根の検索
        while (par[x] != x) {
            x = par[x] = par[par[x]]; // x の親の親を x の親とする
        }
        return x;
    }

    // Union(Unite, Merge)
    bool merge(ll x, ll y) {
        x = root(x);
        y = root(y);
        if (x == y) return false;
        // merge technique（データ構造をマージするテク．小を大にくっつける）
        if (siz[x] < siz[y]) swap(x, y);
        siz[x] += siz[y];
        par[y] = x;
        return true;
    }

    bool issame(ll x, ll y) { // 連結判定
        return root(x) == root(y);
    }

    ll size(ll x) { // 素集合のサイズ
        return siz[root(x)];
    }
};

int main() {
    int n,m;
    cin >> n >> m;
    ll a[n];
    rep(i,n)cin >> a[i];
    ll b[n];
    rep(i,n)cin >> b[i];
    UnionFind tree(n);
    rep(i,m){
        int c,d;
        cin >> c >> d;
        c--;
        d--;
        tree.merge(c,d);
    }
    rep(i,n){
        if(tree.root(i)!=i){
            a[tree.root(i)]+=a[i];
            b[tree.root(i)]+=b[i];
        }
    }
    rep(i,n){
        if(tree.root(i)==i){
            if(a[i]!=b[i]){
                cout << "No";
                return 0;
            }
        }
    }
    cout << "Yes";
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct UnionFind {
    //自身が親であれば、その集合に属する頂点数に-1を掛けたもの
    //そうでなければ親のid
    vector<int> r;
 
    UnionFind(int N) {
        r = vector<int>(N, -1);
    }
 
    int root(int x) {
        if (r[x] < 0) return x;
        return r[x] = root(r[x]);
    }
 
    bool unite(int x, int y) {
        x = root(x);
        y = root(y);
        if (x == y) return false;
        if (r[x] > r[y]) swap(x, y);
        r[x] += r[y];
        r[y] = x;
        return true;
    }
 
    int size(int x) {
        return -r[root(x)];
    }
};

int main(){
    int n, m; cin >> n >> m;
    vector<int> a(n), b(n);
    for(int i=0; i<n; ++i){cin >> a[i];}
    for(int i=0; i<n; ++i){cin >> b[i];}
    UnionFind uf(n);
    vector<vector<int>> g(n);
    for(int i=0; i<m; ++i){
        int c, d; cin >> c >> d; c--; d--;
        g[c].push_back(d); g[d].push_back(c);
        uf.unite(c, d);
    }
    vector<ll> sa(n, 0), sb(n, 0);
    for(int v=0; v<n; ++v){
        int r = uf.root(v);
        sa[r] += a[v]; sb[r] += b[v];
    }
    bool res = true;
    for(int v=0; v<n; ++v){
        int r = uf.root(v);
        if(sa[r]!=sb[r]){res = false;}
    }
    if(res) cout << "Yes" << endl;
    else cout << "No" << endl;
    return 0;
}