#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
const int dy8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx8[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

struct UnionFind {
  UnionFind(int n) : data(n, -1) {}

  int root(int ver) { return data[ver] < 0 ? ver : data[ver] = root(data[ver]); }

  bool unite(int u, int v) {
    u = root(u);
    v = root(v);
    if (u == v) return false;
    if (data[u] > data[v]) swap(u, v);
    data[u] += data[v];
    data[v] = u;
    return true;
  }

  bool same(int u, int v) { return root(u) == root(v); }

  int size(int ver) { return -data[root(ver)]; }

private:
  vector<int> data;
};

int main() {
  int n, m; cin >> n >> m;
  vector<int> a(n), b(n); REP(i, n) cin >> a[i] >> b[i];
  vector<int> x(a);
  sort(ALL(x));
  vector<int> bs(n + 1, 0);
  REP(i, n) {
    a[i] = lower_bound(ALL(x), a[i]) - x.begin();
    bs[a[i]] = b[i];
  }
  vector<int> v(n + 1);
  v[0] = bs[0];
  FOR(i, 1, n + 1) v[i] = bs[i - 1] ^ bs[i];
  // REP(i, n + 1) cout << v[i];
  UnionFind uf(n + 1);
  vector<vector<pair<int, int> > > graph(n + 1);
  REP(i, m) {
    int l, r; cin >> l >> r;
    if (x.back() < l || r < x.front()) continue;
    l = lower_bound(ALL(x), l) - x.begin();
    r = prev(upper_bound(ALL(x), r)) - x.begin();
    // cout << l << ' ' << r << '\n';
    if (l <= r) {
      // cout << l << ' ' << r + 1 << '\n';
      graph[l].emplace_back(r + 1, i);
      uf.unite(l, r + 1);
    }
  }
  vector<int> ans;
  map<int, vector<int> > rt;
  REP(i, n + 1) rt[uf.root(i)].emplace_back(i);
  vector<bool> visited(n + 1, false);
  REP(i, n + 1) {
    if (visited[i]) continue;
    vector<int> &vers = rt[uf.root(i)];
    // cout << i << ": ";
    // for (int e : vers) cout << e << ' ';
    // cout << endl;
    int p = vers.size();
    vector<int> power(p);
    map<int, int> mp;
    for (int e : vers) {
      int sz = mp.size();
      mp[e] = sz;
      power[sz] = v[e];
    }
    // cout << accumulate(ALL(power), 0) << endl;
    if (accumulate(ALL(power), 0) & 1) {
      cout << "-1\n";
      return 0;
    }
    vector<vector<pair<int, int> > > g(p);
    for (int src : vers) {
      for (auto dst : graph[src]) {
        // cout << src << ' ' << dst.first << '\n';
        g[mp[src]].emplace_back(mp[dst.first], dst.second);
        g[mp[dst.first]].emplace_back(mp[src], dst.second);
      }
    }
    vector<int> deg(p, 0);
    function<int(int)> dfs = [&](int ver) {
      for (auto e : g[ver]) {
        // cout << ver << ' ' << e.first << endl;
        if (visited[vers[e.first]]) continue;
        visited[vers[e.first]] = true;
        if (dfs(e.first) == 1) {
          ++deg[ver];
          ans.emplace_back(e.second);
        }
      }
      return (power[ver] ^ deg[ver]) & 1;
    };
    visited[vers[0]] = true;
    dfs(0);
  }
  sort(ALL(ans));
  int k = ans.size();
  cout << k << '\n';
  REP(i, k) cout << ans[i] + 1 << " \n"[i + 1 == k];
  return 0;
}


Measured memory_bytes: 29048