#include <bits/stdc++.h>
using namespace std;
struct pt {
  long long x, y;
  int id;
  pt() {}
  pt(long long a, long long b, int c = -1) : x(a), y(b), id(c) {}
};
pt operator+(pt a, pt b) { return pt(a.x + b.x, a.y + b.y); }
pt operator-(pt a, pt b) { return pt(a.x - b.x, a.y - b.y); }
long long dot(pt a, pt b) { return a.x * b.x + a.y * b.y; }
long long cross(pt a, pt b) { return a.x * b.y - a.y * b.x; }
long long sq(pt a) { return dot(a, a); }
long long dist(pt a, pt b) { return sq(a - b); }
bool operator<(pt a, pt b) { return make_pair(a.x, a.y) < make_pair(b.x, b.y); }
vector<pt> ConvexHull(vector<pt> a) {
  sort(a.begin(), a.end());
  vector<pt> b;
  for (int i = 0; i < a.size(); i++) {
    while (b.size() > 1 &&
           cross(a[i] - b.back(), b[b.size() - 2] - b.back()) <= 0)
      b.pop_back();
    b.push_back(a[i]);
  }
  int sz = b.size();
  for (int i = (int)a.size() - 2; i >= 0; i--) {
    while (b.size() > sz &&
           cross(a[i] - b.back(), b[b.size() - 2] - b.back()) <= 0)
      b.pop_back();
    b.push_back(a[i]);
  }
  b.pop_back();
  return b;
}
const int N = 1050;
int ty[N];
void rot(vector<pt> &a) {
  int p = -1;
  for (int i = 1; i < a.size(); i++)
    if (ty[a[i].id] != ty[a[0].id]) {
      p = i;
      break;
    }
  if (p == -1) return;
  vector<pt> b;
  for (int i = 0; i < a.size(); i++) b.push_back(a[(i + p) % a.size()]);
  a = b;
}
vector<pair<int, int> > edges;
void AddEdge(int u, int v) { edges.push_back(make_pair(u, v)); }
long long Area(pt a, pt b, pt c) {
  return abs(cross(a, b) + cross(b, c) + cross(c, a));
}
bool Inside(pt a, pt b, pt c, pt d) {
  return Area(a, b, c) == Area(a, b, d) + Area(a, c, d) + Area(b, c, d);
}
void SolveTriangle(pt a, pt b, pt c, vector<pt> ps) {
  int p = -1;
  for (int i = 0; i < ps.size(); i++)
    if (ty[ps[i].id] == ty[c.id]) p = i;
  if (p == -1) {
    for (int i = 0; i < ps.size(); i++) AddEdge(a.id, ps[i].id);
  } else {
    pt d = ps[p];
    AddEdge(d.id, c.id);
    vector<pt> nxt[3];
    for (int i = 0; i < ps.size(); i++)
      if (i != p) {
        if (Inside(a, b, d, ps[i]))
          nxt[0].push_back(ps[i]);
        else if (Inside(c, d, a, ps[i]))
          nxt[1].push_back(ps[i]);
        else
          nxt[2].push_back(ps[i]);
      }
    SolveTriangle(a, b, d, nxt[0]);
    SolveTriangle(c, d, a, nxt[1]);
    SolveTriangle(c, d, b, nxt[2]);
  }
}
bool Check(vector<pt> hull) {
  int l = -1, r = hull.size();
  while (l + 1 < hull.size() && ty[hull[l + 1].id] == ty[hull[0].id]) l++;
  while (r - 1 >= 0 && ty[hull[r - 1].id] == ty[hull.back().id]) r--;
  if (r - l > 1) return 0;
  return 1;
}
bool onHull[N];
void Triangulate(vector<pt> a) {
  vector<pt> hull = ConvexHull(a);
  rot(hull);
  if (!Check(hull)) {
    printf("Impossible\n");
    exit(0);
  }
  for (int i = 0; i < hull.size(); i++) onHull[hull[i].id] = 1;
  if (ty[hull[0].id] == ty[hull.back().id]) {
    for (int i = 0; i + 1 < hull.size(); i++)
      AddEdge(hull[i].id, hull[i + 1].id);
    int p = -1;
    for (int i = 0; i < a.size(); i++)
      if (!onHull[a[i].id]) {
        if (ty[a[i].id] != ty[hull[0].id]) {
          p = i;
          break;
        }
      }
    if (p != -1) {
      for (int i = 0; i < hull.size(); i++) {
        pt A = hull[i], B = hull[(i + 1) % hull.size()], C = a[p];
        vector<pt> work;
        for (int j = 0; j < a.size(); j++)
          if (!onHull[a[j].id] && j != p) {
            if (Inside(A, B, C, a[j])) work.push_back(a[j]);
          }
        SolveTriangle(A, B, C, work);
      }
    } else {
      for (int i = 0; i < a.size(); i++)
        if (!onHull[a[i].id]) AddEdge(hull[0].id, a[i].id);
    }
  } else {
    int p = -1;
    for (int i = 0; i < hull.size(); i++)
      if (ty[hull[i].id] != ty[hull[0].id]) {
        p = i;
        break;
      }
    if (p == -1) {
      printf("???\n");
      exit(0);
    }
    for (int i = 0; i + 1 < p; i++) {
      pt A = hull[i], B = hull[i + 1], C = hull[p];
      AddEdge(A.id, B.id);
      vector<pt> work;
      for (int j = 0; j < a.size(); j++)
        if (!onHull[a[j].id]) {
          if (Inside(A, B, C, a[j])) work.push_back(a[j]);
        }
      SolveTriangle(A, B, C, work);
    }
    for (int i = p; i + 1 < hull.size(); i++) {
      pt A = hull[i], B = hull[i + 1], C = hull[0];
      AddEdge(A.id, B.id);
      vector<pt> work;
      for (int j = 0; j < a.size(); j++)
        if (!onHull[a[j].id]) {
          if (Inside(A, B, C, a[j])) work.push_back(a[j]);
        }
      SolveTriangle(A, B, C, work);
    }
  }
}
int main() {
  int n, i;
  scanf("%i", &n);
  vector<pt> ps(n);
  for (int i = 0; i < n; i++) {
    int x, y;
    scanf("%i %i %i", &x, &y, &ty[i]);
    ps[i] = pt(x, y, i);
  }
  if (n == 1) return 0 * printf("0\n");
  if (n == 2) {
    if (ty[0] == ty[1])
      printf("1\n0 1\n");
    else
      printf("0\n");
    return 0;
  }
  Triangulate(ps);
  printf("%i\n", edges.size());
  for (auto p : edges) printf("%i %i\n", p.first, p.second);
  return 0;
}
