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 C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second
template<typename A, typename B> inline bool chmax(A &a, B b) { if (a<b) { a=b; return 1; } return 0; }
template<typename A, typename B> inline bool chmin(A &a, B b) { if (a>b) { a=b; return 1; } return 0; }
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, pii> pip;
const ll INF = 1e9+100;
const ll MOD = 1e9+7;
const double EPS = 1e-10;
const bool debug = 0;
//------------------------------//

ll mod = 998244353;
int N;
vector<pii> p;
int cnt[11234];

ll mod_pow(ll x, ll n, ll mod) {
	if (n == 0) return 1;
	ll res = mod_pow(x * x % mod, n / 2, mod);
	if (n & 1) res = res * x % mod;
	return res;
}

int calcn(int x) { // a*(a-1)/2 = xを満たすxを求める
	int l = 1, r = INF;
	while (r - l > 1) {
		int m = (l + r) / 2;
		if ((ll)m * (m - 1) / 2 <= x) l = m;
		else r = m;
	}
	return l;
}

int main() {
	cin >> N;
	p.resize(N);
	REP(i, N) {
		int a, b;
		scanf("%d %d", &a, &b);
		p[i] = pii(a, b);
	}
	sort(ALL(p));
	
	ll ans = (mod_pow(2, N, mod) - 1 - N + mod) % mod;
	
	REP(i, N) cnt[p[i].fi]++;
	REP(i, 11234) { // x=iの線分
		ll now = (mod_pow(2, cnt[i], mod) - 1 - cnt[i] + mod) % mod;
		ans = (ans - now + mod) % mod;
	}
	
	map<pll, int> m; // (傾き, x=0でのy)*1e8
	REP(i, N) {
		REP(j, i) {
			if (p[i].fi == p[j].fi) continue;
			long double a = (long double)(p[i].se - p[j].se) / (p[i].fi - p[j].fi);
			long double b = p[i].se - a * p[i].fi;
			m[make_pair((ll)round(a * 1e8), (ll)round(b * 1e8))]++;
		}
	}
	
	for (map<pll, int>::iterator it = m.begin(); it != m.end(); ++it) {
		int c = calcn(it->se);
		ll now = (mod_pow(2, c, mod) - 1 - c + mod) % mod;
		ans = (ans - now + mod) % mod;
	}
	
	cout << ans << endl;
	
	
	return 0;
}