diff --git a/day 21/day_21_max_n.cpp b/day 21/day_21_max_n.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6cbbb236053220a90049b8c72a99bc7d0b0ccf6b
--- /dev/null
+++ b/day 21/day_21_max_n.cpp	
@@ -0,0 +1,157 @@
+#include <bits/stdc++.h>
+
+#ifdef LOCAL
+#include "./cpp-dump/cpp-dump.hpp"
+#define pr(x) cpp_dump(x)
+#endif
+
+using namespace std;
+
+#define Mod(x,y) (((x)%(y)+(y))%(y))
+#define rep(i, a, b) for(ll (i) = (a); (i) < (b); ++(i))
+#define all(x) begin(x), end(x)
+#define pb push_back
+#define gcd __gcd 
+#define sz(x) (ll)(x.size())
+
+typedef long long ll;
+typedef unsigned long long ull;
+typedef pair<ll, ll> pii;
+typedef vector<ll> vi;
+typedef vector<pii> vii;
+
+const bool debug = false;
+
+const int DEPTH = 25;
+
+vector<string> key1 = {
+    "789",
+    "456",
+    "123",
+    "!0A"
+};
+vector<string> key2 = {
+    "!^A",
+    "<v>"
+};
+
+pii key_to_go(char c, int keypad) {
+    if (keypad == 1) {
+        rep(i, 0, sz(key1)) rep(j, 0, sz(key1[i])) if (key1[i][j] == c) return pii(i, j);
+    } else {
+        rep(i, 0, sz(key2)) rep(j, 0, sz(key2[i])) if (key2[i][j] == c) return pii(i, j);   
+    }
+    assert(false);
+    return pii(0, 0);
+}
+
+string to_chars(vector<pii> v) {
+    string res;
+    for (auto p : v) {
+        int x = p.first;
+        int y = p.second;
+        
+        if (y > 0) while(y--) res.pb('>');
+        else if (y < 0) while(y++) res.pb('<');
+        
+        if (x > 0) while(x--) res.pb('v');
+        else if (x < 0) while(x++) res.pb('^');
+    }
+    return res;
+}
+
+bool valid(string v, pii cur, int keypad) {
+    int i = cur.first, j = cur.second;
+    for (auto c : v) {
+        if (keypad == 1 && key1[i][j] == '!') return false; 
+        if (keypad != 1 && key2[i][j] == '!') return false; 
+        if (c == '>') j++;
+        if (c == '<') j--;
+        if (c == '^') i--;
+        if (c == 'v') i++;
+
+    }
+    if (keypad == 1 && key1[i][j] == '!') return false; 
+    if (keypad == 2 && key2[i][j] == '!') return false; 
+    return true;
+}
+
+vector<string> get_paths(pii go, pii cur, int keypad) {
+    int i1 = cur.first, j1 = cur.second;
+    int i2 = go.first, j2 = go.second;
+
+    vector<pii> res1 = {pii(0, j2-j1), pii(i2-i1, 0)};
+    vector<pii> res2 = {pii(i2-i1, 0), pii(0, j2-j1)};
+
+    vector<string> res;
+    if (valid(to_chars(res1), cur, keypad)) res.pb(to_chars(res1));
+    if (valid(to_chars(res2), cur, keypad)) res.pb(to_chars(res2));
+
+    return res;
+}
+
+
+map<string, ll> dp[DEPTH+1];
+ll get_length(string path, int depth) {
+    if (depth == DEPTH) return sz(path);
+    if (dp[depth].count(path)) return dp[depth][path];
+
+    ll res = 0;
+
+    pii cur = {0, 2};
+    for (char c : path) {
+        pii to_go = key_to_go(c, 2);
+        vector<string> paths2 = get_paths(to_go, cur, 2);
+        cur = to_go;
+
+        ll cur_res = LLONG_MAX;
+
+        for (auto path2 : paths2) {
+            path2.pb('A');
+            cur_res = min(cur_res, get_length(path2, depth+1));
+        }
+
+        res += cur_res;
+    }
+
+    return (dp[depth][path] = res);
+}
+
+void solve() {
+    ll ans = 0;
+
+    string s;
+    while(cin >> s) {
+        ll res = 0;
+        pii cur = {3, 2};
+
+        for (char c : s) {
+            pii to_go = key_to_go(c, 1);
+            vector<string> paths = get_paths(to_go, cur, 1);
+            cur = to_go;
+
+            ll cur_res = LLONG_MAX;
+
+            for (auto path : paths) {
+                path.pb('A');
+                cur_res = min(cur_res,get_length(path, 0));
+            }
+            
+            res += cur_res;
+        }
+        ans += res*stoi(s.substr(0, 3));
+    }
+    pr(ans);
+} 
+
+
+int main() {
+    ios::sync_with_stdio(0);cin.tie(0);
+    cout << setprecision(15) << fixed;
+
+#ifdef LOCAL
+    freopen("input.txt", "r", stdin);
+#endif
+
+    solve();
+}