#include <bits/stdc++.h>
using namespace std;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 1000;
struct P {
  int x, y, col, id;
  P() {}
  P(int x, int y) : x(x), y(y), col(-1), id(-1) {}
};
bool operator<(const P &a, const P &b) {
  if (a.x != b.x) return a.x < b.x;
  return a.y < b.y;
}
P operator-(const P &a, const P &b) { return P(a.x - b.x, a.y - b.y); }
long long operator^(const P &a, const P &b) {
  return (long long)a.x * b.y - (long long)a.y * b.x;
}
long long side(const P &a, const P &b, const P &c) { return (b - a) ^ (c - a); }
int np;
P p[MAXN];
int nh;
P h[MAXN + 1];
void makehull() {
  sort(p, p + np);
  nh = 0;
  h[nh++] = p[0];
  int tmp;
  tmp = nh;
  for (int i = (1); i < (np); ++i) {
    while (nh > tmp && side(h[nh - 2], h[nh - 1], p[i]) < 0) --nh;
    h[nh++] = p[i];
  }
  tmp = nh;
  for (int i = np - 2; i >= 0; --i) {
    while (nh > tmp && side(h[nh - 2], h[nh - 1], p[i]) < 0) --nh;
    h[nh++] = p[i];
  }
  --nh;
}
vector<pair<int, int>> ans;
bool inside(const P &d, const P &a, const P &b, const P &c) {
  if (side(a, b, c) < 0) return inside(d, a, c, b);
  return side(a, b, d) > 0 && side(b, c, d) > 0 && side(c, a, d) > 0;
}
void solvetri(const P &a, const P &b, const P &c, const vector<P> &rem) {
  if (((int)(rem).size()) == 0) return;
  vector<int> cnt(2);
  ++cnt[a.col], ++cnt[b.col], ++cnt[c.col];
  int idx = -1;
  for (int i = (0); i < (((int)(rem).size())); ++i) {
    assert(cnt[rem[i].col] > 0);
    if (cnt[rem[i].col] == 1) {
      idx = i;
      break;
    }
    idx = i;
  }
  assert(idx != -1);
  P oth;
  if (a.col == rem[idx].col)
    oth = a;
  else if (b.col == rem[idx].col)
    oth = b;
  else if (c.col == rem[idx].col)
    oth = c;
  else
    assert(false);
  ans.push_back(make_pair(oth.id, rem[idx].id));
  vector<P> remab, rembc, remca;
  for (int i = (0); i < (((int)(rem).size())); ++i)
    if (i != idx) {
      if (inside(rem[i], rem[idx], a, b)) remab.push_back(rem[i]);
      if (inside(rem[i], rem[idx], b, c)) rembc.push_back(rem[i]);
      if (inside(rem[i], rem[idx], c, a)) remca.push_back(rem[i]);
    }
  solvetri(rem[idx], a, b, remab);
  solvetri(rem[idx], b, c, rembc);
  solvetri(rem[idx], c, a, remca);
}
void solvetri(const P &a, const P &b, const P &c) {
  vector<P> rem;
  for (int i = (0); i < (np); ++i)
    if (inside(p[i], a, b, c)) rem.push_back(p[i]);
  solvetri(a, b, c, rem);
}
bool solve() {
  ans.clear();
  makehull();
  int l = INT_MAX, r = INT_MIN;
  bool any = false;
  for (int i = (0); i < (nh); ++i)
    if (h[i].col != h[0].col) l = min(l, i), r = max(r, i), any = true;
  if (!any) {
    for (int i = (0); i < (nh - 1); ++i)
      ans.push_back(make_pair(h[i].id, h[i + 1].id));
    int diff = -1;
    for (int i = (0); i < (np); ++i)
      if (p[i].col != h[0].col) {
        diff = i;
        break;
      }
    if (diff != -1) {
      for (int i = (0); i < (nh - 1); ++i) solvetri(h[i], h[i + 1], p[diff]);
    } else {
      for (int i = (1); i <= (nh - 1); ++i) solvetri(h[0], h[i], h[i + 1]);
    }
  } else {
    for (int i = (l); i <= (r); ++i)
      if (h[i].col == h[0].col) return false;
    for (int i = (0); i < (l - 1); ++i)
      ans.push_back(make_pair(h[i].id, h[i + 1].id));
    for (int i = (l); i < (r); ++i)
      ans.push_back(make_pair(h[i].id, h[i + 1].id));
    for (int i = (r + 1); i < (nh); ++i)
      ans.push_back(make_pair(h[i].id, h[i + 1].id));
    for (int i = (0); i < (l - 1); ++i) solvetri(h[i], h[i + 1], h[r]);
    for (int i = (l); i < (r); ++i) solvetri(h[i], h[i + 1], h[l - 1]);
    for (int i = (r + 1); i < (nh); ++i) solvetri(h[i], h[i + 1], h[r]);
  }
  return true;
}
void run() {
  scanf("%d", &np);
  for (int i = (0); i < (np); ++i)
    scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].col), p[i].id = i;
  if (!solve()) {
    printf("Impossible\n");
    return;
  }
  printf("%d\n", ((int)(ans).size()));
  for (int i = (0); i < (((int)(ans).size())); ++i)
    printf("%d %d\n", ans[i].first + 1, ans[i].second + 1);
}
int main() {
  run();
  return 0;
}
