#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <unordered_map>
#include <numeric>
#include <iomanip>
using namespace std;
#define pii pair<int , int>
#define ll long long
#define FAST ios_base::sync_with_stdio(false); cin.tie(NULL)
const long long dx[4] = {1, 0, -1, 0}, dy[4] = {0, -1, 0, 1};
const long long dl[2] = {1, -1};
const long long MOD = 1000000007;
const long long MAXN = 55;
int n;
pair<int, pii> arr[MAXN];
vector<int> v[MAXN];
vector<pii> shark;
vector<bool> visited;
vector<int> prey;
void init(){
cin >> n;
for(int x, y, z, i = 0; i < n; i++){
cin >> arr[i].first >> arr[i].second.first >> arr[i].second.second;
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(i == j) continue;
if(arr[i].first >= arr[j].first && arr[i].second.first >= arr[j].second.first && arr[i].second.second >= arr[j].second.second){
v[i].push_back(j);
}
}
}
for(int i = 0; i < n; i++){
shark.push_back({(int) v[i].size(), i});
}
sort(shark.begin(), shark.end());
}
bool dfs(int cur){
if(visited[cur]){
return false;
}
visited[cur] = true;
for(auto nxt : v[cur]){
if(nxt == cur || (nxt > cur && arr[nxt] == arr[cur])) continue;
if(prey[nxt] == -1 || dfs(prey[nxt])){
prey[nxt] = cur;
return true;
}
}
return false;
}
int solve(){
int ans = 0;
prey.assign(n, -1);
for(pii s : shark){
visited.assign(n, false);
if(dfs(s.second)){
ans++;
}
visited.assign(n, false);
if(dfs(s.second)){
ans++;
}
}
return max(n - ans, 1);
}
int main() {
FAST;
init();
cout << solve();
}