int n, m, q; int u[kMaxM], v[kMaxM], x[kMaxM], y[kMaxM], nxt[kMaxM], f[kMaxM][20]; std::vector<int> vec[kMaxM * 4];
structDSU { int fa[kMaxN], rnk[kMaxN]; std::vector<std::tuple<int, int, int>> stk; voidinit(int n){ stk.clear(); for (int i = 1; i <= n; ++i) fa[i] = i, rnk[i] = 0; } intfind(int x){ return x == fa[x] ? x : find(fa[x]); } voidunionn(int x, int y){ int fx = find(x), fy = find(y); if (fx == fy) return; if (rnk[fx] > rnk[fy]) std::swap(fx, fy); int det = (rnk[fx] == rnk[fy]); fa[fx] = fy, rnk[fy] += det, stk.emplace_back(fx, fy, det); } voidback(int t){ for (; stk.size() > t; stk.pop_back()) { auto [fx, fy, det] = stk.back(); fa[fx] = fx, rnk[fy] -= det; } } } dsu;
intgetid(int x, int op){ return x + op * n; }
voidupdate(int x, int l, int r, int ql, int qr, int id){ if (l > qr || r < ql) return; elseif (l >= ql && r <= qr) returnvoid(vec[x].emplace_back(id)); int mid = (l + r) >> 1; update(x << 1, l, mid, ql, qr, id), update(x << 1 | 1, mid + 1, r, ql, qr, id); }
voidsolve(int x, int l, int r){ int t = dsu.stk.size(); for (auto i : vec[x]) { dsu.unionn(getid(u[i], ::x[i]), getid(v[i], y[i])); dsu.unionn(getid(u[i], ::x[i] ^ 1), getid(v[i], y[i] ^ 1)); } if (l == r) { for (int i = std::max(nxt[l - 1] + 1, l); i <= m; ++i) { dsu.unionn(getid(u[i], ::x[i]), getid(v[i], y[i])); dsu.unionn(getid(u[i], ::x[i] ^ 1), getid(v[i], y[i] ^ 1)); if (dsu.find(getid(u[i], 0)) == dsu.find(getid(u[i], 1))) { nxt[l] = i - 1; break; } } if (!nxt[l]) nxt[l] = m; for (int i = nxt[l - 1] + 1; i <= nxt[l]; ++i) update(1, 1, m, l + 1, i, i); } else { int mid = (l + r) >> 1; solve(x << 1, l, mid), solve(x << 1 | 1, mid + 1, r); } dsu.back(t); }
intquery(int l, int r){ int ret = 0; for (int i = std::__lg(m); ~i; --i) if (f[l][i] <= r) l = f[l][i], ret += (1 << i); if (f[l][0] <= r) return-1; return ret + 1; }
voiddickdreamer(){ std::cin >> n >> m >> q; for (int i = 1; i <= m; ++i) std::cin >> u[i] >> x[i] >> v[i] >> y[i]; dsu.init(2 * n), solve(1, 1, m); for (int i = 1; i <= m + 1; ++i) f[i][0] = (i <= m ? nxt[i] + 1 : m + 1); for (int i = 1; i <= std::__lg(m); ++i) for (int j = 1; j <= m + 1; ++j) f[j][i] = f[f[j][i - 1]][i - 1]; // for (int i = 1; i <= m; ++i) std::cerr << nxt[i] << " \n"[i == m]; for (int i = 1; i <= q; ++i) { // int l, r, ans = 0; // std::cin >> l >> r; // for (int j = l; j <= r; j = nxt[j] + 1, ++ans) {} // std::cout << ans << '\n'; int l, r; std::cin >> l >> r; std::cout << query(l, r) << '\n'; } }