#include <iostream>
#include <vector>
#include <algorithm>
#include <bitset>
#include <map>
using namespace std;

const int GRAPH_SIZE = 50;
using gbit = bitset<GRAPH_SIZE>;

namespace std {
    bool operator<(const gbit &a, const gbit &b) {
        gbit ab = a ^ b;
        int k = ab._Find_first();
        return k < GRAPH_SIZE and b[k] == 1;
    }
}

template <typename Tp>
struct Edge {
    int to;
    Edge() {}
    Edge(int to_) : to(to_) {}
};

template <typename Tp>
using Graph = vector< vector< Edge<Tp> > >;

template <typename CostType = int>
struct MaximalIndependentSet {
    Graph<int> G;
    int N; vector<CostType> costs;
    gbit alive;
    vector<gbit> adj;
    bool weighted;
    map<gbit, CostType> rec;

    MaximalIndependentSet(Graph<int> G_,
                          vector<CostType> costs_ = vector<CostType>())
        : G(G_), costs(costs_) {
        N = G_.size();
        if(costs.size() != N) {
            costs = vector<CostType>(N, 1);
            weighted = false;
        }
        else weighted = true;

        alive = gbit();
        adj = vector<gbit>(N);

        for(int i=0; i<N; i++) {
            alive[i] = true;
            for(auto e : G[i]) adj[i][e.to] = 1;
        }
    }

    inline int deg(int v) { return (alive & adj[v]).count(); }

    int argmax_deg() {
        int max_deg = -1, res = -1;
        for(int i=0; i<N; i++) {
            if(!alive[i]) continue;
            int d = deg(i);
            if(d > max_deg) max_deg = d, res = i;
        }
        return res;
    }

    pair< CostType, gbit > solve_part1() {
        CostType d = 0; gbit res;
        for(int i=0; i<N; i++) {
            if(alive[i] and !res[i] and deg(i) <= !weighted) {
                res[i] = true; d += costs[i];
                res |= (alive & adj[i]);
            }
        }
        return make_pair(d, res);
    }

    CostType solve_part2() {
        int v = argmax_deg(); CostType res = 0;
        if(v < 0) return CostType(0);

        alive[v] = false;
        res = max(res, solve());

        gbit vs = alive & adj[v];
        alive ^= vs;
        res = max(res, solve() + costs[v]);
        alive ^= vs;

        alive[v] = true;
        return res;
    }

    CostType solve() {
        if(rec.count(alive)) return rec[alive];

        CostType v1; gbit vs;
        tie(v1, vs) = solve_part1();
        alive ^= vs;
        CostType v2 = solve_part2();
        alive ^= vs;
        return rec[alive] = v1 + v2;
    }
};

int main() {
    int N; cin >> N;

    vector<int> ast(N), aet(N), hst(N), het(N), bst(N), bet(N);
    for(int i=0; i<N; i++) {
        for(int j=0; j<6; j++) {
            int h, m; cin >> h >> m;
            int t = h * 60 + m;
            if(j == 0) ast[i] = t;
            if(j == 1) aet[i] = t;
            if(j == 2) hst[i] = t;
            if(j == 3) het[i] = t;
            if(j == 4) bst[i] = t;
            if(j == 5) bet[i] = t;
        }
    }

    Graph<int> G(N);
    for(int i=0; i<N; i++) {
        for(int j=i+1; j<N; j++) {
            bool isc = true;
            if(aet[i] < ast[j]) isc = false;
            if(aet[j] < ast[i]) isc = false;
            if(bet[i] < bst[j]) isc = false;
            if(bet[j] < bst[i]) isc = false;
            if(het[i] < hst[j]) isc = false;
            if(het[j] < hst[i]) isc = false;

            if(!isc) {
                // fprintf(stderr, "edge: %d and %d\n", i+1, j+1);
                G[i].emplace_back(j);
                G[j].emplace_back(i);
            }
        }
    }

    MaximalIndependentSet<> mis(G);
    cout << mis.solve() << endl;
}



Measured memory_bytes: 3132