Implement a function tail(path: string, N: int) that prints the last N lines of a potentially multi-GB text file without loading the whole file into memory. Assume variable-length lines and unknown line count. Explain and implement approaches for (a) random-access files using seeking/backward scan or a fixed-size ring buffer, and (b) an unbounded input stream where seeking is impossible, maintaining only O (N) memory. Discuss handling of UTF-8 multibyte characters, files missing a trailing newline, different newline conventions, and extremely long lines. Provide time and space complexities and key test cases.