#include <bits/stdc++.h>   template <class T>   inline void chkmax(T &x, const T &y) {     if (x < y) x = y;   }   template <class T>   inline void chkmin(T &x, const T &y) {     if (x > y) x = y;   }   template <class T>   inline void read(T &x) {     char c;     int f = 1;     x = 0;     while (((c = getchar()) <  0  || c >  9 ) && c !=  - )       ;     if (c ==  - )       f = -1;     else       x = c -  0 ;     while ((c = getchar()) >=  0  && c <=  9 ) x = x * 10 + c -  0 ;     x *= f;   }   int outn;   char out[(int)2e7];   template <class T>   inline void write(T x) {     if (x < 0) out[outn++] =  - , x = -x;     if (x) {       static int tmpn;       static char tmp[20];       tmpn = 0;       while (x) tmp[tmpn++] = x % 10 +  0 , x /= 10;       while (tmpn) out[outn++] = tmp[--tmpn];     } else       out[outn++] =  0 ;   }   const int N = 1e5;   const double lim = 1.8 * CLOCKS_PER_SEC;   const double eps = 1e-8;   int n, k;   struct pot {     double x, y;     pot() { x = y = 0; }     pot(double _x, double _y) : x(_x), y(_y) {}     inline friend pot operator+(const pot &p, const pot &q) {       return pot(p.x + q.x, p.y + q.y);     }     inline friend pot operator-(const pot &p, const pot &q) {       return pot(p.x - q.x, p.y - q.y);     }     inline friend double operator*(const pot &p, const pot &q) {       return p.x * q.x + p.y * q.y;     }     inline friend double operator^(const pot &p, const pot &q) {       return p.x * q.y - p.y * q.x;     }     inline friend pot operator*(const pot &p, const double &k) {       return pot(p.x * k, p.y * k);     }     inline friend pot operator/(const pot &p, const double &k) {       return pot(p.x / k, p.y / k);     }   };   struct line {     pot p, v;     line() {}     line(pot _p, pot _v) : p(_p), v(_v) {}     line(int a, int b, int c) {       if (!b)         p = pot((double)-c / a, 0), v = pot(0, 1);       else if (!a)         p = pot(0, (double)-c / b), v = pot(1, 0);       else         p = pot(0, (double)-c / b), v = pot(1, (double)-a / b);     }   } l[N + 9];   std::vector<int> res;   std::vector<std::pair<int, int> > ans;   inline int getrand(int lim) { return 1ll * rand() * rand() % lim; }   inline bool parallel(const line &a, const line &b) {     return fabs(a.v ^ b.v) < eps;   }   inline pot intersection(const line &a, const line &b) {     pot w = b.p - a.p;     double k = (w ^ a.v) / (a.v ^ b.v);     return b.p + b.v * k;   }   inline bool online(const pot &x, const line &l) {     return fabs((l.p - x) ^ l.v) < eps;   }   void dfs(int k, std::vector<int> res) {     if (!(int)(res).size()) {       puts( YES );       write((int)(ans).size()), out[outn++] =   n ;       for (int i = 0; i < (int)(ans).size(); ++i) {         write(ans[i].first), out[outn++] =    ;         write(ans[i].second), out[outn++] =   n ;       }       printf( %s , out);       exit(0);     }     if (!k) return;     int p = getrand((int)(res).size()), q = getrand((int)(res).size());     if (p == q) {       ans.push_back(std::make_pair(res[p], -1));       res.erase(find(res.begin(), res.end(), res[p]));       dfs(k - 1, res);       ans.pop_back();     } else {       if (parallel(l[res[p]], l[res[q]])) return;       ans.push_back(std::make_pair(res[p], res[q]));       if ((res[p] == 1 && res[q] == 2) || (res[p] == 2 && res[q] == 1)) p++, p--;       pot x = intersection(l[res[p]], l[res[q]]);       std::vector<int> nex;       for (int i = 0; i < (int)(res).size(); ++i)         if (!online(x, l[res[i]])) nex.push_back(res[i]);       dfs(k - 1, nex);       ans.pop_back();     }   }   int main() {     read(n), read(k);     for (int i = 1; i <= n; ++i) {       int a, b, c;       read(a), read(b), read(c);       l[i] = line(a, b, c);     }     for (int i = 1; i <= n; ++i) res.push_back(i);     while (clock() < lim) dfs(k, res);     puts( NO );     return 0;   }