#include <bits/stdc++.h>
using namespace std;
int get() {
  char ch;
  while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-')
    ;
  if (ch == '-') {
    int s = 0;
    while (ch = getchar(), ch >= '0' && ch <= '9') s = s * 10 + ch - '0';
    return -s;
  }
  int s = ch - '0';
  while (ch = getchar(), ch >= '0' && ch <= '9') s = s * 10 + ch - '0';
  return s;
}
const int N = 1e3 + 5;
int n;
struct point {
  int x, y, col, id;
  void read() {
    x = get();
    y = get();
    col = get();
  }
} a[N];
int cross(point a, point b, point c) {
  return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
int operator*(point a, point b) { return a.x * b.y - a.y * b.x; }
point operator-(point a, point b) {
  a.x -= b.x, a.y -= b.y;
  return a;
}
point operator+(point a, point b) {
  a.x += b.x, a.y += b.y;
  return a;
}
int be[N];
point sta[N];
int top;
bool cmp(point a, point b) { return a.x == b.x ? a.y < b.y : a.x < b.x; }
struct edge {
  int x, y;
  edge(const int x_ = 0, const int y_ = 0) {
    x = x_;
    y = y_;
  }
} ed[N];
int tot;
point que[N];
int k;
bool inside(point a, point b, point c, point q) {
  return ((cross(a, b, q) >= 0) != (cross(a, c, q) >= 0)) &&
         ((cross(b, a, q) >= 0) != cross(b, c, q) >= 0) &&
         ((cross(c, a, q) >= 0) != (cross(c, b, q) >= 0));
}
void solve(point A, point B, point C) {
  for (int i = 1; i <= n; i++)
    if (a[i].col == C.col && inside(A, B, C, a[i])) {
      ed[++tot] = edge(C.id, a[i].id);
      solve(A, B, a[i]);
      solve(a[i], C, A);
      solve(a[i], C, B);
      return;
    }
  for (int i = 1; i <= n; i++)
    if (inside(A, B, C, a[i])) ed[++tot] = edge(A.id, a[i].id);
}
int main() {
  n = get();
  int all = 0;
  for (int i = 1; i <= n; i++) {
    a[i].read();
    a[i].id = i;
    all |= 1 << a[i].col;
  }
  if (all != 3) {
    printf("%d\n", n - 1);
    for (int i = 1; i <= n - 1; i++) printf("%d %d\n", 0, i);
    return 0;
  }
  sort(a + 1, a + 1 + n, cmp);
  top = 0;
  for (int i = 1; i <= n; i++) {
    if (top && sta[top].x == a[i].x) continue;
    while (top > 1 && cross(sta[top - 1], a[i], sta[top]) >= 0) top--;
    sta[++top] = a[i];
  }
  for (int i = 1; i <= top; i++) be[sta[i].id] = 1;
  top = 0;
  for (int i = n; i >= 1; i--) {
    if (top && sta[top].x == a[i].x) continue;
    while (top > 1 && cross(sta[top - 1], a[i], sta[top]) >= 0) top--;
    sta[++top] = a[i];
  }
  for (int i = 1; i <= top; i++)
    if (!be[sta[i].id]) be[sta[i].id] = 2;
  k = 0;
  for (int i = 1; i <= n; i++)
    if (be[a[i].id] == 1) que[++k] = a[i];
  for (int i = n; i >= 1; i--)
    if (be[a[i].id] == 2) que[++k] = a[i];
  int cnt = 0, keyw = 0;
  for (int i = 1; i <= k; i++)
    if (que[i].col != que[(i + k - 2) % k + 1].col) {
      cnt++;
      keyw = i;
    }
  if (cnt > 2) return printf("Impossible\n"), 0;
  if (cnt == 0) {
    for (int i = 1; i <= k - 1; i++) ed[++tot] = edge(que[i].id, que[i + 1].id);
    point other;
    for (int i = 1; i <= n; i++)
      if (a[i].col != que[1].col) {
        other = a[i];
        break;
      }
    for (int i = 1; i <= k - 1; i++) solve(que[i], que[i + 1], other);
    solve(que[k], que[1], other);
  } else {
    int x = keyw;
    for (; que[x].col == que[keyw].col; x = x % k + 1) {
      if (que[x].col == que[x % k + 1].col) {
        solve(que[x], que[x % k + 1], que[(keyw + k - 2) % k + 1]);
        ed[++tot] = edge(que[x].id, que[x % k + 1].id);
      }
    }
    int lst = (x + k - 2) % k + 1;
    for (; x != keyw; x = x % k + 1) {
      if (que[x].col == que[x % k + 1].col) {
        solve(que[x], que[x % k + 1], que[lst]);
        ed[++tot] = edge(que[x].id, que[x % k + 1].id);
      }
    }
  }
  printf("%d\n", tot);
  for (int i = 1; i <= tot; i++) printf("%d %d\n", ed[i].x - 1, ed[i].y - 1);
  return 0;
}
