Understanding Meet-in-the-Middle attack on block ciphers
We really only need one plaintext-ciphertext pair, but the second can be used as a way to check candidate keys.


Make a guess to the final subkey (ie guess all of them).
Decrypt the final round of your ciphertext using your key. Store this result and the subkey you used.
Repeat for all 2^16 candidates for the final subkey.
Make a guess for the first three subkeys.
Using these keys, go through the first three rounds of encryption of your plaintext.
If there is a collision between your intermediary encrypted result and your partially decrypted ciphertext, good! You (probably) found the key! You can double check using your other ciphertext/plaintext pair.


Alternatively, if you have enough storage space, you could build your storage of partially-decrypted-ciphertexts by going through the first two rounds of decryption (which are the reverse of the final two rounds of encryption). In this case, you'd bruteforce all candidates for the final two subkeys instead of just the final one. This requires storing 2^(16 * 2) partially decrypted ciphertexts, but has a speedup of 2^16.