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>
const int MAXN = 300005;
const int MAXN_LOG = 20;
struct Node;
struct Edge;
struct Chain;
struct Node {
  Edge *e;
  Chain *c;
  Node *max, *fa, *f[MAXN_LOG];
  int dfn, dep, size, d, pre;
} N[MAXN];
struct Edge {
  Node *u, *v;
  Edge *next;
  int ind;
  Edge() {}
  Edge(Node *u, Node *v, int ind) : u(u), v(v), ind(ind), next(u->e) {}
} _poolE[MAXN << 1], *_currE = _poolE;
void addEdge(int u, int v, int ind) {
  N[u].e = new (_currE++) Edge(&N[u], &N[v], ind);
  N[v].e = new (_currE++) Edge(&N[v], &N[u], ind);
}
struct Chain {
  Node *top;
  Chain(Node *top = NULL) : top(top) {}
} _poolC[MAXN], *_currC = _poolC;
void dfs1(Node *u) {
  u->size = 1;
  for (int i = 1; i < MAXN_LOG; i++) u->f[i] = u->f[i - 1]->f[i - 1];
  for (Edge *e = u->e; e; e = e->next)
    if (e->v != u->fa) {
      e->v->dep = u->dep + 1;
      e->v->fa = e->v->f[0] = u;
      e->v->pre = e->ind;
      dfs1(e->v);
      u->size += e->v->size;
      if (!u->max || u->max->size < e->v->size) u->max = e->v;
    }
}
void dfs2(Node *u, Node *fa = NULL) {
  static int dfsClock = 0;
  u->dfn = ++dfsClock;
  if (!u->fa || u->fa->max != u)
    u->c = new (_currC++) Chain(u);
  else
    u->c = u->fa->c;
  if (u->max) dfs2(u->max);
  for (Edge *e = u->e; e; e = e->next)
    if (e->v != u->fa && e->v != u->max) dfs2(e->v);
}
void split() {
  N[1].dep = 1;
  N[1].f[0] = &N[1];
  dfs1(&N[1]);
  dfs2(&N[1]);
}
Node *lca(Node *u, Node *v) {
  if (u->dep < v->dep) std::swap(u, v);
  for (int i = MAXN_LOG - 1; ~i; i--) {
    if (u->f[i]->dep >= v->dep) u = u->f[i];
  }
  for (int i = MAXN_LOG - 1; ~i; i--) {
    if (u->f[i] != v->f[i]) {
      u = u->f[i];
      v = v->f[i];
    }
  }
  return u == v ? u : u->f[0];
}
struct SegT {
  struct Node {
    int l, r;
    Node *lc, *rc;
    int cnt0, cnt1;
    bool rev;
    Node() {}
    Node(int l, int r, Node *lc = NULL, Node *rc = NULL)
        : l(l), r(r), lc(lc), rc(rc), rev(false), cnt0(r - l + 1), cnt1(0) {
      maintain();
    }
    void reverse() {
      std::swap(cnt0, cnt1);
      rev ^= 1;
    }
    void pushDown() {
      if (rev) {
        if (lc) lc->reverse();
        if (rc) rc->reverse();
        rev = false;
      }
    }
    void maintain() {
      cnt0 = (lc ? lc->cnt0 : 0) + (rc ? rc->cnt0 : 0);
      cnt1 = (lc ? lc->cnt1 : 0) + (rc ? rc->cnt1 : 0);
    }
    void update(int l, int r) {
      if (l > this->r || this->l > r) return;
      if (l <= this->l && this->r <= r) {
        reverse();
        return;
      }
      pushDown();
      lc->update(l, r), rc->update(l, r);
      maintain();
    }
    int query(int l, int r) {
      if (l > this->r || this->l > r) return INT_MIN;
      if (l <= this->l && this->r <= r) return cnt1;
      pushDown();
      return lc->query(l, r) + rc->query(l, r);
    }
  } * root, _pool[MAXN << 1], *_curr;
  SegT() : root(NULL), _curr(_pool) {}
  Node *_build(int l, int r) {
    if (l > r) return NULL;
    if (l == r) return new (_curr++) Node(l, r);
    int mid = l + (r - l) / 2;
    return new (_curr++) Node(l, r, _build(l, mid), _build(mid + 1, r));
  }
  void build(int l, int r) { root = _build(l, r); }
  void update(int l, int r) { root->update(l, r); }
  int query(int l, int r) { return root->query(l, r); }
} segT;
void update(int a, int b) {
  Node *u = &N[a], *v = &N[b];
  while (u->c != v->c) {
    if (u->c->top->dep < v->c->top->dep) std::swap(u, v);
    segT.update(u->c->top->dfn, u->dfn);
    u = u->c->top->fa;
  }
  if (u->dep > v->dep) std::swap(u, v);
  segT.update(u->dfn, v->dfn);
}
struct UnionFindSet {
  int fa[MAXN];
  void init(int n) {
    for (int i = 1; i <= n; i++) fa[i] = i;
  }
  int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
  bool merge(int x, int y) {
    if (find(x) == find(y)) return false;
    fa[find(x)] = find(y);
    return true;
  }
} ufs;
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  std::vector<int> odd, spe;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &N[i].d);
    if (N[i].d == 1) odd.push_back(i);
    if (N[i].d == -1) spe.push_back(i);
  }
  if (odd.size() % 2 && spe.empty()) return puts("-1"), 0;
  ufs.init(n);
  for (int i = 1, u, v; i <= m; i++) {
    scanf("%d %d", &u, &v);
    if (ufs.merge(u, v)) addEdge(u, v, i);
  }
  split();
  segT.build(1, n);
  for (int i = 1; i < odd.size(); i += 2) {
    update(odd[i - 1], odd[i]);
    int p = lca(&N[odd[i - 1]], &N[odd[i]]) - N;
    update(p, p);
  }
  if (odd.size() % 2) {
    update(odd[odd.size() - 1], spe[0]);
    int p = lca(&N[odd[odd.size() - 1]], &N[spe[0]]) - N;
    update(p, p);
  }
  std::vector<int> ans;
  for (int i = 2; i <= n; i++)
    if (segT.query(N[i].dfn, N[i].dfn)) ans.push_back(N[i].pre);
  std::sort(ans.begin(), ans.end());
  printf("%d\n", (int)ans.size());
  for (int i = 0; i < ans.size(); i++) printf("%d\n", ans[i]);
  return 0;
}
