#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;   }