diff --git a/day 023/day_23_felix.cpp b/day 023/day_23_felix.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..54d50ca417c4889e3076638d52a078c38b8a805c
--- /dev/null
+++ b/day 023/day_23_felix.cpp	
@@ -0,0 +1,134 @@
+/*
+Usage:
+    g++ -o main day_X_felix.cpp     (or compile however you like)
+    ./main < input.txt              (pipe the input)
+
+    Options:
+        -d : debug mode
+*/
+
+#include <bits/stdc++.h>
+using namespace std;
+bool DEBUG = false;
+
+// Standard definitions for many problems
+#define coord pair <int, int>
+#define ll long long
+
+array<set<int>, 676> LINKS;
+
+set<int> t_starters;
+set<int> all_ids;
+
+int int_id(char c1, char c2) {
+    int i1 = (int)(c1) - 97;
+    int i2 = (int)(c2) - 97;
+    return i1*26 + i2;
+}
+
+string id_to_str(int id) {
+    string s = "";
+    s += (char)(id / 26 + 97);
+    s += (char)(id % 26 + 97);
+    return s;
+}
+
+void read_input() {
+    string line;
+    while (getline(cin, line)) {
+        stringstream ss(line);
+        char c1, c2, dash;
+        ss >> c1 >> c2 >> dash;
+        int id1 = int_id(c1, c2);
+        all_ids.insert(id1);
+        if (c1 == 't') t_starters.insert(id1);
+        ss >> c1 >> c2;
+        int id2 = int_id(c1, c2);
+        all_ids.insert(id2);
+        if (c1 == 't') t_starters.insert(id2);
+        LINKS[id1].insert(id2);
+        LINKS[id2].insert(id1);
+    }
+    cout << "Total number of nodes: " << all_ids.size() << endl;
+}
+
+ll part1() {
+    ll total = 0;
+    set<tuple<int, int, int>> counted;
+    
+
+    for (int n1 : t_starters) for (int n2 : LINKS[n1]) for (int n3 : LINKS[n2]) {
+        if (counted.find({n1, n2, n3}) != counted.end()) continue;
+        if (!count(LINKS[n3].begin(), LINKS[n3].end(), n1)) continue;   
+        counted.insert({n1, n2, n3});
+        counted.insert({n1, n3, n2});
+        counted.insert({n2, n1, n3});
+        counted.insert({n2, n3, n1});
+        counted.insert({n3, n1, n2});
+        counted.insert({n3, n2, n1});
+        total++;
+    }
+    return total;
+}
+
+bool all_linked(int n, set<int> s) {
+    for (int n2 : s) if (LINKS[n].find(n2) == LINKS[n].end()) return false;
+    return true;
+}
+
+// check if set s contains all elements of set t
+bool contains_all(set<int> s, set<int> t) {
+    for (int n : t) if (s.find(n) == s.end()) return false;
+    return true;
+}
+
+string set_to_str(set<int> s) {
+    string str = "";
+    set<string> str_set;
+    for (int n : s) str_set.insert(id_to_str(n)); // automatically sorted
+    for (string s : str_set) str += s + ",";
+    // remove last ,
+    str.pop_back();
+    return str;
+}
+
+set<int> part2() {
+    set<set<int>> sets;
+    for (int n : all_ids) sets.insert({n});
+    int set_size = 1;
+    while (sets.size() > 1) {
+        if (DEBUG) cout << "Set size: " << set_size << " | Number of sets: " << sets.size() << endl;
+        set<set<int>> new_sets;
+        for (set<int> s : sets) for (int n : all_ids) {
+            if (s.find(n) != s.end()) continue;
+            if (all_linked(n, s)) {
+                set<int> new_s = s;
+                new_s.insert(n);
+                new_sets.insert(new_s);
+            }
+        }
+        sets = new_sets;
+        set_size++;
+    }
+    return *sets.begin();
+}
+
+int main (int argc, char* argv[]) {
+    for (int i = 0; i < argc; i++) if (string(argv[i]) == "-d") DEBUG = true;
+    
+    read_input();
+
+    if (DEBUG) {
+        int largest = 0;
+        for (int id : all_ids) if (LINKS[id].size() > largest) largest = LINKS[id].size();
+        cout << "Most links: " << largest << endl;
+    }
+
+    ll p1 = part1();
+    cout << "Part 1: " << p1 << endl;
+
+    set<int> p2 = part2();
+    cout << "Part 2: " << set_to_str(p2) << endl;
+
+    return 0;
+}
\ No newline at end of file