Problem:
Score : 700 points

Problem Statement

You are given N points (x_i,y_i) located on a two-dimensional plane.
Consider a subset S of the N points that forms a convex polygon.
Here, we say a set of points S forms a convex polygon when there exists a convex polygon with a positive area that has the same set of vertices as S. All the interior angles of the polygon must be strictly less than 180°.

For example, in the figure above, {A,C,E} and {B,D,E} form convex polygons; {A,C,D,E}, {A,B,C,E}, {A,B,C}, {D,E} and {} do not.

For a given set S, let n be the number of the points among the N points that are inside the convex hull of S (including the boundary and vertices). Then, we will define the score of S as 2^{n-|S|}.

Compute the scores of all possible sets S that form convex polygons, and find the sum of all those scores.

However, since the sum can be extremely large, print the sum modulo 998244353.

Constraints

1≤N≤200

0≤x_i,y_i<10^4 (1≤i≤N)

If i≠j, x_i≠x_j or y_i≠y_j.

x_i and y_i are integers.

Input

The input is given from Standard Input in the following format:

N
x_1 y_1
x_2 y_2
:
x_N y_N

Output

Print the sum of all the scores modulo 998244353.

Sample Input 1

4
0 0
0 1
1 0
1 1

Sample Output 1

5

We have five possible sets as S, four sets that form triangles and one set that forms a square. Each of them has a score of 2^0=1, so the answer is 5.

Sample Input 2

5
0 0
0 1
0 2
0 3
1 1

Sample Output 2

11

We have three "triangles" with a score of 1 each, two "triangles" with a score of 2 each, and one "triangle" with a score of 4. Thus, the answer is 11.

Sample Input 3

1
3141 2718

Sample Output 3

0

There are no possible set as S, so the answer is 0.

Solution in Rust (1.42.0) (judge verdict: Accepted)

use proconio::input;
// modint {{{
#[allow(dead_code)]
mod modint {
    use std::{
        cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
        fmt::{Debug, Display},
        iter::{Product, Sum},
        mem::swap,
        ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
    };

    pub type ModValue = i64;

    #[derive(Debug, Clone, Copy)]
    struct Rational {
        num: ModValue,
        den: ModValue,
    }

    #[allow(clippy::many_single_char_names)]
    fn red(r: i64, p: i64) -> (i64, i64, i64) {
        if r.abs() <= 10000 {
            return (r, 1, 0);
        }
        let mut nxt_r = p % r;
        let mut q = p / r;
        if 2 * nxt_r >= r {
            nxt_r -= r;
            q += 1;
        }
        if 2 * nxt_r <= -r {
            nxt_r += r;
            q -= 1;
        }
        let (x, z, y) = red(nxt_r, r);
        (x, y - q * z, z)
    }

    #[derive(Clone, Copy)]
    pub struct Mint<Mod: ModTrait>(ModValue, std::marker::PhantomData<Mod>);

    impl<Mod: ModTrait> Mint<Mod> {
        fn from_value_unchecked(value: ModValue) -> Self {
            Self(value, std::marker::PhantomData)
        }
        fn normalize(value: ModValue) -> ModValue {
            let value = value % Mod::modulus();
            if 0 <= value {
                value
            } else {
                value + Mod::modulus()
            }
        }
        fn guess(&self) -> Rational {
            let (mut num, mut den, _) = red(self.0, Mod::modulus());
            if den < 0 {
                num = -num;
                den = -den;
            }
            Rational { num, den }
        }
        pub fn from_i64(value: ModValue) -> Self {
            Self::from_value_unchecked(Self::normalize(value))
        }
        pub fn from_frac(num: ModValue, den: ModValue) -> Self {
            Self::from_i64(num) / Self::from_i64(den)
        }
        pub fn zero() -> Self {
            Self::from_value_unchecked(0)
        }
        pub fn one() -> Self {
            Self::from_value_unchecked(1)
        }
        #[allow(clippy::many_single_char_names)]
        pub fn inv(self) -> Self {
            assert_ne!(
                self,
                Self::zero(),
                "attempted to take the inverse of zero mint"
            );
            let mut x = self.0;
            let mut y = Mod::modulus();
            let mut u = 1;
            let mut v = 0;
            while x != 0 {
                let q = y / x;
                y -= q * x;
                v -= q * u;
                swap(&mut x, &mut y);
                swap(&mut u, &mut v);
            }
            assert!(x == 0 && y == 1 && u.abs() == Mod::modulus() && v.abs() < Mod::modulus());
            Self::from_value_unchecked(if v < 0 { v + Mod::modulus() } else { v })
        }
        pub fn pow(mut self, mut p: u64) -> Self {
            let mut ans = Self::one();
            while 0 != p {
                if p % 2 == 1 {
                    ans *= self;
                }
                self *= self;
                p /= 2;
            }
            ans
        }
        pub fn from_pow(a: ModValue, p: u64) -> Self {
            Self::from_i64(a).pow(p)
        }
    }

    impl<Mod: ModTrait> Debug for Mint<Mod> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
            let Rational { num, den } = self.guess();
            f.debug_tuple("Mint")
                .field(&if den == 1 {
                    num.to_string()
                } else {
                    format!("{}/{}", num, den)
                })
                .finish()
        }
    }

    impl<Mod: ModTrait> Display for Mint<Mod> {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
            write!(f, "{}", self.0)
        }
    }

    macro_rules! forward_ref_binop {
        ($(impl $imp:ident, $method:ident)*) => {
            $(
                impl<'a, Mod: ModTrait> $imp<Mint<Mod>> for &'a Mint<Mod> {
                    type Output = Mint<Mod>;

                    #[inline]
                    fn $method(self, other: Mint<Mod>) -> Self::Output {
                        $imp::$method(*self, other)
                    }
                }

                impl<'a, Mod: ModTrait> $imp<&'a Mint<Mod>> for Mint<Mod> {
                    type Output = Mint<Mod>;

                    #[inline]
                    fn $method(self, other: &Mint<Mod>) -> Self::Output {
                        $imp::$method(self, *other)
                    }
                }

                impl<'a, Mod: ModTrait> $imp<&'a Mint<Mod>> for &'a Mint<Mod> {
                    type Output = Mint<Mod>;

                    #[inline]
                    fn $method(self, other: &Mint<Mod>) -> Self::Output {
                        $imp::$method(*self, *other)
                    }
                }
            )*
        };
    }

    macro_rules! forward_ref_op_assign {
        ($(impl $imp:ident, $method:ident)*) => {
            $(
                impl<'a, Mod: ModTrait> $imp<&Mint<Mod>> for Mint<Mod> {
                    #[inline]
                    fn $method(&mut self, other: &Mint<Mod>) {
                        $imp::$method(self, *other);
                    }
                }
            )*
        }
    }

    #[allow(clippy::suspicious_arithmetic_impl)]
    impl<Mod: ModTrait> Add for Mint<Mod> {
        type Output = Self;

        #[inline]
        fn add(self, rhs: Self) -> Self {
            let value = self.0 + rhs.0;
            Self::from_value_unchecked(if value < Mod::modulus() {
                value
            } else {
                value - Mod::modulus()
            })
        }
    }

    #[allow(clippy::suspicious_arithmetic_impl)]
    impl<Mod: ModTrait> Sub for Mint<Mod> {
        type Output = Self;

        #[inline]
        fn sub(self, rhs: Self) -> Self {
            let value = self.0 - rhs.0;
            Self::from_value_unchecked(if 0 <= value {
                value
            } else {
                value + Mod::modulus()
            })
        }
    }

    #[allow(clippy::suspicious_arithmetic_impl)]
    impl<Mod: ModTrait> Mul for Mint<Mod> {
        type Output = Self;

        #[inline]
        fn mul(self, rhs: Self) -> Self {
            Self::from_value_unchecked(self.0 * rhs.0 % Mod::modulus())
        }
    }

    #[allow(clippy::suspicious_arithmetic_impl)]
    impl<Mod: ModTrait> Div for Mint<Mod> {
        type Output = Self;

        #[inline]
        fn div(self, rhs: Self) -> Self {
            self * rhs.inv()
        }
    }

    impl<Mod: ModTrait> Neg for Mint<Mod> {
        type Output = Self;

        #[inline]
        fn neg(self) -> Self {
            if self.0 == 0 {
                Self::zero()
            } else {
                Self::from_value_unchecked(Mod::modulus() - self.0)
            }
        }
    }

    impl<Mod: ModTrait> Neg for &Mint<Mod> {
        type Output = Mint<Mod>;

        #[inline]
        fn neg(self) -> Self::Output {
            (*self).neg()
        }
    }

    macro_rules! forward_assign_biop {
        ($(impl $trait: ident, $fn_assign: ident, $fn: ident)*) => {
            $(
                impl<Mod: ModTrait> $trait for Mint<Mod> {
                    #[inline]
                    fn $fn_assign(&mut self, rhs: Self) {
                        *self = self.$fn(rhs);
                    }
                }
            )*
        };
    }

    forward_assign_biop! {
        impl AddAssign, add_assign, add
        impl SubAssign, sub_assign, sub
        impl MulAssign, mul_assign, mul
        impl DivAssign, div_assign, div
    }

    forward_ref_binop! {
        impl Add, add
        impl Sub, sub
        impl Mul, mul
        impl Div, div
    }

    forward_ref_op_assign! {
        impl AddAssign, add_assign
        impl SubAssign, sub_assign
        impl MulAssign, mul_assign
        impl DivAssign, div_assign
    }

    impl<Mod: ModTrait> PartialEq for Mint<Mod> {
        fn eq(&self, other: &Self) -> bool {
            self.0 == other.0
        }
    }
    impl<Mod: ModTrait> Eq for Mint<Mod> {}
    impl<Mod: ModTrait> Ord for Mint<Mod> {
        fn cmp(&self, other: &Self) -> Ordering {
            self.0.cmp(&other.0)
        }
    }
    impl<Mod: ModTrait> PartialOrd for Mint<Mod> {
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl<Mod: ModTrait> From<ModValue> for Mint<Mod> {
        fn from(value: ModValue) -> Self {
            Self::from_i64(value)
        }
    }

    impl<Mod: ModTrait> From<Mint<Mod>> for ModValue {
        fn from(mint: Mint<Mod>) -> Self {
            mint.0
        }
    }

    impl<Mod: ModTrait> Sum for Mint<Mod> {
        fn sum<I>(iter: I) -> Self
        where
            I: Iterator<Item = Self>,
        {
            iter.fold(Self::zero(), Add::add)
        }
    }
    impl<'a, Mod: 'a + ModTrait> Sum<&'a Self> for Mint<Mod> {
        fn sum<I>(iter: I) -> Self
        where
            I: Iterator<Item = &'a Self>,
        {
            iter.fold(Self::zero(), Add::add)
        }
    }
    impl<Mod: ModTrait> Product for Mint<Mod> {
        fn product<I>(iter: I) -> Self
        where
            I: Iterator<Item = Self>,
        {
            iter.fold(Self::one(), Mul::mul)
        }
    }
    impl<'a, Mod: 'a + ModTrait> Product<&'a Self> for Mint<Mod> {
        fn product<I>(iter: I) -> Self
        where
            I: Iterator<Item = &'a Self>,
        {
            iter.fold(Self::one(), Mul::mul)
        }
    }

    #[macro_export]
    macro_rules! mint {
        ($value: expr) => {
            Mint::from_i64($value)
        };
    }

    #[macro_export]
    macro_rules! from_frac {
        ($num: expr, $den: expr) => {
            Mint::from_frac($num, $den)
        };
    }

    #[macro_export]
    macro_rules! from_pow {
        ($a: expr, $b: expr) => {
            Mint::from_pow($a, $b)
        };
    }

    pub trait ModTrait: Clone + Copy + Debug {
        fn modulus() -> ModValue;
    }

    #[derive(Debug, Clone)]
    pub struct Factorial<Mod: ModTrait> {
        normal: Vec<Mint<Mod>>,
        inverse: Vec<Mint<Mod>>,
    }

    impl<Mod: ModTrait> Factorial<Mod> {
        pub fn is_empty(&self) -> bool {
            self.normal.is_empty()
        }
        pub fn len(&self) -> usize {
            self.normal.len()
        }
        pub fn with_len(len: usize) -> Self {
            if len == 0 {
                Self {
                    normal: Vec::new(),
                    inverse: Vec::new(),
                }
            } else {
                let mut normal = vec![Mint::one(); len];
                for i in 1..len {
                    normal[i] = normal[i - 1] * Mint::from_i64(i as i64);
                }
                let mut inverse = vec![normal.last().unwrap().inv(); len];
                for i in (1..len).rev() {
                    inverse[i - 1] = inverse[i] * Mint::from_i64(i as i64);
                }
                Self { normal, inverse }
            }
        }
        pub fn inv(&self, i: usize) -> Mint<Mod> {
            self.inverse[i]
        }
        pub fn falling(&self, n: usize, p: usize) -> Mint<Mod> {
            if p == 0 {
                Mint::one()
            } else if n < p {
                Mint::zero()
            } else {
                self[n] * self.inv(n - p)
            }
        }
        pub fn binom(&self, n: usize, k: usize) -> Mint<Mod> {
            if k == 0 {
                Mint::one()
            } else if n < k {
                Mint::zero()
            } else {
                self[n] * self.inv(n - k) * self.inv(k)
            }
        }
    }

    impl<Mod: ModTrait, I: std::slice::SliceIndex<[Mint<Mod>]>> std::ops::Index<I> for Factorial<Mod> {
        type Output = I::Output;

        #[inline]
        fn index(&self, index: I) -> &Self::Output {
            &self.normal[index]
        }
    }

    #[derive(Clone, Copy, Debug)]
    pub struct Mod100000007 {}
    #[derive(Clone, Copy, Debug)]
    pub struct Mod998244353 {}
    impl ModTrait for Mod100000007 {
        fn modulus() -> ModValue {
            1_000_000_007
        }
    }
    impl ModTrait for Mod998244353 {
        fn modulus() -> ModValue {
            998_244_353
        }
    }
    pub type Mint100000007 = Mint<Mod100000007>;

    pub type Mint998244353 = Mint<Mod998244353>;
}
// }}}
type Mint = modint::Mint998244353;

fn main() {
    input!(n: usize, xy: [(i32, i32); n]);
    let max = 10_000;
    let mut g = vec![vec![false; max + 1]; max + 1];
    for &(x, y) in &xy {
        g[x as usize][y as usize] = true;
    }
    let mut pow_of_two = vec![Mint::one(); n + 1];
    for i in 0..n {
        pow_of_two[i + 1] = pow_of_two[i] + pow_of_two[i];
    }
    let mut ans = pow_of_two[n] - Mint::from_i64(n as i64) - Mint::one();
    for &(x, y) in &xy {
        for &(x1, y1) in xy.iter().filter(|&p| p != &(x, y)) {
            let mut pts = vec![(x, y), (x1, y1)];
            for &(x2, y2) in xy.iter().filter(|&p| p != &(x, y) && p != &(x1, y1)) {
                let det = (x1 - x) * (y2 - y) - (x2 - x) * (y1 - y);
                if det == 0 {
                    pts.push((x2, y2));
                }
            }
            pts.sort();
            if pts[0] == (x, y) && pts[1] == (x1, y1) {
                let cnt = pts.len();
                ans -= pow_of_two[cnt] - Mint::from_i64(cnt as i64) - Mint::one();
            }
        }
    }
    println!("{}", ans);
}