#include <bits/stdc++.h>
using namespace std;
long long rdtsc() {
  long long tmp;
  asm("rdtsc" : "=A"(tmp));
  return tmp;
}
inline int myrand() { return abs((rand() << 15) ^ rand()); }
inline int rnd(int x) { return myrand() % x; }
const int INF = (int)1e9 + 1;
const long double EPS = 1e-9;
void precalc() {}
struct Line {
  int a, b, c;
  int id;
  int read(int _id) {
    id = _id;
    if (scanf("%d%d%d", &a, &b, &c) < 3) {
      return 0;
    }
    return 1;
  }
};
long long gcd(long long a, long long b) {
  for (; b; a %= b, swap(a, b))
    ;
  return a;
}
struct Ratio {
  long long a, b;
  Ratio() {}
  Ratio(long long _a, long long _b) : a(_a), b(_b) {
    assert(b != 0ll);
    normalize();
  }
  void normalize() {
    long long d = gcd(a, b);
    a /= d, b /= d;
    if (b < 0) {
      a = -a, b = -b;
    }
  }
  inline bool operator<(const Ratio &r) const {
    if (a != r.a) {
      return a < r.a;
    }
    return b < r.b;
  }
  inline bool operator==(const Ratio &r) const { return a == r.a && b == r.b; }
};
struct Point {
  Ratio x, y;
  Point() {}
  Point(Ratio _x, Ratio _y) : x(_x), y(_y) {}
  inline bool operator<(const Point &p) const {
    if (x == p.x) {
      return y < p.y;
    }
    return x < p.x;
  }
  inline bool operator==(const Point &p) const { return x == p.x && y == p.y; }
};
bool inter(const Line &l1, const Line &l2, Point &res) {
  long long D = (long long)l1.a * l2.b - (long long)l1.b * l2.a;
  if (D == 0ll) {
    return 0;
  }
  long long Dx = (long long)l1.b * l2.c - (long long)l1.c * l2.b;
  long long Dy = (long long)l1.c * l2.a - (long long)l1.a * l2.c;
  res = Point(Ratio(Dx, D), Ratio(Dy, D));
  return 1;
}
int n, k;
const int maxn = (int)1e5 + 10;
Line lines[maxn];
bool read() {
  if (scanf("%d%d", &n, &k) < 2) {
    return 0;
  }
  for (int i = 0; i < n; ++i) {
    lines[i].read(i);
  }
  return 1;
}
const int maxk = 5;
int ans[maxk][2];
int res;
Line tmp[maxn];
int used[maxn];
bool gen(int pos, int k) {
  if (pos == n) {
    return 1;
  }
  if (used[pos]) {
    return gen(pos + 1, k);
  }
  if (k == 0) {
    return 0;
  }
  {
    ans[res][0] = lines[pos].id + 1, ans[res][1] = -1;
    ++res;
    if (gen(pos + 1, k - 1)) {
      return 1;
    }
    --res;
  }
  int oks[n];
  Point ps[maxk * maxk + 5];
  for (int j = pos + 1; j < n; ++j) {
    oks[j] = 0;
    if (used[j]) {
      continue;
    }
    Point p;
    if (!inter(lines[pos], lines[j], p)) {
      continue;
    }
    oks[j] = 1;
    ps[j] = p;
  }
  int tmp[n];
  for (int j = pos + 1; j < n; ++j) {
    if (!oks[j]) {
      continue;
    }
    ans[res][0] = lines[pos].id + 1, ans[res][1] = lines[j].id + 1;
    ++res;
    for (int k = pos + 1; k < n; ++k) {
      tmp[k] = used[k];
      if (!oks[k]) {
        continue;
      }
      if (ps[j] == ps[k]) {
        used[k] += 1;
        oks[k] = 0;
      }
    }
    if (gen(pos + 1, k - 1)) {
      return 1;
    }
    --res;
    for (int k = pos + 1; k < n; ++k) {
      used[k] = tmp[k];
    }
  }
  return 0;
}
bool solveSmall() {
  random_shuffle(lines, lines + n, rnd);
  for (int i = 0; i < n; ++i) {
    used[i] = 0;
  }
  return gen(0, k);
}
void solve() {
  res = 0;
  while (n > k * k && k > 0) {
    const int K = 250;
    pair<Point, pair<int, int> > ps[K];
    int cnt = 0;
    bool ok = 0;
    for (int iter = 0; iter < K; ++iter) {
      int x = rnd(n), y = rnd(n);
      Point p;
      if (x == y || !inter(lines[x], lines[y], p)) {
        continue;
      }
      ps[cnt++] = make_pair(p, make_pair(x, y));
    }
    sort(ps, ps + cnt);
    Point p;
    int x, y;
    bool found = 0;
    for (int i = 0; i < cnt;) {
      int i0 = i;
      while (i < cnt && ps[i].first == ps[i0].first) {
        ++i;
      }
      if (i - i0 > k) {
        found = 1;
        p = ps[i0].first;
        x = ps[i0].second.first, y = ps[i0].second.second;
        break;
      }
    }
    if (!found) {
      printf("NO\n");
      return;
    }
    {
      int cnt = 0, cntp = 0;
      for (int i = 0; i < n; ++i) {
        Point q;
        if (!inter(lines[i], lines[i == x ? y : x], q)) {
          continue;
        }
        if (q == p) {
          ++cntp;
        } else {
          tmp[cnt++] = lines[i];
        }
      }
      assert(cntp > k);
      ans[res][0] = lines[x].id + 1, ans[res][1] = lines[y].id + 1;
      ++res;
      for (int i = 0; i < cnt; ++i) {
        lines[i] = tmp[i];
      }
      n = cnt;
      --k;
    }
  }
  if (solveSmall()) {
    printf("YES\n");
    printf("%d\n", res);
    for (int i = 0; i < res; ++i) {
      printf("%d %d\n", ans[i][0], ans[i][1]);
    }
  } else {
    printf("NO\n");
  }
}
int main() {
  srand(rdtsc());
  precalc();
  while (1) {
    if (!read()) {
      break;
    }
    solve();
  }
  return 0;
}
