How would you optimize LLM encoding for performance and efficiency? Implement byte-pair encoding over an initial token sequence using merge priorities, always applying the lowest-priority adjacent pair and breaking ties from left to right. The function receives a list of token strings and an ordered list of merge rules, and returns the final merged token list. Use a data structure that avoids rescanning every adjacent pair after each merge.
def bpe_encode(tokens, merge_rules):