#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100100;
bool E[MAXN];
struct compare {
  bool operator()(const pair<int, int> &l, const pair<int, int> &r) const {
    if (l.first != r.first) return l.first < r.first;
    if (E[l.second] == E[r.second]) return l.second < r.second;
    return E[l.second] < E[r.second];
  }
};
int n, m;
set<pair<int, int>, compare> S;
vector<int> graf[MAXN], grafR[MAXN];
int kol[MAXN];
void load() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    int a;
    scanf("%d", &a);
    E[i] = a;
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    graf[b].push_back(a);
    ++kol[a];
    grafR[a].push_back(b);
  }
}
bool bio[MAXN];
void dfs(int x) {
  if (bio[x]) return;
  bio[x] = true;
  for (int sus : graf[x]) {
    S.erase(pair<int, int>(kol[sus], sus));
    --kol[sus];
    S.insert(pair<int, int>(kol[sus], sus));
    if (!kol[sus] && E[sus] == E[x]) dfs(sus);
  }
}
void solve() {
  for (int i = 0; i < n; i++) S.insert(pair<int, int>(kol[i], i));
  int sol = 0;
  while (!S.empty()) {
    while (!S.empty()) {
      auto cur = S.begin();
      if (E[cur->second]) break;
      if (cur->first == 0) {
        dfs(cur->second);
        S.erase(cur);
      } else
        break;
    }
    if (S.empty()) break;
    while (!S.empty()) {
      auto cur = prev(S.lower_bound(pair<int, int>(1, -1)));
      if (!E[cur->second]) break;
      if (cur->first == 0) {
        dfs(cur->second);
        S.erase(cur);
      } else
        break;
    }
    while (!S.empty()) {
      auto cur = S.begin();
      if (E[cur->second]) break;
      if (cur->first == 0) {
        dfs(cur->second);
        S.erase(cur);
      } else
        break;
    }
    ++sol;
  }
  printf("%d\n", sol);
}
int main() {
  load();
  solve();
  return 0;
}
