#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct DSU {
vector<int> p;
DSU() {}
DSU(int n) { init(n); }
void init(int n) {
p.resize(n + 1);
iota(p.begin(), p.end(), 0);
}
int find(int x) {
int r = x;
while (p[r] != r) r = p[r];
while (p[x] != x) {
int y = p[x];
p[x] = r;
x = y;
}
return r;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector<ll> s(n + 1);
for (int i = 1; i <= n; ++i) cin >> s[i];
vector<vector<int>> adj(n + 1);
for (int i = 0; i < m; ++i) {
int a, b;
cin >> a >> b;
adj[a].push_back(b);
adj[b].push_back(a);
}
vector<int> ord(n);
iota(ord.begin(), ord.end(), 1);
sort(ord.begin(), ord.end(), [&](int a, int b) {
if (s[a] != s[b]) return s[a] < s[b];
return a < b;
});
int maxNodes = 2 * n + 5;
DSU dsu(maxNodes);
vector<ll> sum(maxNodes, 0), mx(maxNodes, 0);
vector<int> parent(maxNodes, 0), seen(maxNodes, 0);
vector<char> active(n + 1, 0);
for (int i = 1; i <= n; ++i) {
sum[i] = s[i];
mx[i] = s[i];
}
int tot = n, timer = 0;
for (int v : ord) {
active[v] = 1;
++timer;
vector<int> roots;
for (int to : adj[v]) {
if (!active[to]) continue;
int r = dsu.find(to);
if (seen[r] != timer) {
seen[r] = timer;
roots.push_back(r);
}
}
if (roots.empty()) continue;
++tot;
dsu.p[tot] = tot;
sum[tot] = s[v];
mx[tot] = s[v];
parent[tot] = 0;
for (int r : roots) {
parent[r] = tot;
dsu.p[r] = tot;
sum[tot] += sum[r];
}
parent[v] = tot;
dsu.p[v] = tot;
sum[tot] += s[v];
}
int root = dsu.find(1);
int LOG = 1;
while ((1 << LOG) <= tot) ++LOG;
vector<vector<int>> up(LOG, vector<int>(tot + 1, 0));
for (int i = 1; i <= tot; ++i) up[0][i] = parent[i];
for (int k = 1; k < LOG; ++k) {
for (int i = 1; i <= tot; ++i) {
up[k][i] = up[k - 1][up[k - 1][i]];
}
}
auto climb = [&](int x, ll lim) {
for (int k = LOG - 1; k >= 0; --k) {
int y = up[k][x];
if (y && mx[y] <= lim) x = y;
}
return x;
};
vector<int> nxt(tot + 1);
for (int i = 1; i <= tot; ++i) {nxt[i] = climb(i, sum[i]);cerr<<nxt[i]<<' ';}
vector<char> good(tot + 1, 0);
vector<int> nodes(tot);
iota(nodes.begin(), nodes.end(), 1);
sort(nodes.begin(), nodes.end(), [&](int a, int b) {
if (sum[a] != sum[b]) return sum[a] > sum[b];
return a < b;
});
for (int x : nodes) {
if (nxt[x] == x) good[x] = (x == root);
else good[x] = good[nxt[x]];
}
string ans;
ans.reserve(n);
for (int i = 1; i <= n; ++i) ans.push_back(good[i] ? '1' : '0');
cout << ans << '\n';
return 0;
}