rewrote everything, data structures are now super-clean but I'd be surprised if this works on the first try