Undefined behavior is simply behavior that is not defined by the C++ specification. For example, if you have multiple unary increment/decrement operations in an expression like i++ + ++i, they result in behavior that is not defined. This is simply due to the fact that some language constructs are syntactically valid but you can't predict the behavior when the code is run. Another example is the expression: u = (u++);
Implementation-defined behavior is behavior unspecified by the specification and left for the implementor to decide and document how the choice is made. In this case, the choice that is made must be guaranteed, ie, only that should happen.
In case of unspecified behavior, the C++ standard provides multiple possible paths doesn't require the implementation to document or guarantee anything.