#include <bits/stdc++.h>   using namespace std;   int nr, N, K, ap[100009], last_N;   pair<int, int> ans[10];   struct line {     int a, b, c, init;   };   vector<line> v;   struct point {     long long a, b, c, d;     bool operator==(const point &other) const {       return (1LL * a * other.b == 1LL * b * other.a &&               1LL * c * other.d == 1LL * d * other.c);     }     bool operator<(const point &other) const {       if (1LL * a * other.b == 1LL * b * other.a)         return (1LL * c * other.d < 1LL * d * other.c);       return (1LL * a * other.b < 1LL * b * other.a);     }   };   bool OnLine(point p, line l) {     return ((long long)1LL * l.a * p.a * p.d + 1LL * l.b * p.b * p.c +                 1LL * l.c * p.b * p.d ==             0LL);   }   bool Exist_Intersection(line p, line q) {     return (1LL * p.a * q.b != 1LL * p.b * q.a);   }   point Intersect(line p, line q) {     point ans;     ans.c = (long long)1LL * q.c * p.a - 1LL * q.a * p.c;     ans.d = (long long)1LL * p.b * q.a - 1LL * q.b * p.a;     ans.a = (long long)1LL * q.c * p.b - 1LL * q.b * p.c;     ans.b = (long long)1LL * p.a * q.b - 1LL * q.a * p.b;     return ans;   }   void Push(int i, int j) { ans[++nr] = make_pair(i, j); }   void Pop() { nr--; }   bool back(int pos, int K, vector<line> v) {     if (pos == v.size()) return 1;     if (K < 0) return 0;     if (ap[pos]) return back(pos + 1, K, v);     point I;     for (int i = pos + 1; i < N; i++) {       if (ap[i]) continue;       if (Exist_Intersection(v[i], v[pos]) == 0) continue;       I = Intersect(v[i], v[pos]);       for (int j = pos; j < N; j++)         if (OnLine(I, v[j])) ap[j]++;       Push(v[pos].init, v[i].init);       if (back(pos + 1, K - 1, v) == 1) return 1;       Pop();       for (int j = pos; j < N; j++)         if (OnLine(I, v[j])) ap[j]--;     }     Push(v[pos].init, -1), ap[pos]++;     if (back(pos + 1, K - 1, v) == 1) return 1;     Pop(), ap[pos]--;     return 0;   }   bool solve(int K, vector<line> v) {     int N = v.size();     if (K >= N) {       for (int i = 0; i < N; i++) Push(v[i].init, -1);       return 1;     }     if (K < 0) return 0;     if (N <= K * K) {       if (back(0, K, v)) return 1;       return 0;     }     int M = K * K + 1, needed = K + 1;     set<point> inters;     for (int i = 0; i < M; i++)       for (int j = i + 1; j < M; j++) {         if (Exist_Intersection(v[i], v[j]) == 0) continue;         point curr = Intersect(v[i], v[j]);         if (inters.count(curr)) continue;         inters.insert(curr);         int nr = 0;         for (int p = i; p < M; p++)           if (OnLine(curr, v[p])) nr++;         if (nr >= needed) {           vector<line> apel;           for (int p = 0; p < N; p++)             if (!OnLine(curr, v[p])) apel.push_back(v[p]);           Push(v[i].init, v[j].init);           if (solve(K - 1, apel)) return 1;           Pop();           return 0;         }       }     return 0;   }   int main() {     scanf( %d %d , &N, &K);     for (int i = 1; i <= N; i++) {       line curr;       scanf( %d %d %d , &curr.a, &curr.b, &curr.c), curr.init = i;       v.push_back(curr);     }     if (solve(K, v)) {       printf( YES n );       printf( %d n , nr);       for (int i = 1; i <= nr; i++)         printf( %d %d n , ans[i].first, ans[i].second);       return 0;     }     printf( NO n );     return 0;   }