#include <bits/stdc++.h>

using namespace std;

template<typename S, typename T>
ostream& operator<<(ostream& out, const pair<S, T> p) {
    out << "(" << p.first << "," << p.second << ")";
    return out;
}

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& v) {
    for (auto a: v)
        out << a << " ";
    return out;
}

template<typename T>
ostream& operator<<(ostream& out, const set<T>& S) {
    for (auto a: S)
        cout << a << " ";
    return out;
}

template<typename T>
ostream& operator<<(ostream& out, const multiset<T>& S) {
    for (auto a: S)
        cout << a << " ";
    return out;
}

template<typename S, typename T>
ostream& operator<<(ostream& out, const map<S, T>& M) {
    for (auto m: M)
        cout << "(" << m.first << "->" << m.second << ") ";
    return out;
}

template<typename S, typename T>
pair<S, T> operator+(pair<S, T> a, pair<S, T> b) {
    return make_pair(a.first + b.first, a.second + b.second);
}

template<typename S, typename T>
pair<S, T> operator-(pair<S, T> a, pair<S, T> b) {
    return make_pair(a.first - b.first, a.second - b.second);
}

struct UndirectedGraph {
    int n;
    vector<vector<int>> E;
    vector<int> vis;
    vector<int> parent;
    vector<int> dist;
    vector<int> low;
    vector<int> sa;
    vector<vector<int>> group;
    vector<int> cut_point;
    vector<pair<int,int>> bridge;
    vector<int> topo_sort;
    const int inf = numeric_limits<int>::max();

    void init(int n) {
        this->n = n;
        E.resize(n);
        for (int i = 0; i < n; i++)
            E[i].clear();
    }

    void add_undirected_edge(int s, int t) {
        E[s].push_back(t);
        E[t].push_back(s);
    }

    void refactor_edge() {
        for (int i = 0; i < n; i++) {
            sort(E[i].begin(), E[i].end());
            E[i].erase(unique(E[i].begin(), E[i].end()), E[i].end());
        }
    }

    void dfs(const vector<vector<int>>& E, int s) {
        int island = (parent[s] == -1? 0: 1);
        vis[s] = 1;
        low[s] = dist[s];

        for (auto t: E[s]) {
            if (!vis[t]) {
                dist[t] = dist[s] + 1;
                parent[t] = s;
                dfs(E, t);
                if (low[t] > dist[s])
                    bridge.emplace_back(s, t);
                if (low[t] >= dist[s])
                    island++;
                low[s] = min(low[s], low[t]);
            } else if (vis[t] == 1 && t != parent[s]) {
                low[s] = min(low[s], dist[t]);
            }

        }
        if (island > 1)
            cut_point.push_back(s);
        sa.push_back(s);
        topo_sort.push_back(s);
        vis[s] = 2;
    }

    void source_dfs() {
        vis.assign(n, 0);
        parent.assign(n, -1);
        dist.assign(n, inf);
        low.assign(n, inf);
        group.clear();
        cut_point.clear();
        bridge.clear();
        topo_sort.clear();
        for (int i = 0; i < n; i++) {
            if (!vis[i]) {
                sa.clear();
                dist[i] = 0;
                dfs(E, i);
                reverse(sa.begin(), sa.end());
                group.push_back(sa);
            }
        }
        reverse(topo_sort.begin(), topo_sort.end());
    }

    void source_dfs(const vector<int>& A) {
        vis.assign(n, 0);
        parent.assign(n, -1);
        dist.assign(n, inf);
        low.assign(n, inf);
        group.clear();
        cut_point.clear();
        bridge.clear();
        topo_sort.clear();
        for (auto a: A) {
            if (!vis[a]) {
                sa.clear();
                dist[a] = 0;
                dfs(E, a);
                reverse(sa.begin(), sa.end());
                group.push_back(sa);
            }
        }
        reverse(topo_sort.begin(), topo_sort.end());
    }

    void source_dfs(int src) {
        vis.assign(n, 0);
        parent.assign(n, -1);
        dist.assign(n, inf);
        low.assign(n, inf);
        group.clear();
        cut_point.clear();
        bridge.clear();
        topo_sort.clear();
        if (!vis[src]) {
            sa.clear();
            dist[src] = 0;
            dfs(E, src);
            reverse(sa.begin(), sa.end());
            group.push_back(sa);
        }
        reverse(topo_sort.begin(), topo_sort.end());
    }

    void source_bfs(vector<int>& src) {
        queue<int> q;
        vis.assign(n, 0);
        dist.assign(n, inf);
        parent.assign(n, -1);
        for (auto s: src) {
            vis[s] = 1;
            dist[s] = 0;
            parent[s] = -1;
            q.push(s);
        }
        while (!q.empty()) {
            int s = q.front();
            q.pop();
            vis[s] = 2;
            for (auto t: E[s]) {
                if (!vis[t]) {
                    vis[t] = 1;
                    dist[t] = dist[s] + 1;
                    parent[t] = s;
                    q.push(t);
                }
            }
        }
    }
    void source_bfs(int src) {
        vector<int> v;
        v.push_back(src);
        source_bfs(v);
    }

    void source_dynamic_programming(vector<int>& dp) {
        dp.assign(n, 0);
        for (auto p: bridge) {
            dp[p.second]++;
        }
        for (auto s: topo_sort) {
            if (parent[s] != -1) {
                dp[s] += dp[parent[s]];
            }
        }
    }

    vector<vector<int>> query_group() {
        return group;
    }

    int query_group_size() {
        return group.size();
    }

    vector<int> query_cut_point() {
        return cut_point;
    }

    int query_cut_point_size() {
        return cut_point.size();
    }

    vector<pair<int,int>> query_bridge() {
        return bridge;
    }

    int query_bridge_size() {
        return bridge.size();
    }

    void dump_edge() {
        for (int i = 0; i < E.size(); i++)
            cout << "E[" << i << "]: " << E[i] << endl;
    }

    void dump() {
        for (int i = 0; i < n; i++) {
            if (!vis.empty())
                cout << "vis[" << i << "]: " << vis[i] << ", ";
            if (!dist.empty())
                cout << "dist[" << i << "]: " << dist[i] << ", ";
            if (!parent.empty())
                cout << "parent[" << i << "]: " << parent[i] << " , ";
            if (!low.empty())
                cout << "low[" << i << "]: " << low[i] << ", ";
            cout << endl;
        }
        cout << "group.size(): " << group.size() << endl;
        for (int i = 0; i < group.size(); i++)
            cout << "group[" << i << "]: " << group[i] << endl;
        cout << "cut_point.size(): " << cut_point.size() << endl;
        cout << "cut_point: " << cut_point << endl;
        cout << "birdge.size(): " << bridge.size() << endl;
        cout << "bridge: " << bridge << endl;
        cout << "topo_sort: " << topo_sort << endl;
    }
};

UndirectedGraph graph;

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n, m;
    vector<int> A;
    cin >> n >> m;
    A.resize(n);
    for (int i = 0; i < n; i++)
        cin >> A[i];
    graph.init(n);
    while (m--) {
        int s, t;
        cin >> s >> t;
        graph.add_undirected_edge(s - 1, t - 1);
    }
    vector<vector<int>>& E = graph.E;
    int ans = 0;
    for (int s = 0; s < n; s++) {
        bool ok = true;
        for (auto t: E[s]) {
            if (A[t] >= A[s]) {
                ok = false;
                break;
            }
        }
        ans += ok;
    }
    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 8728