#include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) begin(v),end(v)
#define fi first
#define se second
template<typename A, typename B> inline bool chmax(A &a, B b) { if (a<b) { a=b; return 1; } return 0; }
template<typename A, typename B> inline bool chmin(A &a, B b) { if (a>b) { a=b; return 1; } return 0; }
using ll = long long;
using pii = pair<int, int>;
constexpr ll INF = 1ll<<30;
constexpr ll longINF = 1ll<<60;
constexpr ll MOD = 1000000007;
constexpr bool debug = 0;
//---------------------------------//

struct LowestCommonAncestor {
public:
	LowestCommonAncestor(std::size_t _size) : _size(_size) {
		g.resize(_size, std::vector<pii>());
		mxid = 0;
		isbuilt = false;
	}
	
	void add_edge(int s, int t, std::size_t id) {
		g[s].emplace_back(t, id);
		if (mxid < id) mxid = id;
	}
	
	void build() {
		logsize = 1;
		while (1<<logsize < _size) ++logsize;
		par.resize(logsize, std::vector<int>(_size, -1));
		nrg.resize(_size, std::vector<pii>());
		depth.resize(_size, -1);
		roots.clear();
		query_init();
		
		for (int i = 0; i < _size; ++i) {
			if (~depth[i]) continue;
			depth[i] = 0;
			roots.push_back(i);
			dfs(i, -1);
		}
		
		for (int i = 1; i < logsize; ++i) {
			for (int j = 0; j < _size; ++j) {
				if (~par[i - 1][j]) par[i][j] = par[i - 1][ par[i - 1][j] ];
			}
		}
		
		isbuilt = true;
	}
	
	int find(int a, int b) const {
		assert(isbuilt);
		if (depth[a] < depth[b]) std::swap(a, b);
		
		int up = depth[a] - depth[b];
		for (int i = 0; i < logsize; ++i) if (up >> i & 1) a = par[i][a];
		if (a == b) return a;
		for (int i = logsize - 1; i >= 0; --i) {
			if (par[i][a] != par[i][b]) {
				a = par[i][a];
				b = par[i][b];
			}
		}
		return par[0][a];
	}
	
	int get_root(int a) const {
		assert(isbuilt);
		int res = a;
		for (int i = logsize - 1; i >= 0; --i) {
			if (~par[i][res]) res = par[i][res];
		}
		return res;
	}
	
private:
	using pii = std::pair<int, int>;
	std::size_t _size, logsize, mxid;
	std::vector<std::vector<int> > par;
	std::vector<std::vector<pii> > g, nrg;
	std::vector<int> depth, roots;
	bool isbuilt;
		
	void dfs(int u, int p) {
		for (pii e : g[u]) {
			int v = e.fi;
			int id = e.se;
			if (~depth[v]) continue;
			depth[v] = depth[u] + 1;
			par[0][v] = u;
			nrg[v].emplace_back(u, id);
			dfs(v, u);
		}
	}
	

public:
	void add(int a, int b) {
		if (a == b) return;
		if (depth[a] < depth[b]) std::swap(a, b);
		imos[a] ^= 1;
		imos[b] ^= 1;
		// int lca = find(a, b);
		// imos[lca] ^= 1;
		// imos[a] ^= 1;
		// if (lca != b) imos[b] ^= 1;
	}
	
	void sum() {
		std::vector<int> indeg(_size, 0);
		for (int i = 0; i < _size; ++i) {
			for (pii e : nrg[i]) ++indeg[e.fi];
		}
		std::queue<int> que;
		for (int i = 0; i < _size; ++i) if (!indeg[i]) que.push(i);
		
		while (!que.empty()) {
			int u = que.front(); que.pop();
			for (pii e : nrg[u]) {
				int v = e.fi;
				int id = e.se;
				imos[v] ^= imos[u];
				sume[id] = imos[u];
				if (!--indeg[v]) que.push(v);
			}
		}
	}
	
	std::vector<int> get_sume() {
		return sume;
	}

private:
	std::vector<int> imos, sume;
	
	void query_init() {
		imos.resize(_size, 0);
		sume.resize(mxid + 1, 0);
	}
};

int N, M;
int A[112345], B[112345], C[112345]; // C: 左からi番目の爆弾のオンオフ(1-indexed)
int L[212345], R[212345];
bool ans[212345];
bool diff[112345];
vector<int> gr[112345]; // [i] 木iに属する頂点

int main() {
	cin >> N >> M;
	REP(i, N) scanf("%d %d", A + i, B + i);
	REP(i, M) scanf("%d %d", L + i, R + i);
	
	vector<int> cx;
	REP(i, N) cx.push_back(A[i]);
	sort(ALL(cx));
	cx.erase(unique(ALL(cx)), cx.end());
	
	C[0] = 0;
	REP(i, N) {
		int idx = lower_bound(ALL(cx), A[i]) - cx.begin();
		C[idx + 1] = B[i];
	}
	
	REP(i, N) diff[i] = C[i] ^ C[i + 1];
	diff[N] = 0;
	
	LowestCommonAncestor lca(N + 1);
	REP(i, M) {
		L[i] = lower_bound(ALL(cx), L[i]) - cx.begin();
		R[i] = upper_bound(ALL(cx), R[i]) - cx.begin();
		lca.add_edge(L[i], R[i], i);
		lca.add_edge(R[i], L[i], i);
	}
	lca.build();
	
	
	int proot; // Nの属する木(任意に調整可能)
	REP(i, N + 1) {
		int root = lca.get_root(i);
		if (root == -1) root = i;
		if (i == N) proot = root;
		gr[root].push_back(i);
	}
	
	REP(i, N + 1) {
		vector<int> dmb;
		for (int u : gr[i]) if (diff[u]) dmb.push_back(u);
		if (dmb.empty()) continue;
		
		if (i == proot) {
			for (int u : dmb) lca.add(u, N);
		}
		else {
			if (dmb.size() & 1) {
				puts("-1");
				return 0;
			}
			for (int j = 0; j + 1 < dmb.size(); j += 2) {
				lca.add(dmb[j], dmb[j + 1]);
			}
		}
	}
	lca.sum();
	
	vector<int> sume = lca.get_sume();
	vector<int> ans;
	
	REP(i, sume.size()) if (sume[i]) ans.push_back(i);
	
	cout << ans.size() << endl;
	REP(i, ans.size()) printf("%d%c", ans[i] + 1, i == ans.size() - 1 ? '\n' : ' ');
	return 0;
}

Measured memory_bytes: 33392