Fast Algorithms and Lower Bounds for Temporal Reasoning