#include <bits/stdc++.h>
using namespace std;
struct node {
  int a[4], index;
  node() { memset(a, 0, sizeof(a)); }
} no1[100005];
int n;
int ans = 0, flag = 1, indexa, indexb;
vector<pair<int, int> > ve;
map<pair<int, int>, int> mp;
int l = 0;
set<pair<int, int> > se[1000000];
void update(int a, int b, int c, int index) {
  set<pair<int, int> >::iterator it;
  int pre = mp[make_pair(a, b)];
  it = se[pre].end();
  if (it != se[pre].begin()) {
    it--;
    if (min(min(a, b), it->first + c) > ans) {
      ans = min(min(a, b), it->first + c);
      flag = 2;
      indexa = it->second;
      indexb = index;
    }
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    int a, b, c;
    scanf("%d%d%d", &no1[i].a[0], &no1[i].a[1], &no1[i].a[2]);
    a = no1[i].a[0];
    b = no1[i].a[1];
    c = no1[i].a[2];
    ve.push_back(make_pair(min(a, b), max(a, b)));
    ve.push_back(make_pair(min(a, c), max(a, c)));
    ve.push_back(make_pair(min(c, b), max(c, b)));
    no1[i].index = i + 1;
    if (min(no1[i].a[0], min(no1[i].a[1], no1[i].a[2])) > ans) {
      ans = min(no1[i].a[0], min(no1[i].a[1], no1[i].a[2]));
      indexa = i + 1;
    }
  }
  sort(ve.begin(), ve.end());
  mp[ve[0]] = l;
  for (int i = 1; i < ve.size(); i++) {
    if (ve[i].first != ve[i - 1].first || ve[i].second != ve[i - 1].second) l++;
    mp[ve[i]] = l;
  }
  for (int i = 0; i < n; i++) {
    int a = no1[i].a[0];
    int b = no1[i].a[1];
    int c = no1[i].a[2];
    update(min(a, b), max(a, b), c, i + 1);
    update(min(a, c), max(a, c), b, i + 1);
    update(min(b, c), max(b, c), a, i + 1);
    se[mp[make_pair(min(a, b), max(a, b))]].insert(make_pair(c, i + 1));
    se[mp[make_pair(min(c, b), max(c, b))]].insert(make_pair(a, i + 1));
    se[mp[make_pair(min(a, c), max(a, c))]].insert(make_pair(b, i + 1));
  }
  printf("%d\n", flag);
  if (flag == 1) {
    printf("%d\n", indexa);
  } else {
    printf("%d %d\n", indexa, indexb);
  }
  return 0;
}
