diff --git a/day 20/day_20_max_n.cpp b/day 20/day_20_max_n.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..741af9393d4433e65ea24f1b935725c5abe11775
--- /dev/null
+++ b/day 20/day_20_max_n.cpp	
@@ -0,0 +1,131 @@
+#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;
+
+vector<string> mat;
+int n, m;
+int i4[4] = {-1, 0, 0, 1};
+int j4[4] = { 0,-1, 1, 0};
+
+typedef pii TT; // often ll or string or pii
+
+vector<pair<ll, TT>> get_edges(TT u, char pass_through) { // here it is possible to implement an infinite graph
+
+    vector<pair<ll, TT>> edges; // this is example for 2d graph without explicit gr
+    rep(x, 0, 4) { // or rep(di, -1, 2) rep(dj, -1, 2) if (di != 0 || dj != 0)
+        int i = u.first + i4[x], j = u.second + j4[x];
+        if (pass_through == '.' && min(i, j) >= 0 && i < n && j < m && mat[i][j] == '.') { 
+            edges.pb(pair<ll, pii>(1, pii(i, j))); 
+        }
+        if (pass_through == '#' && min(i, j) >= 0 && i < n && j < m) {
+            edges.pb(pair<ll, pii>(1, pii(i, j)));
+        }
+    }
+
+    return edges;
+}
+
+map<TT, ll> dijkstra(TT src, ll mx_time, char pass_through) { // needs a defined get_edges, and if you want to return dist/prev just ...
+    map<TT, ll> dist;
+    map<TT, TT> prev;
+    set<TT> vis;
+    priority_queue<pair<ll, TT>, vector<pair<ll, TT>>, greater<pair<ll, TT>>> pq;
+    dist[src] = 0;
+    pq.push(pair<ll, TT>(0, src));
+
+    while(pq.size()) {
+        pair<ll, TT> p = pq.top(); pq.pop();
+        ll du = p.first;
+        TT u = p.second;
+        if (dist[u] < du) continue;
+
+        for (auto [d, v] : get_edges(u, pass_through)) {
+            if (dist[u] + d > mx_time) //
+                break;
+
+            if (dist.count(v) == 0 || dist[v] > dist[u] + d) {
+                dist[v] = dist[u] + d;
+                prev[v] = u;
+                pq.push(pair<ll, TT>(dist[v], v));
+            }
+        }
+    }
+
+    return dist; // ... and change this to corresponding output
+}
+
+void solve() {
+    string s;
+    while(cin >> s) mat.pb(s);
+    n = sz(mat);
+    m = sz(mat[0]);
+
+    pii src, targ;
+    rep(i, 0, n) rep(j, 0, m) {
+        if (mat[i][j] == 'S') {
+            src = pii(i, j);
+            mat[i][j] = '.';
+        }
+        if (mat[i][j] == 'E') {
+            targ = pii(i, j);
+            mat[i][j] = '.';
+        }
+    }
+
+    ll mx_time = 20;
+
+    map<TT, ll> normal = dijkstra(src, LLONG_MAX, '.');
+    map<ll, set<pair<pii, pii>>> save;
+
+    rep(i, 1, n-1) rep(j, 1, m-1) {
+
+        if (mat[i][j] == '.') {
+            map<TT, ll> cheat = dijkstra(pii(i, j), mx_time, '#');
+            for (auto p : cheat) {
+                pii q = p.first;
+                int x = q.first, y = q.second;
+                if (mat[x][y] == '.' && normal[pii(i, j)] + p.second < normal[q]) {
+                    ll to_save = normal[q] - (normal[pii(i, j)] + p.second);
+                    save[to_save].insert(make_pair(pii(i, j), pii(x, y)));
+                
+                }
+            }
+        }
+    }
+
+    ll ans = 0;
+    for (auto p : save) if (p.first >= 100) ans += sz(p.second);
+    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();
+}