#pragma GCC optimize("Ofast")
#define _USE_MATH_DEFINES
#include "bits/stdc++.h"

using namespace std;

using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i8 = int8_t;
using i32 = int32_t;
using i64 = int64_t;

constexpr char newl = '\n';
constexpr double eps = 1e-10;

#define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define F0R(i,b) FOR(i,0,b)
#define RFO(i,a,b) for (int i = ((b)-1); i >=(a); i--)
#define RF0(i,b) RFO(i,0,b)
//#define fi first
//#define se second
#define debug(x) cout << #x << ": " << x << '\n';
#define rng(a) a.begin(),a.end()
#define rrng(a) a.rbegin(),a.rend()

template<typename T1, typename T2> inline void chmin(T1& a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
template<class T> void Print(vector<T> v) {
  F0R(i, v.size()) {
    cout << v[i] << ' ';
  }
  cout << newl;
}

#if 1


// INSERT ABOVE HERE
signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  // 0    1    00 1   0
  // ↓
  // 座標の圧縮
  // ↓
  // 010010
  // ↓
  // 隣接要素の差分を取る
  // - 両端は見えない0があるものとする
  // ↓
  // 0110110
  // - 累積和をとれば上の状態に戻せる
  //
  // 区間の変更は、変更する値がたくさんあるけれど、
  // 差分配列だと、区間の長さに関わらず2か所を変更すると考えることが出来る
  //
  // 目的:差分配列を0にする
  //
  // 変更する2か所を繋げてグラフにする
  // 例
  // 0-1-0-1-1
  //   |   |
  //   0-1-1-0-1
  //
  // 木にする
  // 例
  // 0-1-0-1-1
  //   |   
  //   0-1-1-0-1
  //
  // 末端から順に「つないでいる奥側の数が1なら、そのコードを切る」をやっていくと、全て0にできる
  // （最後に1が残ったときは、不可能だったということ）
  //
  // 差分配列を実際に用意して変更していかなくても、
  // 上の木で「それ以降に繋がっている差分の合計が奇数か偶数か」で切るか判断することで、上と同じことができる
  // （奇数なら切る）

  int N, M;
  cin >> N >> M;

  struct Bomb {
    int a = 0, b = 0;
    Bomb(int a = 0, int b = 0) : a(a), b(b) {}
  };

  //vector<int> as(N), bs(N);
  vector<Bomb> bs(N);
  F0R(i, N) {
    //cin >> as[i] >> bs[i];
    cin >> bs[i].a >> bs[i].b;
  }

  auto bombComp = [](const Bomb& l, const Bomb& r) {
    return l.a < r.a;
  };

  sort(rng(bs), bombComp);

  struct Wire {
    int n = 0, link = 0;
    Wire(int n = 0, int link = 0) : n(n), link(link) {}
  };

  vector<vector<Wire>> ws(N + 1);
  vector<bool> vs(N + 1, false);  // 既に訪問済みか

  F0R(i, M) {
    int l, r;
    cin >> l >> r;
    // [l, r)
    l = lower_bound(rng(bs), Bomb(l), bombComp) - bs.begin();
    r = lower_bound(rng(bs), Bomb(r + 1), bombComp) - bs.begin();

    // l == r のとき、区間に含まれる爆弾はない
    if (l != r) {
      ws[l].emplace_back(i + 1, r);
      ws[r].emplace_back(i + 1, l);
      //cout << "#" << (i + 1) << " " << l << "->" << r << newl;
    }
  }

  // 差分配列の指定した位置を取得
  auto gd = [&](int index) -> int{
    if (index == 0) return bs[0].b;
    else if (index == N) return bs.back().b;
    else return bs[index].b ^ bs[index-1].b;
  };

  bool result = true;
  vector<int> results;
  F0R(i, N + 1) {
    auto dfs = [&](auto dfs, int v)->int {

      int score = 0;
      vs[v] = true;

      for (auto& w : ws[v]) {

        if (vs[w.link]) continue;
        int c = dfs(dfs, w.link);
        score += c;
        if ((c & 1) == 1) {
          results.push_back(w.n);
        }
      }

      //cout << "#" << v << " score=" << (score + gd(v)) << newl;
      return score + gd(v);
    };
    
    if (!vs[i] && (dfs(dfs, i) & 1) == 1) {
      result = false;
      break;
    }
  }

  if (!result) {
    cout << -1;
  }
  else {
    cout << results.size() << newl;
    sort(rng(results));
    for (auto n : results) {
      cout << n << ' ';
    }
  }

}
#endif


Measured memory_bytes: 14076