#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 3;
const int MAXK = 5;
const int ACC = 100;
int n, k;
template <typename T>
struct point {
  T x, y;
};
template <typename T>
struct line {
  T a, b, c;
  T eval(point<T> &p) { return a * p.x + b * p.y + c; }
  double slope() { return (double)-a / b; }
  point<T> intersect(line &other) {
    return {(other.c * b - c * other.b) / (a * other.b - other.a * b),
            (other.c * a - c * other.a) / (other.a * b - a * other.b)};
  }
};
line<double> lines[MAXN];
int main() {
  ios_base::sync_with_stdio(false);
  srand(time(NULL));
  cin >> n >> k;
  for (int i = 1; i <= n; i++) {
    cin >> lines[i].a >> lines[i].b >> lines[i].c;
  }
  bool ok = true;
  vector<pair<int, int> > res;
  vector<int> avail;
  for (int i = 1; i <= n; i++) avail.push_back(i);
  while (n > k and k > 0 and n > 0) {
    bool found = false;
    for (int i = 0; i < ACC; i++) {
      int id1 = rand() % (avail.size());
      int id2 = rand() % (avail.size());
      auto it = lines[avail[id1]].intersect(lines[avail[id2]]);
      int cnt = 0;
      for (auto &idx : avail) {
        if (abs(lines[idx].eval(it)) < 1e-7) {
          cnt++;
        }
      }
      if (cnt >= avail.size() / k) {
        found = true;
        vector<int> temp;
        for (auto &elem : avail) {
          if (abs(lines[elem].eval(it)) > 1e-7) {
            temp.push_back(elem);
          }
        }
        res.push_back({avail[id1], avail[id2]});
        avail = temp;
        n = avail.size();
        k--;
        break;
      }
    }
    if (found == false) {
      ok = false;
      break;
    }
  }
  ok = (n <= k) || (n == 0);
  if (!ok) {
    cout << "NO\n";
    return 0;
  }
  while (avail.size() > 0) {
    res.push_back({avail.back(), -1});
    avail.pop_back();
  }
  cout << "YES\n";
  cout << res.size() << '\n';
  for (auto &elem : res) {
    cout << elem.first << ' ' << elem.second << '\n';
  }
  return 0;
}
