Problem:
Xor Mart
問題
fine君は日常的に排他的論理和を使うことで有名な「XORマート」というお店にお買い物に来ました。
このお店には $N$ 個の商品があり、それぞれ $1$ から $N$ まで番号が振られています。そして、商品 $i$ の値段は $a_i$ 円であり、fine君が商品 $i$ を購入すると $b_i$ の満足度が得られます。
このとき、fine君が以下の条件を満たすように買い物をした場合に得られる満足度の最大値を求めてください。
$0$ 個以上の商品を購入する
支払う金額が $M$ 円以下となる
ただし、XORマートでは日常的に排他的論理和を使うため、 $K$ 個の異なる商品 $i_1 , i_2 , \cdots , i_K$ を購入したときに支払う金額 $A$ は、排他的論理和の演算 $\oplus$ を用いて、 $A = a_{i_1} \oplus a_{i_2} \oplus \cdots \oplus a_{i_K}$と計算されます。
一方で、 $K$ 個の異なる商品 $i_1 , i_2 , \cdots , i_K$ を購入したときに得られる満足度 $B$ は、 $B = b_{i_1} + b_{i_2} + \cdots + b_{i_K}$と計算されることに注意してください。
制約
$1 \leq N \leq 34$
$0 \leq M \leq 10^9$
$1 \leq a_i \leq 10^9$  ($1 \leq i \leq N$)
$|b_i| \leq 10^9$  ($1 \leq i \leq N$)
入力は全て整数
入力
$N$ $M$
$a_1$ $a_2$ $\cdots$ $a_N$
$b_1$ $b_2$ $\cdots$ $b_N$
出力
適切に買い物をしたときに得られる満足度の最大値を出力してください。
入力例 1
4 3
1 3 4 5
2 5 -3 100
出力例 1
104
商品を全て買うのが最適な買い物となります。
商品 $3$ を買うと満足度が下がってしまいますが、 支払う金額を排他的論理和により計算しているため、商品 $3$ を除く全ての商品を買った場合と比べて支払う金額が少なくなります。
例えば、商品 $3$ を除く全ての商品を買った場合、満足度は最大となるものの支払う金額が $7$ 円となり条件を満たしません。一方、商品 $3$ を含む全ての商品を買うことで支払う金額をちょうど $3$ 円にすることができます。
入力例 2
1 1000000000
1
-1000000000
出力例 2
0
何も買わないのが最適な買い物となります。このとき、支払う金額は $0$ 円で得られる満足度は $0$ です。
入力例 3
4 8
1 2 4 8
13 6 32 50
出力例 3
51

Submitted solutions:

code_snippet: // AOJ #3213 Xor Mart
// 2025.4.22

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#define gc() getchar_unlocked()

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

const int B = 30;
struct Node {
    int nxt[2];
    ll mx;
    Node() {
        nxt[0] = nxt[1] = -1;
        mx = LLONG_MIN;
    }
};

int main(){
    int N = Cin();
    ll M = Cin();
    vector<ll>a(N), b(N);
    for(int i=0;i<N;i++) a[i] = Cin();
    for(int i=0;i<N;i++) b[i] = Cin();

    int n1 = N/2, n2 = N - n1;
    vector<pair<ll,ll>> v1, v2;
    for(int m=0; m<(1<<n1); m++){
        ll x=0, s=0;
        for(int i=0;i<n1;i++) if(m>>i &1){
            x ^= a[i];
            s += b[i];
        }
        v1.emplace_back(x,s);
    }
    for(int m=0; m<(1<<n2); m++){
        ll x=0, s=0;
        for(int i=0;i<n2;i++) if(m>>i &1){
            x ^= a[n1+i];
            s += b[n1+i];
        }
        v2.emplace_back(x,s);
    }

    unordered_map<ll,ll> mp;
    mp.reserve(v2.size()*2);
    for(auto &p: v2){
        ll x2 = p.first, s2 = p.second;
        auto it = mp.find(x2);
        if(it == mp.end()) mp[x2] = s2;
        else it->second = max(it->second, s2);
    }

    vector<Node> trie;
    trie.reserve(mp.size() * (B+1));
    trie.emplace_back();

    for(auto &e: mp){
        ll x2 = e.first, s2 = e.second;
        int u = 0;
        trie[u].mx = max(trie[u].mx, s2);
        for(int p=B; p>=0; p--){
            int b2 = (x2>>p)&1;
            if(trie[u].nxt[b2] == -1){
                trie[u].nxt[b2] = trie.size();
                trie.emplace_back();
            }
            u = trie[u].nxt[b2];
            trie[u].mx = max(trie[u].mx, s2);
        }
    }

    function<ll(int,int,ll,bool)> dfs = [&](int u, int p, ll x1, bool tight){
        if(u<0) return LLONG_MIN;
        if(p<0 || !tight) return trie[u].mx;
        int mb = (M>>p)&1;
        int xb = (x1>>p)&1;
        ll res = LLONG_MIN;
        for(int cb=0; cb<2; cb++){
            int xb2 = xb ^ cb;
            if(xb2 > mb) continue;
            bool nt = tight && (xb2 == mb);
            int v = trie[u].nxt[cb];
            if(v==-1) continue;
            res = max(res, dfs(v, p-1, x1, nt));
        }
        return res;
    };

    ll ans = 0;
    for(auto &p: v1){
        ll x1 = p.first, s1 = p.second;
        ll best2 = dfs(0, B, x1, true);
        if(best2 != LLONG_MIN) ans = max(ans, s1 + best2);
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 45744
final_rank: 3

code_snippet: #line 1 "library-cpp/other/template.hpp"
// clang-format off
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <deque>
#include <forward_list>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using i128 = __int128_t;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
template <class T> using maxheap = priority_queue<T>;
template <class T> using minheap = priority_queue<T, vector<T>, greater<T>>;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vector<T>>;
#define OVERLOAD_REP(_1, _2, _3, name, ...) name
#define REP0(n) for (auto minato = decay_t<decltype(n)>{}; minato < (n); ++minato)
#define REP1(i, n) for (auto i = decay_t<decltype(n)>{}; (i) < (n); (i)++)
#define REP2(i, l, r) for (auto i = (l); (i) < (r); (i)++)
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define OVERLOAD_RREP(_1, _2, _3, name, ...) name
#define RREP1(i, n) for (auto i = (n) - 1; (i) >= decay_t<decltype(n)>{}; (i)--)
#define RREP2(i, l, r) for (auto i = (r) - 1; (i) >= (l); (i)--)
#define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP2, RREP1)(__VA_ARGS__)
#define ALL(x) begin(x), end(x)
template <class Container> int SZ(const Container& v) { return int(v.size()); }
template <class T> void UNIQUE(vector<T>& v) { v.erase(unique(v.begin(), v.end()), v.end()); }
template <class T> T MAX(const vector<T>& v) { return *max_element(v.begin(), v.end()); }
template <class T> T MIN(const vector<T>& v) { return *min_element(v.begin(), v.end()); }
template <class T> T SUM(const vector<T>& v) { return accumulate(v.begin(), v.end(), T(0)); }
template <class T> T ABS(T x) { return max(x, -x); }
template <class T1, class T2> bool chmax(T1& a, T2 b) { if (a < b) { a = b; return true; } return false; }
template <class T1, class T2> bool chmin(T1& a, T2 b) { if (a > b) { a = b; return true; } return false; }
int topbit(ull x) { return x == 0 ? -1 : 63 - __builtin_clzll(x); }
int botbit(ull x) { return x == 0 ? 64 : __builtin_ctzll(x); }
int popcount(ull x) { return __builtin_popcountll(x); }
int kthbit(ull x, int k) { return (x >> k) & 1; }
constexpr long long TEN(int x) { return x == 0 ? 1 : TEN(x - 1) * 10; }
template <typename S> void rearrange(const vector<S>& id) { (void)id; }
template <typename S, typename T> void rearrange_exec(const vector<S>& id, vector<T>& v) { vector<T> w(v.size()); for (size_t i = 0; i < id.size(); i++) { w[i] = v[id[i]]; } v.swap(w); }
template <typename S, typename Head, typename... Tail> void rearrange(const vector<S>& id, Head& a, Tail& ...tail) { rearrange_exec(id, a); rearrange(id, tail...); }
istream& operator>>(istream& is, __int128_t& x) {
    x = 0;
    string s;
    is >> s;
    int n = int(s.size()), it = 0;
    if (s[0] == '-') it++;
    for (; it < n; it++) x = (x * 10 + s[it] - '0');
    if (s[0] == '-') x = -x;
    return is;
}
ostream& operator<<(ostream& os, __int128_t x) {
    if (x == 0) return os << 0;
    if (x < 0) os << '-', x = -x;
    deque<int> deq;
    while (x) deq.emplace_front(x % 10), x /= 10;
    for (int e : deq) os << e;
    return os;
}
template <class T> vector<T> &operator++(vector<T>& v) { for (auto& e : v) { e++; } return v;} 
template <class T> vector<T> operator++(vector<T>& v, int) { auto res = v; for (auto& e : v) { e++; } return res; }
template <class T> vector<T> &operator--(vector<T>& v) { for (auto& e : v) { e--; } return v; }
template <class T> vector<T> operator--(vector<T>& v, int) { auto res = v; for (auto& e : v) { e--; } return res; }
template <class T1, class T2> pair<T1, T2> operator-(const pair<T1, T2>& x) { return pair<T1, T2>(-x.first, -x.second); }
template <class T1, class T2> pair<T1, T2> operator-(const pair<T1, T2>& x, const pair<T1, T2>& y) { return pair<T1, T2>(x.first - y.first, x.second - y.second); }
template <class T1, class T2> pair<T1, T2> operator+(const pair<T1, T2>& x, const pair<T1, T2>& y) { return pair<T1, T2>(x.first + y.first, x.second + y.second); }
template <class T1, class T2> pair<T1, T2> operator+=(pair<T1, T2>& l, const pair<T1, T2>& r) { return l = l + r; }
template <class T1, class T2> pair<T1, T2> operator-=(pair<T1, T2>& l, const pair<T1, T2>& r) { return l = l - r; }
constexpr char ln = '\n';
const string YESNO[2] = {"NO", "YES"};
const string YesNo[2] = {"No", "Yes"};
void YES(bool t = true) { cout << YESNO[t] << "\n"; }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = true) { cout << YesNo[t] << "\n"; }
void No(bool t = 1) { Yes(!t); }
template <class T> void drop(T x) { cout << x << "\n"; exit(0); }
#define INT(...)     \
    int __VA_ARGS__; \
    IN(__VA_ARGS__)
#define LL(...)     \
    ll __VA_ARGS__; \
    IN(__VA_ARGS__)
#define STR(...)        \
    string __VA_ARGS__; \
    IN(__VA_ARGS__)
#define CHR(...)      \
    char __VA_ARGS__; \
    IN(__VA_ARGS__)
#define LDB(...)             \
    long double __VA_ARGS__; \
    IN(__VA_ARGS__)
#define VEC(type, name, size) \
    vector<type> name(size);  \
    IN(name)
#define VEC2(type, name1, name2, size)     \
    vector<type> name1(size), name2(size); \
    for (int i = 0; i < size; i++) IN(name1[i], name2[i])
#define VEC3(type, name1, name2, name3, size)           \
    vector<type> name1(size), name2(size), name3(size); \
    for (int i = 0; i < size; i++) IN(name1[i], name2[i], name3[i])
#define VEC4(type, name1, name2, name3, name4, size)                 \
    vector<type> name1(size), name2(size), name3(size), name4(size); \
    for (int i = 0; i < size; i++) IN(name1[i], name2[i], name3[i], name4[i]);
#define VV(type, name, N, M)                       \
    vector<vector<type>> name(N, vector<type>(M)); \
    IN(name)
template <class T> void scan(T& a) { cin >> a; }
template <class T> void scan(vector<T>& a) { for (auto& i : a) scan(i); }
void IN() {}
template <class Head, class... Tail> void IN(Head& head, Tail&... tail) { scan(head); IN(tail...); }
void print() { cout << "\n"; }
template <class T> void print(const vector<T>& v) { for (auto it = v.begin(); it != v.end(); ++it) { if (it != v.begin()) { cout << " "; } cout << *it; } print(); }
template <class T, class... Args> void print(const T& x, const Args& ... args) { cout << x; if (sizeof...(Args)) cout << " "; print(args...); }
#ifdef MINATO_LOCAL
template <class T1, class T2> ostream& operator<<(ostream& os, pair<T1, T2> p) { return os << "(" << p.first << ", " << p.second << ")"; }
template <size_t N, class TUPLE> void debug_tuple(ostream& os, TUPLE _) { (void)os; (void)_; }
template <size_t N, class TUPLE, class T, class ...Args> void debug_tuple(ostream &os, TUPLE t) { os << (N == 0 ? "" : ", ") << get<N>(t); debug_tuple<N + 1, TUPLE, Args...>(os, t); }
template <class ...Args> ostream& operator<<(ostream& os, tuple<Args...> t) { os << "("; debug_tuple<0, tuple<Args...>, Args...>(os, t); return os << ")"; }
string debug_delim(int& i) { return i++ == 0 ? "" : ", "; }
#define debug_embrace(x) { int i = 0; os << "{";  { x } return os << "}"; }
template <class T> ostream& operator<<(ostream& os, vector<T> v) { debug_embrace( for (T e : v) { os << debug_delim(i) << e; } ) }
template <class T, size_t N> ostream& operator<<(ostream& os, array<T, N> a) { debug_embrace( for (T e : a) { os << debug_delim(i) << e; } ) }
template <class T, size_t N> enable_if_t<!is_same_v<char, remove_cv_t<T>>, ostream>& operator<<(ostream& os, T(&a)[N]) { debug_embrace( for (T e : a) { os << debug_delim(i) << e; } ) }
template <class Key> ostream& operator<<(ostream& os, set<Key> s) { debug_embrace( for (Key e : s) { os << debug_delim(i) << e; }) }
template <class Key, class T> ostream& operator<<(ostream& os, map<Key, T> mp) { debug_embrace( for (auto e : mp) { os << debug_delim(i) << e; }) }
template <class Key> ostream& operator<<(ostream& os, multiset<Key> s) { debug_embrace( for (Key e : s) { os << debug_delim(i) << e; }) }
template <class T> ostream& operator<<(ostream& os, queue<T> q) { debug_embrace( for (; !q.empty(); q.pop()) { os << debug_delim(i) << q.front(); } ) }
template <class T> ostream& operator<<(ostream& os, deque<T> q) { debug_embrace( for (T e : q) { os << debug_delim(i) << e; } ) }
template <class T> ostream& operator<<(ostream& os, priority_queue<T> q) { debug_embrace( for (; !q.empty(); q.pop()) { os << debug_delim(i) << q.top(); } ) }
template <class T> ostream& operator<<(ostream& os, priority_queue<T, vector<T>, greater<T>> q) { debug_embrace( for (; !q.empty(); q.pop()) { os << debug_delim(i) << q.top(); } ) }
void debug_out() { cerr << endl; }
template <class T, class... Args> void debug_out(const T& x, const Args& ... args) { cerr << " " << x; debug_out(args...); }
#define debug(...) cerr << __LINE__ << " : [" << #__VA_ARGS__ << "] =", debug_out(__VA_ARGS__)
#else
#define debug(...) (void(0))
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// clang-format on
#line 2 "library-cpp/datastructure/BinaryTrie.hpp"

#line 6 "library-cpp/datastructure/BinaryTrie.hpp"

template <class Key, class T, int B, class F> struct BinaryTrie {
    struct Node {
        int parent;
        std::array<int, 2> child;
        T value;
        Node(int parent, T value) : parent(parent), value(value) {
            child[0] = child[1] = -1;
        }
    };

    F op;
    T e;
    vector<Node> nodes;

    BinaryTrie(const F& op, T e) : op(op), e(e), nodes(1, Node(-1, e)) {
    }

    int create_node(int parent, T value) {
        int ret = int(nodes.size());
        nodes.emplace_back(parent, value);
        return ret;
    }

    void insert(Key key, T value) {
        int cur = 0;

        for (int i = B - 1; i >= 0; i--) {
            int b = kthbit(key, i);
            if (nodes[cur].child[b] == -1) {
                nodes[cur].child[b] = create_node(cur, e);
            }
            cur = nodes[cur].child[b];
        }

        nodes[cur].value = value;
        for (int i = 0; i < B; i++) {
            cur = nodes[cur].parent;
            nodes[cur].value = op(
                nodes[cur].child[0] == -1 ? e
                                          : nodes[nodes[cur].child[0]].value,
                nodes[cur].child[1] == -1 ? e
                                          : nodes[nodes[cur].child[1]].value);
        }
    }

    void erase(Key key) {
        int cur = 0;

        for (int i = B - 1; i >= 0; i--) {
            int b = kthbit(key, i);
            assert(nodes[cur].child[b] != -1);
            cur = nodes[cur].child[b];
        }

        for (int i = 0; i < B; i++) {
            cur = nodes[cur].parent;
            int b = kthbit(key, i);
            nodes[cur].child[b] = -1;
            if (nodes[cur].child[1 ^ b] != -1) {
                nodes[cur].value = op(nodes[cur].child[0] == -1
                                          ? e
                                          : nodes[nodes[cur].child[0]].value,
                                      nodes[cur].child[1] == -1
                                          ? e
                                          : nodes[nodes[cur].child[1]].value);
                break;
            }
        }
    }

    int find(Key key) const {
        int cur = 0;
        for (int i = B - 1; i >= 0; i--) {
            int b = kthbit(key, i);
            if (nodes[cur].child[b] == -1) {
                return -1;
            }
            cur = nodes[cur].child[b];
        }

        return cur;
    }

    /**
     * key からなる集合に値 x で xor したときの最小値を求める
     * 最小値は xor したあとの値
     * O(B)
     */
    Key min_element(Key x = 0) const {
        int cur = 0;

        Key ret = 0;
        for (int i = B - 1; i >= 0; i--) {
            int b = kthbit(x, i);
            if (nodes[cur].child[b] == -1) {
                ret ^= 1 << i;
                cur = nodes[cur].child[1 ^ b];
            } else {
                cur = nodes[cur].child[b];
            }
        }
        return ret;
    }

    Key max_element(Key x = 0) const {
        int cur = 0;

        Key ret = 0;
        for (int i = B - 1; i >= 0; i--) {
            int b = kthbit(x, i);
            if (nodes[cur].child[1 ^ b] == -1) {
                cur = nodes[cur].child[b];
            } else {
                ret ^= 1 << i;
                cur = nodes[cur].child[1 ^ b];
            }
        }
        return ret;
    }

    int kthbit(Key key, int k) const {
        return (key >> k) & 1;
    }
};
#line 3 "A.cpp"
void solve() {
    INT(N, M);
    VEC(int, A, N);
    VEC(ll, B, N);
    auto f = [](ll a, ll b) { return max(a, b); };
    constexpr ll INF = 1e18;
    constexpr ll e = -INF;
    constexpr int W = 30;
    BinaryTrie<int, ll, W, decltype(f)> trie(f, e);
    int H1 = (N + 1) / 2;
    int H2 = N - H1;

    ll ans = 0;
    rep(mask, 1 << H1) {
        ll cost = 0, value = 0;
        rep(i, H1) {
            if (kthbit(mask, i)) {
                cost ^= A[i];
                value += B[i];
            }
        }
        int id = trie.find(cost);
        if (id != -1 and trie.nodes[id].value < value) {
            trie.insert(cost, value);
        } else {
            trie.insert(cost, value);
        }
        if (cost <= M) chmax(ans, value);
    }
    debug(trie.nodes[0].value);
    rep(mask, 1 << H2) {
        ll cost = 0, value = 0;
        rep(i, H2) {
            if (kthbit(mask, i)) {
                cost ^= A[H1 + i];
                value += B[H1 + i];
            }
        }
        if (cost <= M) chmax(ans, value);
        int cur = 0;
        rrep(i, W) {
            int m = kthbit(M, i);
            if (m) {
                int t = kthbit(cost, i);
                if (trie.nodes[cur].child[t] != -1)
                    chmax(ans,
                          trie.nodes[trie.nodes[cur].child[t]].value + value);
                if (trie.nodes[cur].child[t ^ 1] != -1)
                    cur = trie.nodes[cur].child[t ^ 1];
                else {
                    cur = -1;
                    break;
                }
            } else {
                int t = kthbit(cost, i);
                if (trie.nodes[cur].child[t] != -1)
                    cur = trie.nodes[cur].child[t];
                else {
                    cur = -1;
                    break;
                }
            }
        }
        if (cur != -1) {
            chmax(ans, trie.nodes[cur].value + value);
        }
    }
    print(ans);
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    cerr << fixed << setprecision(7);

    int T = 1;
    // cin >> T;
    for (int test_case = 1; test_case <= T; test_case++) {
        // debug(test_case);
        solve();
    }
}
accuracy: 1
time_ms: 70
memory_kb: 54372
final_rank: 2

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <stack>
#include <tuple>
#include <deque>
#include <array>
#include <numeric>
#include <bitset>
#include <iomanip>
#include <cassert>
#include <chrono>
#include <random>
#include <limits>
#include <iterator>
#include <functional>
#include <sstream>
#include <fstream>
#include <complex>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <memory>
using namespace std;

// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
// #pragma GCC target("avx512f,avx512dq,avx512cd,avx512bw,avx512vl")

using ll = long long;
constexpr int INF = 1001001001;
// constexpr int mod = 1000000007;
constexpr int mod = 998244353;

template<class T>
inline bool chmax(T& x, T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}
template<class T>
inline bool chmin(T& x, T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

constexpr int dx[] = {1, 0, -1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, 1, 0, -1, 1, -1, 1, -1};

template<typename T, int MAX_LOG>
struct BinaryTrie {
    struct Node;
    using Node_ptr = shared_ptr<Node>;

    struct Node {
        int cnt, unique_cnt, accept;
        ll weight;
        T lazy;
        Node_ptr chl[2];
        
        Node() : cnt(0), unique_cnt(0), accept(0), weight(-(ll)1e+18), lazy(0) {
            chl[0] = chl[1] = nullptr;
        }
    };

    Node_ptr root;

    BinaryTrie() { root = make_shared<Node>(); }

    int insert(Node_ptr node, int bit_id, const T& x, const ll& w){
        propagate(node, bit_id);

        int res = 0;
        node->cnt += 1;
        chmax(node->weight, w);

        if(bit_id == -1){
            node->accept += 1;
            if(node->unique_cnt == 0){
                node->unique_cnt = 1;
                res = 1;
            }
            return res;
        }

        int i = x >> bit_id & 1;
        if(node->chl[i] == nullptr){
            node->chl[i] = make_shared<Node>();
        }
        res = insert(node->chl[i], bit_id - 1, x, w);
        node->unique_cnt += res;

        return res;
    }

    int insert(const T& x, const ll& w) { return insert(root, MAX_LOG - 1, x, w); }

    bool is_exist(Node_ptr node, int bit_id, const T& x){
        if(bit_id == -1)    return node->accept > 0;

        int i = x >> bit_id & 1;
        if(node->chl[i] == nullptr) return false;
        return is_exist(node->chl[i], bit_id - 1, x);
    }

    bool is_exist(const T& x){
        assert(x < (T(1) << MAX_LOG));
        return is_exist(root, MAX_LOG - 1, x);
    }

    T kth_element(Node_ptr node, int bit_id, int k, const T& x){
        if(bit_id == -1)    return 0;

        propagate(node, bit_id);

        int i = x >> bit_id & 1;
        if(node->chl[i] != nullptr){
            if(k <= node->chl[i]->cnt){
                return kth_element(node->chl[i], bit_id - 1, k, x);
            }
            k -= node->chl[i]->cnt;
        }
        
        return (T(1) << bit_id) + kth_element(node->chl[i ^ 1], bit_id - 1, k, x);
    }

    T kth_element(int k, const T& x = 0){
        assert(k <= root->cnt);
        return kth_element(root, MAX_LOG - 1, k, x);
    }

    T min_element(const T& x){
        assert(root->cnt > 0);
        return kth_element(root, MAX_LOG - 1, 1, x);
    }

    T max_element(const T& x){
        assert(root->cnt > 0);
        return kth_element(root, MAX_LOG - 1, root->cnt, x);
    }

    ll max_weight(Node_ptr node, int bit_id, const T& x, const T& y){
        if(bit_id == -1)    return node->weight;

        ll res = -(ll)1e+18;
        int i = y >> bit_id & 1;
        if(x >> bit_id & 1){
            if(node->chl[i] != nullptr){
                chmax(res, node->chl[i]->weight);
            }
            if(node->chl[i ^ 1] != nullptr){
                chmax(res, max_weight(node->chl[i ^ 1], bit_id - 1, x, y));
            }
        }
        else{
            if(node->chl[i] != nullptr){
                chmax(res, max_weight(node->chl[i], bit_id - 1, x, y));
            }
        }

        return res;
    }

    ll max_weight(const T& x, const T& y = 0) { return max_weight(root, MAX_LOG - 1, x, y); }

    // don't verify
    int count_less(Node_ptr node, int bit_id, const T& x, const T& y){
        if(bit_id == -1)    return 0;

        propagate(node, bit_id);

        int res = 0;
        int i = y >> bit_id & 1;
        if(x >> bit_id & 1){
            if(node->chl[i] != nullptr){
                res += node->chl[i]->cnt;
            }
            if(node->chl[i ^ 1] != nullptr){
                res += count_less(node->chl[i ^ 1], bit_id - 1, x, y);
            }
        }
        else{
            if(node->chl[i] != nullptr){
                res += count_less(node->chl[i], bit_id - 1, x, y);
            }
        }

        return res;
    }

    int count_less(const T& x, const T& y = 0) { return count_less(root, MAX_LOG - 1, x, y); }

    T lower_bound(const T& x, const T& y = 0){
        int cnt = count_less(x, y);
        if(cnt == root->cnt)    return T(1) << MAX_LOG;
        return kth_element(cnt + 1, y);
    }

    T upper_bound(const T& x, const T& y = 0) { return lower_bound(x + 1, y); }

    T get_mex(Node_ptr node, int bit_id, const T& x){
        propagate(node, bit_id);

        int i = x >> bit_id & 1;
        if(node->chl[i] == nullptr) return 0;

        if(node->chl[i]->unique_cnt != T(1) << bit_id){
            return get_mex(node->chl[i], bit_id - 1, x);
        }
        else if(node->chl[i ^ 1] == nullptr){
            return T(1) << bit_id;
        }

        return (T(1) << bit_id) + get_mex(node->chl[i ^ 1], bit_id - 1, x);
    }

    T get_mex(const T& x = 0) {
        if(root->unique_cnt == T(1) << MAX_LOG){
            return T(1) << MAX_LOG;
        }
        return get_mex(root, MAX_LOG - 1, x);
    }

    void xor_all(T x) { root->lazy ^= x; }

    void propagate(Node_ptr node, int bit_id){
        if(node->lazy == 0 || bit_id == -1) return;

        if(node->lazy >> bit_id & 1){
            swap(node->chl[0], node->chl[1]);
        }
        if(node->chl[0]){
            node->chl[0]->lazy ^= node->lazy;
        }
        if(node->chl[1]){
            node->chl[1]->lazy ^= node->lazy;
        }
        node->lazy = 0;
    }

    int erase(Node_ptr node, int bit_id, T x){
        propagate(node, bit_id);

        int res = 0;

        if(bit_id == -1){
            if(node->cnt == 0)  return -1;

            node->cnt -= 1; node->accept -= 1;
            if(node->cnt == 0){
                node->unique_cnt = 0;
                res = 1;
            }

            return res;
        }

        int i = x >> bit_id & 1;
        if(node->chl[i] == nullptr) return -1;
        node->cnt -= 1;
        res = erase(node->chl[i], bit_id - 1, x);
        node->unique_cnt -= res;
        
        return res;
    }

    int erase(const T& x) {
        int res = erase(root, MAX_LOG - 1, x);
        assert(res != -1);
        return res;
    }
};

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, M;
    cin >> N >> M;
    vector<int> a(N), b(N);
    for(int i = 0; i < N; ++i)  cin >> a[i];
    for(int i = 0; i < N; ++i)  cin >> b[i];

    BinaryTrie<int, 30> trie;
    int H = N / 2;
    for(int mask = 0; mask < (1 << H); ++mask){
        int XOR_SUM = 0;
        ll COST_SUM = 0;
        for(int i = 0; i < H; ++i){
            if(mask >> i & 1){
                XOR_SUM ^= a[i];
                COST_SUM += b[i];
            }
        }
        trie.insert(XOR_SUM, COST_SUM);
    }
    ll ans = 0;
    for(int mask = 0; mask < (1 << (N - H)); ++mask){
        int XOR_SUM = 0;
        ll COST_SUM = 0;
        for(int i = H; i < N; ++i){
            if(mask >> (i - H) & 1){
                XOR_SUM ^= a[i];
                COST_SUM += b[i];
            }
        }
        chmax(ans, COST_SUM + trie.max_weight(M, XOR_SUM));
    }
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 187720
final_rank: 10

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=2167167167167167167;
const int INF=2100000000;
const ll mod=998244353;
#define rep(i,a) for (ll i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}
template<class T> T min(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmin(ans,x);return ans;}
template<class T> T max(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmax(ans,x);return ans;}
template<class T> T sum(vector<T> &a){assert(!a.empty());T ans=a[0]-a[0];for(auto &x:a) ans+=x;return ans;}



void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t=1;
	//cin>>t;
	rep(i,t) solve();
	//while(1) solve();
}

void solve(){
	int N,M;
	cin>>N>>M;
	vector<int> A(N);
	vector<ll> B(N);
	rep(i,N) cin>>A[i];
	rep(i,N) cin>>B[i];
	int D=N/2;
	vector<pair<int,ll>> p;
	vector<pair<int,ll>> q;
	rep(i,1<<D){
		int X=0;
		ll Y=0;
		rep(j,D){
			if(i&(1<<j)) X^=A[j],Y+=B[j];
		}
		p.push_back({X,Y});
	}
	rep(i,1<<(N-D)){
		int X=0;
		ll Y=0;
		rep(j,N-D){
			if(i&(1<<j)) X^=A[j+D],Y+=B[j+D];
		}
		q.push_back({X,Y});
	}
	ll ans=0;
	auto op=[&](vector<pair<int,ll>> &L,vector<pair<int,ll>> &R)->void{
		ll S=-ILL,T=-ILL;
		for(auto x:L) chmax(S,x.second);
		for(auto x:R) chmax(T,x.second);
		chmax(ans,S+T);
		return;
	};
	auto f=[&](auto self,vector<pair<int,ll>> L,vector<pair<int,ll>> R,int dig)->void{
		if(dig==-1){
			op(L,R);
			return;
		}
		if(L.empty()||R.empty()) return;
		vector<vector<pair<int,ll>>> n_L(2),n_R(2);
		for(auto x:L){
			n_L[0==(x.first&(1<<dig))].push_back(x);
		}
		for(auto x:R){
			n_R[0==(x.first&(1<<dig))].push_back(x);
		}
		if(M&(1<<dig)){
			op(n_L[0],n_R[0]);
			op(n_L[1],n_R[1]);
			self(self,n_L[1],n_R[0],dig-1);
			self(self,n_L[0],n_R[1],dig-1);
		}else{
			self(self,n_L[1],n_R[1],dig-1);
			self(self,n_L[0],n_R[0],dig-1);
		}
		return;
	};
	f(f,p,q,29);
	cout<<ans<<"\n";
}
accuracy: 1
time_ms: 110
memory_kb: 236700
final_rank: 9

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 3213.cc: Xor Mart
 */

#include<cstdio>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_N = 34;
const int MAX_R = MAX_N / 2;
const int RBITS = 1 << MAX_R;
const int BN = 30;
const int BUFSIZE = RBITS * BN;
const long long LINF = 1LL << 62;

/* typedef */

typedef long long ll;

/* global variables */

int as[MAX_N], bs[MAX_N];
int cs[BUFSIZE][2], bpt = 0;
ll ss[BUFSIZE];

/* subroutines */

int allocbuf() {
  cs[bpt][0] = cs[bpt][1] = -1;
  ss[bpt] = -LINF;
  return bpt++;
}

void trie_add(int x, ll s) {
  int u = 0;
  ss[u] = max(ss[u], s);
  for (int i = BN - 1; i >= 0; i--) {
    int ci = (x >> i) & 1;
    if (cs[u][ci] < 0) cs[u][ci] = allocbuf();
    int v = cs[u][ci];
    ss[v] = max(ss[v], s);
    u = v;
  }
}

ll trie_max(int x, int m) {
  ll s = -LINF;
  int u = 0;
  for (int i = BN - 1; u >= 0 && i >= 0; i--) {
    int ci = (x >> i) & 1, mi = (m >> i) & 1;
    if (mi) {
      if (cs[u][ci] >= 0) s = max(s, ss[cs[u][ci]]);
      u = cs[u][ci ^ 1];
    }
    else
      u = cs[u][ci];
  }
  return s;
}

/* main */

int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  m++;
  
  for (int i = 0; i < n; i++) scanf("%d", as + i);
  for (int i = 0; i < n; i++) scanf("%d", bs + i);

  int l = n / 2, r = n - l;
  int lbits = 1 << l, rbits = 1 << r;

  allocbuf();

  for (int bits = 0; bits < rbits; bits++) {
    int x = 0;
    ll bsum = 0;
    for (int i = 0, bi = 1; i < r; i++, bi <<= 1)
      if (bits & bi) x ^= as[l + i], bsum += bs[l + i];
    trie_add(x, bsum);
  }

  ll maxs = 0;
  for (int bits = 0; bits < lbits; bits++) {
    int x = 0;
    ll bsum = 0;
    for (int i = 0, bi = 1; i < l; i++, bi <<= 1)
      if (bits & bi) x ^= as[i], bsum += bs[i];

    ll s = trie_max(x, m);
    maxs = max(maxs, bsum + s);
  }

  printf("%lld\n", maxs);

  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 35724
final_rank: 1

code_snippet: #ifdef LOGX
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
using namespace std;
//#include <atcoder/all>
//using namespace atcoder;

/*---------macro---------*/
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep2(i, s, n) for (int i = s; i < (int)(n); i++)
#define unless(x) if(!(x))
#define until(x) while(!(x))
#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()
#define mybit(i,j) (((i)>>(j))&1)

/*---------type/const---------*/
constexpr int big=1000000007;
//constexpr int big=998244353;
constexpr double EPS=1e-8; //適宜変える
typedef long long ll;
typedef unsigned long long ull;
typedef std::string::const_iterator state; //構文解析
constexpr int dx[4]={1,0,-1,0};
constexpr int dy[4]={0,1,0,-1};
constexpr char newl='\n';
struct{
    constexpr operator int(){return -int(1e9)-10;}
    constexpr operator ll(){return -ll(1e18)-10;}
}neginf;
struct{
    constexpr operator int(){return int(1e9)+10;}
    constexpr operator ll(){return ll(1e18)+10;}
    constexpr auto operator -(){return neginf;}
}inf;

/*---------debug---------*/
#ifdef LOGX
#include <template/debug.hpp>
#else
#define dbg(...) ;
#define dbgnewl ;
#define prt(x) ;
#define _prt(x) ;
#endif

/*---------function---------*/
template<typename T> T max(const std::vector<T> &a){T ans=a[0];for(T elem:a){ans=max(ans,elem);}return ans;}
template<typename T> T min(const std::vector<T> &a){T ans=a[0];for(T elem:a){ans=min(ans,elem);}return ans;}
template<typename T,typename U> bool chmin(T &a,const U b){if(a>b){a=b;return true;}return false;}
template<typename T,typename U> bool chmax(T &a,const U b){if(a<b){a=b;return true;}return false;}
bool valid(int i,int j,int h,int w){return (i>=0 && j>=0 && i<h && j<w);}
template<class T,class U>T expm(T x,U y,const ll mod=big){T res=1;while(y){if(y&1)(res*=x)%=mod;(x*=x)%=mod;y>>=1;}return res;}
template<class T,class U>T exp(T x,U y){T res=1;while(y){if(y&1)res*=x;x*=x;y>>=1;}return res;}

#include<cassert>

//特殊なtrie
//個数の代わりにmax
template<typename T,int SZ=32>
struct BinaryTrie{
    BinaryTrie():root(nullptr){}
    //xを追加する。同じ値を複数個追加することも可能。
    void insert(T x,const ll v){
        root=insert_inner(root,x,v);
    }
    //y^XOR_val<=xとなる範囲でのvalのmax
    ll lower_count(T x,T XOR_val=0){
        return lower_count_inner(root,x,XOR_val);
    }
private:
    struct Node{
        ll val;
        Node *child[2];
        Node():val(0),child{nullptr,nullptr}{}
    };
    Node *root;
    Node* insert_inner(Node *now,const T x,const ll v,const int now_height=SZ-1){
        if(!now){
            now=new Node;
            now->val=-inf;
        }
        if(now_height==-1){
            chmax(now->val,v);
            return now;
        }
        int ne=x>>now_height & 1;
        now->child[ne]=insert_inner(now->child[ne],x,v,now_height-1);
        now->val=-inf;
        rep(i,2)if(now->child[i])chmax(now->val,now->child[i]->val);
        return now;
    }
    ll lower_count_inner(Node *now,const T x,const T XOR_val,const int now_height=SZ-1){
        assert(now);
        if(now_height==-1)return now->val;
        //XOR_valのビットが0：(xのビットが1 ? 0の個数を足して1に潜る : 0に潜る)
        //そうでない：(xのビットが1 ? 1の個数を0に足して0に潜る : 1に潜る)
        const int XOR_bit=(XOR_val>>now_height)&1;
        const int x_bit=(x>>now_height)&1;
        //-> (x_bit==1 ? XOR_bitの個数を足して!XOR_bitに潜る:XOR_bitに潜る)
        ll ans=-inf;
        if(x_bit){
            if(now->child[XOR_bit]){
                chmax(ans,now->child[XOR_bit]->val);
            }
            if(now->child[!XOR_bit]){
                chmax(ans,lower_count_inner(now->child[!XOR_bit],x,XOR_val,now_height-1));
            }
        }
        else{
            if(now->child[XOR_bit]){
                chmax(ans,lower_count_inner(now->child[XOR_bit],x,XOR_val,now_height-1));
            }
        }
        return ans;
    }
};

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout << std::fixed << std::setprecision(10);
/*------------------------------------*/
    
    int n,m;
    cin >> n >> m;
    vector<int> a(n);
    vector<ll> b(n);
    rep(i,n)cin >> a[i];
    rep(i,n)cin >> b[i];
    const int frsz=n/2;
    BinaryTrie<int> bt;
    rep(i,1<<frsz){
        int A=0;
        ll B=0;
        rep(j,frsz)if(mybit(i,j))A^=a[j],B+=b[j];
        bt.insert(A,B);
    }
    reverse(ALL(a));
    reverse(ALL(b));
    rep(i,frsz)a.pop_back();
    rep(i,frsz)b.pop_back();
    ll ans=0;
    rep(i,1<<a.size()){
        int A=0;
        ll B=0;
        rep(j,a.size())if(mybit(i,j))A^=a[j],B+=b[j];
        ll T=bt.lower_count(m,A);
        if(A<=m)chmax(T,0);
        chmax(ans,B+T);
    }
    cout << ans << newl;
}
accuracy: 1
time_ms: 120
memory_kb: 64904
final_rank: 5

code_snippet: #ifdef LOGX
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
using namespace std;
//#include <atcoder/all>
//using namespace atcoder;

/*---------macro---------*/
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep2(i, s, n) for (int i = s; i < (int)(n); i++)
#define unless(x) if(!(x))
#define until(x) while(!(x))
#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()
#define mybit(i,j) (((i)>>(j))&1)

/*---------type/const---------*/
constexpr int big=1000000007;
//constexpr int big=998244353;
constexpr double EPS=1e-8; //適宜変える
typedef long long ll;
typedef unsigned long long ull;
typedef std::string::const_iterator state; //構文解析
constexpr int dx[4]={1,0,-1,0};
constexpr int dy[4]={0,1,0,-1};
constexpr char newl='\n';
struct{
    constexpr operator int(){return -int(1e9)-10;}
    constexpr operator ll(){return -ll(1e18)-10;}
}neginf;
struct{
    constexpr operator int(){return int(1e9)+10;}
    constexpr operator ll(){return ll(1e18)+10;}
    constexpr auto operator -(){return neginf;}
}inf;

/*---------debug---------*/
#ifdef LOGX
#include <template/debug.hpp>
#else
#define dbg(...) ;
#define dbgnewl ;
#define prt(x) ;
#define _prt(x) ;
#endif

/*---------function---------*/
template<typename T> T max(const std::vector<T> &a){T ans=a[0];for(T elem:a){ans=max(ans,elem);}return ans;}
template<typename T> T min(const std::vector<T> &a){T ans=a[0];for(T elem:a){ans=min(ans,elem);}return ans;}
template<typename T,typename U> bool chmin(T &a,const U b){if(a>b){a=b;return true;}return false;}
template<typename T,typename U> bool chmax(T &a,const U b){if(a<b){a=b;return true;}return false;}
bool valid(int i,int j,int h,int w){return (i>=0 && j>=0 && i<h && j<w);}
template<class T,class U>T expm(T x,U y,const ll mod=big){T res=1;while(y){if(y&1)(res*=x)%=mod;(x*=x)%=mod;y>>=1;}return res;}
template<class T,class U>T exp(T x,U y){T res=1;while(y){if(y&1)res*=x;x*=x;y>>=1;}return res;}

#include<cassert>

//特殊なtrie
//個数の代わりにmax
template<typename T,int SZ=32>
struct BinaryTrie{
    BinaryTrie():root(nullptr){}
    //xを追加する。同じ値を複数個追加することも可能。
    void insert(T x,const ll v){
        root=insert_inner(root,x,v);
    }
    //y^XOR_val<=xとなる範囲でのvalのmax
    ll lower_count(T x,T XOR_val=0){
        return lower_count_inner(root,x,XOR_val);
    }
private:
    struct Node{
        ll val;
        Node *child[2];
        Node():val(0),child{nullptr,nullptr}{}
    };
    Node *root;
    Node* insert_inner(Node *now,const T x,const ll v,const int now_height=SZ-1){
        if(!now)now=new Node;
        if(now_height==-1){
            chmax(now->val,v);
            return now;
        }
        int ne=x>>now_height & 1;
        now->child[ne]=insert_inner(now->child[ne],x,v,now_height-1);
        now->val=-inf;
        rep(i,2)if(now->child[i])chmax(now->val,now->child[i]->val);
        return now;
    }
    ll lower_count_inner(Node *now,const T x,const T XOR_val,const int now_height=SZ-1){
        assert(now);
        if(now_height==-1)return now->val;
        //XOR_valのビットが0：(xのビットが1 ? 0の個数を足して1に潜る : 0に潜る)
        //そうでない：(xのビットが1 ? 1の個数を0に足して0に潜る : 1に潜る)
        const int XOR_bit=(XOR_val>>now_height)&1;
        const int x_bit=(x>>now_height)&1;
        //-> (x_bit==1 ? XOR_bitの個数を足して!XOR_bitに潜る:XOR_bitに潜る)
        ll ans=-inf;
        if(x_bit){
            if(now->child[XOR_bit]){
                chmax(ans,now->child[XOR_bit]->val);
            }
            if(now->child[!XOR_bit]){
                chmax(ans,lower_count_inner(now->child[!XOR_bit],x,XOR_val,now_height-1));
            }
        }
        else{
            if(now->child[XOR_bit]){
                chmax(ans,lower_count_inner(now->child[XOR_bit],x,XOR_val,now_height-1));
            }
        }
        return ans;
    }
};

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout << std::fixed << std::setprecision(10);
/*------------------------------------*/
    
    int n,m;
    cin >> n >> m;
    vector<int> a(n);
    vector<ll> b(n);
    rep(i,n)cin >> a[i];
    rep(i,n)cin >> b[i];
    const int frsz=n/2;
    BinaryTrie<int> bt;
    rep(i,1<<frsz){
        int A=0;
        ll B=0;
        rep(j,frsz)if(mybit(i,j))A^=a[j],B+=b[j];
        bt.insert(A,B);
    }
    reverse(ALL(a));
    reverse(ALL(b));
    rep(i,frsz)a.pop_back();
    rep(i,frsz)b.pop_back();
    ll ans=0;
    rep(i,1<<a.size()){
        int A=0;
        ll B=0;
        rep(j,a.size())if(mybit(i,j))A^=a[j],B+=b[j];
        ll T=bt.lower_count(m,A);
        if(A<=m)chmax(T,0);
        chmax(ans,B+T);
    }
    cout << ans << newl;
}
accuracy: 0.030612244897959183
time_ms: 30
memory_kb: 18412
final_rank: 14

code_snippet: #ifdef LOGX
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
using namespace std;
//#include <atcoder/all>
//using namespace atcoder;

/*---------macro---------*/
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep2(i, s, n) for (int i = s; i < (int)(n); i++)
#define unless(x) if(!(x))
#define until(x) while(!(x))
#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()
#define mybit(i,j) (((i)>>(j))&1)

/*---------type/const---------*/
constexpr int big=1000000007;
//constexpr int big=998244353;
constexpr double EPS=1e-8; //適宜変える
typedef long long ll;
typedef unsigned long long ull;
typedef std::string::const_iterator state; //構文解析
constexpr int dx[4]={1,0,-1,0};
constexpr int dy[4]={0,1,0,-1};
constexpr char newl='\n';
struct{
    constexpr operator int(){return -int(1e9)-10;}
    constexpr operator ll(){return -ll(1e18)-10;}
}neginf;
struct{
    constexpr operator int(){return int(1e9)+10;}
    constexpr operator ll(){return ll(1e18)+10;}
    constexpr auto operator -(){return neginf;}
}inf;

/*---------debug---------*/
#ifdef LOGX
#include <template/debug.hpp>
#else
#define dbg(...) ;
#define dbgnewl ;
#define prt(x) ;
#define _prt(x) ;
#endif

/*---------function---------*/
template<typename T> T max(const std::vector<T> &a){T ans=a[0];for(T elem:a){ans=max(ans,elem);}return ans;}
template<typename T> T min(const std::vector<T> &a){T ans=a[0];for(T elem:a){ans=min(ans,elem);}return ans;}
template<typename T,typename U> bool chmin(T &a,const U b){if(a>b){a=b;return true;}return false;}
template<typename T,typename U> bool chmax(T &a,const U b){if(a<b){a=b;return true;}return false;}
bool valid(int i,int j,int h,int w){return (i>=0 && j>=0 && i<h && j<w);}
template<class T,class U>T expm(T x,U y,const ll mod=big){T res=1;while(y){if(y&1)(res*=x)%=mod;(x*=x)%=mod;y>>=1;}return res;}
template<class T,class U>T exp(T x,U y){T res=1;while(y){if(y&1)res*=x;x*=x;y>>=1;}return res;}

#include<cassert>

//特殊なtrie
//個数の代わりにmax
template<typename T,int SZ=32>
struct BinaryTrie{
    BinaryTrie():root(nullptr){}
    //xを追加する。同じ値を複数個追加することも可能。
    void insert(T x,const ll v){
        root=insert_inner(root,x,v);
    }
    //y^XOR_val<=xとなる範囲でのvalのmax
    ll lower_count(T x,T XOR_val=0){
        return lower_count_inner(root,x,XOR_val);
    }
private:
    struct Node{
        ll val;
        Node *child[2];
        Node():val(0),child{nullptr,nullptr}{}
    };
    Node *root;
    Node* insert_inner(Node *now,const T x,const ll v,const int now_height=SZ-1){
        if(!now)now=new Node;
        if(now_height==-1){
            chmax(now->val,v);
            return now;
        }
        int ne=x>>now_height & 1;
        now->child[ne]=insert_inner(now->child[ne],x,v,now_height-1);
        now->val=-inf;
        rep(i,2)if(now->child[i])chmax(now->val,now->child[i]->val);
        return now;
    }
    ll lower_count_inner(Node *now,const T x,const T XOR_val,const int now_height=SZ-1){
        assert(now);
        if(now_height==-1)return now->val;
        //XOR_valのビットが0：(xのビットが1 ? 0の個数を足して1に潜る : 0に潜る)
        //そうでない：(xのビットが1 ? 1の個数を0に足して0に潜る : 1に潜る)
        const int XOR_bit=(XOR_val>>now_height)&1;
        const int x_bit=(x>>now_height)&1;
        //-> (x_bit==1 ? XOR_bitの個数を足して!XOR_bitに潜る:XOR_bitに潜る)
        ll ans=-inf;
        if(x_bit){
            if(now->child[XOR_bit]){
                chmax(ans,now->child[XOR_bit]->val);
            }
            if(now->child[!XOR_bit]){
                chmax(ans,lower_count_inner(now->child[!XOR_bit],x,XOR_val,now_height-1));
            }
        }
        else{
            if(now->child[XOR_bit]){
                chmax(ans,lower_count_inner(now->child[XOR_bit],x,XOR_val,now_height-1));
            }
        }
        return ans;
    }
};

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout << std::fixed << std::setprecision(10);
/*------------------------------------*/
    
    int n,m;
    cin >> n >> m;
    vector<int> a(n);
    vector<ll> b(n);
    rep(i,n)cin >> a[i];
    rep(i,n)cin >> b[i];
    const int frsz=n/2;
    BinaryTrie<int> bt;
    rep(i,1<<frsz){
        int A=0;
        ll B=0;
        rep(j,frsz)if(mybit(i,j))A^=a[j],B+=b[j];
        bt.insert(A,B);
    }
    reverse(ALL(a));
    reverse(ALL(b));
    rep(i,frsz)a.pop_back();
    rep(i,frsz)b.pop_back();
    ll ans=0;
    rep(i,1<<a.size()){
        int A=0;
        ll B=0;
        rep(j,a.size())if(mybit(i,j))A^=a[j],B+=b[j];
        B+=bt.lower_count(m,A);
        chmax(ans,B);
    }
    cout << ans << newl;
}
accuracy: 0.030612244897959183
time_ms: 30
memory_kb: 18300
final_rank: 13

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
using namespace std;
 
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<int, int> pii;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
 
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
 
 
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
 
#define MOD 1000000007
 
template<class T1, class T2> inline bool chmax(T1 &a, T2 b) {if (a < b) {a = b; return true;} return false;}
template<class T1, class T2> inline bool chmin(T1 &a, T2 b) {if (a > b) {a = b; return true;} return false;}
const double EPS = 1e-8, PI = acos(-1);
const double pi = 3.141592653589793238462643383279;
//ここから編集    
typedef string::const_iterator State;
ll GCD(ll a, ll b){
  return (b==0)?a:GCD(b, a%b);
}
ll LCM(ll a, ll b){
  return a/GCD(a, b) * b;
}
template< int mod >
struct ModInt {
  int x;
 
  ModInt() : x(0) {}
 
  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
 
  ModInt &operator+=(const ModInt &p) {
    if((x += p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator-=(const ModInt &p) {
    if((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator*=(const ModInt &p) {
    x = (int) (1LL * x * p.x % mod);
    return *this;
  }
 
  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }
 
  ModInt operator-() const { return ModInt(-x); }
 
  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
 
  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
 
  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
 
  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
 
  bool operator==(const ModInt &p) const { return x == p.x; }
 
  bool operator!=(const ModInt &p) const { return x != p.x; }
 
  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while(b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }
 
  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while(n > 0) {
      if(n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }
 
  friend ostream &operator<<(ostream &os, const ModInt &p) {
    return os << p.x;
  }
 
  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt< mod >(t);
    return (is);
  }
 
  static int get_mod() { return mod; }
};
 
using modint = ModInt< 1000000007 >;
template< typename T >
struct Combination {
  vector< T > _fact, _rfact, _inv;
 
  Combination(int sz) : _fact(sz + 1), _rfact(sz + 1), _inv(sz + 1) {
    _fact[0] = _rfact[sz] = _inv[0] = 1;
    for(int i = 1; i <= sz; i++) _fact[i] = _fact[i - 1] * i;
    _rfact[sz] /= _fact[sz];
    for(int i = sz - 1; i >= 0; i--) _rfact[i] = _rfact[i + 1] * (i + 1);
    for(int i = 1; i <= sz; i++) _inv[i] = _rfact[i] * _fact[i - 1];
  }
 
  inline T fact(int k) const { return _fact[k]; }
 
  inline T rfact(int k) const { return _rfact[k]; }
 
  inline T inv(int k) const { return _inv[k]; }
 
  T P(int n, int r) const {
    if(r < 0 || n < r) return 0;
    return fact(n) * rfact(n - r);
  }
 
  T C(int p, int q) const {
    if(q < 0 || p < q) return 0;
    return fact(p) * rfact(q) * rfact(p - q);
  }
 
  T H(int n, int r) const {
    if(n < 0 || r < 0) return (0);
    return r == 0 ? 1 : C(n + r - 1, r);
  }
};
 
ll modpow(ll x, ll n, ll mod) {
  ll res = 1;
  x %= mod;
  if(x == 0) return 0;
  while(n) {
    if(n&1) res = (res * x) % mod;
    x = (x * x) % mod;
    n >>= 1;
  }
  return res;
} 
inline long long mod(long long a, long long m) {
    return (a % m + m) % m;
}
template<typename T> 
struct BIT{
  int N;
  std::vector<T> node;
  BIT(){}
  BIT(int n){
    N = n;
    node.resize(N+10);
  }
  void build(int n) {
    N = n;
    node.resize(N+10);
  }
  /* a: 1-indexed */
  void add(int a, T x){
    for(int i=a; i<(int)node.size(); i += i & -i) node[i] += x;
  }

  /* [1, a] */
  T sum(int a){
    T res = 0;
    for(int x=a; x>0; x -= x & -x) res += node[x];
    return res;
  }

  /* [l, r] */
  T rangesum(int l, int r){
    return sum(r) - sum(l-1);
  }

  /* 
    a1+a2+...+aw >= valとなるような最小のwを返す
    @verify https://codeforces.com/contest/992/problem/E
  */
  int lower_bound(T val) {
    if(val < 0) return 0;

    int res = 0;
    int n = 1; 
    while (n < N) n *= 2;

    T tv=0;
    for (int k = n; k > 0; k /= 2) {
      if(res + k < N && node[res + k] < val){
        val -= node[res+k];
        res += k;
      }
    }
    return res+1; 
  }
};

struct UnionFind{
  std::vector<int> par;
  std::vector<int> siz;

  UnionFind(int sz_): par(sz_), siz(sz_) {
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  void init(int sz_){
    par.resize(sz_);
    siz.resize(sz_);
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

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

  bool merge(int x, int y){
    x = root(x), y = root(y);
    if(x == y) return false;
    if(siz[x] < siz[y]) std::swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(int x, int y){
    return root(x) == root(y);
  }

  int size(int x){
    return siz[root(x)];
  }
};
struct RollingHash{

    using ull = unsigned long long;
    const ull mod = (1ULL << 61) - 1;
    const ull MASK30 = (1ULL << 30) - 1;
    const ull MASK31 = (1ULL << 31) - 1;

    const ull MASK61 = mod;

    ull base;
    int n;
    vector<ull> hash, pow;

    RollingHash(const string &s)
    {
        random_device rnd;
        mt19937_64 mt(rnd());
        base = 1001;
        
        n = (int)s.size();
        hash.assign(n+1, 0);
        pow.assign(n+1, 1);
        
        for(int i=0; i<n; i++){
            hash[i+1] = calc_mod(mul(hash[i], base) + s[i]);
            pow[i+1] = calc_mod(mul(pow[i], base));
        }
    }

    ull calc_mod(ull x){
        ull xu = x >> 61;
        ull xd = x & MASK61;
        ull res = xu + xd;
        if(res >= mod) res -= mod;
        return res;
    }

    ull mul(ull a, ull b){
        ull au = a >> 31;
        ull ad = a & MASK31;
        ull bu = b >> 31;
        ull bd = b & MASK31;
        ull mid = ad * bu + au * bd;
        ull midu = mid >> 30;
        ull midd = mid & MASK30;
        return calc_mod(au * bu * 2 + midu + (midd << 31) + ad * bd);
    }

    //[l,r)のハッシュ値
    inline ull get(int l, int r){
        ull res = calc_mod(hash[r] + mod*3-mul(hash[l], pow[r-l]));
        return res;
    }
    //string tのハッシュ値
    inline ull get(string t){
        ull res = 0;
        for(int i=0; i<t.size(); i++){
            res = calc_mod(mul(res, base)+t[i]);
        }
        return res;
    }
    //string s中のtの数をカウント
    inline int count(string t) {
        if(t.size() > n) return 0;
        auto hs = get(t);
        int res = 0;
        for(int i=0; i<n-t.size()+1; i++){
            if(get(i, i+t.size()) == hs) res++; 
        }
        return res;
    }

    /* 
        concat 
        @verify https://codeforces.com/problemset/problem/514/C
    */
    inline ull concat(ull h1, ull h2, int h2len){
      return calc_mod(h2 + mul(h1, pow[h2len]));
    }

    // LCPを求める S[a:] T[b:]
    inline int LCP(int a, int b){
        int len = min((int)hash.size()-a, (int)hash.size()-b);
        
        int lb = -1, ub = len;
        while(ub-lb>1){
            int mid = (lb+ub)/2;

            if(get(a, a+mid) == get(b, b+mid)) lb = mid;
            else ub = mid;
        }
        return lb;
    }
};
template<typename T, int B = 32>
struct binary_trie {

  struct trie_node{
    T val;
    T sub_val;
    int sz = 0;
    trie_node* ch[2];
    trie_node() : sz(0), val(-(1LL<<60)), ch { nullptr, nullptr } {} 
  };

  using np = trie_node*;
  np root;

  binary_trie() : root(nullptr){}

  np insert(np t, T x, T p, int b = B-1) {
    if(!t) t = new trie_node();
    t->sz += 1;
    chmax(t->val, p);
    if(b < 0) return t;
    bool f = (x >> b) & 1;
    t->ch[f] = insert(t->ch[f], x, p, b-1);
    return t;
  }
  T query(np t, T x, T M, int b = B-1) {
    if(!t) return -(1LL<<60);
    if(b < 0) return t->val;
    ll res = -(1LL<<60);
    if(x >> b & 1) {
      if(M >> b & 1) {
        if(t->ch[1])res = max(res, t->ch[1]->val);
        res = max(res, query(t->ch[0], x, M, b-1));
      }else res = max(res, query(t->ch[1], x, M, b-1));

    }else{
      if(M >> b & 1) {
        if(t->ch[0])res = max(res, t->ch[0]->val);
        res = max(res, query(t->ch[1], x, M, b-1));
      }else res = max(res, query(t->ch[0], x, M, b-1));
    }
    return res;
  }
  void insert(T x, T val) { root = insert(root, x, val); }
  T query(T x, T M) { return query(root, x, M); }
};

int main() {  
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(12);
  
  int n, m; cin >> n >> m;
  int n1 = n/2, n2 = n-n1;
  vector<int> a(n), b(n);
  REP(i,n) cin >> a[i];
  REP(i,n) cin >> b[i];
  binary_trie<ll> trie;
  REP(bit,(1<<n1)) {
    int t = 0;
    ll sum = 0;
    REP(i,n1) {
      if(bit >> i & 1) {
        t ^= a[i];
        sum += b[i];
      }
    }
    trie.insert(t, sum);
  }
  ll ans = -(1LL<<60);
  REP(bit,(1<<n2)) {
    int t = 0;
    ll sum = 0;
    REP(i,n2) {
      if(bit >> i & 1) {
        t ^= a[n1+i];
        sum += b[n1+i];
      }
    }
    ans = max(ans, sum + trie.query(t, m));
  }
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 95636
final_rank: 8

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 5000005
#define SIZE2 35
#define MAX 32

struct Node{
	void init(){

		child[0] = -1;
		child[1] = -1;
		num_nodes = 1;
		maxi = -HUGE_NUM;
	}

	ll child[2];
	ll num_nodes,maxi;
};

int root = 0;
int IND = 1;

ll A[SIZE2],B[SIZE2];
ll POW[MAX+1];
Node nodes[SIZE];

void insert(ll key,ll value){

	int now = root;

	for(int i = MAX; i >= 0; i--){

		nodes[now].maxi = max(nodes[now].maxi,value);
		nodes[now].num_nodes++;

		ll b = (key&POW[i])/POW[i];
		if(nodes[now].child[b] == -1){

			nodes[IND].init();
			nodes[now].child[b] = IND++;
		}
		now = nodes[now].child[b];
	}
	nodes[now].maxi = max(nodes[now].maxi,value);
}

ll dfs(ll key,ll LIMIT,int digit,int node){

	if(node == -1){

		return -HUGE_NUM;
	}
	if(digit == -1){

		return nodes[node].maxi;
	}

	ll a = (key&POW[digit])/POW[digit];
	ll b = (LIMIT&POW[digit])/POW[digit];

	ll ret = -HUGE_NUM;

	if(b == 0){ //LIMITのビットが0

		if(a == 0){

			ret = dfs(key,LIMIT,digit-1,nodes[node].child[0]);

		}else{ //a == 1

			ret = dfs(key,LIMIT,digit-1,nodes[node].child[1]);
		}

	}else{ //b == 1

		if(a == 0){

			int id = nodes[node].child[0];
			if(id != -1){

				ret = nodes[id].maxi;
			}

			ret = max(ret,dfs(key,LIMIT,digit-1,nodes[node].child[1]));

		}else{ //a == 1

			int id = nodes[node].child[1];
			if(id != -1){

				ret = nodes[id].maxi;
			}

			ret = max(ret,dfs(key,LIMIT,digit-1,nodes[node].child[0]));

		}

	}

	return ret;
}

int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N,LIMIT;
	scanf("%lld %lld",&N,&LIMIT);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	if(N == 1){

		ll ans = 0;
		if(A[0] <= LIMIT){

			ans = max(ans,B[0]);
		}
		printf("%lld\n",ans);

		return 0;
	}

	vector<int> L,R;

	for(int i = 0; i < N/2; i++){

		L.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		R.push_back(i);
	}

	nodes[root].init();

	for(int state = 0; state < POW[L.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < L.size(); loop++){
			if(state&POW[loop]){

				a ^= A[L[loop]];
				b += B[L[loop]];
			}
		}
		insert(a,b);
	}

	ll ans = 0;

	for(int state = 0; state < POW[R.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < R.size(); loop++){
			if(state&POW[loop]){

				a ^= A[R[loop]];
				b += B[R[loop]];
			}
		}
		ans = max(ans,b+dfs(a,LIMIT,MAX,root));
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 64704
final_rank: 7

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 5000005
#define SIZE2 35
#define MAX 32

struct Node{
	void init(){

		child[0] = -1;
		child[1] = -1;
		num_nodes = 1;
		maxi = -HUGE_NUM;
	}

	ll child[2];
	ll num_nodes,maxi;
};

int root = 0;
int IND = 1;

ll A[SIZE2],B[SIZE2];
ll POW[MAX+1];
Node nodes[SIZE];

void insert(ll key,ll value){

	int now = root;

	for(int i = MAX; i >= 0; i--){

		nodes[now].maxi = max(nodes[now].maxi,value);
		nodes[now].num_nodes++;

		ll b = (key&POW[i])/POW[i];
		if(nodes[now].child[b] == -1){

			nodes[IND].init();
			nodes[now].child[b] = IND++;
		}
		now = nodes[now].child[b];
	}
	nodes[now].maxi = max(nodes[now].maxi,value);
}

ll dfs(ll key,ll LIMIT,int digit,int node){

	if(node == -1){

		return -HUGE_NUM;
	}
	if(digit == -1){

		return nodes[node].maxi;
	}

	ll a = (key&POW[digit])/POW[digit];
	ll b = (LIMIT&POW[digit])/POW[digit];

	ll ret = -HUGE_NUM;

	if(b == 0){ //LIMITのビットが0

		if(a == 0){

			ret = dfs(key,LIMIT,digit-1,nodes[node].child[0]);

		}else{ //a == 1

			ret = dfs(key,LIMIT,digit-1,nodes[node].child[1]);
		}

	}else{ //b == 1

		if(a == 0){

			int id = nodes[node].child[0];
			if(id != -1){

				ret = nodes[id].maxi;
			}

			ret = max(ret,dfs(key,LIMIT,digit-1,nodes[node].child[1]));

		}else{ //a == 1

			int id = nodes[node].child[1];
			if(id != -1){

				ret = nodes[id].maxi;
			}

			ret = max(ret,dfs(key,LIMIT,digit-1,nodes[node].child[0]));

		}

	}

	return ret;
}

int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N,LIMIT;
	scanf("%lld %lld",&N,&LIMIT);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	if(N == 1){

		ll ans = 0;
		if(A[0] <= LIMIT){

			ans = max(ans,B[0]);
		}
		printf("%lld\n",ans);

		return 0;
	}

	vector<int> L,R;

	for(int i = 0; i < N/2; i++){

		L.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		R.push_back(i);
	}

	nodes[root].init();

	for(int state = 0; state < POW[L.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < L.size(); loop++){
			if(state&POW[loop]){

				a ^= A[L[loop]];
				b += B[L[loop]];
			}
		}
		insert(a,b);
	}

	ll ans = 0;

	for(int state = 0; state < POW[R.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < R.size(); loop++){
			if(state&POW[loop]){

				a ^= A[R[loop]];
				b += B[R[loop]];
			}
		}
		ans = max(ans,b+max(0LL,dfs(a,LIMIT,MAX,root)));
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 0.030612244897959183
time_ms: 70
memory_kb: 18168
final_rank: 18

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 5000005
#define SIZE2 35
#define MAX 18

struct Node{
	void init(){

		child[0] = -1;
		child[1] = -1;
		num_nodes = 1;
		maxi = -HUGE_NUM;
	}

	ll child[2];
	ll num_nodes,maxi;
};

int root = 0;
int IND = 1;

ll A[SIZE2],B[SIZE2];
ll POW[MAX+1];
Node nodes[SIZE];

void insert(ll key,ll value){

	int now = root;

	for(int i = MAX; i >= 0; i--){

		nodes[now].maxi = max(nodes[now].maxi,value);
		nodes[now].num_nodes++;

		ll b = (key&POW[i])/POW[i];
		if(nodes[now].child[b] == -1){

			nodes[IND].init();
			nodes[now].child[b] = IND++;
		}
		now = nodes[now].child[b];
	}
	nodes[now].maxi = max(nodes[now].maxi,value);
}

ll dfs(ll key,ll LIMIT,int digit,int node){

	if(node == -1){

		return -HUGE_NUM;
	}
	if(digit == -1){

		return nodes[node].maxi;
	}

	ll a = (key&POW[digit])/POW[digit];
	ll b = (LIMIT&POW[digit])/POW[digit];

	ll ret = -HUGE_NUM;

	if(b == 0){

		if(a == 0){

			ret = dfs(key,LIMIT,digit-1,nodes[node].child[0]);

		}else{ //a == 1

			ret = dfs(key,LIMIT,digit-1,nodes[node].child[1]);
		}

	}else{ //b == 1

		if(a == 0){

			int id = nodes[node].child[0];
			if(id != -1){

				ret = nodes[id].maxi;
			}

			ret = max(ret,dfs(key,LIMIT,digit-1,nodes[node].child[1]));

		}else{ //a == 1

			int id = nodes[node].child[1];
			if(id != -1){

				ret = nodes[id].maxi;
			}

			ret = max(ret,dfs(key,LIMIT,digit-1,nodes[node].child[0]));

		}

	}

	return ret;
}

int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N,LIMIT;
	scanf("%lld %lld",&N,&LIMIT);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	if(N == 1){

		ll ans = 0;
		if(A[0] <= LIMIT){

			ans = max(ans,B[0]);
		}
		printf("%lld\n",ans);

		return 0;
	}

	vector<int> L,R;

	for(int i = 0; i < N/2; i++){

		L.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		R.push_back(i);
	}

	nodes[root].init();

	for(int state = 0; state < POW[L.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < L.size(); loop++){
			if(state&POW[loop]){

				a ^= A[L[loop]];
				b += B[L[loop]];
			}
		}
		insert(a,b);
	}

	ll ans = 0;

	for(int state = 0; state < POW[R.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < R.size(); loop++){
			if(state&POW[loop]){

				a ^= A[R[loop]];
				b += B[R[loop]];
			}
		}
		ans = max(ans,b+dfs(a,LIMIT,MAX,root));
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 0.01020408163265306
time_ms: 10
memory_kb: 5296
final_rank: 19

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 5000005
#define MAX 32

struct Node{
	void init(){

		child[0] = -1;
		child[1] = -1;
		num_nodes = 1;
		maxi = -HUGE_NUM;
	}

	int child[2];
	ll num_nodes,maxi;
};


int root = 0,IND = 1;
ll POW[MAX+1];
ll A[35],B[35];
Node nodes[SIZE];

void insert(ll key,ll value){

	int now = root;

	for(int i = MAX; i >= 0; i--){

		nodes[now].maxi = max(nodes[now].maxi,value);
		ll b = (key&POW[i])/POW[i];

		if(nodes[now].child[b] == -1){

			nodes[IND].init();
			nodes[now].child[b] = IND++;
		}

		now = nodes[now].child[b];
	}
	nodes[now].maxi = max(nodes[now].maxi,value);
}

//keyとxorしてLIMIT以下になる中での、最大値
ll query(ll key,int node,ll LIMIT,int digit){

	if(node == -1){

		return -HUGE_NUM;
	}
	if(digit == -1){

		return nodes[node].maxi; //葉にたどり着いた
	}

	ll ret = -HUGE_NUM;

	ll a = (LIMIT&POW[digit])/POW[digit];
	ll b = (key&POW[digit])/POW[digit];

	if(a == 0){

		if(b == 0){

			ret = max(ret,query(key,nodes[node].child[0],LIMIT,digit-1)); //0方向をたどる

		}else{ //b == 1

			ret = max(ret,query(key,nodes[node].child[1],LIMIT,digit-1)); //1方向をたどる
		}

	}else{ //a == 1

		if(b == 0){

			int id = nodes[node].child[0];
			if(id != -1){

				ret = max(ret,nodes[id].maxi);
			}

			ret = max(ret,query(key,nodes[node].child[1],LIMIT,digit-1));

		}else{ //b == 1

			int id = nodes[node].child[1];
			if(id != -1){

				ret = max(ret,nodes[id].maxi);
			}

			ret = max(ret,query(key,nodes[node].child[0],LIMIT,digit-1));
		}
	}

	return ret;
}


int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N,M;
	scanf("%lld %lld",&N,&M);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	if(N == 1){

		ll ans = 0;

		if(A[0] <= M){

			ans = max(ans,B[0]);
		}
		printf("%lld\n",ans);
		return 0;
	}

	vector<int> L,R;

	for(int i = 0; i < N/2; i++){

		L.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		R.push_back(i);
	}

	nodes[root].init();

	for(int state = 0; state < POW[L.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < L.size(); loop++){
			if(state&POW[loop]){

				a ^= A[L[loop]];
				b += B[L[loop]];
			}
		}

		insert(a,b);
	}

	ll ans = 0;

	for(int state = 0; state < POW[R.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < R.size(); loop++){
			if(state&POW[loop]){

				a ^= A[R[loop]];
				b += B[R[loop]];
			}
		}
		ll tmp = b+query(a,root,M,MAX);
		ans = max(ans,tmp);
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 49348
final_rank: 4

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 5000005
#define MAX 32

struct Node{
	void init(){

		child[0] = -1;
		child[1] = -1;
		num_nodes = 1;
		maxi = -HUGE_NUM;
	}

	int child[2];
	ll num_nodes,maxi;
};


int root = 0,IND = 1;
ll POW[MAX+1];
ll A[35],B[35];
Node nodes[SIZE];

void insert(ll key,ll value){

	int now = root;

	for(int i = MAX; i >= 0; i--){

		nodes[now].maxi = max(nodes[now].maxi,value);
		ll b = (key&POW[i])/POW[i];

		if(nodes[now].child[b] == -1){

			nodes[IND].init();
			nodes[now].child[b] = IND++;
		}

		now = nodes[now].child[b];
	}
	nodes[now].maxi = value;
}

//keyとxorしてLIMIT以下になる中での、最大値
ll query(ll key,int node,ll LIMIT,int digit){

	if(node == -1){

		return -HUGE_NUM;
	}
	if(digit == -1){

		return nodes[node].maxi; //葉にたどり着いた
	}

	ll ret = 0;

	ll a = (LIMIT&POW[digit])/POW[digit];
	ll b = (key&POW[digit])/POW[digit];

	if(a == 0){

		if(b == 0){

			ret = max(ret,query(key,nodes[node].child[0],LIMIT,digit-1)); //0方向をたどる

		}else{ //b == 1

			ret = max(ret,query(key,nodes[node].child[1],LIMIT,digit-1)); //1方向をたどる
		}

	}else{ //a == 1

		if(b == 0){

			int id = nodes[node].child[0];
			if(id != -1){

				ret = max(ret,nodes[id].maxi);
			}

			ret = max(ret,query(key,nodes[node].child[1],LIMIT,digit-1));

		}else{ //b == 1

			int id = nodes[node].child[1];
			if(id != -1){

				ret = max(ret,nodes[id].maxi);
			}

			ret = max(ret,query(key,nodes[node].child[0],LIMIT,digit-1));
		}
	}

	return ret;
}


int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N,M;
	scanf("%lld %lld",&N,&M);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	if(N == 1){

		ll ans = 0;

		if(A[0] <= M){

			ans = max(ans,B[0]);
		}
		printf("%lld\n",ans);
		return 0;
	}

	vector<int> L,R;

	for(int i = 0; i < N/2; i++){

		L.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		R.push_back(i);
	}

	nodes[root].init();

	for(int state = 0; state < POW[L.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < L.size(); loop++){
			if(state&POW[loop]){

				a ^= A[L[loop]];
				b += B[L[loop]];
			}
		}

		insert(a,b);
	}

	ll ans = 0;

	for(int state = 0; state < POW[R.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < R.size(); loop++){
			if(state&POW[loop]){

				a ^= A[R[loop]];
				b += B[R[loop]];
			}
		}
		ll tmp = b+query(a,root,M,MAX);
		ans = max(ans,tmp);
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 0.030612244897959183
time_ms: 70
memory_kb: 14400
final_rank: 17

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 5000005
#define MAX 32

struct Node{
	void init(){

		child[0] = -1;
		child[1] = -1;
		num_nodes = 1;
		maxi = -HUGE_NUM;
	}

	int child[2];
	ll num_nodes,maxi;
};


int root = 0,IND = 1;
ll POW[MAX+1];
ll A[35],B[35];
Node nodes[SIZE];

void insert(ll key,ll value){

	int now = root;

	for(int i = MAX; i >= 0; i--){

		nodes[now].maxi = max(nodes[now].maxi,value);
		ll b = (key&POW[i])/POW[i];

		if(nodes[now].child[b] == -1){

			nodes[IND].init();
			nodes[now].child[b] = IND++;
		}

		now = nodes[now].child[b];
	}
	nodes[now].maxi = value;
}

//keyとxorしてLIMIT以下になる中での、最大値
ll query(ll key,int node,ll LIMIT,int digit){

	if(node == -1){

		return -HUGE_NUM;
	}
	if(digit == -1){

		return nodes[node].maxi; //葉にたどり着いた
	}

	ll ret = -HUGE_NUM;

	ll a = (LIMIT&POW[digit])/POW[digit];
	ll b = (key&POW[digit])/POW[digit];

	if(a == 0){

		if(b == 0){

			ret = query(key,nodes[node].child[0],LIMIT,digit-1); //0方向をたどる

		}else{ //b == 1

			ret = query(key,nodes[node].child[1],LIMIT,digit-1); //1方向をたどる
		}

	}else{ //a == 1

		if(b == 0){

			int id = nodes[node].child[0];
			if(id != -1){

				ret = max(ret,nodes[id].maxi);
			}

			ret = max(ret,query(key,nodes[node].child[1],LIMIT,digit-1));

		}else{ //b == 1

			int id = nodes[node].child[1];
			if(id != -1){

				ret = max(ret,nodes[id].maxi);
			}

			ret = max(ret,query(key,nodes[node].child[0],LIMIT,digit-1));
		}
	}

	return ret;
}


int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N,M;
	scanf("%lld %lld",&N,&M);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	if(N == 1){

		ll ans = 0;

		if(A[0] <= M){

			ans = max(ans,B[0]);
		}
		printf("%lld\n",ans);
		return 0;
	}

	vector<int> L,R;

	for(int i = 0; i < N/2; i++){

		L.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		R.push_back(i);
	}

	nodes[root].init();

	for(int state = 0; state < POW[L.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < L.size(); loop++){
			if(state&POW[loop]){

				a ^= A[L[loop]];
				b += B[L[loop]];
			}
		}

		insert(a,b);
	}

	ll ans = 0;

	for(int state = 0; state < POW[R.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < R.size(); loop++){
			if(state&POW[loop]){

				a ^= A[R[loop]];
				b += B[R[loop]];
			}
		}
		ll tmp = b+max(0LL,query(a,root,M,MAX));
		ans = max(ans,tmp);
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 0.030612244897959183
time_ms: 60
memory_kb: 14516
final_rank: 16

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 5000005
#define MAX 32

struct Node{
	void init(){

		child[0] = -1;
		child[1] = -1;
		num_nodes = 1;
		maxi = -HUGE_NUM;
	}

	int child[2];
	ll num_nodes,maxi;
};


int root = 0,IND = 1;
ll POW[MAX+1];
ll A[35],B[35];
Node nodes[SIZE];

void insert(ll key,ll value){

	int now = root;

	for(int i = MAX; i >= 0; i--){

		nodes[now].maxi = max(nodes[now].maxi,value);
		ll b = (key&POW[i])/POW[i];

		if(nodes[now].child[b] == -1){

			nodes[IND].init();
			nodes[now].child[b] = IND++;
		}

		now = nodes[now].child[b];
	}
	nodes[now].maxi = value;
}

//keyとxorしてLIMIT以下になる中での、最大値
ll query(ll key,int node,ll LIMIT,int digit){

	if(node == -1){

		return -HUGE_NUM;
	}
	if(digit == -1){

		return nodes[node].maxi; //葉にたどり着いた
	}

	ll ret = -HUGE_NUM;

	ll a = (LIMIT&POW[digit])/POW[digit];
	ll b = (key&POW[digit])/POW[digit];

	if(a == 0){

		if(b == 0){

			ret = query(key,nodes[node].child[0],LIMIT,digit-1); //0方向をたどる

		}else{ //b == 1

			ret = query(key,nodes[node].child[1],LIMIT,digit-1); //1方向をたどる
		}

	}else{ //a == 1

		if(b == 0){

			int id = nodes[node].child[0];
			if(id != -1){

				ret = max(ret,nodes[id].maxi);
			}

			ret = max(ret,query(key,nodes[node].child[1],LIMIT,digit-1));

		}else{ //b == 1

			int id = nodes[node].child[1];
			if(id != -1){

				ret = max(ret,nodes[id].maxi);
			}

			ret = max(ret,query(key,nodes[node].child[0],LIMIT,digit-1));
		}
	}

	return ret;
}


int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N,M;
	scanf("%lld %lld",&N,&M);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	if(N == 1){

		ll ans = 0;

		if(A[0] <= M){

			ans = max(ans,B[0]);
		}
		printf("%lld\n",ans);
		return 0;
	}

	vector<int> L,R;

	for(int i = 0; i < N/2; i++){

		L.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		R.push_back(i);
	}

	nodes[root].init();

	for(int state = 0; state < POW[L.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < L.size(); loop++){
			if(state&POW[loop]){

				a ^= A[L[loop]];
				b += B[L[loop]];
			}
		}

		insert(a,b);
	}

	ll ans = 0;

	for(int state = 0; state < POW[R.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < R.size(); loop++){
			if(state&POW[loop]){

				a ^= A[R[loop]];
				b += B[R[loop]];
			}
		}
		ll tmp = b+query(a,root,M,MAX);
		ans = max(ans,tmp);
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 0.04081632653061224
time_ms: 60
memory_kb: 14356
final_rank: 12

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define MAX 32



struct Node{
	void init(){
		child[0] = -1;
		child[1] = -1;
		num_nodes = 1;
		maxi = -HUGE_NUM;
	}
	int child[2];
	ll num_nodes,maxi;
};

int root = 0;
int IND = 1;
ll POW[MAX+1],A[35],B[35];
Node nodes[5000005];

void insert(ll key,ll value){

	int now = root;

	//トライ木を辿る
	for(int digit = MAX; digit >= 0; digit--){

		nodes[now].maxi = max(nodes[now].maxi,value);
		nodes[now].num_nodes++; //部分木サイズ

		ll bit = (key&POW[digit])/POW[digit];

		if(nodes[now].child[bit] == -1){

			nodes[IND].init();
			nodes[now].child[bit] = IND++;
		}

		now = nodes[now].child[bit];
	}

	nodes[now].maxi = max(nodes[now].maxi,value);
}

//X^key <= LIMITとなる中で、最大の価値を求める
ll query(int node_id,int digit,ll key,ll LIMIT){

	/*★node_idはdigit+1の高さにある★*/
	if(node_id == -1){

		return -HUGE_NUM;
	}
	if(digit == -1){

		return nodes[node_id].maxi;
	}

	ll bit_k = (key&POW[digit])/POW[digit];
	ll bit_L = (LIMIT&POW[digit])/POW[digit];

	ll ret = -HUGE_NUM;

	if(bit_k == 0){

		if(bit_L == 0){ //0方向の枝を辿る

			ret = query(nodes[node_id].child[0],digit-1,key,LIMIT);

		}else{ //bit_L == 1

			//0方向は全てOK
			int id = nodes[node_id].child[0];
			if(id !=-1){
				ret = nodes[id].maxi;
			}

			//1方向をたどる
			ret = max(ret,query(nodes[node_id].child[1],digit-1,key,LIMIT));
		}

	}else{ //bit_k == 1

		if(bit_L == 0){

			//1方向の枝をたどる
			ret = query(nodes[node_id].child[1],digit-1,key,LIMIT);

		}else{ //bit_L == 1

			//1方向は全てOK
			int id = nodes[node_id].child[1];
			if(id != -1){
				ret = nodes[id].maxi;
			}

			//0方向をたどる
			ret = max(ret,query(nodes[node_id].child[0],digit-1,key,LIMIT));
		}
	}

	return ret;
}

int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N,M;
	scanf("%lld %lld",&N,&M);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	if(N == 1){

		ll ans = 0;
		if(A[0] <= M){

			ans = max(ans,B[0]);
		}
		printf("%lld\n",ans);

		return 0;
	}

	vector<int> L,R;

	for(int i = 0; i < N/2; i++){

		L.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		R.push_back(i);
	}

	nodes[root].init();

	for(ll state = 0; state < POW[L.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < L.size(); loop++){
			if(state&POW[loop]){

				a ^= A[L[loop]];
				b += B[L[loop]];
			}
		}

		insert(a,b);
	}

	ll ans = 0;

	for(int state = 0; state < POW[R.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < R.size(); loop++){
			if(state&POW[loop]){

				a ^= A[R[loop]];
				b += B[R[loop]];
			}
		}

		ll add =query(root,MAX,a,M);
		ans = max(ans,b+add);
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 49348
final_rank: 6

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define MAX 32



struct Node{
	void init(){
		child[0] = -1;
		child[1] = -1;
		num_nodes = 1;
		maxi = -HUGE_NUM;
	}
	int child[2];
	ll num_nodes,maxi;
};

int root = 0;
int IND = 1;
ll POW[MAX+1],A[35],B[35];
Node nodes[1000005];

void insert(ll key,ll value){

	int now = root;

	//トライ木を辿る
	for(int digit = MAX; digit >= 0; digit--){

		nodes[now].maxi = max(nodes[now].maxi,value);
		nodes[now].num_nodes++; //部分木サイズ

		ll bit = (key&POW[digit])/POW[digit];

		if(nodes[now].child[bit] == -1){

			nodes[IND].init();
			nodes[now].child[bit] = IND++;
		}

		now = nodes[now].child[bit];
	}

	nodes[now].maxi = max(nodes[now].maxi,value);
}

//X^key <= LIMITとなる中で、最大の価値を求める
ll query(int node_id,int digit,ll key,ll LIMIT){

	/*★node_idはdigit+1の高さにある★*/
	if(node_id == -1){

		return -HUGE_NUM;
	}
	if(digit == -1){

		return nodes[node_id].maxi;
	}

	ll bit_k = (key&POW[digit])/POW[digit];
	ll bit_L = (LIMIT&POW[digit])/POW[digit];

	ll ret = -HUGE_NUM;

	if(bit_k == 0){

		if(bit_L == 0){ //0方向の枝を辿る

			ret = query(nodes[node_id].child[0],digit-1,key,LIMIT);

		}else{ //bit_L == 1

			//0方向は全てOK
			int id = nodes[node_id].child[0];
			if(id !=-1){
				ret = nodes[id].maxi;
			}

			//1方向をたどる
			ret = max(ret,query(nodes[node_id].child[1],digit-1,key,LIMIT));
		}

	}else{ //bit_k == 1

		if(bit_L == 0){

			//1方向の枝をたどる
			ret = query(nodes[node_id].child[1],digit-1,key,LIMIT);

		}else{ //bit_L == 1

			//1方向は全てOK
			int id = nodes[node_id].child[1];
			if(id != -1){
				ret = nodes[id].maxi;
			}

			//0方向をたどる
			ret = max(ret,query(nodes[node_id].child[0],digit-1,key,LIMIT));
		}
	}

	return ret;
}

int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N,M;
	scanf("%lld %lld",&N,&M);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	if(N == 1){

		ll ans = 0;
		if(A[0] <= M){

			ans = max(ans,B[0]);
		}
		printf("%lld\n",ans);

		return 0;
	}

	vector<int> L,R;

	for(int i = 0; i < N/2; i++){

		L.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		R.push_back(i);
	}

	nodes[root].init();

	for(ll state = 0; state < POW[L.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < L.size(); loop++){
			if(state&POW[loop]){

				a ^= A[L[loop]];
				b += B[L[loop]];
			}
		}

		insert(a,b);
	}

	ll ans = 0;

	for(int state = 0; state < POW[R.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < R.size(); loop++){
			if(state&POW[loop]){

				a ^= A[R[loop]];
				b += B[R[loop]];
			}
		}

		ll add =query(root,MAX,a,M);
		ans = max(ans,b+add);
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 0.3673469387755102
time_ms: 110
memory_kb: 22580
final_rank: 11

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define MAX 32



struct Node{
	void init(){
		child[0] = -1;
		child[1] = -1;
		num_nodes = 1;
		maxi = -HUGE_NUM;
	}
	int child[2];
	ll num_nodes,maxi;
};

int root = 0;
int IND = 1;
ll POW[MAX+1],A[35],B[35];
Node nodes[100005];

void insert(ll key,ll value){

	int now = root;

	//トライ木を辿る
	for(int digit = MAX; digit >= 0; digit--){

		nodes[now].maxi = max(nodes[now].maxi,value);
		nodes[now].num_nodes++; //部分木サイズ

		ll bit = (key&POW[digit])/POW[digit];

		if(nodes[now].child[bit] == -1){

			nodes[IND].init();
			nodes[now].child[bit] = IND++;
		}

		now = nodes[now].child[bit];
	}

	nodes[now].maxi = max(nodes[now].maxi,value);
}

//X^key <= LIMITとなる中で、最大の価値を求める
ll query(int node_id,int digit,ll key,ll LIMIT){

	/*★node_idはdigit+1の高さにある★*/
	if(node_id == -1){

		return -HUGE_NUM;
	}
	if(digit == -1){

		return nodes[node_id].maxi;
	}

	ll bit_k = (key&POW[digit])/POW[digit];
	ll bit_L = (LIMIT&POW[digit])/POW[digit];

	ll ret = -HUGE_NUM;

	if(bit_k == 0){

		if(bit_L == 0){ //0方向の枝を辿る

			ret = query(nodes[node_id].child[0],digit-1,key,LIMIT);

		}else{ //bit_L == 1

			//0方向は全てOK
			int id = nodes[node_id].child[0];
			if(id !=-1){
				ret = nodes[id].maxi;
			}

			//1方向をたどる
			ret = max(ret,query(nodes[node_id].child[1],digit-1,key,LIMIT));
		}

	}else{ //bit_k == 1

		if(bit_L == 0){

			//1方向の枝をたどる
			ret = query(nodes[node_id].child[1],digit-1,key,LIMIT);

		}else{ //bit_L == 1

			//1方向は全てOK
			int id = nodes[node_id].child[1];
			if(id != -1){
				ret = nodes[id].maxi;
			}

			//0方向をたどる
			ret = max(ret,query(nodes[node_id].child[0],digit-1,key,LIMIT));
		}
	}

	return ret;
}

int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N,M;
	scanf("%lld %lld",&N,&M);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	if(N == 1){

		ll ans = 0;
		if(A[0] <= M){

			ans = max(ans,B[0]);
		}
		printf("%lld\n",ans);

		return 0;
	}

	vector<int> L,R;

	for(int i = 0; i < N/2; i++){

		L.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		R.push_back(i);
	}

	nodes[root].init();

	for(ll state = 0; state < POW[L.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < L.size(); loop++){
			if(state&POW[loop]){

				a ^= A[L[loop]];
				b += B[L[loop]];
			}
		}

		insert(a,b);
	}

	ll ans = 0;

	for(int state = 0; state < POW[R.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < R.size(); loop++){
			if(state&POW[loop]){

				a ^= A[R[loop]];
				b += B[R[loop]];
			}
		}

		ll add =query(root,MAX,a,M);
		ans = max(ans,b+add);
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 0.030612244897959183
time_ms: 50
memory_kb: 4676
final_rank: 15

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define MAX 32



struct Node{
	void init(){
		child[0] = -1;
		child[1] = -1;
		num_nodes = 1;
		maxi = -HUGE_NUM;
	}
	int child[2];
	ll num_nodes,maxi;
};

int root = 0;
int IND = 1;
ll POW[MAX+1],A[35],B[35];
Node nodes[50*35];

void insert(ll key,ll value){

	int now = root;

	//トライ木を辿る
	for(int digit = MAX; digit >= 0; digit--){

		nodes[now].maxi = max(nodes[now].maxi,value);
		nodes[now].num_nodes++; //部分木サイズ

		ll bit = (key&POW[digit])/POW[digit];

		if(nodes[now].child[bit] == -1){

			nodes[IND].init();
			nodes[now].child[bit] = IND++;
		}

		now = nodes[now].child[bit];
	}

	nodes[now].maxi = max(nodes[now].maxi,value);
}

//X^key <= LIMITとなる中で、最大の価値を求める
ll query(int node_id,int digit,ll key,ll LIMIT){

	/*★node_idはdigit+1の高さにある★*/
	if(node_id == -1){

		return -HUGE_NUM;
	}
	if(digit == -1){

		return nodes[node_id].maxi;
	}

	ll bit_k = (key&POW[digit])/POW[digit];
	ll bit_L = (LIMIT&POW[digit])/POW[digit];

	ll ret = -HUGE_NUM;

	if(bit_k == 0){

		if(bit_L == 0){ //0方向の枝を辿る

			ret = query(nodes[node_id].child[0],digit-1,key,LIMIT);

		}else{ //bit_L == 1

			//0方向は全てOK
			int id = nodes[node_id].child[0];
			if(id !=-1){
				ret = nodes[id].maxi;
			}

			//1方向をたどる
			ret = max(ret,query(nodes[node_id].child[1],digit-1,key,LIMIT));
		}

	}else{ //bit_k == 1

		if(bit_L == 0){

			//1方向の枝をたどる
			ret = query(nodes[node_id].child[1],digit-1,key,LIMIT);

		}else{ //bit_L == 1

			//1方向は全てOK
			int id = nodes[node_id].child[1];
			if(id != -1){
				ret = nodes[id].maxi;
			}

			//0方向をたどる
			ret = max(ret,query(nodes[node_id].child[0],digit-1,key,LIMIT));
		}
	}

	return ret;
}

int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	ll N,M;
	scanf("%lld %lld",&N,&M);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	if(N == 1){

		ll ans = 0;
		if(A[0] <= M){

			ans = max(ans,B[0]);
		}
		printf("%lld\n",ans);

		return 0;
	}

	vector<int> L,R;

	for(int i = 0; i < N/2; i++){

		L.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		R.push_back(i);
	}

	nodes[root].init();

	for(ll state = 0; state < POW[L.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < L.size(); loop++){
			if(state&POW[loop]){

				a ^= A[L[loop]];
				b += B[L[loop]];
			}
		}

		insert(a,b);
	}

	ll ans = 0;

	for(int state = 0; state < POW[R.size()]; state++){

		ll a = 0,b = 0;
		for(int loop = 0; loop < R.size(); loop++){
			if(state&POW[loop]){

				a ^= A[R[loop]];
				b += B[R[loop]];
			}
		}

		ll add =query(root,MAX,a,M);
		ans = max(ans,b+add);
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 0.01020408163265306
time_ms: 20
memory_kb: 3252
final_rank: 20