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/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
#include "ext/rope"

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

/*
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx,avx2,fma")
*/

void trace(int x)                         { cerr << x; }
void trace(long x)                        { cerr << x; }
void trace(long long x)                   { cerr << x; }
void trace(unsigned x)                    { cerr << x; }
void trace(unsigned long x)               { cerr << x; }
void trace(unsigned long long x)          { cerr << x; }
void trace(float x)                       { cerr << x; }
void trace(double x)                      { cerr << x; }
void trace(long double x)                 { cerr << x; }
void trace(char x)                        { cerr << '\'' << x << '\''; }
void trace(const char *x)                 { cerr << '\"' << x << '\"'; }
void trace(const string &x)               { cerr << '\"' << x << '\"'; }
void trace(bool x)                        { cerr << (x ? "true" : "false"); }

template <typename A, typename B>                         void trace(const pair <A, B> &x)         { cerr << '{'; trace(x.first); cerr << ','; trace(x.second); cerr << '}'; }
template <typename A, typename B, typename C>             void trace(const tuple <A, B, C> &x)     { cerr << '{'; trace(get <0> (x)); cerr << ','; trace(get <1> (x)); cerr << ','; trace(get <2> (x)); cerr << '}'; }
template <typename A, typename B, typename C, typename D> void trace(const tuple <A, B, C, D> &x)  { cerr << '{'; trace(get <0> (x)); cerr << ','; trace(get <1> (x)); cerr << ','; trace(get <2> (x)); cerr << ','; trace(get <3> (x)); cerr << '}'; }
template <typename T>                                     void trace(const T &x)                   { int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), trace(i); cerr << "}"; }
template <size_t N>                                       void trace(bitset <N> v)                 { cerr << '{'; for (size_t i = 0; i < N; i++) cerr << static_cast <char> ('0' + v[i]); cerr << '}'; }
void _print()                                                                                      { cerr << "]\n"; }
template <typename T, typename... V>                      void _print(T t, V... v)                 { trace(t); if (sizeof...(v)) cerr << ", "; _print(v...); }

#ifndef ONLINE_JUDGE
      #define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
      #define debug(x...)
#endif

template <typename T> using ordered_set                = tree <T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T1, typename T2> using ordered_map  = tree <T1, T2, less <T1>, rb_tree_tag, tree_order_statistics_node_update>;

template <class T> bool MIN(T &a, T b)                 { return a > b ? (a = b, true) : false; }
template <class T> bool MAX(T &a, T b)                 { return a < b ? (a = b, true) : false; }

template <class T> T binaryExpo(T a, T p)              { if (p == 0) { return 1LL; } if (p == 1) { return a; } if (p & 1) { return a * binaryExpo(a, p - 1); } T ret = binaryExpo(a, p / 2); return ret * ret; }
template <class T> T bigMod(T a, T p, T m)             { if (p == 0) { return 1LL % m; } if (p == 1) { return a % m; } if (p & 1) { return (a % m * bigMod(a, p - 1, m)) % m; } T ret = bigMod(a, p / 2, m) % m; return (ret * ret) % m; }
template <class T> T modInv(T a, T m)                  { return bigMod(a, m - 2, m); }

template <typename T> string num_str(T num)            { stringstream ss; ss << num; return ss.str(); }
long long str_num(string s)                            { long long num; istringstream iss(s); iss >> num; return num; }

inline long long ON(long long mask, int pos)           { return mask |= (1LL << pos); }
inline long long OFF(long long mask, int pos)          { return mask &= ~(1LL << pos); }
inline long long TOGGLE(long long mask, int pos)       { return mask ^= (1LL << pos); }
inline bool CHECK(long long mask, int pos)             { return (bool)(mask >> pos & 1LL); }

inline int ONE(long long mask)                         { return __builtin_popcountll(mask); }
inline int LZERO(long long mask)                       { return 31 - __builtin_clzll(mask); };
inline int TZERO(long long mask)                       { return __builtin_ctzll(mask); };

int dr4[] = {+1, -1, +0, +0};                       // 4 Direction - DOWN, UP, RIGHT, LEFT
int dc4[] = {+0, +0, +1, -1};
int dr8[] = {+0, +0, +1, -1, +1, +1, -1, -1};       // 8 Direction - RIGHT, LEFT, DOWN, UP, RIGHT-DOWN, LEFT-DOWN, UP-RIGHT, UP-LEFT
int dc8[] = {+1, -1, +0, +0, +1, -1, +1, -1};
int drk[] = {-1, +1, -2, -2, -1, +1, +2, +2};       // knight Moves
int dck[] = {-2, -2, -1, +1, +2, +2, +1, -1};

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define ll              long long int
#define ull             unsigned long long int
#define endl            '\n'
#define pii             pair <int, int>
#define pll             pair <ll, ll>
#define mk              make_pair
#define ff              first
#define ss              second
#define all(a)          (a).begin(), (a).end()
#define rall(a)         (a).rbegin(), (a).rend()
#define eb              emplace_back
#define pb              push_back
#define pf              push_front
#define allUpper(a)     transform(all(a), a.begin(), :: toupper)
#define allLower(a)     transform(all(a), a.begin(), :: tolower)
#define LINE            cerr << __LINE__ << " ";
#define memo(a, b)      memset(a, b, sizeof a)
#define sz(a)           (int)(a.size())
#define ook             order_of_key
#define fbo             find_by_order

#define int             long long int

const int maxn = 3e5 + 5;
const int logn = 19;
const long long MOD = 1e9 + 7;
const long long INF = 1e18;

struct Node {
      int v, e;
      Node(int v = 0, int e = 0)
            : v(v), e(e) {}
};

vector < vector <Node> > graph;
vector < vector <Node> > zgraph;
vector <pii> edges;
int value[maxn];
int n;
int m;

bool visEdge[maxn];
bool visNode[maxn];
int par[maxn];
int parEdge[maxn];

void find_cycle(int u) {
      visNode[u] = 1;
      for (Node it : zgraph[u]) {
            int v = it.v;
            int e = it.e;
            if (visEdge[e]) {
                  continue;
            }
            if (visNode[v]) {
                  vector <int> mypath;
                  vector <int> myedges;
                  myedges.push_back(e);
                  int now = u;
                  do {
                        myedges.push_back(parEdge[now]);
                        now = par[now];
                  } while (now != v);
                  reverse(all(myedges));
                  cout << sz(myedges) << endl;
                  for (int x : myedges) {
                        cout << x << endl;
                  }
                  exit(0);
            }
            else {
                  visNode[v] = 1;
                  visEdge[e] = 1;
                  par[v] = u;
                  parEdge[v] = u;
                  find_cycle(v);
            }
      }
}

int mostparrent[maxn];
int par_edge[maxn];
int par_node[maxn];
int dist[maxn];

void dijkstra() {
      priority_queue <pii> pq;
      for (int i = 1; i <= n; i++) {
            if (value[i] == 1) {
                  dist[i] = 0;
                  mostparrent[i] = i;
                  par_node[i] = i;
                  pq.emplace(0, i);
            }
            else {
                  dist[i] = INF;
                  mostparrent[i] = -1;
                  par_node[i] = -1;
                  par_edge[i] = -1;
            }
      }
      while (pq.size()) {
            int u = pq.top().second; pq.pop();
            for (Node it : graph[u]) {
                  int v = it.v;
                  int e = it.e;
                  if (MIN(dist[v], dist[u] + 1)) {
                        mostparrent[v] = mostparrent[u];
                        par_node[v] = u;
                        par_edge[v] = e;
                        pq.emplace(dist[v], v);
                  }
            }
      }
      for (int i = 1; i <= m; i++) {
            int u = edges[i].first;
            int v = edges[i].second;

            debug(i, u, mostparrent[u], v, mostparrent[v]);

            if (mostparrent[u] != mostparrent[v]) {
                  int p = mostparrent[u];
                  int q = mostparrent[v];

                  vector <int> myedges;
                  myedges.push_back(i);
                  int now = u;
                  do {
                        myedges.push_back(par_edge[now]);
                        now = par_node[now];
                  } while (now != p);
                  reverse(all(myedges));
//                  debug(myedges);

                  now = v;
                  do {
//                        debug(now, par_edge[now]);
                        myedges.push_back(par_edge[now]);
                        now = par_node[now];
                  } while (now != q);

                  cout << sz(myedges) << endl;
                  for (int x : myedges) {
                        cout << x << endl;
                  }
                  exit(0);
            }
      }
}

signed main()
{
      ios_base::sync_with_stdio(false);
      cin.tie(nullptr); cout.tie(nullptr);
      cout.precision(12);

      #ifndef ONLINE_JUDGE
          freopen("in.txt", "r", stdin);
      #endif // ONLINE_JUDGE

      cin >> n >> m;
      for (int i = 1; i <= n; i++) {
            cin >> value[i];
            if (value[i] == -1) {
                  cout << 0 << endl;
                  return 0;
            }
      }
      graph.resize(n + 1);
      zgraph.resize(n + 1);
      edges.resize(m + 1);
      for (int e = 1; e <= m; e++) {
            int u, v;
            cin >> u >> v;
            edges[e] = mk(u, v);
            if (value[u] == 1 and value[v] == 1) {
                  cout << 1 << endl;
                  cout << e << endl;
                  return 0;
            }
            if ((value[u] == 1 and value[v] == -1) or (value[u] == -1 and value[v] == 1)) {
                  cout << 1 << endl;
                  cout << e << endl;
                  return 0;
            }
            graph[u].eb(v, e);
            graph[v].eb(u, e);
            if (value[u] == 0 and value[v] == 0) {
                  zgraph[u].eb(v, e);
                  zgraph[v].eb(u, e);
            }
      }
      for (int i = 1; i <= n; i++) {
            if (value[i] == 0 and visNode[i] == 0) {
                  find_cycle(i);
            }
      }
      dijkstra();
      cout << -1 << endl;


      #ifndef ONLINE_JUDGE
            cerr << endl << "Time : " << 1.0 * clock() / CLOCKS_PER_SEC << " s." << endl;
      #endif // ONLINE_JUDGE

      return 0;
}
