#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define ull unsigned long long
#define db long double
#define pb push_back
#define ppb pop_back
#define F first
#define S second
#define mp make_pair
#define all(x) (x).begin(), (x).end()

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <int> vi;
typedef vector <ll> vll;

typedef tree <pii, null_type, less <pii>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

const int N = 2e5 + 123;
int n, m, a[N], k, par[N];
pii b[N];

struct query {
	int l = 0, r = 0, ind = 0;
	bool operator < (const query & q) const {
		return l > q.l;
	}
};

void make_set(int x) {
	par[x] = x;
}

int find_set(int x) {
	if (par[x] == x) {
		return x;
	}
	return par[x] = find_set(par[x]);
}

void union_set(int x, int y) {
	x = find_set(x);
	y = find_set(y);
	if (x != y) {
		par[x] = y;
	}
}

vector <query> s;

pii edge[N];
vi g[N], ans;
int cnt, ind[N], used[N], val[N], was[N];

int fen[N], tin[N], tout[N], timer;

void upd(int x) {
	for (; x <= k + 1; x |= (x + 1)) {
		fen[x] ^= 1;
	}
}

int get(int x) {
	int res = 0;
	for (; x >= 0; x = (x & (x + 1)) - 1) {
		res ^= fen[x];
	}
	return res;
}

void go(int v) {
	was[v] = 1;
	tin[v] = ++timer;
	for (int i : g[v]) {
		int to = edge[i].S;
		go(to);
	}
	tout[v] = timer;
}

void dfs(int v) {
	was[v] = 1;
	for (int i : g[v]) {
		int ind = s[edge[i].F].ind;
		int r = s[edge[i].F].r, to = edge[i].S;
		
		int flag = (used[i] ^ get(tout[to]) ^ get(tin[to] - 1));
		if (flag) {
			ans.pb(ind);
			upd(tin[r]);
		}
		dfs(to);
		if (flag) {
			upd(tin[r]);
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false), cin.tie(NULL);
	#ifdef LOCAL
		freopen("input.txt", "r", stdin);
	#endif
	
	cin >> n >> m;
	vi comp;
	for (int i = 1; i <= n; i++) {
		cin >> b[i].F >> b[i].S;
		comp.pb(b[i].F);
	}
	sort(all(comp));
	comp.erase(unique(all(comp)), comp.end());
	k = comp.size();
	for (int i = 1; i <= n; i++) {
		int pos = lower_bound(all(comp), b[i].F) - comp.begin() + 1;
		a[pos] = b[i].S;
	}
	query q;
	for (int i = 1; i <= m; i++) {
		int l, r;
		cin >> l >> r;
		l = lower_bound(all(comp), l) - comp.begin() + 1;
		r = upper_bound(all(comp), r) - comp.begin();
		if (l > r || r < 1) {
			continue;
		}
		q.l = l, q.r = r + 1;
		q.ind = i;
		s.pb(q);
	}
	sort(all(s));
	m = s.size();
	for (int i = 1; i <= k + 1; i++) {
		make_set(i);
	}
	for (int i = 0; i < m; i++) {
		int l = s[i].l, r = s[i].r;
		int f = find_set(r);
		if (l == f) {
			continue;
		}
		union_set(f, l);
		edge[++cnt] = {i, f};
		g[l].pb(cnt);
		ind[f - 1] = cnt;
	}
	int cur = 0;
	for (int i = k; i >= 1; i--) {
		cur ^= val[i];
		if (a[i] ^ cur) {
			if (!ind[i]) {
				cout << -1;
				return 0;
			}
			used[ind[i]] = 1;
			cur ^= 1;
			val[s[edge[ind[i]].F].l - 1] ^= 1;
		}
	}
	for (int i = 1; i <= k + 1; i++) {
		if (!was[i]) {
			go(i);
		}
	}
	memset(& was, 0, sizeof(was));
	for (int i = 1; i <= k + 1; i++) {
		if (!was[i]) {
			dfs(i);
		}
	}
	sort(all(ans));
	cout << ans.size() << '\n';
	for (int i : ans) {
		cout << i << ' ';
	}
}


Measured memory_bytes: 23532