<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def max_range(ranges, combined=True):
 """ Computes the maximal lower and upper bounds from a list bounds. Args: ranges (list of tuples):
 A list of range tuples combined (boolean, optional):
 Whether to combine bounds Whether range should be computed on lower and upper bound independently or both at once Returns: The maximum range as a single tuple """

    try:
        with warnings.catch_warnings():
            warnings.filterwarnings('ignore', r'All-NaN (slice|axis) encountered')
            values = [tuple(np.NaN if v is None else v for v in r) for r in ranges]
            if pd and any(isinstance(v, datetime_types) and not isinstance(v, cftime_types)
                          for r in values for v in r):
                converted = []
                for l, h in values:
                    if isinstance(l, datetime_types) and isinstance(h, datetime_types):
                        l, h = (pd.Timestamp(l).to_datetime64(),
                                pd.Timestamp(h).to_datetime64())
                    converted.append((l, h))
                values = converted

            arr = np.array(values)
            if not len(arr):
                return np.NaN, np.NaN
            elif arr.dtype.kind in 'OSU':
                arr = list(python2sort([
                    v for r in values for v in r
                    if not is_nan(v) and v is not None]))
                return arr[0], arr[-1]
            elif arr.dtype.kind in 'M':
                return ((arr.min(), arr.max()) if combined else
                        (arr[:, 0].min(), arr[:, 1].min()))

            if combined:
                return (np.nanmin(arr), np.nanmax(arr))
            else:
                return (np.nanmin(arr[:, 0]), np.nanmax(arr[:, 1]))
    except:
        return (np.NaN, np.NaN)