easy peasy python O(nlogn) solution with comments
\tdef maxEnvelopes(self, envelopes: List[List[int]]) -> int:\n        # sort in one property and find the longest increasing subsequence\n        # in the other
\tdef maxEnvelopes(self, envelopes: List[List[int]]) -> int:\n        # sort in one property and find the longest increasing subsequence\n        # in the other property, that\'s it\n        # to avoid cases such as [(3, 4), (3, 6)] - output should be 1\n        # sort the (w) in ascending and (h) in descending\n    \n        #let\'s sort in second property(h) and then find LIS using first property(w)\n        ln = len(envelopes)\n        if ln <= 1:\n            return ln\n        \n        envelopes = sorted(envelopes, key=lambda x:(x[1], -x[0]))\n        #now find the LIS\n        q = [envelopes[0][0]]\n        \n        for i in range(1, ln):\n            num = envelopes[i][0]\n            if q[-1] < num:\n                q.append(num)\n            elif q[-1] > num:\n                # use binary search \n                idx = self.upperbound(q, num)\n                q[idx] = num\n        \n        return len(q)\n    \n    def upperbound(self, ls, num):\n        ln = len(ls)\n        s, e = 0, ln-1\n        while s <= e:\n            mid = (e-s)//2 + s\n            if ls[mid] == num:\n                #we can or we don\'t have to replace this\n                return mid\n            elif ls[mid] < num:\n                if mid+1 < ln and ls[mid+1] > num:\n                    return mid+1\n                s = mid + 1\n            else:\n                if mid == 0:\n                    return mid\n                e = mid-1
['Binary Tree', 'Python', 'Python3']