Problem:
C - Extreme Balance
Time Limit: 2 sec
問題文
Alice と Bob が石取りゲームをします。最初、山が $N$ 個あり、それぞれの山には $2$ 個の石があります。
Alice と Bob は、Alice から始めて、交互に以下の操作を繰り返します。
山を一つ選ぶ。その山に $X$ 個の石が残っている場合、$1$ 個以上 $X$ 個以下の任意の個数の石をその山から取り除く。
また、$3$ ターンに一度、石 $2$ 個からなる山が $1$ つ追加されます。厳密には、$n$ 回目の操作 (両者の操作を合わせた回数) の後、$n$ が $3$ で割り切れる場合、石 $2$ 個からなる山が $1$ つ追加されます。
$n$ 回目の操作で石が全て取り除かれたとしても、$n$ が $3$ で割り切れる場合は新たに石が追加されて、ゲームが続くことに注意してください。
先に操作できなくなったプレイヤーが負けです。両者が最善を尽くしたとき、どちらのプレイヤーが勝つか判定してください。
制約
$1 \leq N \leq 1000$
$N$は整数
入力
$N$
出力
Aliceが勝つなら
Alice
を、Bobが勝つなら
Bob
を出力せよ。
入力例1
1
出力例1
Alice
入力例2
998
出力例2
Bob

Submitted solutions:

code_snippet: #include<bits/stdc++.h>

#define ll long long
#define all(v) v.begin(), v.end()

using namespace std;
const int N = 3000;

bool dp[N][N][3][2];
bool vis[N][N][3][2];
int n;

bool slv(int ones, int twos, int mod3, bool turn) {
    if (ones == 0 && twos == 0)
        return 0;
    if (vis[ones][twos][mod3][turn])
        return dp[ones][twos][mod3][turn];
    vis[ones][twos][mod3][turn] = 1;
    bool &ret = dp[ones][twos][mod3][turn];
    if (mod3 == 0)
        twos++;
    ret = 1;
    if (ones)
        ret &= slv(ones - 1, twos, (mod3 + 1) % 3, !turn);
    if (twos) {
        ret &= slv(ones, twos - 1, (mod3 + 1) % 3, !turn);
        ret &= slv(ones + 1, twos - 1, (mod3 + 1) % 3, !turn);
    }
    ret = !ret;
    return ret;
}

int main() {
    cin >> n;
    if (slv(0, n, 1, 0))
        cout << "Alice\n";
    else
        cout << "Bob\n";
}
accuracy: 1
time_ms: 50
memory_kb: 57844
final_rank: 6

code_snippet: // AOJ #3256
// Extreme Balance 2025.2.4

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

const int M = 2200;
int dp[6][M][M];

int calc(int turn, int i, int j) {
    if (i == 0 && j == 0) return 0;
    if (dp[turn][i][j] != -1) return dp[turn][i][j];
    
    int addNew = ((turn + 1) % 3 == 0) ? 1 : 0;
    int nextTurn = (turn + 1) % 6;
    
    int ans = 0;
    if (j > 0) {
        if (calc(nextTurn, i + addNew, j - 1) == 0) ans = 1;
    }
    if (i > 0) {
        if (calc(nextTurn, i - 1 + addNew, j) == 0) ans = 1;
        if (calc(nextTurn, i - 1 + addNew, j + 1) == 0) ans = 1;
    }
    dp[turn][i][j] = ans;
    return ans;
}

int main(){
    int N; cin >> N;
    memset(dp, -1, sizeof(dp));
    cout << (calc(0, N, 0)? "Alice": "Bob") << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 116952
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
	int N;
	cin >> N;
	vector<vector<array<bool, 3> > > vis(2 * N + 1, vector<array<bool, 3> >(2 * N + 1, {false, false, false}));
	vector<vector<array<bool, 3> > > dp(2 * N + 1, vector<array<bool, 3> >(2 * N + 1, {false, false, false}));
	auto calc = [&](auto& self, int n1, int n2, int t) -> bool {
		if (n1 == 0 && n2 == 0) {
			return false;
		}
		if (vis[n1][n2][t]) {
			return dp[n1][n2][t];
		}
		bool ans = false;
		// case of 1 -> 0
		if (n1 >= 1 && !self(self, n1 - 1, n2 + (t == 2 ? 1 : 0), (t + 1) % 3)) {
			ans = true;
		}
		// case of 2 -> 1
		if (n2 >= 1 && !self(self, n1 + 1, n2 - 1 + (t == 2 ? 1 : 0), (t + 1) % 3)) {
			ans = true;
		}
		// case of 2 -> 0
		if (n2 >= 1 && !self(self, n1, n2 - 1 + (t == 2 ? 1 : 0), (t + 1) % 3)) {
			ans = true;
		}
		vis[n1][n2][t] = true;
		dp[n1][n2][t] = ans;
		return ans;
	};
	bool ans = calc(calc, 0, N, 0);
	cout << (ans ? "Alice" : "Bob") << endl;
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 26888
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

int N;
int dp[3][1009][1009];

int main() {
    // Step 1. Input
    cin >> N;
    
    // Step 2. Enumerate
    vector<tuple<int, int, int, int>> vec;
    for (int i = 0; i <= 2; i++) {
        for (int j = 0; j <= N + 2; j++) {
            for (int k = 0; k <= N + 2; k++) {
                vec.push_back(make_tuple(i + j + 2 * k, -i, j, k));
            }
        }
    }
    sort(vec.begin(), vec.end());

    // Step 3. Dynamic Programming
    for (tuple<int, int, int, int> tup : vec) {
        int idx1 = get<1>(tup) * -1;
        int idx2 = get<2>(tup) * +1;
        int idx3 = get<3>(tup);
        dp[idx1][idx2][idx3] = 2;

        // Get 1 -> 0
        if (idx2 >= 1) {
            int nex1 = (idx1 + 1) % 3;
            int nex2 = idx2 - 1;
            int nex3 = idx3 - 0; if (nex1 == 0) nex3 += 1;
            if (dp[nex1][nex2][nex3] == 2) dp[idx1][idx2][idx3] = 1;
        }

        // Get 2 -> 0
        if (idx3 >= 1) {
            int nex1 = (idx1 + 1) % 3;
            int nex2 = idx2 - 0;
            int nex3 = idx3 - 1; if (nex1 == 0) nex3 += 1;
            if (dp[nex1][nex2][nex3] == 2) dp[idx1][idx2][idx3] = 1;
        }

        // Get 2 -> 1
        if (idx3 >= 1) {
            int nex1 = (idx1 + 1) % 3;
            int nex2 = idx2 + 1;
            int nex3 = idx3 - 1; if (nex1 == 0) nex3 += 1;
            if (dp[nex1][nex2][nex3] == 2) dp[idx1][idx2][idx3] = 1;
        }
    }

    // Step 4. Output
    if (dp[0][0][N] == 1) cout << "Alice" << endl;
    else cout << "Bob" << endl;
    return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 69120
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define chmin(x,y) x = min(x,y)
#define chmax(x,y) x = max(x,y)
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001


#define SIZE 2005

enum Type{
	Sente,
	Gote,
	Undef,
};

int N;
Type dp[2][3][SIZE][SIZE],REV[2] = {Gote,Sente};

Type dfs(Type type,int mod,int num1,int num2){

	if(dp[type][mod][num1][num2] != Undef){

		return dp[type][mod][num1][num2];
	}

	int sum = num1 + 2*num2;

	if(mod == 0 && sum < 2*N){

		if(num1 == 0 && num2 == 0){

			return type;

		}else{

			bool FLG = false;

			//1→0にする
			if(num1 > 0){
				if(dfs(REV[type],mod+1,num1-1,num2+1) == type){

					FLG = true;
				}
			}

			//2→0にする
			if(dfs(REV[type],mod+1,num1,num2) == type){

				FLG = true;
			}
			//2→1にする
			if(dfs(REV[type],mod+1,num1+1,num2) == type){

				FLG = true;
			}

			if(FLG){

				return dp[type][mod][num1][num2] = type;

			}else{

				return dp[type][mod][num1][num2] = REV[type];
			}
		}


	}else{

		if(num1 == 0 && num2 == 0){

			return REV[type];

		}else{

			bool FLG = false;

			//1→0にする
			if(num1 > 0){
				if(dfs(REV[type],(mod+1)%3,num1-1,num2) == type){

					FLG = true;
				}
			}


			if(num2 > 0){
				//2→0にする
				if(dfs(REV[type],(mod+1)%3,num1,num2-1) == type){

					FLG = true;
				}
				//2→1にする
				if(dfs(REV[type],(mod+1)%3,num1+1,num2-1) == type){

					FLG = true;
				}
			}

			if(FLG){

				return dp[type][mod][num1][num2] = type;

			}else{

				return dp[type][mod][num1][num2] = REV[type];
			}
		}
	}
}

int main(){

	scanf("%d",&N);

	for(int i = 0; i < 2; i++){
		for(int k = 0; k < 3; k++){
			for(int a = 0; a < SIZE; a++){
				for(int b = 0; b < SIZE; b++){

					dp[i][k][a][b] = Undef;
				}
			}
		}
	}

	Type ret = dfs(Sente,0,0,N);

	if(ret == Sente){

		printf("Alice\n");

	}else{

		printf("Bob\n");
	}

	return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 97464
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define chmin(x,y) x = min(x,y)
#define chmax(x,y) x = max(x,y)
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001


#define SIZE 2005

enum Type{
	Sente,
	Gote,
	Undef,
};

int N;
Type dp[2][3][SIZE][SIZE],REV[2] = {Gote,Sente};

Type dfs(Type type,int mod,int num1,int num2){

	if(dp[type][mod][num1][num2] != Undef){

		return dp[type][mod][num1][num2];
	}

	int sum = num1 + 2*num2;

	if(mod == 0 && sum < 2*N){

		if(num1 == 0 && num2 == 0){

			return type;

		}else{

			bool FLG = false;

			//1→0にする
			if(num1 > 0){
				if(dfs(REV[type],mod+1,num1-1,num2+1) == type){

					FLG = true;
				}
			}


			if(num2 > 0){
				//2→0にする
				if(dfs(REV[type],mod+1,num1,num2) == type){

					FLG = true;
				}
				//2→1にする
				if(dfs(REV[type],mod+1,num1+1,num2) == type){

					FLG = true;
				}
			}

			if(FLG){

				return dp[type][mod][num1][num2] = type;

			}else{

				return dp[type][mod][num1][num2] = REV[type];
			}
		}


	}else{

		if(num1 == 0 && num2 == 0){

			return REV[type];

		}else{

			bool FLG = false;

			//1→0にする
			if(num1 > 0){
				if(dfs(REV[type],(mod+1)%3,num1-1,num2) == type){

					FLG = true;
				}
			}


			if(num2 > 0){
				//2→0にする
				if(dfs(REV[type],(mod+1)%3,num1,num2-1) == type){

					FLG = true;
				}
				//2→1にする
				if(dfs(REV[type],(mod+1)%3,num1+1,num2-1) == type){

					FLG = true;
				}
			}

			if(FLG){

				return dp[type][mod][num1][num2] = type;

			}else{

				return dp[type][mod][num1][num2] = REV[type];
			}
		}
	}
}

int main(){

	scanf("%d",&N);

	for(int i = 0; i < 2; i++){
		for(int k = 0; k < 3; k++){
			for(int a = 0; a <= 2*N; a++){
				for(int b = 0; b <= 2*N; b++){

					dp[i][k][a][b] = Undef;
				}
			}
		}
	}

	Type ret = dfs(Sente,0,0,N);

	if(ret == Sente){

		printf("Alice\n");

	}else{

		printf("Bob\n");
	}

	return 0;
}
accuracy: 0.09523809523809523
time_ms: 170
memory_kb: 97080
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define chmin(x,y) x = min(x,y)
#define chmax(x,y) x = max(x,y)
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001


#define SIZE 1005

enum Type{
	Sente,
	Gote,
	Undef,
};

int N;
Type dp[2][3][SIZE][SIZE],REV[2] = {Gote,Sente};

Type dfs(Type type,int mod,int num1,int num2){

	if(dp[type][mod][num1][num2] != Undef){

		return dp[type][mod][num1][num2];
	}

	int sum = num1 + 2*num2;

	if(mod == 0 && sum < 2*N){

		if(num1 == 0 && num2 == 0){

			return type;

		}else{

			bool FLG = false;

			//1→0にする
			if(num1 > 0){
				if(dfs(REV[type],mod+1,num1-1,num2+1) == type){

					FLG = true;
				}
			}


			if(num2 > 0){
				//2→0にする
				if(dfs(REV[type],mod+1,num1,num2) == type){

					FLG = true;
				}
				//2→1にする
				if(dfs(REV[type],mod+1,num1+1,num2) == type){

					FLG = true;
				}
			}

			if(FLG){

				return dp[type][mod][num1][num2] = type;

			}else{

				return dp[type][mod][num1][num2] = REV[type];
			}
		}


	}else{

		if(num1 == 0 && num2 == 0){

			return REV[type];

		}else{

			bool FLG = false;

			//1→0にする
			if(num1 > 0){
				if(dfs(REV[type],(mod+1)%3,num1-1,num2) == type){

					FLG = true;
				}
			}


			if(num2 > 0){
				//2→0にする
				if(dfs(REV[type],(mod+1)%3,num1,num2-1) == type){

					FLG = true;
				}
				//2→1にする
				if(dfs(REV[type],(mod+1)%3,num1+1,num2-1) == type){

					FLG = true;
				}
			}

			if(FLG){

				return dp[type][mod][num1][num2] = type;

			}else{

				return dp[type][mod][num1][num2] = REV[type];
			}
		}
	}
}

int main(){

	scanf("%d",&N);

	for(int i = 0; i < 2; i++){
		for(int k = 0; k < 3; k++){
			for(int a = 0; a <= N; a++){
				for(int b = 0; b <= N; b++){

					dp[i][k][a][b] = Undef;
				}
			}
		}
	}

	Type ret = dfs(Sente,0,0,N);

	if(ret == Sente){

		printf("Alice\n");

	}else{

		printf("Bob\n");
	}

	return 0;
}
accuracy: 0.09523809523809523
time_ms: 100
memory_kb: 26780
final_rank: 15

code_snippet: #ifdef __LOCAL
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using u8 = unsigned char;
using u16 = unsigned short;
using uint = unsigned int;
using ull = unsigned long long;
using ld = long double;
using P = pair<int,int>;
using PIL = pair<int,ll>;
using PLI = pair<ll,int>;
using PLL = pair<ll,ll>;
template<class T> using Matrix = vector<vector<T>>;
template <class T> using PQmax = priority_queue<T>;
template <class T> using PQmin = priority_queue<T, std::vector<T>, std::greater<T>>;
#define REP(i,n) for(int i=0;i<int(n);i++)
#define foa(s,v) for (auto &s : v)

const int inf = 1001001001;
const ll INF = 1LL << 60;
// const ll MOD = 1000000007LL;
const ll MOD = 998244353LL;
const ld pi = 3.14159265358979;
const ld eps = 1e-10;
const ld dinf = 1e12;
inline bool dequal(const double &a, const double &b) {return fabs(a - b) < eps;}
inline int sgn(const ld &r) {return ((r > eps) - (r < -eps));}
inline int sgn(const ld &a, const ld &b) {return sgn(a - b);}
ld degtorad(ld deg) {return deg * pi / 180.0;}
ld radtodeg(ld rad) {return rad * 180 / pi;}
const vector<int> h_idx4 = {-1, 0,0,1};
const vector<int> w_idx4 = { 0,-1,1,0};
const vector<int> h_idx8 = {-1,-1,-1, 0,0, 1,1,1};
const vector<int> w_idx8 = {-1, 0, 1,-1,1,-1,0,1};

template<class T> void show_vec(T v) {for (int i = 0; i < v.size(); i++) cout << v[i] << "\n";}
template<class T> void show_pair(T p) {cout << p.first << " " << p.second << "\n";}
void YESNO(bool f) {cout << ((f) ? "YES" : "NO") << "\n";}
void YesNo(bool f) {cout << ((f) ? "Yes" : "No") << "\n";}
void yesno(bool f) {cout << ((f) ? "yes" : "no") << "\n";}

template<class T> bool chmin(T &a, T b) {if (a > b){a = b; return 1;} return 0;}
template<class T> bool chmax(T &a, T b) {if (a < b){a = b; return 1;} return 0;}
template<class T> bool is_bit_set(T x,T bit) {return (x & (1LL << bit));}
template<class T> T ROUNDUP(T a, T b) {return ((a + b - 1) / b);}
template<class T> T tousa_sumFLN(T first, T last, T n) {return (n * (first + last) / 2);}
template<class T> T tousa_sumFDN(T first, T diff, T n) {return (n * ((first * 2) + ((n - 1) * diff)) / 2);}
template<class T> T tousa_sumFLD(T first, T last, T diff) {assert(first <= last); return tousa_sum2(first,diff,((last - first) / diff) + 1);}
ll intpow(ll a, ll n) {ll res = 1; while (n > 0){if (n & 1){res *= a;} a = a * a; n >>= 1;} return res;}
ll modpow(ll a, ll n) {ll res = 1; while (n > 0){if (n & 1){res = res * a % MOD;} a = a * a % MOD; n >>= 1;} return res;}
ll eachmodpow(ll a, ll n,ll mod){
	ll res = 1; while (n > 0){if (n & 1){res = res * a % mod;} a = a * a % mod; n >>= 1;} return res;
}

template<class T> T GCD(T a, T b) {if (b == 0) return a; return (GCD(b, a % b));}
template<class T> T LCM(T a, T b) {if (b == 0) return (0); return ((a / GCD(a, b)) * b);}
template<class T> T extGCD(T a, T b, T &x, T &y){ // ax + by = GCD(a,b)
	if (b == 0){ x = 1; y = 0; return a;}
	T d = extGCD(b, a % b, y, x); y -= ((a / b) * x); return d;
}
template<class T> T modinv(T a,T mod){ // only GCD(a,mod) = 1
	T x,y; extGCD(a,mod,x,y); return ((x % mod) + mod) % mod;
}

template<class T> vector<int> sort_with_index(vector<T> &vec){
	vector<int> indices(vec.size());
	iota(indices.begin(),indices.end(),0);
	sort(indices.begin(), indices.end(),[&](int &lhs,int &rhs){ return vec[lhs] < vec[rhs]; });
	vector<T> sorted(vec.size());
	for (int i = 0; i < (int)vec.size(); i++) sorted[i] = vec[indices[i]];
	vec = sorted; return indices;
}
template<class T,class Func> vector<int> sort_with_index(vector<T> &vec,Func comp){
	vector<int> indices(vec.size());
	iota(indices.begin(),indices.end(),0);
	sort(indices.begin(), indices.end(),[&](int lhs,int rhs){ return comp(vec[lhs],vec[rhs]);});
	vector<T> sorted(vec.size());
	for (int i = 0; i < (int)vec.size(); i++) sorted[i] = vec[indices[i]];
	vec = sorted; return indices;
}
template<class T,class U> vector<int> sort_with_basevec(vector<T> &base,vector<U> &with){
	assert(base.size() == with.size());
	vector<int> indices(base.size());
	iota(indices.begin(),indices.end(),0);
	sort(indices.begin(), indices.end(),[&](int &lhs,int &rhs){ return base[lhs] < base[rhs]; });
	vector<T> sorted_base(base.size()); vector<U> sorted_with(with.size());
	for (int i = 0; i < (int)base.size(); i++){ sorted_base[i] = base[indices[i]]; sorted_with[i] = with[indices[i]];}
	base = sorted_base; with = sorted_with; return indices;
}

ll ceilsqrt(ll n,ll r = 2){ // nのr乗根を切り上げた整数
	assert(n >= 0);
	ll res = (ll)floor(pow((double)n, 1.0 / r)) - 1; while (res < 0 || intpow(res,r) < n) res++; return res;
}
ll floorsqrt(ll n,ll r = 2){ // nのr乗根を切り捨てた整数
	assert(n >= 0); 
	ll res = (ll)ceil(pow((double)n, 1.0 / r)) + 1; while (intpow(res,r) > n) res--; return res;
}

// min_it s.t. vec[it] >(=) val [0,n]
template<class T>
int higher_minindex(vector<T> &vec,T val,bool equal = false){
	int ok = (int)vec.size(),ng = -1;
		while (abs(ok - ng) > 1){
			int mid = (ok + ng) / 2;
			if (equal){(vec[mid] >= val) ? (ok = mid) : (ng = mid);}
			else {(vec[mid] > val) ? (ok = mid) : (ng = mid);}
		}
	return ok;
}
// max_it s.t. vec[it] <(=) val [-1,n-1]
template<class T>
int lower_maxindex(vector<T> &vec,T val,bool equal = false){
	int ok = -1,ng = (int)vec.size();
		while (abs(ok - ng) > 1){
			int mid = (ok + ng) / 2;
			if (equal){(vec[mid] <= val) ? (ok = mid) : (ng = mid);}
			else {(vec[mid] < val) ? (ok = mid) : (ng = mid);}
		}
	return ok;
}

int dp[2012][2012][3];
int func(int a,int b,int c){
	if (dp[a][b][c] != -1) return dp[a][b][c];
	int x = 1;
	if (c <= 1){
		if (a > 0) chmin(x,func(a - 1,b,c + 1));
		if (b > 0) chmin(x,func(a,b - 1,c + 1));
		if (b > 0) chmin(x,func(a + 1,b - 1,c + 1));

		if (x == 0) return dp[a][b][c] = 1;
		else return dp[a][b][c] = 0;
	}
	else{
		if (a > 0) chmin(x,func(a - 1,b + 1,0));
		if (b > 0) chmin(x,func(a,b,0));
		if (b > 0) chmin(x,func(a + 1,b,0));

		if (x == 0) return dp[a][b][c] = 1;
		else return dp[a][b][c] = 0;
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(15);

	int n;
	cin >> n;
	for (int i = 0; i < 2012; i++){
		for (int j = 0; j < 2012; j++){
			for (int k = 0; k < 3; k++){
				dp[i][j][k] = -1;
			}
		}
	}
	dp[0][0][1] = 0;
	dp[0][0][2] = 0;

	if (func(0,n,0) == 0) cout << "Bob" << endl;
	else cout << "Alice" << endl;

}
accuracy: 1
time_ms: 20
memory_kb: 50972
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

const int M = 2200;
int dp[6][M][M];
// turn % 6, 2 * i, 1 * j

int calc(int turn, int i, int j) {
    if(i == 0 && j == 0) return 0;
    if(dp[turn][i][j] != -1) return dp[turn][i][j];

    int NEW = (turn + 1) % 3 == 0 ? 1 : 0;
    int nt_turn = (turn + 1) % 6;
    int ans = 0;
    if(j) {
        // 1 -> 0
        ans |= calc(nt_turn, i + NEW, j - 1) == 0;
    }
    if(i) {
        // 2 -> 0
        ans |= calc(nt_turn, i - 1 + NEW, j) == 0;
        // 2 -> 1
        ans |= calc(nt_turn, i - 1 + NEW, j + 1) == 0;
    }
    return dp[turn][i][j] = ans;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    int N; cin >> N;
    rep(i,6)rep(j,M)rep(k,M) dp[i][j][k] = -1;
    cout << (calc(0, N, 0) == 1 ? "Alice" : "Bob") << '\n';
}
accuracy: 1
time_ms: 40
memory_kb: 116968
final_rank: 9

code_snippet: /*	author:  Kite_kuma
	created: 2022.03.12 20:35:37 */

// #ifdef LOCAL
// #define _GLIBCXX_DEBUG
// #endif
#include <bits/stdc++.h>
using namespace std;

#pragma region macros

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))

#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

#pragma endregion

#pragma region aliases

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

#pragma endregion

#pragma region constants

const int inf = 1e9;
const long long INF = 1e18;
const long double pi = acos(-1);
const char dl = '\n';
const char sp = ' ';
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

const int mod_1000000007 = 1000000007;
const int mod_998244353 = 998244353;

#pragma endregion

#pragma region basic_operation

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

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

void Yes(bool f = 1) { std::cout << (f ? "Yes" : "No") << '\n'; }
void No() { std::cout << "No\n"; }
void YES(bool f = 1) { std::cout << (f ? "YES" : "NO") << '\n'; }
void NO() { std::cout << "NO\n"; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

void err(bool flag = true) {
	if(!flag) return;
	std::cout << -1 << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(T x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T val) {
	for(auto &a : v) a += val;
	return;
}

template <class T>
T dup(T a, T b) {
	assert(b != 0);
	return (a + b - 1) / b;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

long long POW(long long a, long long n) {
	long long res = 1;
	while(n > 0) {
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(std::vector<T> &a) {
	auto vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}

#pragma endregion

#pragma region input
#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region debug

#pragma region output
template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(int i = 0; i < (int)v.size(); i++) {
		if(i) os << " ";
		os << v[i];
	}
	return os;
}
#pragma endregion

#pragma region view

namespace viewer {
void view(const long long e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T e) {
	std::cerr << e;
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << "(";
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ")";
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ")";
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ")";
}

template <typename T>
void view(const std::set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<T> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(const auto &e : v) {
		view(e);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	std::cerr << "{\n";
	for(const auto &v : vv) {
		std::cerr << "\t";
		view(v);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	std::cerr << "{\n";
	for(const auto &c : v) {
		std::cerr << "\t(";
		view(c.first);
		std::cerr << ", ";
		view(c.second);
		std::cerr << ")\n";
	}
	std::cerr << "}";
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}
}  // namespace viewer

#pragma endregion

// when debugging : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(0)
#define dump(x)                                      \
	do {                                             \
		std::cerr << __LINE__ << " " << #x << " : "; \
		viewer::view(x);                             \
		std::cerr << '\n';                           \
	} while(0)

#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

#pragma endregion

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout << std::fixed << std::setprecision(15);
	srand((unsigned)time(NULL));

	// one, two
	const int sz = 2100;
	vector<vector<vi>> first_wins(sz, vvi(sz, vi(3, -1)));

	auto judge = [&first_wins, &sz](auto self, int one, int two, int ope) {
		if(!in_range(one, 0, sz) || !in_range(two, 0, sz)) return -2;
		int &tmp = first_wins[one][two][ope];
		if(tmp != -1) return tmp;
		const int nxtope = (ope + 1) % 3;
		const int two_add = !(nxtope);
		bool unknown = false;
		if(one) {
			int res = self(self, one - 1, two + two_add, nxtope);
			if(res == 0) return tmp = 1;
			if(res == -2) unknown = true;
		}
		if(two) {
			int res = self(self, one, two - 1 + two_add, nxtope);
			if(res == 0) return tmp = 1;
			if(res == -2) unknown = true;

			res = self(self, one + 1, two - 1 + two_add, nxtope);
			if(res == 0) return tmp = 1;
			if(res == -2) unknown = true;
		}
		if(unknown) return tmp = -2;
		return tmp = 0;
	};

	// rep(one, sz) rep(two, sz) rep(ope, 1) {
	// 	debug(one, two, ope);
	// 	debug(judge(judge, one, two, ope), dl);
	// }

	int n;
	cin >> n;

	cout << (!judge(judge, 0, n, 0) ? "Bob":"Alice") << dl;

	return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 244636
final_rank: 14

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<complex>
#include<numeric>
#include<functional>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,LL> LP;
const int INF=1<<30;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
template<typename T> ostream& operator<<(ostream& os,const vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++){
        if(i)os<<" ";
        os<<v1[i];
    }
    return os;
}
template<typename T1,typename T2> ostream& operator<<(ostream& os,const pair<T1,T2>& p){
    os<<p.first<<" "<<p.second;
    return os;
}
template<typename T> istream& operator>>(istream& is,vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++)is>>v1[i];
    return is;
}
template<typename T1,typename T2> istream& operator>>(istream& is,pair<T1,T2>& p){
    is>>p.first>>p.second;
    return is;
}

namespace sol{
    const int N=2222,M=3;
    vector<vector<vector<char>>> win(M,vector<vector<char>>(N,vector<char>(N)));
    vector<vector<vector<int>>> cnt(M,vector<vector<int>>(N,vector<int>(N)));
    typedef tuple<int,int,int> T;

    void solve(){
        int n,m;
        int i,j,k;
        int a,b,c;
        int x,y,z;
        cin>>n;
        auto inN=[](int x){return 0<=x && x<N;};
        for(i=0;i<M;i++){
            for(j=0;j<N;j++){
                for(k=0;k<N;k++){
                    x=j,y=k;
                    if(i==2)y++;
                    if(inN(x-1) && inN(y))cnt[i][j][k]++;
                    if(inN(x+1) && inN(y-1))cnt[i][j][k]++;
                    if(inN(x) && inN(y-1))cnt[i][j][k]++;
                }
            }
        }
        queue<T> q1;
        for(i=0;i<M;i++){
            q1.push({i,0,0});
        }
        auto push=[&](int f,int g,int h){
            if(!inN(g) || !inN(h))return;
            cnt[f][g][h]--;
            if(cnt[f][g][h]==0)q1.push({f,g,h});
        };
        while(!q1.empty()){
            tie(a,b,c)=q1.front();q1.pop();
            x=(a+1)%M,y=b,z=c;
            if(a==2)z++;
            if(b>0 || c>0){
                if(inN(y-1) && inN(z) && !win[x][y-1][z])win[a][b][c]=1;
                if(inN(y) && inN(z-1) && !win[x][y][z-1])win[a][b][c]=1;
                if(inN(y+1) && inN(z-1) && !win[x][y+1][z-1])win[a][b][c]=1;
            }
            x=(a+M-1)%M,y=b,z=c;
            if(a==0)z--;
            push(x,y+1,z),push(x,y,z+1),push(x,y-1,z+1);
        }
        if(win[0][0][n])cout<<"Alice"<<endl;
        else cout<<"Bob"<<endl;
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    sol::solve();
}
accuracy: 1
time_ms: 440
memory_kb: 95124
final_rank: 13

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<complex>
#include<numeric>
#include<functional>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,LL> LP;
const int INF=1<<30;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
template<typename T> ostream& operator<<(ostream& os,const vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++){
        if(i)os<<" ";
        os<<v1[i];
    }
    return os;
}
template<typename T1,typename T2> ostream& operator<<(ostream& os,const pair<T1,T2>& p){
    os<<p.first<<" "<<p.second;
    return os;
}
template<typename T> istream& operator>>(istream& is,vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++)is>>v1[i];
    return is;
}
template<typename T1,typename T2> istream& operator>>(istream& is,pair<T1,T2>& p){
    is>>p.first>>p.second;
    return is;
}

namespace sol{
    const int N=2222,M=3;
    vector<vector<vector<char>>> win(M,vector<vector<char>>(N,vector<char>(N)));
    vector<vector<vector<int>>> cnt(M,vector<vector<int>>(N,vector<int>(N)));
    typedef tuple<int,int,int> T;

    void solve(){
        int n,m;
        int i,j,k;
        int a,b,c;
        int x,y,z;
        cin>>n;
        auto inN=[](int x){return 0<=x && x<N;};
        for(i=0;i<M;i++){
            for(j=0;j<N;j++){
                for(k=0;k<N;k++){
                    x=j,y=k;
                    if(i==2)y++;
                    if(inN(x-1) && inN(y))cnt[i][j][k]++;
                    if(inN(x+1) && inN(y-1))cnt[i][j][k]++;
                    if(inN(x) && inN(y-1))cnt[i][j][k]++;
                }
            }
        }
        queue<T> q1;
        for(i=0;i<M;i++){
            q1.push({i,0,0});
        }
        auto push=[&](int f,int g,int h){
            if(!inN(g) || !inN(h))return;
            cnt[f][g][h]--;
            if(cnt[f][g][h]==0)q1.push({f,g,h});
        };
        while(!q1.empty()){
            tie(a,b,c)=q1.front();q1.pop();
            x=(a+1)%M,y=b,z=c;
            if(a==2)z++;
            if(j>0 || k>0){
                if(inN(y-1) && inN(z) && !win[x][y-1][z])win[a][b][c]=1;
                if(inN(y) && inN(z-1) && !win[x][y][z-1])win[a][b][c]=1;
                if(inN(y+1) && inN(z-1) && !win[x][y+1][z-1])win[a][b][c]=1;
            }
            x=(a+M-1)%M,y=b,z=c;
            if(a==0)z--;
            push(x,y+1,z),push(x,y,z+1),push(x,y-1,z+1);
        }
        if(win[0][0][n])cout<<"Alice"<<endl;
        else cout<<"Bob"<<endl;
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    sol::solve();
}
accuracy: 0.07142857142857142
time_ms: 440
memory_kb: 95056
final_rank: 19

code_snippet: #include <algorithm>
// #include <atcoder/all>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
// using namespace atcoder;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vvvll = vector<vector<vector<ll>>>;
using vii = vector<int>;
using vvii = vector<vector<int>>;
using vvvii = vector<vector<vector<int>>>;
using vdd = vector<ld>;
using vvdd = vector<vector<ld>>;
using vvvdd = vector<vector<vector<ld>>>;
using vbb = vector<bool>;
using vvbb = vector<vector<bool>>;
using vvvbb = vector<vector<vector<bool>>>;
using vpll = vector<pll>;
using vvpll = vector<vector<pll>>;
using vvvpll = vector<vector<vector<pll>>>;
/*
using vmm1 = vector<modint1000000007>;
using vvmm1 = vector<vector<modint1000000007>>;
using vvvmm1 = vector<vector<vector<modint1000000007>>>;
using vmm2 = vector<modint998244353>;
using vvmm2 = vector<vector<modint998244353>>;
using vvvmm2 = vector<vector<vector<modint998244353>>>;
*/
#define pb push_back
#define mp make_pair
#define sc second
#define fr first
#define endl '\n'
#define stpr std::fixed << setprecision
#define cYES cout << "YES" << endl
#define cNO cout << "NO" << endl
#define cYes cout << "Yes" << endl
#define cNo cout << "No" << endl
#define cerr cout << -1 << endl
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define drep(i, a, b, d) for (ll i = (a); i <= (b); i += d)
#define Rep(i, a, b) for (ll i = (a); i < (b); ++i)
#define rrep(i, n) for (ll i = n - 1; i >= 0; i--)
#define drrep(i, a, b, d) for (ll i = (a); i >= (b); i -= d)
#define rRep(i, a, b) for (ll i = a; i >= b; i--)
#define crep(i) for (char i = 'a'; i <= 'z'; ++i)
#define Crep(i) for (char i = 'A'; i <= 'Z'; ++i)
#define ALL(x) (x).begin(), (x).end()
#define rALL(x) (x).rbegin(), (x).rend()
#define sort2(A, N) \
  sort(A, A + N,    \
       [](const pii &a, const pii &b) { return a.second < b.second; });
#define debug(v)      \
  cout << #v << ":";  \
  for (auto x : v) {  \
    cout << x << ' '; \
  }                   \
  cout << endl;
int ctoi(const char c) {
  if ('0' <= c && c <= '9') return (c - '0');
  return -1;
}
ll gcd(ll a, ll b) { return (b == 0 ? a : gcd(b, a % b)); }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
ll rup(ll a, ll b) { return a + (b - a % b) % b; }
ll rdc(ll a, ll b) { return a / b * b; }
constexpr ll INF = 1000000011;
constexpr ll MOD = 1000000007;
constexpr ll MOD2 = 998244353;
constexpr ll LINF = 1001002003004005006ll;
constexpr ld EPS = 10e-15;
/*
using mint = modint998244353;
using mint2 = modint1000000007;
*/
template <class T, class U>
inline bool chmax(T &lhs, const U &rhs) {
  if (lhs < rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <class T, class U>
inline bool chmin(T &lhs, const U &rhs) {
  if (lhs > rhs) {
    lhs = rhs;
    return 1;
  }
  return 0;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &&x : v) is >> x;
  return is;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first;
  is >> p.second;
  return is;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << p.first << ' ' << p.second;
  return os;
}
template <class T>
ostream &operator<<(ostream &os, vector<T> &v) {
  for (auto i = begin(v); i != end(v); ++i) {
    if (i != begin(v)) os << ' ';
    os << *i;
  }
  return os;
}

vvvii dp;

bool dfs(ll X, ll Y, ll T) {
  // cout << X << " " << Y << " " << T << endl;
  // 負けが0勝ちが1
  if (dp[X][Y][T] != -1) {
    return dp[X][Y][T];
  }
  bool ret = 0;
  if (X == 0 && Y == 0) {
    return 0;
  }
  if (Y > 0) {
    if (T == 0 && dfs(X + 1, Y - 1, (T + 1) % 3) == 0) {
      ret = 1;
    }
    if (T != 0 && dfs(X, Y - 1, (T + 1) % 3) == 0) {
      ret = 1;
    }
  }
  if (X > 0) {
    if (T == 0 && dfs(X, Y, (T + 1) % 3) == 0) {
      ret = 1;
    }
    if (T == 0 && dfs(X, Y + 1, (T + 1) % 3) == 0) {
      ret = 1;
    }
    if (T != 0 && dfs(X - 1, Y, (T + 1) % 3) == 0) {
      ret = 1;
    }
    if (T != 0 && dfs(X - 1, Y + 1, (T + 1) % 3) == 0) {
      ret = 1;
    }
  }
  dp[X][Y][T] = ret;
  return ret;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  ll N;
  cin >> N;
  dp = vvvii(N + 1, vvii(2 * N + 1, vii(3, -1)));
  bool ans = dfs(N, 0, 1);
  if (ans) {
    cout << "Alice" << endl;
  } else {
    cout << "Bob" << endl;
  }
}
accuracy: 1
time_ms: 120
memory_kb: 112232
final_rank: 12

code_snippet: #pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> P;
typedef vector<ll> V;
typedef unordered_map<ll, ll> U_MAP;
typedef priority_queue<ll> pq;
typedef priority_queue<ll, vector<ll>, greater<ll>> rpq;
constexpr ll INF = 1e9, MOD = 1e9 + 7, ohara = 1e6 + 10;
constexpr ll LINF = 1e18;

#define rep(i, n) for (ll i = 0LL; (i) < (ll)(n); (i)++)
#define rrep(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rrrep(i, a, b) for (ll i = (ll)(a); i >= (ll)(b); i--)
#define all(v) (v).begin(), (v).end()
#define Size(n) (n).size()
#define Cout(x) cout << (x) << endl
#define doublecout(a) cout << fixed << setprecision(15) << a << endl;
#define fi first
#define se second
#define m_p make_pair
#define p_b push_back

//------ Believe yourself as a genius!!!!!! ------

int dy[] = {1, 0, -1, 0};
int dx[] = {0, 1, 0, -1};
// int dy[]={-1,0,1,-1,1,-1,0,1};int dx[]={-1,-1,-1,0,0,1,1,1};
string alph("abcdefghijklmnopqrstuvwxyz"), s;
ll n, cnt, ans, a, b, c, d, tmp, m, h, w, x, y, sum, k, q;
ll mem[1100][1100][10];

ll judge(ll one, ll two, ll turn) {
  if (mem[one][two][turn] != -1) return mem[one][two][turn];
  int res = 0;
  //一個取る
  //一個から一個取る
  if (one >= 1) {
    int new_two = two;
    if ((turn + 1) % 3 == 0) new_two++;
    res |= !judge(one - 1, new_two, (turn + 1) % 3);
  }
  if (two >= 1) {
    //二個から一個取る
    int new_two = two;
    if ((turn + 1) % 3 == 0) new_two++;
    res |= !judge(one + 1, new_two - 1, (turn + 1) % 3);
    //二個取る
    new_two = two;
    if ((turn + 1) % 3 == 0) new_two++;
    res |= !judge(one, new_two - 1, (turn + 1) % 3);
  }
  mem[one][two][turn] = res;
  return res;
}

int main(void) {
  cin.tie(0);
  cout.tie(0);
  ios::sync_with_stdio(false);

  cin >> n;
  rep(i, 1050) rep(j, 1050) rep(k, 9) mem[i][j][k] = -1;
  if (judge(0, n, 0) == 1)
    Cout("Alice");
  else
    Cout("Bob");
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 95940
final_rank: 7

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<complex>
#include<numeric>
#include<functional>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,LL> LP;
const int INF=1<<30;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
template<typename T> ostream& operator<<(ostream& os,const vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++){
        if(i)os<<" ";
        os<<v1[i];
    }
    return os;
}
template<typename T1,typename T2> ostream& operator<<(ostream& os,const pair<T1,T2>& p){
    os<<p.first<<" "<<p.second;
    return os;
}
template<typename T> istream& operator>>(istream& is,vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++)is>>v1[i];
    return is;
}
template<typename T1,typename T2> istream& operator>>(istream& is,pair<T1,T2>& p){
    is>>p.first>>p.second;
    return is;
}

namespace sol{
    const int N=3333,M=3;
    vector<vector<vector<char>>> win(M,vector<vector<char>>(N,vector<char>(N)));
    vector<vector<vector<int>>> cnt(M,vector<vector<int>>(N,vector<int>(N)));
    typedef tuple<int,int,int> T;

    void solve(){
        int n,m;
        int i,j,k;
        int a,b,c;
        int x,y,z;
        cin>>n;
        auto inN=[](int x){return 0<=x && x<N;};
        for(i=0;i<M;i++){
            for(j=0;j<N;j++){
                for(k=0;k<N;k++){
                    x=j,y=k;
                    if(i==2)y++;
                    if(inN(x-1) && inN(y))cnt[i][j][k]++;
                    if(inN(x+1) && inN(y-1))cnt[i][j][k]++;
                    if(inN(x) && inN(y-1))cnt[i][j][k]++;
                }
            }
        }
        queue<T> q1;
        for(i=0;i<M;i++){
            q1.push({i,0,0});
        }
        auto push=[&](int f,int g,int h){
            if(!inN(g) || !inN(h))return;
            cnt[f][g][h]--;
            if(cnt[f][g][h]==0)q1.push({f,g,h});
        };
        while(!q1.empty()){
            tie(a,b,c)=q1.front();q1.pop();
            x=(a+1)%M,y=b,z=c;
            if(a==2)z++;
            if(inN(y-1) && inN(z) && !win[x][y-1][z])win[a][b][c]=1;
            if(inN(y) && inN(z-1) && !win[x][y][z-1])win[a][b][c]=1;
            if(inN(y+1) && inN(z-1) && !win[x][y+1][z-1])win[a][b][c]=1;
            x=(a+M-1)%M,y=b,z=c;
            if(a==0)z--;
            push(x,y+1,z),push(x,y,z+1),push(x,y-1,z+1);
        }
        if(win[0][0][n])cout<<"Alice"<<endl;
        else cout<<"Bob"<<endl;
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    sol::solve();
}
accuracy: 0.07142857142857142
time_ms: 920
memory_kb: 209964
final_rank: 20

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<complex>
#include<numeric>
#include<functional>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,LL> LP;
const int INF=1<<30;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
template<typename T> ostream& operator<<(ostream& os,const vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++){
        if(i)os<<" ";
        os<<v1[i];
    }
    return os;
}
template<typename T1,typename T2> ostream& operator<<(ostream& os,const pair<T1,T2>& p){
    os<<p.first<<" "<<p.second;
    return os;
}
template<typename T> istream& operator>>(istream& is,vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++)is>>v1[i];
    return is;
}
template<typename T1,typename T2> istream& operator>>(istream& is,pair<T1,T2>& p){
    is>>p.first>>p.second;
    return is;
}

namespace sol{
    const int N=2222,M=3;
    vector<vector<vector<char>>> win(M,vector<vector<char>>(N,vector<char>(N)));
    vector<vector<vector<int>>> cnt(M,vector<vector<int>>(N,vector<int>(N)));
    typedef tuple<int,int,int> T;

    void solve(){
        int n,m;
        int i,j,k;
        int a,b,c;
        int x,y,z;
        cin>>n;
        auto inN=[](int x){return 0<=x && x<N;};
        for(i=0;i<M;i++){
            for(j=0;j<N;j++){
                for(k=0;k<N;k++){
                    x=j,y=k;
                    if(i==2)y++;
                    if(inN(x-1) && inN(y))cnt[i][j][k]++;
                    if(inN(x+1) && inN(y-1))cnt[i][j][k]++;
                    if(inN(x) && inN(y-1))cnt[i][j][k]++;
                }
            }
        }
        queue<T> q1;
        for(i=0;i<2;i++){
            q1.push({i,0,0});
        }
        auto push=[&](int f,int g,int h){
            if(!inN(g) || !inN(h))return;
            cnt[f][g][h]--;
            if(cnt[f][g][h]==0)q1.push({f,g,h});
        };
        while(!q1.empty()){
            tie(a,b,c)=q1.front();q1.pop();
            x=(a+1)%M,y=b,z=c;
            if(a==2)z++;
            if(inN(y-1) && inN(z) && !win[x][y-1][z])win[a][b][c]=1;
            if(inN(y) && inN(z-1) && !win[x][y][z-1])win[a][b][c]=1;
            if(inN(y+1) && inN(z-1) && !win[x][y+1][z-1])win[a][b][c]=1;
            x=(a+M-1)%M,y=b,z=c;
            if(a==0)z--;
            push(x,y+1,z),push(x,y,z+1),push(x,y-1,z+1);
        }
        if(win[0][0][n])cout<<"Alice"<<endl;
        else cout<<"Bob"<<endl;
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    sol::solve();
}
accuracy: 0.07142857142857142
time_ms: 400
memory_kb: 95016
final_rank: 17

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<complex>
#include<numeric>
#include<functional>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,LL> LP;
const int INF=1<<30;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
template<typename T> ostream& operator<<(ostream& os,const vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++){
        if(i)os<<" ";
        os<<v1[i];
    }
    return os;
}
template<typename T1,typename T2> ostream& operator<<(ostream& os,const pair<T1,T2>& p){
    os<<p.first<<" "<<p.second;
    return os;
}
template<typename T> istream& operator>>(istream& is,vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++)is>>v1[i];
    return is;
}
template<typename T1,typename T2> istream& operator>>(istream& is,pair<T1,T2>& p){
    is>>p.first>>p.second;
    return is;
}

namespace sol{
    const int N=2222,M=3;
    vector<vector<vector<char>>> win(M,vector<vector<char>>(N,vector<char>(N)));
    vector<vector<vector<int>>> cnt(M,vector<vector<int>>(N,vector<int>(N)));
    typedef tuple<int,int,int> T;

    void solve(){
        int n,m;
        int i,j,k;
        int a,b,c;
        int x,y,z;
        cin>>n;
        auto inN=[](int x){return 0<=x && x<N;};
        for(i=0;i<M;i++){
            for(j=0;j<N;j++){
                for(k=0;k<N;k++){
                    x=j,y=k;
                    if(i==2)y++;
                    if(inN(x-1) && inN(y))cnt[i][j][k]++;
                    if(inN(x+1) && inN(y-1))cnt[i][j][k]++;
                    if(inN(x) && inN(y-1))cnt[i][j][k]++;
                }
            }
        }
        queue<T> q1;
        for(i=0;i<M;i++){
            q1.push({i,0,0});
        }
        auto push=[&](int f,int g,int h){
            if(!inN(g) || !inN(h))return;
            cnt[f][g][h]--;
            if(cnt[f][g][h]==0)q1.push({f,g,h});
        };
        while(!q1.empty()){
            tie(a,b,c)=q1.front();q1.pop();
            x=(a+1)%M,y=b,z=c;
            if(a==2)z++;
            if(inN(y-1) && inN(z) && !win[x][y-1][z])win[a][b][c]=1;
            if(inN(y) && inN(z-1) && !win[x][y][z-1])win[a][b][c]=1;
            if(inN(y+1) && inN(z-1) && !win[x][y+1][z-1])win[a][b][c]=1;
            x=(a+M-1)%M,y=b,z=c;
            if(a==0)z--;
            push(x,y+1,z),push(x,y,z+1),push(x,y-1,z+1);
        }
        if(win[0][0][n])cout<<"Alice"<<endl;
        else cout<<"Bob"<<endl;
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    sol::solve();
}
accuracy: 0.07142857142857142
time_ms: 420
memory_kb: 95056
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T> bool chmax(T& a, const T& b) { return a < b ? (a = b, 1) : 0; }
template <typename T> bool chmin(T& a, const T& b) { return a > b ? (a = b, 1) : 0; }

int memo[2010][2010][3];

int rec(int i, int j, int r) {
    if (memo[i][j][r] != -1) return memo[i][j][r];

    int win = 0;
    if (i > 0) {
        win |= !rec(i-1, j+(r+1)/3, (r+1)%3);
    }
    if (j > 0) {
        win |= !rec(i+1, j-1+(r+1)/3, (r+1)%3);
        win |= !rec(i, j-1+(r+1)/3, (r+1)%3);
    }
    return memo[i][j][r] = win;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    memset(memo, -1, sizeof(memo));
    cout << (rec(0, N, 0) ? "Alice" : "Bob") << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 51160
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < int(n); ++i)
typedef long long ll;

bool dp[1100][2100][3] = {};
bool vs[1100][2100][3] = {};

bool dfs(int i, int j, int k) {
	if (vs[i][j][k]) return dp[i][j][k];
	vs[i][j][k] = true;
	int t = i;
	if (k == 2) i++;
	if (i == 0) {
		if (j == 0) return dp[0][0][(k+1)%3];
		return (dp[t][j][k] = !dfs(0, j-1, (k+1)%3));
	}
	bool a, b, c;
	a = dfs(i-1, j+1, (k+1)%3);
	b = dfs(i-1, j, (k+1)%3);
	if (j == 0) return (dp[t][j][k] = ((!a) || (!b)));
	c = dfs(i, j-1, (k+1)%3);
	return (dp[t][j][k] = ((!a) || (!b) || (!c)));
}

int main(void) {
	int n;
	cin >> n;
	
	vs[0][0][1] = true;
	vs[0][0][2] = true;
	bool ans = dfs(n, 0, 0);

	if (ans) cout << "Alice";
	else cout << "Bob";
	cout << endl;

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 16500
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

#ifdef _RUTHEN
#include "debug.hpp"
#else
#define show(...) true
#endif

using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); i++)
template <class T> using V = vector<T>;

int memo[2005][2005][3], seen[2005][2005][3];

int dp(int i, int j, int k) {
    if (seen[i][j][k]) return memo[i][j][k];
    if (i == 0 && j == 0) return 0;
    seen[i][j][k] = 1;
    // 1つ取るか,2つ取るか
    int ret = 0;
    // 2つの山から2つ取る
    if (i > 0 && dp(i - 1 + (k % 3 == 2), j, (k + 1) % 3) == 0) ret = 1;
    // 2つの山から1つ取る
    if (i > 0 && dp(i - 1 + (k % 3 == 2), j + 1, (k + 1) % 3) == 0) ret = 1;
    // 1つの山から1つ取る
    if (j > 0 && dp(i + (k % 3 == 2), j - 1, (k + 1) % 3) == 0) ret = 1;
    return memo[i][j][k] = ret;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int N;
    cin >> N;
    show(dp(0, 1, 0));
    show(dp(1, 0, 0));
    cout << (dp(N, 0, 0) ? "Alice" : "Bob") << '\n';
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 52476
final_rank: 5