#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
#include <cassert>
#include <bitset>
using namespace std;
using LL = long long;

const LL m_MOD = 998244353;

//負数がないMOD関数
inline long long imod(long long a, long long b)
{
	return (a >= 0) ? (a % b) : (a % b + b);
}

//mint_base型用の累乗関数
template <long long MOD> class mint_base;
template <long long MOD> mint_base<MOD> m_pow(long long x, long long n);

//mod計算を自動で行う整数テンプレートクラス
template <long long MOD = 1000000007>
class mint_base
{
public:
	mint_base<MOD> operator+(const mint_base<MOD> &other)const
	{
		return mint_base<MOD>(imod(a + other.a, MOD));
	}
	mint_base<MOD> operator-(const mint_base<MOD> &other)const
	{
		return mint_base<MOD>(imod(a - other.a, MOD));
	}
	mint_base<MOD> operator*(const mint_base<MOD> &other)const
	{
		return mint_base<MOD>(imod(a * other.a, MOD));
	}
	mint_base<MOD> operator+=(const mint_base<MOD> &other)
	{
		a = imod(a + other.a, MOD);
		return mint_base<MOD>(a);
	}
	mint_base<MOD> operator-=(const mint_base<MOD> &other)
	{
		a = imod(a - other.a, MOD);
		return mint_base<MOD>(a);
	}
	mint_base<MOD> operator*=(const mint_base<MOD> &other)
	{
		a = imod(a * other.a, MOD);
		return mint_base<MOD>(a);
	}
	mint_base<MOD> operator+()const
	{
		return *this;
	}
	mint_base<MOD> operator-()const
	{
		return mint_base<MOD>(-a);
	}
	mint_base<MOD>& operator++()
	{
		*this += 1;
		return *this;
	}
	mint_base<MOD> operator++(int)
	{
		auto tmp = *this;
		*this += 1;
		return tmp;
	}
	mint_base<MOD>& operator--()
	{
		*this -= 1;
		return *this;
	}
	mint_base<MOD> operator--(int)
	{
		auto tmp = *this;
		*this -= 1;
		return tmp;
	}
	mint_base<MOD> operator~()const
	{
		return m_pow<MOD>(a, (long long)e_phi - 1);
	}
	mint_base<MOD>& operator=(const mint_base<MOD> &other)
	{
		a = other.a;
		return *this;
	}
	explicit operator long long()const
	{
		return a;
	}
	explicit operator int()const
	{
		return (int)a;
	}

	//無効な数値を指定された場合
	static_assert(MOD >= 2, "MOD cannot be below 2.");
	mint_base(long long a_) :a(imod(a_, MOD))
	{
		if (e_phi > 0)return;
		//オイラー値の導出
		e_phi = MOD;
		long long m_ = MOD;
		for (int i = 2; i * i <= m_; ++i)
		{
			if (m_ % i == 0)
			{
				e_phi = e_phi / i * (i - 1);
				for (; m_ % i == 0; m_ /= i);
			}
		}
		if (m_ != 1)e_phi = e_phi / m_ * (m_ - 1);
	}
	mint_base() :a(0) {}
private:
	static long long e_phi;
	long long a;
};

//mint_base型用の累乗関数
template<long long MOD>mint_base<MOD> m_pow(long long x, long long n)
{
	mint_base<MOD> res = 1;
	while (n > 0)
	{
		if (n & 1)res *= x;
		x *= x;
		x %= MOD;
		n >>= 1;
	}
	return res;
}


//mint_baseの階乗計算
//O(x)時間が必要のため、fact_set関数を推奨する。
template<long long MOD>mint_base<MOD> fact(mint_base<MOD> x)
{
	mint_base<MOD> res(1);
	for (long long i = 1; i <= (long long)x; ++i)
	{
		res *= i;
	}
	return res;
}

//mint_baseの階乗計算
//0からxまでの階乗をsetに出力する
template<long long MOD>void fact_set(std::vector<mint_base<MOD>> &set, mint_base<MOD> x = mint_base<MOD>(-1))
{
	mint_base<MOD> res(1);
	set.push_back(1);
	for (long long i = 1; i <= (long long)x; ++i)
	{
		res *= i;
		set.push_back(res);
	}
}

template<long long MOD>long long mint_base<MOD>::e_phi = -1;

//mint_base型のstreamへの出力
template<long long MOD> std::ostream& operator<<(std::ostream& os, mint_base<MOD> i)
{
	os << (long long)i;
	return os;
}

//mint_base型のstreamからの入力
template<long long MOD> std::istream& operator >> (std::istream& is, mint_base<MOD>& i)
{
	long long tmp;
	is >> tmp;
	i = tmp;
	return is;
}

typedef mint_base<m_MOD> mint;

template <typename T>
class point
{
private:
	T x_m, y_m;
public:
	point(T x_, T y_)
		:x_m(x_), y_m(y_)
	{}
	point()
		:x_m(0), y_m(0)
	{}

	T x()const
	{
		return x_m;
	}
	T y()const
	{
		return y_m;
	}

	point operator+(const point& other)const
	{
		return point(x_m + other.x(), y_m + other.y());
	}
	point operator-(const point& other)const
	{
		return point(x_m - other.x(), y_m - other.y());
	}
	point operator+()const
	{
		return *this;
	}
	point& operator+=(const point& other)const
	{
		x_m += other.x();
		y_m += other.y();
		return *this;
	}
	point& operator-=(const point& other)const
	{
		x_m -= other.x();
		y_m -= other.y();
		return *this;
	}
	point& operator*=(const T& k)const
	{
		x_m *= k;
		y_m *= k;
		return *this;
	}
	point operator-()const
	{
		return point(-x_m, -y_m);
	}
	T dot(const point& other)const
	{
		return x_m * other.x() + y_m * other.y();
	}
	T cross(const point& other)const
	{
		return x_m * other.y() - y_m * other.x();
	}
	point mult(const T& k)const
	{
		return point(x_m * k, y_m * k);
	}
};

class union_find
{
private:
	std::vector<int>parent;
	std::vector<int>rank;
	std::vector<int>clump;
public:
	union_find(int siz)
	{
		parent.resize(siz);
		rank.resize(siz);
		clump.resize(siz);
		for (int i = 0; i < siz; ++i)
		{
			parent[i] = i;
			rank[i] = 0;
			clump[i] = 1;
		}
	}
	void unite(int x, int y)
	{
		int xr = find(x);
		int yr = find(y);
		if (xr == yr)return;
		if (rank[xr] > rank[yr])
		{
			parent[yr] = xr;
			clump[xr] += clump[yr];
		}
		else if (rank[yr] > rank[xr])
		{
			parent[xr] = yr;
			clump[yr] += clump[xr];
		}
		else if (xr != yr)
		{
			parent[yr] = xr;
			clump[xr] += clump[yr];
			++rank[xr];
		}
	}
	int find(int x)
	{
		if (parent[x] == x)
		{
			return x;
		}
		else
		{
			return parent[x] = find(parent[x]);
		}
	}
	bool check(int x, int y)
	{
		return find(x) == find(y);
	}
	int size(int x)
	{
		return clump[find(x)];
	}
};



int main(void)
{
	int n;
	cin >> n;
	vector<mint>vec;
	fact_set(vec, mint(1000));
	auto cond = [&](int n,int k)
	{
		return vec[n] * ~vec[k] * ~vec[n - k];
	};
	mint ans = 0;
	for (int i = 3; i <= n; ++i)
	{
		ans += cond(n, i);
	}
	vector<point<int>>input;
	for (int i = 0; i < n; ++i)
	{
		int x, y; cin >> x >> y;
		input.push_back({ x, y });
	}
	union_find uf(n * n);//i * n + j
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < i; ++j)
		{
			for (int k = 0; k < j; ++k)
			{
				if ((input[i] - input[j]).cross(input[i] - input[k]) == 0)
				{
					uf.unite(i * n + j, j * n + k);
					uf.unite(j * n + k, k * n + i);
					uf.unite(j * n + i, k * n + j);
					uf.unite(k * n + j, i * n + k);
					uf.unite(i * n + j, j * n + i);
				}
			}
		}
	}
	map<int, set<int>>S;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < i; ++j)
		{
			int cos = uf.find(i * n + j);
			S[cos].insert(i);
			S[cos].insert(j);
		}
	}
	set<set<int>>T;
	for (auto& p : S)
	{
		if(p.second.size() > 2)
			T.insert(p.second);
	}
	for (auto& q : T)
	{
		int shuf = q.size();
		//TLE?
		for (int i = 3; i <= shuf; ++i)
		{
			ans -= cond(shuf, i);
		}
	}
	cout << ans << endl;
	return 0;
}


Measured memory_bytes: 4480