#include <bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int n;
vector<pair<int, int> > ed;
class Point {
 public:
  int x, y, c, id;
  Point() {}
  Point(int x_, int y_, int c_, int id_) : x(x_), y(y_), c(c_), id(id_) {}
  inline bool operator<(const Point &oth) const {
    return make_pair(x, id) < make_pair(oth.x, oth.id);
  }
  inline int operator^(const Point &oth) const { return x * oth.y - y * oth.x; }
  inline bool operator!=(const Point &oth) const { return id != oth.id; }
  inline Point operator-(const Point &oth) const {
    return Point(x - oth.x, y - oth.y, -1, -1);
  }
};
inline int isNeg(int x) { return x < 0; }
inline void sameColour(vector<Point> &vec, Point p) {
  for (int i = (0); i < (vec.size()); ++i)
    if (vec[i].id != p.id) ed.push_back(make_pair(vec[i].id, p.id));
  return;
}
inline bool inTriangle(Point p, Point a, Point b, Point c) {
  bool f1 = isNeg((p - a) ^ (p - b)), f2 = isNeg((p - b) ^ (p - c)),
       f3 = isNeg((p - c) ^ (p - a));
  return (f1 == f2 && f2 == f3);
}
inline void solve(vector<Point> &tr, Point p, Point q, Point r) {
  int col = p.c ^ q.c ^ r.c, sid = -1;
  for (int i = (0); i < (tr.size()); ++i)
    if (tr[i].c == col && tr[i] != p && tr[i] != q && tr[i] != r) {
      sid = i;
      break;
    }
  if (!~sid) {
    sameColour(tr, (p.c == col) ? ((q.c == col) ? r : q) : p);
    return;
  }
  Point s = tr[sid];
  vector<Point> ntr;
  ntr.clear();
  for (int i = (0); i < (tr.size()); ++i)
    if (inTriangle(tr[i], p, q, s)) ntr.push_back(tr[i]);
  solve(ntr, p, q, s);
  ntr.clear();
  for (int i = (0); i < (tr.size()); ++i)
    if (inTriangle(tr[i], q, r, s)) ntr.push_back(tr[i]);
  solve(ntr, q, r, s);
  ntr.clear();
  for (int i = (0); i < (tr.size()); ++i)
    if (inTriangle(tr[i], r, p, s)) ntr.push_back(tr[i]);
  solve(ntr, r, p, s);
  ed.push_back(make_pair(
      s.id, (p.c == s.c) * p.id + (q.c == s.c) * q.id + (r.c == s.c) * r.id));
  return;
}
inline vector<Point> convex(vector<Point> vec) {
  sort(vec.begin(), vec.end());
  Point upp[maxn], low[maxn];
  int p = 0, q = 0;
  for (int i = (0); i < (vec.size()); ++i) {
    for (; p > 1 && ((vec[i] - upp[p - 1]) ^ (vec[i] - upp[p - 2])) <= 0; --p)
      ;
    upp[p++] = vec[i];
    for (; q > 1 && ((vec[i] - low[q - 1]) ^ (vec[i] - low[q - 2])) >= 0; --q)
      ;
    low[q++] = vec[i];
  }
  vector<Point> ret;
  for (int i = (0); i < (p); ++i) ret.push_back(upp[i]);
  for (int i = q - 2; i > 0; --i) ret.push_back(low[i]);
  return ret;
}
int main() {
  scanf("%d", &n);
  vector<Point> all;
  for (int i = (0); i < (n); ++i) {
    int x, y, c;
    scanf("%d%d%d", &x, &y, &c);
    all.push_back(Point(x, y, c, i));
  }
  vector<Point> hull = convex(all);
  int p = -1, q = -1;
  for (int i = (0); i < (hull.size()); ++i) {
    if (hull[i].c != hull[(i + 1) % hull.size()].c) {
      if (!~p)
        p = i;
      else if (!~q)
        q = i;
      else {
        puts("Impossible");
        return 0;
      }
    }
  }
  if (!~p) {
    for (int i = (0); i < (all.size()); ++i)
      if (all[i].c != hull[0].c) p = i;
    if (!~p)
      sameColour(all, all[0]);
    else {
      for (int i = (0); i < (hull.size()); ++i) {
        vector<Point> tr;
        for (int j = (0); j < (all.size()); ++j)
          if (inTriangle(all[j], all[p], hull[i], hull[(i + 1) % hull.size()]))
            tr.push_back(all[j]);
        solve(tr, all[p], hull[i], hull[(i + 1) % hull.size()]);
        if (i)
          ed.push_back(make_pair(hull[i].id, hull[(i + 1) % hull.size()].id));
      }
    }
  } else {
    for (int i = (0); i < (hull.size()); ++i)
      if (hull[i].c != hull[p].c &&
          hull[i].c == hull[(i + 1) % hull.size()].c) {
        vector<Point> tr;
        for (int j = (0); j < (all.size()); ++j)
          if (inTriangle(all[j], hull[p], hull[i], hull[(i + 1) % hull.size()]))
            tr.push_back(all[j]);
        solve(tr, hull[p], hull[i], hull[(i + 1) % hull.size()]);
        ed.push_back(make_pair(hull[i].id, hull[(i + 1) % hull.size()].id));
      }
    for (int i = (0); i < (hull.size()); ++i)
      if (hull[i].c != hull[q].c &&
          hull[i].c == hull[(i + 1) % hull.size()].c) {
        vector<Point> tr;
        for (int j = (0); j < (all.size()); ++j)
          if (inTriangle(all[j], hull[q], hull[i], hull[(i + 1) % hull.size()]))
            tr.push_back(all[j]);
        solve(tr, hull[q], hull[i], hull[(i + 1) % hull.size()]);
        ed.push_back(make_pair(hull[i].id, hull[(i + 1) % hull.size()].id));
      }
  }
  sort(ed.begin(), ed.end());
  ed.erase(unique(ed.begin(), ed.end()), ed.end());
  printf("%d\n", ed.size());
  for (int i = (0); i < (ed.size()); ++i)
    printf("%d %d\n", ed[i].first, ed[i].second);
  return 0;
}
