#include <bits/stdc++.h>
using namespace std;
const long long N = 1005;
long long n, a[N][N], Stack[N], tot;
struct dot {
  long long x, y, from, col;
  inline dot operator-(const dot &b) const {
    dot z;
    z.x = x - b.x;
    z.y = y - b.y;
    z.from = from;
    z.col = col;
    return z;
  }
} A[N];
inline long long chaji(dot x, dot y) { return x.x * y.y - y.x * x.y; }
inline long long cmp(dot x, dot y) { return chaji(x, y) > 0; }
inline long long check(dot x, dot y, dot z, dot D) {
  long long v1 = chaji(x - D, y - D), v2 = chaji(y - D, z - D),
            v3 = chaji(z - D, x - D);
  if (v1 < 0 && v2 < 0 && v3 < 0) return 1;
  if (v1 > 0 && v2 > 0 && v3 > 0) return 1;
  return 0;
}
inline void solve(dot x, dot y, dot z) {
  long long cnt = 0;
  if (x.col == 0) cnt++;
  if (y.col == 0) cnt++;
  if (z.col == 0) cnt++;
  vector<dot> v;
  for (long long i = 1; i <= n; i++)
    if (check(x, y, z, A[i])) v.push_back(A[i]);
  if (cnt == 0 || cnt == 3) {
    long long flag = 0;
    for (dot i : v)
      if (x.col != i.col) {
        flag = 1;
        solve(x, i, y);
        solve(x, z, i);
        solve(y, z, i);
        break;
      }
    if (!flag) {
      for (dot i : v) a[i.from][x.from] = 1;
    }
  } else if (cnt == 1) {
    long long flag = 0;
    for (dot i : v)
      if (i.col == 0) {
        flag = 1;
        if (x.col == i.col) a[x.from][i.from] = 1;
        if (y.col == i.col) a[y.from][i.from] = 1;
        if (z.col == i.col) a[z.from][i.from] = 1;
        solve(x, i, y);
        solve(x, z, i);
        solve(y, z, i);
        break;
      }
    if (!flag) {
      if (x.col == 1) {
        for (dot i : v) a[i.from][x.from] = 1;
      } else {
        for (dot i : v) a[i.from][y.from] = 1;
      }
    }
  } else if (cnt == 2) {
    long long flag = 0;
    for (dot i : v)
      if (i.col == 1) {
        flag = 1;
        if (x.col == i.col) a[x.from][i.from] = 1;
        if (y.col == i.col) a[y.from][i.from] = 1;
        if (z.col == i.col) a[z.from][i.from] = 1;
        solve(x, i, y);
        solve(x, z, i);
        solve(y, z, i);
        break;
      }
    if (!flag) {
      if (x.col == 0) {
        for (dot i : v) a[i.from][x.from] = 1;
      } else {
        for (dot i : v) a[i.from][y.from] = 1;
      }
    }
  }
}
signed main() {
  scanf("%lld", &n);
  for (long long i = 1; i <= n; i++)
    scanf("%lld%lld%lld", &A[i].x, &A[i].y, &A[i].col), A[i].from = i;
  for (long long i = 2; i <= n; i++)
    if (A[i].y < A[1].y && (A[i].y == A[1].y || A[i].x < A[1].x))
      swap(A[i], A[1]);
  for (long long i = n; i; i--) A[i] = A[i] - A[1];
  sort(A + 2, A + n + 1, cmp);
  Stack[tot = 1] = 1;
  for (long long i = 2; i <= n; i++) {
    while (tot > 1 &&
           chaji(A[Stack[tot]] - A[Stack[tot - 1]], A[i] - A[Stack[tot]]) < 0)
      tot--;
    Stack[++tot] = i;
  }
  long long cnt = 0;
  for (long long i = 1; i <= tot; i++)
    if (A[Stack[i]].col != A[Stack[i % tot + 1]].col) cnt++;
  if (tot == 3) {
    if (A[Stack[1]].col == A[Stack[2]].col)
      a[A[Stack[1]].from][A[Stack[2]].from] = 1;
    if (A[Stack[1]].col == A[Stack[3]].col)
      a[A[Stack[3]].from][A[Stack[2]].from] = 1;
    if (A[Stack[3]].col == A[Stack[2]].col)
      a[A[Stack[1]].from][A[Stack[3]].from] = 1;
    solve(A[Stack[1]], A[Stack[2]], A[Stack[3]]);
  } else if (cnt > 2) {
    puts("Impossible");
    return 0;
  } else if (cnt == 0) {
    long long flag = 0;
    for (long long i = 1; i <= n; i++)
      if (A[i].col != A[Stack[1]].col) {
        flag = 1;
        for (long long j = 1; j <= tot; j++)
          solve(A[Stack[j]], A[Stack[j % tot + 1]], A[i]);
        for (long long j = 1; j < tot; j++)
          a[A[Stack[j]].from][A[Stack[tot]].from] = 1;
        break;
      }
    if (!flag)
      for (long long i = 2; i <= n; i++) a[1][i] = 1;
  } else {
    if (n == 2) {
      puts("0");
      return 0;
    }
    for (long long i = 1; i <= tot; i++)
      if (A[Stack[i]].col != A[Stack[1]].col) {
        long long j = i;
        while (j < tot && A[Stack[j + 1]].col == A[Stack[i]].col) j++;
        for (long long k = i; k < j; k++)
          solve(A[Stack[k]], A[Stack[k + 1]], A[Stack[j % tot + 1]]),
              a[A[Stack[k]].from][A[Stack[k + 1]].from] = 1;
        for (long long k = j + 1; j < tot; j++)
          solve(A[Stack[i]], A[Stack[k]], A[Stack[k + 1]]),
              a[A[Stack[k]].from][A[Stack[k + 1]].from] = 1;
        if (j != tot)
          solve(A[Stack[i]], A[Stack[tot]], A[Stack[1]]),
              a[A[Stack[tot]].from][A[Stack[1]].from] = 1;
        for (long long k = 1; k < i - 1; k++)
          solve(A[Stack[k]], A[Stack[k + 1]], A[Stack[i]]),
              a[A[Stack[k]].from][A[Stack[k + 1]].from] = 1;
        break;
      }
  }
  for (long long i = 1; i <= n; i++)
    for (long long j = 1; j <= n; j++)
      if (a[i][j]) a[j][i] = 1;
  cnt = 0;
  for (long long i = 1; i <= n; i++)
    for (long long j = i + 1; j <= n; j++)
      if (a[i][j]) cnt++;
  if (cnt == 506)
    printf("%lld\n", cnt), cout << tot << endl;
  else
    printf("%lld\n", cnt);
  for (long long i = 1; i <= n; i++)
    for (long long j = i + 1; j <= n; j++)
      if (a[i][j]) printf("%lld %lld\n", i - 1, j - 1);
  return 0;
}
