#include <bits/stdc++.h>
using namespace std;
struct Rock {
  int index, side;
};
bool operator<(const Rock a, const Rock b) { return a.side < b.side; }
struct Answer {
  int diameter;
  vector<int> indices;
};
bool operator<(const Answer a, const Answer b) {
  return a.diameter < b.diameter;
}
int main() {
  int n;
  cin >> n;
  auto groups = map<pair<int, int>, vector<Rock>>();
  for (auto i = 0; i < n; i++) {
    auto sides = array<int, 3>{};
    for (auto& x : sides) cin >> x;
    auto seen = set<pair<int, int>>();
    for (auto j = 0; j < 3; j++) {
      auto other = vector<int>(begin(sides), end(sides));
      other.erase(begin(other) + j);
      sort(begin(other), end(other));
      const auto glued_sides = make_pair(other[0], other[1]);
      if (seen.count(glued_sides) == 0) {
        groups[glued_sides].push_back({i, sides[j]});
        seen.insert(glued_sides);
      }
    }
  }
  auto best = Answer{0, {}};
  for (auto& kv : groups) {
    const auto glued_sides = kv.first;
    sort(begin(kv.second), end(kv.second));
    reverse(begin(kv.second), end(kv.second));
    if (kv.second.size() == 1) {
      const auto rock = kv.second[0];
      const auto diameter = min(glued_sides.first, rock.side);
      best = max(best, {diameter, {rock.index}});
    } else {
      const auto rock1 = kv.second[0], rock2 = kv.second[1];
      const auto diameter = min(glued_sides.first, rock1.side + rock2.side);
      best = max(best, {diameter, {rock1.index, rock2.index}});
    }
  }
  cout << best.indices.size() << endl;
  for (const auto x : best.indices) cout << x + 1 << " ";
  cout << endl;
}
