#include <bits/stdc++.h>
const int N = 1005;
int sgn(long long x) {
  if (x > 0) return 1;
  if (x < 0) return -1;
  return 0;
}
struct pt {
  long long x, y;
};
pt operator-(const pt &a, const pt &b) { return {a.x - b.x, a.y - b.y}; }
long long cross(const pt &a, const pt &b) { return a.x * b.y - a.y * b.x; }
long long orient(const pt &a, const pt &b, const pt &c) {
  return cross(b - a, c - a);
}
bool inTriangle(const pt &a, const pt &b, const pt &c, const pt &d) {
  bool flg[3] = {};
  flg[sgn(orient(a, b, d)) + 1] = true;
  flg[sgn(orient(b, c, d)) + 1] = true;
  flg[sgn(orient(c, a, d)) + 1] = true;
  return !(flg[0] && flg[2]);
}
std::vector<std::pair<pt, std::pair<int, int> > > Convex(
    std::vector<std::pair<pt, std::pair<int, int> > > &p) {
  std::vector<std::pair<pt, std::pair<int, int> > > q;
  std::sort(p.begin(), p.end(),
            [](const std::pair<pt, std::pair<int, int> > &a,
               const std::pair<pt, std::pair<int, int> > &b) {
              return a.first.x < b.first.x;
            });
  for (int T = 2; T--;) {
    int qn = q.size(), tot = 0;
    for (auto i = p.begin(); i != p.end(); ++i) {
      while (tot > 1 &&
             orient(q[qn + tot - 2].first, q[qn + tot - 1].first, i->first) > 0)
        --tot, q.pop_back();
      ++tot, q.push_back(*i);
    }
    q.pop_back();
    std::reverse(p.begin(), p.end());
  }
  return q;
}
int n;
bool vis[N];
std::vector<std::pair<pt, std::pair<int, int> > > p, q, r;
std::vector<std::pair<int, int> > ans;
void Solve(std::pair<pt, std::pair<int, int> > a,
           std::pair<pt, std::pair<int, int> > b,
           std::pair<pt, std::pair<int, int> > c,
           std::vector<std::pair<pt, std::pair<int, int> > > &v) {
  if (!v.size()) return;
  int flg[2] = {};
  for (std::pair<pt, std::pair<int, int> > &i : v) flg[i.second.first] = true;
  if (!flg[a.second.first]) {
    for (std::pair<pt, std::pair<int, int> > &i : v)
      ans.emplace_back(c.second.second, i.second.second);
  } else if (!flg[c.second.first]) {
    for (std::pair<pt, std::pair<int, int> > &i : v)
      ans.emplace_back(a.second.second, i.second.second);
  } else {
    std::vector<std::pair<pt, std::pair<int, int> > > o;
    std::pair<pt, std::pair<int, int> > p;
    for (std::pair<pt, std::pair<int, int> > &i : v) {
      vis[i.second.second] = false;
      if (i.second.first == c.second.first) p = i;
    }
    vis[p.second.second] = true;
    ans.emplace_back(c.second.second, p.second.second);
    for (std::pair<pt, std::pair<int, int> > &i : v)
      if (!vis[i.second.second] &&
          inTriangle(a.first, b.first, p.first, i.first)) {
        vis[i.second.second] = true;
        o.push_back(i);
      }
    Solve(a, b, p, o);
    o.clear();
    for (std::pair<pt, std::pair<int, int> > &i : v)
      if (!vis[i.second.second] &&
          inTriangle(c.first, p.first, a.first, i.first)) {
        vis[i.second.second] = true;
        o.push_back(i);
      }
    Solve(c, p, a, o);
    o.clear();
    for (std::pair<pt, std::pair<int, int> > &i : v)
      if (!vis[i.second.second]) {
        vis[i.second.second] = true;
        o.push_back(i);
      }
    Solve(c, p, b, o);
  }
}
int main() {
  scanf("%d", &n);
  if (n == 1) return puts("0"), 0;
  p.reserve(n);
  for (int i = 0, x, y, c; i < n; ++i) {
    scanf("%d%d%d", &x, &y, &c);
    p.emplace_back(pt{x, y}, std::pair<int, int>(c, i));
  }
  q = Convex(p);
  for (std::pair<pt, std::pair<int, int> > &i : q) vis[i.second.second] = true;
  for (std::pair<pt, std::pair<int, int> > &i : p)
    if (!vis[i.second.second]) r.push_back(i);
  int cnt = 0;
  memset(vis, 0, n);
  for (auto i = q.begin(); i != q.end(); ++i) {
    if (i->second.first != q.begin()->second.first) break;
    ++cnt;
    vis[i->second.second] = true;
  }
  if (cnt == int(q.size())) {
    for (int i = 0; i < int(q.size()) - 1; ++i)
      ans.emplace_back(q[i].second.second, q[i + 1].second.second);
    std::pair<pt, std::pair<int, int> > p(pt{}, std::pair<int, int>(-1, -1));
    for (std::pair<pt, std::pair<int, int> > &i : r)
      if (i.second.first != q.begin()->second.first) p = i;
    if (p.second.second != -1) {
      q.push_back(q[0]);
      memset(vis, 0, n);
      vis[p.second.second] = true;
      for (int i = 0; i < int(q.size()) - 1; ++i) {
        std::vector<std::pair<pt, std::pair<int, int> > > v;
        for (std::pair<pt, std::pair<int, int> > &j : r)
          if (!vis[j.second.second] &&
              inTriangle(q[i].first, q[i + 1].first, p.first, j.first)) {
            vis[j.second.second] = true;
            v.push_back(j);
          }
        Solve(q[i], q[i + 1], p, v);
      }
    } else {
      for (std::pair<pt, std::pair<int, int> > &i : r)
        ans.emplace_back(q.begin()->second.second, i.second.second);
    }
  } else {
    for (auto i = q.rbegin(); i != q.rend(); ++i) {
      if (i->second.first != q.begin()->second.first) break;
      ++cnt;
      vis[i->second.second] = true;
    }
    for (auto &i : q)
      if (!vis[i.second.second] && i.second.first == q.begin()->second.first)
        return puts("Impossible"), 0;
    std::vector<std::pair<pt, std::pair<int, int> > > p[2];
    bool flg = false;
    for (auto i = q.begin(); i != q.end(); ++i) {
      if (i->second.first == 1)
        flg = true;
      else if (flg)
        p[0].push_back(*i);
    }
    for (auto i = q.begin(); i != q.end(); ++i) {
      if (i->second.first == 1)
        flg = false;
      else if (flg)
        p[0].push_back(*i);
    }
    for (auto i = q.begin(); i != q.end(); ++i) {
      if (i->second.first == 0)
        flg = true;
      else if (flg)
        p[1].push_back(*i);
    }
    for (auto i = q.begin(); i != q.end(); ++i) {
      if (i->second.first == 0)
        flg = false;
      else if (flg)
        p[1].push_back(*i);
    }
    std::reverse(p[1].begin(), p[1].end());
    memset(vis, 0, n);
    for (int i = 0; i < int(p[0].size()) - 1 || i < int(p[1].size()) - 1; ++i) {
      if (i < int(p[0].size()) - 1) {
        ans.emplace_back(p[0][i].second.second, p[0][i + 1].second.second);
        std::vector<std::pair<pt, std::pair<int, int> > > o;
        std::pair<pt, std::pair<int, int> > t =
            p[1][std::min(i, int(p[1].size()) - 1)];
        for (std::pair<pt, std::pair<int, int> > &j : r)
          if (!vis[j.second.second] &&
              inTriangle(p[0][i].first, p[0][i + 1].first, t.first, j.first)) {
            vis[j.second.second] = true;
            o.push_back(j);
          }
        Solve(p[0][i], p[0][i + 1], t, o);
      }
      if (i < int(p[1].size()) - 1) {
        ans.emplace_back(p[1][i].second.second, p[1][i + 1].second.second);
        std::vector<std::pair<pt, std::pair<int, int> > > o;
        std::pair<pt, std::pair<int, int> > t =
            p[0][std::min(i + 1, int(p[0].size()) - 1)];
        for (std::pair<pt, std::pair<int, int> > &j : r)
          if (!vis[j.second.second] &&
              inTriangle(p[1][i].first, p[1][i + 1].first, t.first, j.first)) {
            vis[j.second.second] = true;
            o.push_back(j);
          }
        Solve(p[1][i], p[1][i + 1], t, o);
      }
    }
  }
  printf("%d\n", int(ans.size()));
  for (std::pair<int, int> &i : ans) printf("%d %d\n", i.first, i.second);
  return 0;
}
