diff --git a/day 16/day_16_max_n.cpp b/day 16/day_16_max_n.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..059eb6e888c255756f6bec76cd0cff994ee1cd7f
--- /dev/null
+++ b/day 16/day_16_max_n.cpp	
@@ -0,0 +1,146 @@
+#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;
+
+
+typedef pair<pii, pii> TT; // often ll or string or pi
+map<TT, vector<pair<ll, TT>>> gr, gr_rev;
+
+map<TT, ll> dist;
+
+ll dijkstra(TT src, TT targ) { // needs a defined get_edges, and if you want to return dist/prevv just ...
+    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] : gr[u]) {
+            if (dist.count(v) == 0 || dist[v] > dist[u] + d) {
+                dist[v] = dist[u] + d;
+                pq.push(pair<ll, TT>(dist[v], v));
+            }
+        }
+    }
+
+    return dist[targ]; // ... and change this to corresponding output
+}
+
+
+
+vector<string> mat;
+set<TT> seen;
+int n, m;
+
+void print_cur(TT u, ll tot_dist) {
+    if (seen.count(u)) return;
+    seen.insert(u);
+    mat[u.first.first][u.first.second] = 'O';
+
+    for (auto [d, v] : gr_rev[u]) {
+        if (dist[v] == tot_dist - d) {
+            print_cur(v, tot_dist-d);
+        }
+    }
+}
+
+pii to_pii(int i) {
+    if (i == 0) return pii(-1, 0);
+    if (i == 1) return pii(0, 1);
+    if (i == 2) return pii(1, 0);
+    if (i == 3) return pii(0, -1);
+    return pii(0, 0);
+}
+
+void solve() {
+    string s;
+    while(cin >> s) mat.pb(s);
+    n = sz(mat);
+    m = sz(mat[0]);
+
+    rep(i, 1, n-1) rep(j, 1, m-1) rep(dir, 0, 4) {
+        pii x = pii(i, j);
+        pii y = to_pii(dir);
+
+        if (mat[i][j] != '#' && mat[i+y.first][j+y.second] != '#') {
+            gr[make_pair(x, y)].pb(make_pair(1, make_pair(pii(i+y.first, j+y.second), y)));
+        }
+        pii yn = to_pii(Mod(dir+1, 4));
+        gr[make_pair(x, y)].pb(make_pair(1000, make_pair(x, yn)));
+        yn = to_pii(Mod(dir-1, 4));
+        gr[make_pair(x, y)].pb(make_pair(1000, make_pair(x, yn)));
+    }
+
+    for (auto p : gr) {
+        for (auto q : p.second) {
+            ll d = q.first;
+            auto v = q.second;
+            gr_rev[v].pb(make_pair(d, p.first));
+        }
+    }
+
+    int is, js;
+    rep(i, 0, n) rep(j, 0, m) if (mat[i][j] == 'S') is = i, js = j;
+    
+    int ie, je;
+    rep(i, 0, n) rep(j, 0, m) if (mat[i][j] == 'E') ie = i, je = j;
+
+    auto st = make_pair(pii(is, js), to_pii(1));
+
+
+    ll ans1 = LLONG_MAX;
+    rep(dir, 0, 4) {
+        ans1 = min(ans1, dijkstra(st, make_pair(pii(ie, je), to_pii(dir))));
+    }
+    pr(ans1);
+
+    rep(dir, 0, 4) {
+        auto cur = make_pair(pii(ie, je), to_pii(dir));
+        if (dist[cur] == ans1) {
+            print_cur(cur, dist[cur]);
+        }
+    }
+
+    ll ans2 = 0;
+    rep(i, 0, n) rep(j, 0, m) if (mat[i][j] == 'O') ans2++;
+    pr(ans2);
+} 
+
+// 441
+
+
+int main() {
+    ios::sync_with_stdio(0);cin.tie(0);
+    cout << setprecision(15) << fixed;
+
+#ifdef LOCAL
+    freopen("input.txt", "r", stdin);
+#endif
+
+    solve();
+}