3 2
1 0 1
1 2
2 3
 10 10
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1
6 7
8 3
6 4
4 2
9 2
5 10
9 8
10 7
5 1
6 2

2
1
2
 0

#include <bits/stdc++.h>
#include <ext/rope>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#define int long long
#define pb push_back
#define x first
#define ld long double
#define y second
#define mk(a,b) make_pair(a,b)
#define rr return 0
#define sqr(a) ((a)*(a))
#define all(a) a.begin(),a.end()

using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
template<class value, class cmp = less<value> >
using ordered_set = tree<value, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;
template<class value, class cmp = less_equal<value> >
using ordered_multiset = tree<value, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;
template<class key, class value, class cmp = less<key> >
using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;

/// find_by_order()
/// order_of_key()
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
inline int randll(int l = INT_MIN, int r = INT_MAX) {
    return uniform_int_distribution<int>(l, r)(rng);
}
const int N = 3e5 + 11;
bool used[N] = {};
vector<pair<int, int> > edge[3][N];
int color[N] = {}, cnt[N] = {};
vector<int> ans;
inline bool dfs (int v, bool ok = false) {
    cnt[v] += 1 - ok;
    if (color[v] == -1) return true;
    if (cnt[v] % 2 == color[v]) return true;
    for (int j = 2; j >= 0; j--) {
        for (auto &i : edge[j][v]) {
            if (used[i.y]) continue;
            if (!(cnt[i.x] % 2 == color[i.x] || color[i.x] == -1)) {
                used[i.y] = true;
                ++cnt[i.x];
                if (dfs(i.x, true)) {
                    ++cnt[v];
                    ans.pb(i.y);
                }
                else {
                    used[i.y] = false;
                    --cnt[i.x];
                }
                if (cnt[v] % 2 == color[v]) return true;
            }
        }
    }
    for (int j = 0; j <= 2; j++) {
        for (auto &i : edge[j][v]) {
            if (used[i.y]) continue;
            used[i.y] = true;
            ++cnt[i.x];
            if (dfs(i.x, true)) {
                ++cnt[v];
                ans.pb(i.y);
            }
            else {
                used[i.y] = false;
                --cnt[i.x];
            }
            if (cnt[v] % 2 == color[v]) return true;
        }
    }
    return false;
}
main()
{
    ios::sync_with_stdio(0);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m, a, b;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        cin >> color[i];
    for (int i = 0; i < m; i++) {
        cin >> a >> b;
        --a, --b;
        if (color[b] == 1)
            edge[2][a].pb(mk(b, i));
        else if (color[b] == 0)
            edge[1][a].pb(mk(b, i));
        else edge[0][a].pb(mk(b, i));
        swap(a, b);
        if (color[b] == 1)
            edge[2][a].pb(mk(b, i));
        else if (color[b] == 0)
            edge[1][a].pb(mk(b, i));
        else edge[0][a].pb(mk(b, i));
    }
    for (int i = 0; i < n; i++) {
        dfs(i, true);
    }
    bool ok = true;
    for (int i = 0; i < n; i++)
        ok &= (cnt[i] % 2 == color[i] || color[i] == -1);
    if (!ok) {
        cout << -1;
        rr;
    }
    cout << ans.size() << '\n';
    for (auto &i : ans)
        cout << i + 1 << '\n';
}
