套路拆成 $i\text{ mod }c+j\text{ mod }c$

然后分类讨论,对于 $i+j<c$ 的,显然我们只要记录单向的 $(i,j)$ 即可,没有必要维护双向。

这样做,会导致 $j$ 的最优匹配可能不是 $i$ ,然后这些状态是可以减的,

若 $i>k$ ,则 $(i,j)$ 优于 $(j,k)$ ,则可以把 $(j,k)$ 删去。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <iostream>
#include <ctime>
#include <bitset>
#define gc getchar()
#define ll long long
#define il inline
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define rep(i, a, b) for (int i = a; i <= b; ++i)
#define repn(i, b, a) for (int i = b; i >= a; --i)
#define ite iterator
#define eps 1e-8

using namespace std;

template<class o> il void qr(o &x) {
    x = 0; char c = gc; int f = 1;
    while (c < '0' || c > '9') {if (c == '-') f = -1; c = gc;}
    while (c >= '0' && c <= '9') {x = x * 10 + (c ^ 48); c = gc;}
    x *= f;
}

template<class o> void qw(o x) {
    if(x / 10) qw(x / 10); putchar(x % 10 + 48);
}

template<class o> void pr1(o x) {
    if (x < 0) putchar('-'), x = -x;
    qw(x); putchar(' ');
}

template<class o> void pr2(o x) {
    if (x < 0) putchar('-'), x = -x;
    qw(x); puts("");
}
/* code */

multiset<int> a, b;
int siz, c;

int cal(int x, int op) {
    if (!~x) return -1;
    multiset<int>::ite it = a.upper_bound(c - 1 - x);
    if (it == a.begin()) return -1; --it;
    if (op == 1 && *it == x && a.count(x) == 1) return (it == a.begin()) ? -1 : *(--it);
    return *it;
} 

void ins(int x) {
    ++siz; 
    if (siz == 1) {a.insert(x); return ;}
    int y = cal(x, 0), z = cal(y, 1), w = cal(z, 1);
    if ((~y) && z < x) {
        if (z != -1 && y == w) b.erase(b.find(z + y));
        b.insert(x + y);
    } a.insert(x);
} 

void del(int x) {
    --siz; a.erase(a.find(x));
    if (!siz) return; 
    int y = cal(x, 0), z = cal(y, 1), w = cal(z, 1);
    if ((~y) && z < x) {
        if (z != -1 && y == w) b.insert(y + z);
        b.erase(b.find(x + y));
    } 
} 

int query() {
    multiset<int>::ite it = a.end(); --it;
    if (a.count(*it) > 1) return 2 * (*it) % c;
    int w = *it; --it; w += *it;
    return w % c;
}

void solve() {
    int n; qr(n); qr(c);
    int las = 0;
    rep (i, 1, n) {
        int op, x; qr(op), qr(x); x ^= las;
        if (op == 1) ins(x % c);
        else del(x % c);
        if (siz <= 1) puts("EE"), las = 0;
        else pr2(las = max(query(), b.empty() ? 0 : *--b.end()));
    }
}

int main() {
    //int T; qr(T); while (T--) {
        solve();
    //}
    return 0;
}