use std::cell::{Cell, UnsafeCell};
use std::fmt;
use std::mem;
use std::ops::Deref;
pub struct OnceCell<T> {
        inner: UnsafeCell<Option<T>>,
}
impl<T> Default for OnceCell<T> {
    fn default() -> Self {
        Self::new()
    }
}
impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.get() {
            Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
            None => f.write_str("OnceCell(Uninit)"),
        }
    }
}
impl<T: Clone> Clone for OnceCell<T> {
    fn clone(&self) -> OnceCell<T> {
        let res = OnceCell::new();
        if let Some(value) = self.get() {
            match res.set(value.clone()) {
                Ok(()) => (),
                Err(_) => unreachable!(),
            }
        }
        res
    }
}
impl<T: PartialEq> PartialEq for OnceCell<T> {
    fn eq(&self, other: &Self) -> bool {
        self.get() == other.get()
    }
}
impl<T: Eq> Eq for OnceCell<T> {}
impl<T> From<T> for OnceCell<T> {
    fn from(value: T) -> Self {
        OnceCell {
            inner: UnsafeCell::new(Some(value)),
        }
    }
}
impl<T> OnceCell<T> {
        pub const fn new() -> OnceCell<T> {
        OnceCell {
            inner: UnsafeCell::new(None),
        }
    }
                pub fn get(&self) -> Option<&T> {
                unsafe { &*self.inner.get() }.as_ref()
    }
                pub fn get_mut(&mut self) -> Option<&mut T> {
                unsafe { &mut *self.inner.get() }.as_mut()
    }
                                                                                            pub fn set(&self, value: T) -> Result<(), T> {
                let slot = unsafe { &*self.inner.get() };
        if slot.is_some() {
            return Err(value);
        }
                                        let slot = unsafe { &mut *self.inner.get() };
        *slot = Some(value);
        Ok(())
    }
                                                                                                    pub fn get_or_init<F>(&self, f: F) -> &T
    where
        F: FnOnce() -> T,
    {
        match self.get_or_try_init(|| Ok::<T, ()>(f())) {
            Ok(val) => val,
            Err(()) => unreachable!(),
        }
    }
                                                                                                                    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
    where
        F: FnOnce() -> Result<T, E>,
    {
        if let Some(val) = self.get() {
            return Ok(val);
        }
        let val = f()?;
                                        assert!(self.set(val).is_ok(), "reentrant init");
        Ok(self.get().unwrap())
    }
                                                                            pub fn into_inner(self) -> Option<T> {
                        self.inner.into_inner()
    }
                                                                                        pub fn take(&mut self) -> Option<T> {
        mem::take(self).into_inner()
    }
}
pub struct Lazy<T, F = fn() -> T> {
    cell: OnceCell<T>,
    init: Cell<Option<F>>,
}
impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Lazy")
            .field("cell", &self.cell)
            .field("init", &"..")
            .finish()
    }
}
impl<T, F> Lazy<T, F> {
                                                                        pub const fn new(init: F) -> Lazy<T, F> {
        Lazy {
            cell: OnceCell::new(),
            init: Cell::new(Some(init)),
        }
    }
}
impl<T, F: FnOnce() -> T> Lazy<T, F> {
                                                                        pub fn force(this: &Lazy<T, F>) -> &T {
        this.cell.get_or_init(|| match this.init.take() {
            Some(f) => f(),
            None => panic!("`Lazy` instance has previously been poisoned"),
        })
    }
}
impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
    type Target = T;
    fn deref(&self) -> &T {
        Lazy::force(self)
    }
}
impl<T: Default> Default for Lazy<T> {
        fn default() -> Lazy<T> {
        Lazy::new(T::default)
    }
}