#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
struct point {
  int x, y, c, id;
  point() {}
  point(int x, int y) : x(x), y(y) {}
  point operator-(const point &b) const { return {x - b.x, y - b.y}; }
  int operator^(const point &b) const { return x * b.y - y * b.x; }
  bool operator<(const point &b) const {
    if (x == b.x) return x < b.x;
    return y < b.y;
  }
  void read(int i) {
    scanf("%d %d %d", &x, &y, &c);
    id = i;
  }
};
int n;
vector<point> p, v;
vector<point> ch(vector<point> p) {
  sort(p.begin(), p.end());
  int n = p.size(), k = 0;
  if (n <= 2) return p;
  vector<point> h(2 * n);
  for (int i = 0; i < n; i++) {
    while (k >= 2 and ((h[k - 1] - h[k - 2]) ^ (p[i] - h[k - 2])) <= 0) k--;
    h[k++] = p[i];
  }
  for (int i = n - 2, t = k + 1; i >= 0; i--) {
    while (k >= t and ((h[k - 1] - h[k - 2]) ^ (p[i] - h[k - 2])) <= 0) k--;
    h[k++] = p[i];
  }
  h.resize(k - 1);
  return h;
}
inline bool go(const point &pt, point a, point b, point c) {
  if (((b - a) ^ (c - a)) < 0) swap(b, c);
  if (((b - a) ^ (pt - a)) <= 0) return false;
  if (((c - a) ^ (pt - a)) >= 0) return false;
  return true;
}
inline bool dentro(const point &pt, const point &a, const point &b,
                   const point &c) {
  if (!go(pt, a, b, c)) return false;
  if (!go(pt, b, c, a)) return false;
  if (!go(pt, c, a, b)) return false;
  return true;
}
vector<pair<int, int> > ans;
void go(const point &a, const point &b, const point &c) {
  int cnt[2] = {0, 0};
  cnt[a.c]++;
  cnt[b.c]++;
  cnt[c.c]++;
  int cor = 0;
  if (cnt[1] == 2) cor = 1;
  for (point pt : p) {
    if (pt.c != cor and dentro(pt, a, b, c)) {
      if (a.c == pt.c)
        ans.emplace_back(a.id, pt.id);
      else if (b.c == pt.c)
        ans.emplace_back(b.id, pt.id);
      else if (c.c == pt.c)
        ans.emplace_back(c.id, pt.id);
      go(pt, a, b);
      go(pt, a, c);
      go(pt, b, c);
      return;
    }
  }
  return;
  for (point pt : p)
    if (dentro(pt, a, b, c)) {
      if (a.c == cor)
        ans.emplace_back(a.id, pt.id);
      else
        ans.emplace_back(b.id, pt.id);
    }
}
int main(void) {
  scanf("%d", &n);
  p = vector<point>(n);
  for (int i = 0; i < n; i++) p[i].read(i);
  v = ch(p);
  int cnt = 0;
  int at = v[0].c;
  for (point pt : v)
    if (pt.c != at) {
      cnt++;
      at = pt.c;
    }
  if (cnt > 2) {
    printf("Impossible\n");
    return 0;
  }
  if (!cnt) {
    point center;
    for (point pt : p)
      if (pt.c != v[0].c) center = pt;
    for (int i = 0; i < (int)v.size(); i++) {
      int j = (i + 1) % v.size();
      if (i != v.size() - 1) ans.emplace_back(v[i].id, v[j].id);
      go(p[i], p[j], center);
    }
  } else {
    int id = 0;
    for (int i = 0; i < (int)v.size(); i++) {
      if (v[i].c != v[0].c) {
        id = i;
        for (int j = 0; j < (int)v.size(); j++) {
          int k = (j + 1) % v.size();
          if (v[j].c == v[k].c and v[j].c == v[0].c) {
            go(v[j], v[k], v[i]);
            ans.emplace_back(v[j].id, v[k].id);
          }
        }
        break;
      }
    }
    for (int i = id;; i = (i + 1) % v.size()) {
      if (v[i].c == v[0].c) {
        for (int j = 0; j < (int)v.size(); j++) {
          int k = (j + 1) % v.size();
          if (v[j].c == v[k].c and v[j].c != v[0].c) {
            go(v[j], v[k], v[i]);
            ans.emplace_back(v[j].id, v[k].id);
          }
        }
        break;
      }
    }
  }
  printf("%d\n", (int)ans.size());
  for (auto it : ans) printf("%d %d\n", it.first, it.second);
  return 0;
}
