/********************************************
Task: BalticOI20_Joker
Link: https://oj.uz/problem/view/BOI20_joker
********************************************/
#include <bits/stdc++.h>
#define maxn 200005
#define fi first
#define se second
using namespace std;
using ii = pair<int, int>;
constexpr int B = 100;
int n, m, q;
ii edge[maxn];
int rk[maxn];
ii par[maxn];
bool graph_is_bipartite = true;
int last[maxn];
bool nho[maxn];
vector<tuple<int, int, int, int, int> > Stack;
void rollback() {
    assert(!Stack.empty());
    auto [u, rku, v, rkv, state] = Stack.back(); Stack.pop_back();
    par[u] = {u, 0};
    par[v] = {v, 0};
    rk[u] = rku;
    rk[v] = rkv;
    graph_is_bipartite = state;
}
ii find_set(int v) {
    if (v == par[v].fi) return ii{v, 0};
    ii tr = find_set(par[v].fi);
    return ii{tr.fi, tr.se^par[v].se};
}
bool union_set(int u, int v) {
    ii tu = find_set(u), tv = find_set(v);
    int a = tu.fi, b = tv.fi;
    if (tu.fi == tv.fi) {
        if (tu.se == tv.se) {
            Stack.emplace_back(a, rk[a], b, rk[b], graph_is_bipartite);
            graph_is_bipartite = false;
            return true;
        }
        return false;
    }
    if (rk[a] > rk[b]) swap(a, b);
    Stack.emplace_back(a, rk[a], b, rk[b], graph_is_bipartite);
    par[a] = {b, tu.se^tv.se^1};
    rk[b] += rk[a] == rk[b];
    return true;
}
void solve(int l1 = 1, int l2 = m, int r1 = 1, int r2 = m) {
    int mid = (l1 + l2) / 2;
    for (int i = l1; i <= mid; i++) nho[i] = union_set(edge[i].fi, edge[i].se);
    for (int i = r2; i >= r1; i--) {
        nho[i] = union_set(edge[i].fi, edge[i].se);
        if (!graph_is_bipartite) {
            last[mid] = i+1;
            break;
        }
    }
    assert(last[mid]);
    for (int i = last[mid]-1; i <= r2; i++) if (nho[i]) rollback();
    for (int i = mid; i >= l1; i--) if (nho[i]) rollback();
    for (int i = last[mid]+1; i <= r2; i++) nho[i] = union_set(edge[i].fi, edge[i].se);
    if (l1 < mid) solve(l1, mid-1, r1, last[mid]);
    for (int i = last[mid]+1; i <= r2; i++) if (nho[i]) rollback();
    for (int i = l1; i <= mid; i++) nho[i] = union_set(edge[i].fi, edge[i].se);
    if (mid < l2) solve(mid+1, l2, last[mid], r2);
    for (int i = l1; i <= mid; i++) if (nho[i]) rollback();
}
void sub0() {
    for (int i = 1; i <= m; i++) union_set(edge[i].fi, edge[i].se);
    if (graph_is_bipartite) {
        while (q--) {
            int l, r;
            cin >> l >> r;
            cout << "NO\n";
        }
        exit(0);
    }
    while (!Stack.empty()) rollback();
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> m >> q;
    for (int i = 1; i <= m; i++) cin >> edge[i].fi >> edge[i].se;
    for (int i = 1; i <= n; i++) par[i] = {i, 0};
    sub0();
    int p = m;
    union_set(edge[m].fi, edge[m].se);
    for (int i = 1; i <= m; i++) {
        union_set(edge[i].fi, edge[i].se);
        if (!graph_is_bipartite) {
            p = i-1;
            break;
        }
    }
    for (int i = p+1; i <= m; i++) last[i] = m+1;
    while (!Stack.empty()) rollback();
    solve(1, p, 1, m);
    while (!Stack.empty()) rollback();
    last[0] = m+1;
    for (int i = m; i >= 1; i--) {
        union_set(edge[i].fi, edge[i].se);
        if (!graph_is_bipartite) {
            last[0] = i+1;
            break;
        }
    }
    while (q--) {
        int l, r;
        cin >> l >> r;
        cout << (r+1 >= last[l-1] ? "NO\n" : "YES\n");
    }
}
/*
6 8 2
1 3
1 5
1 6
2 5
2 6
3 4
3 5
5 6
4 8
4 7
*/
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |