#pragma comment(linker, "/STACK:32000000")
#define _CRT_SECURE_NO_DEPRECATE

// ====== <<< PREWRITTEN CODE! Scroll down to the actual solution >>> ========

#include <sstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <cmath>
#include <stdarg.h>
#include <memory.h>
#include <string.h>
#include <assert.h>
#include <type_traits>
#include <limits>
#include <hash_map>
#include <hash_set>

using namespace std;

#ifdef _MSC_VER
#define gcc_typename
using namespace stdext;
#define LL_SPEC "%I64d"
#else
#define gcc_typename typename
using namespace __gnu_cxx;
#define LL_SPEC "%lld"
#endif

#define FUNC2(x,y) x##y
#define FUNC1(x,y) FUNC2(x,y)
#define FUNC(x) FUNC1(x,__COUNTER__)
#define STRUCT_NAME FUNC(struct_)

typedef long long LL;

inline double _randf()
{
    return (rand() * (RAND_MAX + 1) + rand()) / double((RAND_MAX + 1) * (RAND_MAX + 1));
}

inline int _rand(int x)
{
	return int(_randf() * x);
}

template <typename T>
struct Identity { typedef T type; };

struct _DummyType {};

template<typename T>
struct ValueType {
	typedef typename remove_reference<T>::type clean_type;
	typedef typename clean_type::value_type type;
};

#define _wsp printf(" ")
#define _wlf printf("\n")
#define _wstr(s) printf(s)
#define _w(x) _io<decltype(x)>::write(x)

#define cmp_a(a) a < other.a
#define cmp_d(a) a > other.a
#define cmp_aa(a, b) cmp_a(a) || (a == other.a && b < other.b)
#define cmp_ad(a, b) cmp_a(a) || (a == other.a && b > other.b)
#define cmp_da(a, b) cmp_d(a) || (a == other.a && b < other.b)
#define cmp_dd(a, b) cmp_d(a) || (a == other.a && b > other.b)

#define cmp3(a, b, c) cmp2(a) || (a == other.a && b == other.b && c < other.c)

template<typename T>
struct strict_item_type { typedef typename T::value_type type; };
template<typename T>
struct strict_item_type<T*> { typedef T type; };
template<typename T, size_t sz>
struct strict_item_type<T[sz]> { typedef T type; };
template<typename T, size_t sz>
struct strict_item_type<T(&)[sz]> { typedef T type; };
template<typename T>
struct strict_item_type<T*&> { typedef T type; };

template<typename T>
struct item_type { typedef typename T::value_type type; };
template<typename T>
struct item_type<T*> { typedef T type; };
template<typename T, size_t sz>
struct item_type<T[sz]> { typedef T type; };
template<typename T, size_t sz>
struct item_type<T(&)[sz]> { typedef T type; };
template<typename T>
struct item_type<T*&> { typedef T type; };

template<typename T>
struct item_type<T**> { typedef T type; };
template<typename T>
struct item_type<T**&> { typedef T type; };

template<typename T>
struct _null { inline static T value() { return T(-1); } };

template<typename IterableType>
struct citerator
{
	typedef typename IterableType::value_type value_type;
	static inline value_type resolve(const IterableType &a, typename IterableType::iterator it)
		{ return a.resolve_iterator(it); }
	static inline value_type& xresolve(IterableType &a, typename IterableType::iterator it)
		{ return a.resolve_iterator(it); }
};

#ifdef _MSC_VER
namespace stdext
{
    template <typename X>
    inline size_t hash_value(const vector<X> &v)
    {
        return _Hash_value(v.begin(), v.end());
    }
}
#else
namespace __gnu_cxx
{
    template<> struct hash<std::string>
    {
        size_t operator() (const std::string &x) const
        {
            return hash<const char*>()( x.c_str() );
        }
    };
    template<typename T> struct hash< std::vector<T> >
    {
        size_t operator() (const std::vector<T> &v) const
        {
            size_t res = 0;
            for (size_t i = 0; i < v.size(); i++)
                res = res * 1235321 + hash<T>()(v[i]);
            return res;
        }
    };
    template<> struct hash<long long>
    {
        size_t operator() (long long x) const
        {
            union { int i[2]; long long l; } tmp;
            tmp.l = x;
            return tmp.i[0] + 1235321 * tmp.i[1];
        }
    };
}
#endif

template<typename T>
struct citerator<vector<T> >
{
	static inline const T& resolve(const vector<T> &a, typename vector<T>::iterator it)
		{ return *it; }
};

template<typename T>
struct _seq
{
    template<typename F>
    static inline void process(T &t, F f) { t.process(f); }
};

template<typename T>
struct _seq<const T>
{
	template<typename F>
	static inline void process(const T &t, F f) { t.process(f); }
};

template<typename T>
struct _seq<vector<T> >
{
    template<typename F>
    static void process(vector<T> &t, F f)
    {
        for (typename vector<T>::iterator it = t.begin(); it != t.end(); ++it)
            if (!f(*it)) break;
    }
};

template<typename T>
struct _seq<const vector<T> >
{
    template<typename F>
    static void process(const vector<T> &t, F f)
    {
        for (typename vector<T>::const_iterator it = t.begin(); it != t.end(); ++it)
            if (!f(*it)) break;
    }
};

template<typename T, typename F>
inline void _seq_process(T &t, F f)
{
    _seq<T>::template process<F>(t, f);
}

template<typename T, typename F>
inline void _seq_process_c(const T &t, F f)
{
	_seq<const T>::template process<F>(t, f);
}

#define xbreak return false
#define xcontinue return true

#define xforeach_(a, v) \
    _seq_process_c(a, [&](const gcc_typename ValueType<decltype(a)>::type &v) -> bool {

#define xforeachx_(a, v) \
    _seq_process(a, [&](gcc_typename ValueType<decltype(a)>::type &v) -> bool {

#define xforeachi_(a, i, v) \
    { \
    typedef const gcc_typename ValueType<decltype(a)>::type &_T_; \
    int i = -1; \
    _seq_process_c(a, [&](_T_ v) -> bool { ++i; return [&]() -> bool {

#define x_endfe return true; });
#define x_endfei return true; }(); }); }

#define xforeach(a, v, ...)  xforeach_(a, v) __VA_ARGS__; x_endfe
#define xforeachx(a, v, ...)  xforeachx_(a, v) __VA_ARGS__; x_endfe
#define xforeachi(a, i, v, ...) xforeachi_(a, i, v) __VA_ARGS__; x_endfei

template<typename T>
inline T get_max_value()
{
	return T(1000000000);
}

template<typename T>
inline T get_zero()
{
	return T(0);
}

template<typename T>
struct Range
{
	typedef T iterator;
	typedef T value_type;

	Range(T a, T b) : a(a), b(b) {}
	inline iterator begin() const { return a; }
	inline iterator end() const { return b; }
	inline value_type resolve_iterator(const iterator &it) const { return it; }
	inline int size() const { return b - a; }
    template<typename F>
    inline void process(F f) const
    {
        for (T i = a; i < b; ++i)
            if (!f(i)) break;
    }

	const T a, b;
};

template<typename T>
struct _io
{
	inline static void read(T &x, int i) { x._read(i); }
	inline static void write(const T &x) { x._write(); }
};

template<>
struct _io<int>
{
	inline static void read(int &x, int i) { scanf("%d", &x); }
	inline static void write(const int &x) { printf("%d", x); }
};
template<>
struct _io<int&>
{
	inline static void read(int &x, int i) { scanf("%d", &x); }
	inline static void write(const int &x) { printf("%d", x); }
};

template<>
struct _io<long long>
{
	inline static void read(long long &x, int i) { scanf(LL_SPEC, &x); }
	inline static void write(const long long &x) { printf(LL_SPEC, x); }
};
template<>
struct _io<long long&>
{
	inline static void read(long long &x, int i) { scanf(LL_SPEC, &x); }
	inline static void write(const long long &x) { printf(LL_SPEC, x); }
};

template<>
struct _io<double>
{
	inline static void read(double &x, int i) { scanf("%lf", &x); }
	inline static void write(const double &x) { printf("%.9lf", x); }
};

template<>
struct _io<const double>
{
	inline static void read(double &x, int i) { scanf("%lf", &x); }
	inline static void write(const double &x) { printf("%.9lf", x); }
};

template<>
struct _io<double&>
{
	inline static void read(double &x, int i) { scanf("%lf", &x); }
	inline static void write(const double &x) { printf("%.9lf", x); }
};

template<>
struct _io<char>
{
	inline static void read(char &c, int i) { char buf[3]; scanf("%s", buf); c = buf[0]; }
	inline static void write(const char &c) { printf("%c", c); }
};

template<>
struct _io<bool>
{
	inline static void read(bool &b, int i) { int t; scanf("%d", &t); b = t != 0; }
	inline static void write(const bool &b) { printf("%s", b ? "#t" : "#f"); }
};

#ifdef _MSC_VER
template<typename T>
struct _io< _Vector_iterator<T> >
{
	inline static void read(_Vector_iterator<T> &x, int i) { assert(0); }
	inline static void write(const _Vector_iterator<T> &x) { printf("Vector_iterator"); }
};
#endif

template<typename T>
struct Idx2
{
    T i, j;
    Idx2(T i, T j) : i(i), j(j) {}
    Idx2() : i(-1), j(-1) {}
    inline void _write() const { _wstr("("); _io<T>::write(i); _wstr(", "); _io<T>::write(j); _wstr(")"); }
    inline void _read(int idx) { _io<T>::read(i, idx); _io<T>::read(j, idx); }
	inline bool operator == (const Idx2<T> &other) const { return i == other.i && j == other.j; }
	inline bool operator < (const Idx2<T> &other) const { return cmp_aa(i, j); }
};

template<typename T>
struct _null<Idx2<T> > { inline static Idx2<T> value() { return Idx2<T>(-1, -1); } };

template<typename T>
struct cmap
{
};

#define RM(a, i) cmap<decltype(a)>::read(a, i)

template<typename Y>
struct cmap<Y**>
{
	typedef Idx2<int> key_type;
	inline static void write(Y **a, key_type i, const Y &value) { a[i.i][i.j] = value; }
	inline static Y& read(Y **a, key_type i) { return a[i.i][i.j]; }
};
template<typename Y>
struct cmap<Y**&>
{
	typedef Idx2<int> key_type;
	inline static void write(Y **&a, key_type i, const Y &value) { a[i.i][i.j] = value; }
	inline static Y& read(Y **&a, key_type i) { return a[i.i][i.j]; }
};

template<typename Y, int sz>
struct cmap<Y [sz]>
{
	typedef int key_type;
	inline static void write(Y a[sz], int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y a[sz], int i) { return a[i]; }
};
template<typename Y, int sz>
struct cmap<Y (&)[sz]>
{
	typedef int key_type;
	inline static void write(Y (&a)[sz], int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y (&a)[sz], int i) { return a[i]; }
};

template<typename Y>
struct cmap<Y*>
{
	typedef int key_type;
	inline static void write(Y *a, int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y *a, int i) { return a[i]; }
};

template<typename Y>
struct cmap<Y*&>
{
	typedef int key_type;
	inline static void write(Y *&a, int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y *&a, int i) { return a[i]; }
};

template<size_t sz>
void set_clear(bool (&a)[sz]) { memset(a, 0, sizeof(bool) * sz); }

template<size_t sz>
inline bool set_contains(bool (&a)[sz], int x) { return a[x]; }
inline bool set_contains(const bool *a, int x) { return a[x]; }
inline bool set_contains(bool **a, Idx2<int> x) { return a[x.i][x.j]; }

template<size_t sz>
inline void set_insert(bool (&a)[sz], int x) { a[x] = true; }
inline void set_insert(bool *a, int x) { a[x] = true; }
inline void set_insert(bool **a, Idx2<int> x) { a[x.i][x.j] = true; }

template<size_t sz>
inline void set_erase(bool (&a)[sz], int x) { a[x] = false; }
inline void set_erase(bool *a, int x) { a[x] = false; }
inline void set_erase(bool **a, Idx2<int> x) { a[x.i][x.j] = false; }

template<typename T>
struct iterable_wrap
{
    T &base;
    iterable_wrap(T &base) : base(base) {}
    typedef T value_type;
    template<typename F>
    inline void process(F f) const { f(base); }
};

#define _in(type, name) \
	type name; \
	_io<type>::read(name, 0);

#define _inx(type, name, sz) \
	type *name; \
	name = new type[sz]; \
	for (int __i = 0; __i < sz; __i++) _io<type>::read(name[__i], __i);

#define _inxx(type, name, sz1, sz2) \
	type **name; \
	name = new type*[sz1]; \
	for (int i = 0; i < sz1; i++) { \
		name[i] = new type[sz2]; \
		for (int j = 0; j < sz2; j++) _io<type>::read(name[i][j], j); \
	}

#define _tmpx(type, name, sz) \
	type *name; \
	name = new type[sz];

#define _tmpxx(type, name, sz1, sz2) \
	type **name; \
	name = new type*[sz1]; \
	for (int i = 0; i < sz1; i++) name[i] = new type[sz2];

#define _donex(name) delete [] name

#define _donexx(name, n) { \
	for (int i = 0; i < n; i++) delete [] name[i]; \
	delete [] name; }

#define _fillx(name, n, val) \
	for (int i = 0; i < n; i++) \
		cmap<decltype(name)>::write(name, i, val);

#define _fillxx(name, n, m, val) \
	for (int i = 0; i < n; i++) \
		for (int j = 0; j < m; j++) \
			name[i][j] = val;

#define _tmpxv(type, name, sz, val) \
	_tmpx(type, name, sz); \
	_fillx(name, sz, val);

#define _tmpxxv(type, name, sz1, sz2, val) \
	_tmpxx(type, name, sz1, sz2); \
	_fillxx(name, sz1, sz2, val);

#define _tmpxf(type, name, sz, init_expr) \
	_tmpx(type, name, sz); \
	for (int i = 0; i < n; i++) \
		name[i] = (init_expr)

template<typename I, typename M>
inline void _fillit(const I &keys, M &m, const typename item_type<M>::type &val)
{
	xforeach(keys, i, cmap<M>::write(m, i, val));
}

struct SepSpace
{
	static void Print() { _wsp; }
};

struct SepLF
{
	static void Print() { _wlf; }
};

struct SepComma
{
	static void Print() { _wstr(", "); }
};

template<typename T, typename sep>
void write_array(const T &a, int n)
{
	typedef typename item_type<T>::type X;
	for (int i = 0; i + 1 < n; i++)
	{
		_io<X>::write(a[i]);
		sep::Print();
	}
	if (n > 0) _io<X>::write(a[n-1]);
}

template<typename T, typename Sep>
void write_iterable(const T &a, Sep sep)
{
	bool first = true;
    typedef typename T::value_type i_type;
	xforeach(a, i,
		if (!first) sep.Print();
		_io<i_type>::write(i);
		first = false;
	)
}

template<typename T>
struct _io<vector<T> >
{
	inline static void read(vector<T> &x, int idx)
    {
        int sz;
        _io<int>::read(sz, 0);
        assert(sz >= 0);
        x.resize(sz);
        for (int i = 0; i < sz; i++) _io<T>::read(x[i], i);
    }
	inline static void write(const vector<T> &x) { _wstr("["); write_array<vector<T>, SepComma>(x, x.size()); _wstr("]"); }
};

#define _wa(a, n) write_array<decltype(a), SepSpace>(a, n)
#define _walf(a, n) write_array<decltype(a), SepLF>(a, n)
#define _wi(a) write_iterable(a, SepSpace())
#define _wilf(a) write_iterable(a, SepLF())

struct tup0 {
	inline void _read(int i) {}
	inline void __write() const { _wstr("("); }
	inline void _write() const { __write(); _wstr(")"); }
};

template<typename T>
struct _is_empty { enum { value = 0 }; };
template<>
struct _is_empty<tup0> { enum { value = 1 }; };

#define extend_with_cmp(name, base, op) \
	struct name : public base \
	{ \
		bool operator < (const name &other) const { \
			return op; \
		} \
	}

#define extend_field(name, base, type, field_name, init_value) \
	struct name : public base \
	{ \
		type field_name; \
		typedef type field_name##_type; \
		name() : field_name(init_value) {} \
		inline void __write() const { base::__write(); if (!_is_empty<base>::value) _wsp; \
			_wstr(#field_name ":"); _io<type>::write(field_name); } \
		inline void _write() const { __write(); _wstr(")"); } \
	};

#define extend_fieldr(name, base, type, field_name) \
	struct name : public base \
	{ \
		type field_name; \
		typedef type field_name##_type; \
		name() {} \
		inline void __write() const { base::__write(); if (!_is_empty<base>::value) _wsp; \
			_wstr(#field_name ":"); _io<type>::write(field_name); } \
		inline void _write() const { __write(); _wstr(")"); } \
		inline void _read(int i) { base::_read(i); _io<type>::read(field_name, i); }

#define extend_idx(name, base) \
	struct name : public base \
	{ \
		int idx; \
		typedef int idx_type; \
		name() {} \
		inline void __write() const { base::__write(); if (!_is_empty<base>::value) _wsp; \
			_wstr("idx:"); _io<int>::write(idx); } \
		inline void _write() const { __write(); _wstr(")"); } \
		inline void _read(int i) { base::_read(i); idx = i; }

#define _end_extend }

#define tup1(name, t1, name1) \
	extend_fieldr(name, tup0, t1, name1) \
		name(t1 name1) : name1(name1) {} \
	_end_extend

#define tup1ic(name, t1, name1, cmp) tup1ic_(STRUCT_NAME, name, t1, name1, cmp)
#define tup1ic_(bname, name, t1, name1, cmp) \
    tup1(bname, t1, name1); \
    extend_idx(name, bname) \
    bool operator < (const name &other) const { \
			return cmp; \
		} \
    _end_extend

#define tup2(name, t1, name1, t2, name2) tup2c(name, t1, name1, t2, name2, false)
#define tup2c(name, t1, name1, t2, name2, cmp) tup2_(STRUCT_NAME, name, t1, name1, t2, name2, cmp)
#define tup2_(bname, name, t1, name1, t2, name2, cmp) \
	tup1(bname, t1, name1); \
	extend_fieldr(name, bname, t2, name2) \
		name(t1 name1, t2 name2) : bname(name1), name2(name2) {} \
		bool operator < (const name &other) const { \
			return cmp; \
		} \
	_end_extend

#define tup3(name, t1, name1, t2, name2, t3, name3) tup3_(STRUCT_NAME, name, t1, name1, t2, name2, t3, name3)
#define tup3_(bname, name, t1, name1, t2, name2, t3, name3) \
	tup2(bname, t1, name1, t2, name2); \
	extend_fieldr(name, bname, t3, name3) \
		name(t1 name1, t2 name2, t3 name3) : bname(name1, name2), name3(name3) {} \
	_end_extend

#define tup4(name, t1, name1, t2, name2, t3, name3, t4, name4, cmp) tup4c(name, t1, name1, t2, name2, t3, name3, t4, name4, false)
#define tup4c(name, t1, name1, t2, name2, t3, name3, t4, name4, cmp) tup4_(STRUCT_NAME, name, t1, name1, t2, name2, t3, name3, t4, name4, cmp)
#define tup4_(bname, name, t1, name1, t2, name2, t3, name3, t4, name4, cmp) \
	tup3(bname, t1, name1, t2, name2, t3, name3); \
	extend_fieldr(name, bname, t4, name4) \
		name(t1 name1, t2 name2, t3 name3, t4 name4) : bname(name1, name2, name3), name4(name4) {} \
		bool operator < (const name &other) const { \
			return cmp; \
		} \
	_end_extend

#define _sort(a) if (a.size() > 0) sort(&a[0], &a[0] + a.size())
#define _reverse(a) if (a.size() > 0) reverse(&a[0], &a[0] + a.size())

template<typename T, typename F>
int FindFirstI(T &a, F f)
{
	int res = -1;
	xforeachi(a, i, v,
		if (f(v)) { res = i; xbreak; };
	)
	return res;
}

template<typename T, typename F>
int FindLastI(T &a, F f)
{
	int res = -1;
	xforeachi(a, i, v,
		if (f(v)) res = i;
	)
	return res;
}

#define find_firsti(x, cond) \
	FindFirstI(x, [&](const item_type<decltype(x)>::type &_) -> bool { return cond; })

#define find_lasti(x, cond) \
	FindLastI(x, [&](const item_type<decltype(x)>::type &_) -> bool { return cond; })

#define ok(x) (x) != -1
#define _forr(i, st, n) for (int i = st; i < n; i++)
#define _for(i, n) _forr(i, 0, n)

template<typename T, typename F>
typename T::value_type Fold(const T &a, F f, const typename T::value_type &init_val)
{
	typename T::value_type res = init_val;
	xforeach(a, i, res = f(res, i));
	return res;
}

template<typename T>
struct SumFtr
{
	typedef T res_type;
	T operator () (const T &a, const T &b) const { return a + b; }
};

template<typename T>
struct MinFtr
{
	typedef T res_type;
	T operator () (const T &a, const T &b) const { return min(a, b); }
};

template<typename T>
struct MaxFtr
{
	typedef T res_type;
	T operator () (const T &a, const T &b) const { return max(a, b); }
};

template<typename T>
struct _sum_neutral
{
	static T value() { return T(0); }
};

template<typename T>
typename T::value_type _sum(const T &a)
{
	typedef typename T::value_type X;
	return Fold(a, SumFtr<X>(), _sum_neutral<X>::value());
}

template<typename T>
typename T::value_type _min(const T &a)
{
    typedef typename T::value_type X;
    return Fold(a, MinFtr<X>(), numeric_limits<X>::max());
}

template<typename T>
typename T::value_type _max(const T &a)
{
    typedef typename T::value_type X;
    return Fold(a, MaxFtr<X>(), numeric_limits<X>::min());
}

template<typename T, typename F>
void AutoMap(T &a, F f)
{
	xforeachx(a, v, v = f(v));
}
#define _automap(t, ...) \
    AutoMap(t, [&](const ValueType<decltype(t)>::type &_) -> ValueType<decltype(t)>::type { return __VA_ARGS__; })

#define _rng(n) Range<int>(0, n)
#define _rngs(st, n) Range<int>(st, n)

template<typename T>
struct _keys
{
};

#define LI(name, ...) \
    int name##_base_arr[] = { __VA_ARGS__ }; \
    _wrap(name, name##_base_arr, sizeof(name##_base_arr) / sizeof(int))

template<typename T>
inline void swapord(T &a, T &b) { if (b < a) swap(a, b); }

template<typename T>
struct key_type { typedef int type; };

template<typename T>
void relax_min(T &a, const T &b) { a = min(a, b); }
template<typename T>
void relax_max(T &a, const T &b) { a = max(a, b); }

template<typename ArrType>
struct ArrWrapper
{
	typedef ArrType base_type;
	ArrType &a;
	int n;
	ArrWrapper(ArrType &a, int n) : a(a), n(n) {}
	typedef typename item_type<ArrType>::type value_type;
	typedef int iterator;
	inline iterator begin() const { return 0; }
	inline iterator end() const { return n; }
	inline int size() const { return n; }
	inline value_type& resolve_iterator(const iterator &it) const
	{
		return cmap<ArrType>::read(a, it);
	}
	inline value_type& operator [] (int i) { return a[i]; }
	void erase(int p)
	{
		assert(p < n);
		for (int i = p + 1; i < n; ++i) a[i-1] = a[i];
		--n;
	}
    template<typename F>
    void process(F f) const
    {
        for (int i = 0; i < n; i++)
            if (!f(a[i])) break;
    }
};

template<typename T>
struct cmap<ArrWrapper<T> >
{
	typedef typename ArrWrapper<T>::value_type V;
	inline static void write(ArrWrapper<T> &a, int i,
		const V value) { a.a[i] = value; }
	inline static V& read(ArrWrapper<T> &a, int i) { return a.a[i]; }
};

template<typename T>
struct _keys<ArrWrapper<T> >
{
    typedef Range<int> type;
    static type get(ArrWrapper<T> &t) { return type(0, t.n); }
};

#define _wrap(name, base, n) \
	ArrWrapper<decltype(base)> name(base, n)

#define _inxw(type, name, n) \
	_inx(type, name##_base, n); \
	_wrap(name, name##_base, n)

#define _tmpxw(type, name, n) \
	_tmpx(type, name##_base, n); \
	_wrap(name, name##_base, n)

template<typename InIterable, typename F>
struct FoldWrapper
{
	const InIterable a;
	typedef typename F::res_type value_type;
	typedef FoldWrapper<InIterable, F> my_type;
	value_type init_val;
	F f;
	FoldWrapper(const InIterable a, const value_type &init_val, F f) : a(a), init_val(init_val), f(f) {}
	typedef typename InIterable::iterator base_iterator;
	typedef typename InIterable::value_type base_value_type;
	tup3(_iterator, base_iterator, it, value_type, val, const my_type&, owner);
	struct iterator : public _iterator
	{
		iterator(const base_iterator &it, const value_type &val, const my_type &owner) : _iterator(it, val, owner) {}
		inline bool operator != (const iterator &other) const { return _iterator::it != other.it; } // we don't check the owner!
		inline iterator& operator ++ () { _iterator::val = _iterator::owner.f(citerator<InIterable>::resolve(_iterator::owner.a, _iterator::it), _iterator::val); ++_iterator::it; return *this; }
	};
	inline iterator begin() const { return iterator(a.begin(), init_val, *this); }
	inline iterator end() const { return iterator(a.end(), _null<value_type>::value(), *this); }
	inline int size() const { return a.size(); }
	inline value_type resolve_iterator(const iterator &it) const
	{
		return f(citerator<InIterable>::resolve(a, it.it), it.val);
	}
    template<typename Ftr> inline
    void process(Ftr ftr) const
    {
        value_type cur = init_val;
        xforeach(a, x,
            cur = f(x, cur);
            if (!ftr(cur)) xbreak;
        )
    }
};

template<typename T, typename F> inline
FoldWrapper<T, F> create_fold_wrapper(const T a, const typename F::res_type &init_val, F f)
{
    return FoldWrapper<T, F>(a, init_val, f);
}

template<typename T>
struct ProdFolder
{
	typedef T res_type;
	inline T operator () (const T &a, const T &b) const { return a * b; }
};

#define fold_product(name, base) fold_product_(STRUCT_NAME, name, base)
#define fold_product_(type, name, base) \
	typedef decltype(base) type; \
	FoldWrapper<type, ProdFolder<type::value_type> > name(base, type::value_type(1), ProdFolder<type::value_type>())

#define SumFolder_field_macro(fld) \
template<typename T> \
struct ZeroField_##fld \
{ \
    inline static T value() { T res; res.fld = 0; return res; } \
}; \
template<typename T> \
struct SumFolder_##fld \
{ \
    typedef T res_type; \
    inline T operator () (const T &a, const T &b) const { T res = a; res.fld = res.fld + b.fld; return res; } \
}; \
template<typename T> inline \
FoldWrapper<T, SumFolder_##fld<typename T::value_type> > _foldsum_##fld(const T a) \
{ \
    return create_fold_wrapper(a, ZeroField_##fld<typename T::value_type>::value(), SumFolder_##fld<typename T::value_type>()); \
}

SumFolder_field_macro(s)

template<typename T, typename F, typename S>
struct MapWrapper
{
	const T &a;
	typedef S value_type;
	F f;
	MapWrapper(const T &a, F f) : a(a), f(f) {}
	typedef typename T::iterator iterator;
	inline iterator begin() const { return a.begin(); }
	inline iterator end() const { return a.end(); }
	inline int size() const { return a.size(); }
	inline S resolve_iterator(const iterator &it) const
	{
		return f(citerator<T>::resolve(a, it));
	}
    template<typename Ftr>
    inline void process(Ftr ftr) const
    {
        xforeach(a, x,
            if (!ftr(f(x))) xbreak
        );
    }
};

template<typename T, typename F>
MapWrapper<T, F, typename T::value_type> SimpleMapWrapper(const T &a, F f)
{
	return MapWrapper<T, F, typename T::value_type>(a, f);
}

template<typename T, typename F, typename S>
MapWrapper<T, F, S> ExtMapWrapper(const T &a, F f, const S &dummy)
{
	return MapWrapper<T, F, S>(a, f);
}

template<typename T1, typename T2>
struct _pair
{
    tup2(type, T1, f, T2, s);
};

#define _map(a, ...) SimpleMapWrapper(a, [&](const ValueType<decltype(a)>::type &_) -> \
	ValueType<decltype(a)>::type { return __VA_ARGS__; })

#define _mapt(ty, a, ...) ExtMapWrapper(a, [&](const ValueType<decltype(a)>::type &_) -> \
	ty { return __VA_ARGS__; }, ty())

#define _mapzipt(ty, a, ...) ExtMapWrapper(a, [&](const ValueType<decltype(a)>::type &__) \
    { return _pair<ValueType<decltype(a)>::type, ty>::type(__, [&](const ValueType<decltype(a)>::type &_) -> \
    ty { return __VA_ARGS__; }(__)); }, _pair<ValueType<decltype(a)>::type, ty>::type())

template<
	typename T,
	typename Filter
>
struct FilterWrapper
{
	const T &a;
	Filter filter;
	FilterWrapper(const T &a, Filter filter) : a(a), filter(filter) {}
	typedef typename T::value_type value_type;
	template<typename F>
	inline void process(F f) const
	{
		xforeach(a, x,
			if (filter(x))
				if (!f(x)) xbreak
		)
	}
};

template<typename T, typename Filter>
inline FilterWrapper<T, Filter> CreateFilterWrapper(const T &t, Filter f)
{
	return FilterWrapper<T, Filter>(t, f);
}

#define _filter(cond, a) \
	CreateFilterWrapper(a, [&](const ValueType<decltype(a)>::type &_) -> bool { return cond; })

#define _filterN(name, cond, a) \
	CreateFilterWrapper(a, [&](const ValueType<decltype(a)>::type &name) -> bool { return cond; })

template<typename T, typename F> inline
bool Any(const T a, F f)
{
    bool res = false;
    xforeach(a, i,
        if (f(i))
        {
            res = true;
            xbreak;
        }
    )
    return res;
}

#define _any(f, a) \
    Any(a, [&](const ValueType<decltype(a)>::type &_) -> bool { return f; })

template<
    typename T
>
struct TakeWrapper
{
    const T a;
    int cnt;
    TakeWrapper(int cnt, const T a) : cnt(cnt), a(a) { assert(cnt >= 0); }
    typedef typename T::value_type value_type;
    template<typename F>
    inline void process(F f) const
    {
        int i = 0;
        xforeach(a, x,
            if (i >= cnt) xbreak;
            ++i;
            if (!f(x)) xbreak;
        )
    }
};

template<typename T>
inline TakeWrapper<T> _take(int cnt, const T a)
{
    return TakeWrapper<T>(cnt, a);
}

template<
    typename T,
    typename F
>
struct TakeWhileWrapper
{
    const T a;
    F f;
    TakeWhileWrapper(F f, const T a) : a(a), f(f) {}
    typedef typename T::value_type value_type;
    typedef _DummyType iterator;
    template<typename Ftr>
    inline void process(Ftr ftr) const
    {
        xforeach(a, x,
            if (!f(x)) xbreak;
            if (!ftr(x)) xbreak;
        );
    }
};

template<typename T, typename F>
TakeWhileWrapper<T, F> create_take_while(F f, const T a)
{
    return TakeWhileWrapper<T, F>(f, a);
}

#define _takewhile(f, a) \
    create_take_while([&](const ValueType<decltype(a)>::type &_) -> bool { return f; }, a)

template<typename T>
inline int _count(const T &a)
{
    int res = 0;
    xforeach(a, i, ++res);
    return res;
}

struct NaturalSequence
{
	typedef int value_type;
    typedef _DummyType iterator;

	template<typename F>
	void process(F f) const
	{
		for (int i = 0; ; i++) if (!f(i)) break;
	}
};

#define _nat NaturalSequence()

template<typename T>
bool _is_prime(T x)
{
	if (x < 2) return false;
	for (T i = 2; i * i <= x; i++)
		if (x % i == 0)
			return false;
	return true;
}

#define _has(a, x) (a.find(x) != a.end())

template<
	typename ListType,
	typename SeqType
>
void populate(ListType &lst, SeqType seq)
{
	xforeach(seq, x, lst.push_back(x));
}

template<typename T>
struct RevRange
{
    T a, b;
    RevRange(T a, T b) : a(a), b(b) {}
    typedef T value_type;
    typedef _DummyType iterator;
    template<typename F>
    void process(F f) const
    {
        for (T i = b-1; !(i < a); --i)
            if (!f(i)) break;
    }
};

#define _revrng(n) RevRange<int>(0, n)

template<typename S1, typename S2>
struct CartProdWrapper
{
    const S1 &s1;
    const S2 &s2;
    CartProdWrapper(const S1 &s1, const S2 &s2) : s1(s1), s2(s2) {}
    typedef typename S1::value_type s1_type;
    typedef typename S2::value_type s2_type;
    typedef _DummyType iterator;
    tup2(value_type, s1_type, f, s2_type, s);
    template<typename F>
    inline void process(F f) const
    {
        typedef value_type f_type;
        auto const &s1_local = s1; // avoid compiler crash
        auto const &s2_local = s2; // avoid compiler crash
        xforeach(s1_local, a,
            typedef f_type f_type2;
            auto const &s2_local_local = s2_local; // avoid compiler crash
            bool stop = false;
            xforeach(s2_local_local, b,
                if (!f(f_type2(a, b)))
                {
                    stop = true;
                    xbreak;
                }
            )
            if (stop) xbreak;
        )
    }
};

template<typename S1, typename S2>
CartProdWrapper<S1, S2> _cartprod(const S1 &s1, const S2 &s2)
{
    return CartProdWrapper<S1, S2>(s1, s2);
}

template<typename T1, typename T2>
struct ConcatLists
{
    typedef typename T1::value_type value_type;
    const T1 &a;
    const T2 &b;
    ConcatLists(const T1 &a, const T2 &b) : a(a), b(b) {}
    template<typename F>
    inline void process(F f) const
    {
		bool stop = false;
		xforeach(a, i, if (!f(i)) { stop = true; xbreak; } )
        if (!stop)
			xforeach(b, i, if (!f(i)) xbreak )
    }
};

template<typename T1, typename T2>
ConcatLists<T1, T2> operator % (const T1 &a, const T2 &b)
{
    return ConcatLists<T1, T2>(a, b);
}

template<typename ArrType, typename SeqType>
void apply_perm(ArrType &a, const SeqType &s)
{
    int n = a.size();
    typedef typename item_type<ArrType>::type T;
    vector<T> tmp(n);
    xforeachi(s, i, p, tmp[p] = a[i]; assert(i < n && p < n && p >= 0));
    _for(i, n) a[i] = tmp[i];
}

template<typename ArrType>
struct StackWrapper
{
	ArrType &a;
	int n;
	StackWrapper(ArrType &a) : a(a), n(0) {}
	typedef typename item_type<ArrType>::type value_type;
	inline void push_back(value_type x) { cmap<ArrType>::write(a, n, x); ++n; }
	inline value_type pop_back() { assert(n > 0); --n; return cmap<ArrType>::read(a, n); }
	inline bool empty() { return n == 0; }
	inline value_type& back() { assert(n > 0); return cmap<ArrType>::read(a, n-1); }
	inline void clear() { n = 0; }
	inline value_type& bback() { assert(n > 1); return cmap<ArrType>::read(a, n-2); }
	inline int size() { return n; }
};

template<
	typename GraphType,
	typename VertOrderType,
	typename NewTreeFunctor,
	typename EnterVertexFunctor,
	typename LeaveVertexFunctor,
	typename BeforeTraverseFunctor,
	typename AfterTraverseFunctor,
	typename BackEdgeFunctor,
	typename MarkersType
>
struct Dfs
{
	GraphType &g;
	const VertOrderType ℴ
	NewTreeFunctor new_tree;
	EnterVertexFunctor enter_vertex;
	LeaveVertexFunctor leave_vertex;
	BeforeTraverseFunctor before_traverse;
	AfterTraverseFunctor after_traverse;
	BackEdgeFunctor back_edge;
	MarkersType &markers;

	typedef typename GraphType::v_type V;

	Dfs(
		GraphType &g,
		const VertOrderType &order,
		NewTreeFunctor new_tree,
		EnterVertexFunctor enter_vertex,
		LeaveVertexFunctor leave_vertex,
		BeforeTraverseFunctor before_traverse,
		AfterTraverseFunctor after_traverse,
		BackEdgeFunctor back_edge,
		MarkersType &markers
	) : g(g), order(order), new_tree(new_tree), enter_vertex(enter_vertex), leave_vertex(leave_vertex),
		before_traverse(before_traverse), after_traverse(after_traverse), back_edge(back_edge),
		markers(markers) {}

	void Do()
	{
		xforeach_(order, i)
		{
			if (cmap<MarkersType>::read(markers, i) == 0)
			{
				new_tree(i);
				this->DfsRec(i, _null<V>::value());
			}
		} x_endfe
	}

	void DfsRec(V v, V parent)
	{
		cmap<MarkersType>::write(markers, v, 1);
		enter_vertex(v);
		xforeach_(g.v_edges(v), e)
		{
			if (cmap<MarkersType>::read(markers, e.v) == 0)
			{
				if (before_traverse(v, e))
				{
					this->DfsRec(e.v, v);
					after_traverse(v, e);
				}
			}
			else
			{
				if (!(parent == e.v))
					back_edge(v, e);
			}
		} x_endfe
		leave_vertex(v);
	}
};

template<
	typename GraphType,
	typename VertOrderType,
	typename NewTreeFunctor,
	typename EnterVertexFunctor,
	typename LeaveVertexFunctor,
	typename BeforeTraverseFunctor,
	typename AfterTraverseFunctor,
	typename BackEdgeFunctor,
	typename MarkersType
>
inline void invoke_dfs(
	GraphType &g,
	const VertOrderType &order,
	NewTreeFunctor new_tree,
	EnterVertexFunctor enter_vertex,
	LeaveVertexFunctor leave_vertex,
	BeforeTraverseFunctor before_traverse,
	AfterTraverseFunctor after_traverse,
	BackEdgeFunctor back_edge,
	MarkersType &markers
	)
{
	Dfs<GraphType, VertOrderType, NewTreeFunctor, EnterVertexFunctor,
		LeaveVertexFunctor, BeforeTraverseFunctor, AfterTraverseFunctor,
		BackEdgeFunctor, MarkersType>
		X(g, order, new_tree, enter_vertex, leave_vertex, before_traverse, after_traverse, back_edge, markers);
	X.Do();
}

namespace DFS
{

template<typename VType>
struct EmptyFtr
{
	typedef VType v_type;
	inline void operator () (const VType &v) {}
};

template<typename G>
EmptyFtr<typename G::v_type> _V0(G &g) { return EmptyFtr<typename G::v_type>(); }

template<typename VType, typename EType>
struct EmptyFtrVE
{
	typedef VType v_type;
	typedef EType e_type;
	inline bool operator () (const VType &v, const EType &e) { return true; }
};

template<typename G>
EmptyFtrVE<typename G::v_type, typename G::e_type> _E0(G &g) { return EmptyFtrVE<typename G::v_type, typename G::e_type>(); }

#define V0 _V0(g)
#define E0 _E0(g)

#define _V_(G, ...) [&](const typename G::v_type &v) { __VA_ARGS__; }
#define V_(...) _V_(GraphType, __VA_ARGS__)

#define _E_(G, ...) [&](const typename G::v_type &u, const typename G::e_type e) -> bool { __VA_ARGS__; return true; }
#define E_(...) _E_(GraphType, __VA_ARGS__)

template<typename GraphType, typename MarkersType,
	typename LevAndDpType>
int DfsCountBridges(GraphType &g, MarkersType &markers,
	LevAndDpType &lev, LevAndDpType &dp)
{
	int cur_lev = 0, bridges = 0;
	invoke_dfs(
		g,
		g.vertices(),
		V0,
		V_( RM(dp, v) = cur_lev; RM(lev, v) = cur_lev++ ),
		V_( --cur_lev ),
		E0,
		E_( if (RM(lev, u) < RM(dp, e.v)) bridges++; relax_min(RM(dp, u), RM(dp, e.v)) ),
		E_( relax_min(RM(dp, u), RM(lev, e.v)) ),
		markers
	);
	return bridges;
}

template<typename GraphType, typename MarkersType, typename CompsType,
	typename ListsType>
int DfsFindConnComps(GraphType &g, MarkersType &markers, CompsType &comps,
	ListsType &lists)
{
	int cur = -1;
	_fillit(g.vertices(), markers, 0);
	invoke_dfs(
		g,
		g.vertices(),
		V_( ++cur; RM(lists, cur).clear() ),
		V_( RM(comps, v) = cur; RM(lists, cur).push_back(v) ),
		V0,
		E0,
		E0,
		E0,
		markers
	);
	return cur + 1;
}

template<typename GraphType, typename MarkersType, typename ListType>
void DfsReach(GraphType &g, typename GraphType::v_type v0, MarkersType &markers, ListType &list)
{
    _fillit(g.vertices(), markers, 0);
    invoke_dfs(
        g,
        iterable_wrap<typename GraphType::v_type>(v0),
        V0,
		V_( list.push_back(v) ),
        V0,
        E0,
        E0,
        E0,
        markers
    );
}

template<typename GraphType, typename MarkersType, typename ColType>
bool Dfs2Color(GraphType &g, MarkersType &markers, ColType &col)
{
	bool res = true;
	_fillit(g.vertices(), markers, 0);
	vector<typename GraphType::v_type> order;
	xforeach(g.vertices(), i, if (RM(col, i) != -1) order.push_back(i) );
	xforeach(g.vertices(), i, if (RM(col, i) == -1) order.push_back(i) );
	invoke_dfs(
		g,
		order,
		V_( if (RM(col, v) == -1) RM(col, v) = 0 ),
		V_( assert(RM(col, v) == 0 || RM(col, v) == 1) ),
		V0,
		E_( if (RM(col, e.v) == -1) RM(col, e.v) = 1 - RM(col, u); else if (RM(col, u) == RM(col, e.v)) res = false ),
		E0,
		E_( if (RM(col, u) == RM(col, e.v)) res = false ),
		markers
	);
	return res;
}

template<typename GraphType, typename MarkersType>
bool DfsIsTree(GraphType &g, typename GraphType::v_type v0, MarkersType &markers)
{
    _fillit(g.vertices(), markers, 0);
    bool res = true;
    invoke_dfs(
        g,
        iterable_wrap<typename GraphType::v_type>(v0),
        V0,
        V0,
        V0,
        E0,
        E0,
        E_(res = false),
        markers
    );
    return res;
}

}

#define II(i, j) Idx2<int>(i, j)

template<typename T>
struct Range2
{
    T a, b, c, d;
    Range2(const T &a, const T &b, const T &c, const T &d) : a(a), b(b), c(c), d(d) {}
    typedef Idx2<T> value_type;
    template<typename F>
    void process(F f) const
    {
        for (T i = a; i < b; i++)
            for (T j = c; j < d; j++)
                if (!f(Idx2<T>(i, j)))
                    return;
    }
    inline int size() const { return (b - a) * (d - c); }
};

template<
    typename WeightType,
    typename F
>
struct Weighted2DMazeGraph4C
{
    typedef Weighted2DMazeGraph4C<WeightType, F> graph_type;
    typedef Idx2<int> v_type;
    typedef Range2<int> v_set_type;
    typedef WeightType weight_type;
    struct e_type
    {
        Idx2<int> v;
        WeightType w;
        e_type(const v_type &v, const WeightType &w) : v(v), w(w) {}
    };
    struct edge_list_type
    {
        graph_type &g;
        v_type v;
        typedef e_type value_type;
        template<typename Ftr>
        void process(Ftr f) const
        {
            weight_type w(0);
#define process_dir(cond, i, j) \
            if (cond) \
                if (g.f(v, v_type(i, j), w)) \
                    if (!f(e_type(v_type(i, j), w))) \
                        return;

            process_dir(v.j + 1 < g.m, v.i, v.j + 1);
            process_dir(v.i + 1 < g.n, v.i + 1, v.j);
            process_dir(v.j > 0, v.i, v.j - 1);
            process_dir(v.i > 0, v.i - 1, v.j);
#undef process_dir
        }
        edge_list_type(graph_type &g, const v_type &v) : g(g), v(v) {}
    };

    int n, m;
    v_set_type vs;
    F f;

    inline v_set_type& vertices() { return vs; }
    inline edge_list_type v_edges(const v_type &v)
    {
        return edge_list_type(*this, v);
    }

    Weighted2DMazeGraph4C(int n, int m, F f) : n(n), m(m), vs(0, n, 0, m), f(f) {}
};

template<typename W, typename F>
Weighted2DMazeGraph4C<W, F> create_maze2d4cw(int n, int m, W &dummy_w, F f)
{
    return Weighted2DMazeGraph4C<W, F>(n, m, f);
}

#define _maze2d4cw_(w_var, name, w_type, n, m, ...) \
    w_type w_var; \
    auto name = create_maze2d4cw(n, m, w_var, [&](Idx2<int> u, Idx2<int> v, w_type &w) -> bool { __VA_ARGS__; return true; })

#define _maze2d4cw(name, w_type, n, m, ...) _maze2d4cw_(STRUCT_NAME, name, w_type, n, m, __VA_ARGS__)

template<typename T> struct __v_type { typedef typename T::v_type type; };

#define ver_list(g) \
    vector<__v_type<decltype(g)>::type>

template<typename ArrType>
struct ArrWrapper2
{
	typedef ArrType base_type;
	ArrType &a;
	int n, m;
	ArrWrapper2(ArrType &a, int n, int m) : a(a), n(n), m(m) {}
	typedef typename strict_item_type<ArrType>::type sub_type;
	typedef typename item_type<ArrType>::type value_type;
	struct iterator
	{
		int i, j, m;
		iterator(int i, int j, int m): i(i), j(j), m(m) {}
		inline bool operator != (const iterator &other) const { return i != other.i || j != other.j; }
		inline iterator& operator ++ () { ++j; if (j == m) j = 0, ++i; return *this; }
	};
	inline iterator begin() const { return iterator(0, 0, m); }
	inline iterator end() const { return iterator(n, 0, m); }
	inline int size() const { return n * m; }
	inline value_type& resolve_iterator(const iterator &it) const
	{
		return a[it.i][it.j];
	}
	inline ArrWrapper<sub_type> operator [](int i)
	{
		return ArrWrapper<sub_type>(a[i], m);
	}
    inline value_type& operator [](Idx2<int> idx)
    {
        return a[idx.i][idx.j];
    }
};

template<typename T>
struct cmap<ArrWrapper2<T> >
{
    typedef Idx2<int> key_type;
	typedef typename ArrWrapper2<T>::value_type V;
	inline static void write(ArrWrapper2<T> &a, key_type i,
		const V value) { a.a[i.i][i.j] = value; }
	inline static V& read(ArrWrapper2<T> &a, key_type i) { return a.a[i.i][i.j]; }
};

#define _wrap2(name, base, n, m) \
	ArrWrapper2<decltype(base)> name(base, n, m)

#define _inxxw(type, name, n, m) \
	_inxx(type, name##_base, n, m); \
	_wrap2(name, name##_base, n, m)

#define _tmpxxw(type, name, n, m) \
	_tmpxx(type, name##_base, n, m); \
	_wrap2(name, name##_base, n, m)

#define _partread(a, fld) \
	foreachx(a, v, _io<decltype(v.fld)>::read(v.fld, 0))

template<typename T>
struct EventAdder
{
	typedef T value_type;
    vector<T> &v;
    EventAdder(vector<T> &v) : v(v) {}
    inline void operator () (const T &e) { v.push_back(e); }
};

template<typename EType, typename F1, typename F2>
int event_system(const EType &dummy, F1 gen, F2 proc)
{
    vector<EType> _evs;
    gen(EventAdder<EType>(_evs));
    sort(_evs.begin(), _evs.end());
    for (auto it = _evs.begin(); it != _evs.end(); it++)
    {
        int tmp = proc(*it);
        if (tmp) return tmp;
    }
    return 0;
}

#define ev_sys(ev_type, gen, proc) \
    event_system(ev_type(), [&](EventAdder<ev_type> $) { typedef ValueType<decltype($)>::type E; gen; }, [&](const ev_type &_) -> int { proc; return 0; })

template<
	typename Arr,
	typename RevArr
>
struct HeapWithKeys
{
	Arr &a;
	RevArr &pos;
	int n;
	typedef typename item_type<Arr>::type kv_pair_type;
	typedef typename kv_pair_type::key_type key_type;
	typedef typename kv_pair_type::value_type value_type;

	inline int size() const { return n; }
	inline const kv_pair_type& top() const { assert(n > 0); return cmap<Arr>::read(a, 0); }

    HeapWithKeys(Arr &a, RevArr &pos) : a(a), pos(pos), n(0) {}

	inline void push_relax_min(const key_type &key, const value_type &value)
	{
		int idx = cmap<RevArr>::read(pos, key);
		if (idx == -1)
		{
			a[n] = kv_pair_type(key, value);
			cmap<RevArr>::write(pos, key, n);
			++n;
			sift_up(n-1);
			return;
		}
		if (value < a[idx].value)
		{
			a[idx].value = value;
			sift_up(idx);
		}
	}

	inline void pop()
	{
		assert(n > 0);
		exchange(0, n-1);
		cmap<RevArr>::write(pos, a[n-1].key, -1);
		n--;
		if (n > 0) sift_down(0);
	}

	inline void exchange(int i, int j)
	{
		int tmp = cmap<RevArr>::read(pos, a[i].key);
		cmap<RevArr>::read(pos, a[i].key) = cmap<RevArr>::read(pos, a[j].key);
		cmap<RevArr>::read(pos, a[j].key) = tmp;
		swap(a[i], a[j]);
	}

	void sift_down(int i)
	{
		while (2*i+1 < n)
		{
			int left_c = 2*i + 1;
			int right_c = left_c + 1;
			int x = (right_c == n || a[left_c].value < a[right_c].value) ? left_c : right_c;
			if (a[i].value > a[x].value)
			{
				exchange(i, x);
				i = x;
			}
            else
            {
                break;
            }
		}
	}

	void sift_up(int i)
	{
		while (i > 0 && a[i].value < a[(i-1)/2].value)
		{
			exchange(i, (i-1)/2);
			i = (i-1)/2;
		}
	}
};

template<typename T, typename S>
inline HeapWithKeys<T, S> create_heap_with_keys(T &arr, S &rev_arr)
{
    return HeapWithKeys<T, S>(arr, rev_arr);
}

template<
	typename GraphType,
	typename InitVertsType,
	typename DistsType,
	typename MarkersType,
	typename HeapType
>
void heap_dijkstra(
	GraphType graph,
	InitVertsType v0,
	DistsType &dists,
	MarkersType &markers,
	HeapType &heap
)
{
	typedef typename GraphType::weight_type wt;
	_fillit(graph.vertices(), markers, false);
	_fillit(graph.vertices(), dists, get_max_value<wt>());
	xforeach(v0, i, heap.push_relax_min(i, get_zero<wt>()));
	while (heap.size() > 0)
	{
		typename HeapType::kv_pair_type v = heap.top();
		heap.pop();
		cmap<DistsType>::write(dists, v.key, v.value);
		cmap<MarkersType>::write(markers, v.key, true);
		xforeach(graph.v_edges(v.key), e,
			if (!cmap<MarkersType>::read(markers, e.v))
			{
				heap.push_relax_min(e.v, v.value + e.w);
			}
        )
	}
}

template<typename T, typename X>
struct _mapcreator
{
    typedef map<typename T::value_type, X> map_type;
    static map_type create(const T &t) { return map_type(); }
};

template<typename Ordinal, typename X>
struct _mapcreator<Range2<Ordinal>, X>
{
    typedef X **map_type;
    static map_type create(const Range2<Ordinal> &t)
    {
        assert(t.a == 0 && t.c == 0);
        map_type res = new X* [t.b];
        for (int i = 0; i < t.b; i++) res[i] = new X[t.d];
        return res;
    }
};

template<typename Ordinal, typename X>
struct _mapcreator<Range<Ordinal>, X>
{
    typedef X *map_type;
    static map_type create(Range<Ordinal> &t)
    {
        assert(t.a == 0);
        return new X[t.b];
    }
};

template<typename T, typename X, typename F>
struct _mapcreatori
{
	typedef _DummyType map_type;
	static map_type create(const T &t, F init_functor) { return map_type(); }
};

template<typename Ordinal, typename X, typename F>
struct _mapcreatori<Range<Ordinal>, X, F>
{
	typedef ArrWrapper<X*> map_type;
	static map_type create(const Range<Ordinal> &r, F f)
	{
		assert(r.a == 0);
		X *&res = *(new X*);
		res = new X[r.b];
		for (Ordinal i = 0; i < r.b; i++) res[i] = f(i);
		return map_type(res, r.b);
	}
};

#define graph_heap(g, name) graph_heap_(STRUCT_NAME, g, name)

#define graph_heap_(gtype, g, name) \
    typedef decltype(g) gtype; \
    tup2(name##_elem_type, gtype::v_type, key, gtype::weight_type, value); \
    _tmpx(name##_elem_type, name##_heap_arr, g.vertices().size());\
    _mapcreator<gtype::v_set_type, int>::map_type name##_heap_rev_arr = \
        _mapcreator<gtype::v_set_type, int>::create(g.vertices()); \
    _fillit(g.vertices(), name##_heap_rev_arr, -1); \
    auto name = create_heap_with_keys(name##_heap_arr, name##_heap_rev_arr);

#define graph_markers(T, g, name) graph_markers_(STRUCT_NAME, T, g, name)

#define graph_markers_(gtype, T, g, name) \
    typedef decltype(g) gtype; \
    auto name = _mapcreator<gtype::v_set_type, T>::create(g.vertices())

struct choose_rand
{
	const int n, k;
	choose_rand(int n, int k) : n(n), k(k)
	{
		assert(k <= n);
		assert(n >= 0);
	}
    typedef int value_type;
	template <typename F>
	void process(F f) const
	{
		if (k == 0) return;
		int *a = new int[k];
		for (int i = 0; i < k; i++)
		{
			int t = _rand(n - i);
			int j;
			for (j = 0; j < i; j++)
				if (t >= a[j]) t++; else break;
			assert(t < n);
			for (int k = i-1; k >= j; k--)
				a[k+1] = a[k];
            a[j] = t;
		}
        for (int i = 0; i < k; i++)
            if (!f(a[i])) break;
		delete [] a;
	}
};

template<typename VerticesSetType, typename AdjListsType>
struct AdjListsGraph
{
	VerticesSetType &verts;
	AdjListsType &lists;

	AdjListsGraph(VerticesSetType &verts, AdjListsType &lists) : verts(verts), lists(lists) {}

	typedef typename item_type<AdjListsType>::type edge_list_type;
	typedef typename edge_list_type::value_type e_type;
	typedef typename VerticesSetType::value_type v_type;
	typedef VerticesSetType v_set_type;
	inline typename item_type<AdjListsType>::type& v_edges(v_type v)
		{ return cmap<AdjListsType>::read(lists, v); }
	inline v_set_type& vertices()
		{ return verts; }
};

template<typename VerticesSetType, typename AdjListsType>
struct AdjListsWGraph : public AdjListsGraph<VerticesSetType, AdjListsType>
{
	typedef typename AdjListsGraph<VerticesSetType, AdjListsType>::e_type::w_type weight_type;
	AdjListsWGraph(VerticesSetType &verts, AdjListsType &lists) : AdjListsGraph<VerticesSetType, AdjListsType>(verts, lists) {}
};

template<typename V, typename E> inline
AdjListsGraph<V, E> create_adj_lists_graph(V &verts, E &lists)
{
    return AdjListsGraph<V, E>(verts, lists);
}

#define adj_lists_graph(name, lists) \
    auto name##_vset = _keys<decltype(lists)>::get(lists); \
    auto name = create_adj_lists_graph(name##_vset, lists);

template<typename T, typename F>
struct MatrixGraph
{
	T &mat;
	int n;
};

template<typename T>
struct BoolMatrixGraph
{
	T &mat;
	int n;

	typedef typename item_type<T>::type elem_type;

	struct EdgeData
	{
		const int v;
		EdgeData(int v) : v(v) {}
	};

	struct EdgesList
	{
		const int n;
		const elem_type *data;
		EdgesList(int n, elem_type *data) : n(n), data(data) {}
		struct iterator
		{
			int p;
			const EdgesList *owner;
			iterator(int p, const EdgesList *owner) : p(p), owner(owner) {}
			inline iterator& operator ++() { do ++p; while (p < owner->n && !owner->data[p]); return *this; }
			inline bool operator != (const iterator &other) { return p != other.p; } // don't check the owner!
		};
		typedef EdgeData value_type;
		inline iterator begin() const { int t = 0; while (t < n && !data[t]) ++t; return iterator(t, this); }
		inline iterator end() const { return iterator(n, this); }
		inline int size() const { int t = 0; for(int i = 0; i < n; ++i) if (data[i]) ++t; return t; }
		inline value_type resolve_iterator(iterator it) const { return EdgeData(it.p); }
		template<typename F> inline
		void process(F f) const
		{
			for (int i = 0; i < n; i++) if (data[i]) if (!f(i)) return;
		}
	};

	BoolMatrixGraph(T &mat, int n) : mat(mat), n(n) {}
	typedef int v_type;
	typedef EdgesList edges_list_type;
	typedef EdgeData e_type;
	typedef Range<int> v_set_type;
	inline EdgesList v_edges(int v) const { return EdgesList(n, mat[v]); }
	inline Range<int> vertices() const { return Range<int>(0, n); }
};

template<typename T>
struct BoolMatrixGraphBi : public BoolMatrixGraph<T>
{
	BoolMatrixGraphBi(T &mat, int n) : BoolMatrixGraph<T>(mat, n) {}
	inline void add_edge(int u, int v) { this->mat[u][v] = true; this->mat[v][u] = true; }
	inline void erase_edge(int u, int v) { this->mat[u][v] = false; this->mat[v][u] = false; }
};

template<typename G>
inline int g_degree(G &g, typename G::v_type v)
{
	return g.v_edges(v).size();
}

template<typename T>
struct DistMatrixGraph
{
	T &dists;
	int n;

	typedef typename item_type<typename item_type<T>::type>::type weight_type;

	struct EdgeData
	{
		const int v;
		const weight_type w;
		EdgeData(int v, weight_type w) : v(v), w(w) {}
	};

	struct EdgesList
	{
		const int n;
		const weight_type *data;
		EdgesList(int n, weight_type *data) : n(n), data(data) {}
		typedef int iterator;
		typedef EdgeData value_type;
		inline iterator begin() const { return 0; }
		inline iterator end() const { return n; }
		inline int size() const { return n; }
		inline value_type resolve_iterator(iterator it) const { return EdgeData(it, data[it]); }
	};

	DistMatrixGraph(T &a, int n) : dists(a), n(n) {}

	typedef int v_type;
	typedef EdgesList edges_list_type;
	typedef EdgeData e_type;
	typedef Range<int> v_set_type;
	inline EdgesList v_edges(int v) const { return EdgesList(n, dists[v]); }
	inline Range<int> vertices() const { return Range<int>(0, n); }
};

#define DMG(type, name, maxn) \
	type name[maxn][maxn]; \
	typedef DistMatrixGraph<type, maxn, maxn> name##_type

template<
	typename GraphType,
	typename TableType,
	typename InitVertsType,
	typename MarkersType
>
void dijkstra(
	GraphType graph,
	InitVertsType v0,
	MarkersType &markers,
	TableType &dists
	)
{
	typedef typename GraphType::weight_type wt;
	typedef typename GraphType::v_type vt;
	_fillit(graph.vertices(), markers, false);
	_fillit(graph.vertices(), dists, get_max_value<wt>());
	_fillit(v0, dists, get_zero<wt>());
	while (true)
	{
		wt wmin = get_max_value<wt>();
		vt v;
		xforeach(graph.vertices(), i,
			if (!RM(markers, i) && RM(dists, i) < wmin)
			{
				wmin = RM(dists, i);
				v = i;
			}
		);
		if (wmin == get_max_value<wt>()) break;
		RM(markers, v) = true;
		xforeach(graph.v_edges(v), e, relax_min(RM(dists, e.v), wmin + e.w));
	}
}

tup2(int_uv, int, u, int, v);
tup3(int_uvw, int, u, int, v, int, w);
tup1(int_v, int, v);
tup2(int_vw, int, v, int, w);

#define UniWBuildAdjLists_macro(name, eu_expr, ev_expr) \
template<\
	typename SrcIndicesType,\
	typename SrcType,\
	typename DstType\
>\
void name(\
	SrcIndicesType src_idx, \
	SrcType src, \
	DstType dst \
	)\
{\
	xforeach(src_idx, i, \
		typedef typename item_type<SrcType>::type src_type;\
		typedef typename item_type<DstType>::type::value_type dst_type;\
		src_type &e = cmap<SrcType>::read(src, i);\
		cmap<DstType>::read(dst, eu_expr).push_back(dst_type(ev_expr, e.w));\
	)\
}

#define BiWBuildAdjLists_macro(name, eu_expr, ev_expr) \
template<\
	typename SrcIndicesType,\
	typename SrcType,\
	typename DstType\
>\
void name(\
	SrcIndicesType src_idx,\
	SrcType src, \
	DstType dst \
	)\
{\
	xforeach(src_idx, i, \
		typedef typename item_type<SrcType>::type src_type;\
		typedef typename item_type<DstType>::type::value_type dst_type;\
		src_type &e = cmap<SrcType>::read(src, i);\
		cmap<DstType>::read(dst, eu_expr).push_back(dst_type(ev_expr, e.w));\
		cmap<DstType>::read(dst, ev_expr).push_back(dst_type(eu_expr, e.w));\
	)\
}

#define BiBuildAdjLists_macro(name, eu_expr, ev_expr) \
template<\
	typename SrcIndicesType,\
	typename SrcType,\
	typename DstType\
>\
void name(\
	SrcIndicesType src_idx,\
	SrcType src, \
	DstType dst \
	)\
{\
	xforeach(src_idx, i, \
		typedef typename item_type<SrcType>::type src_type;\
		typedef typename item_type<DstType>::type::value_type dst_type;\
		src_type &e = cmap<SrcType>::read(src, i);\
		cmap<DstType>::read(dst, eu_expr).push_back(dst_type(ev_expr));\
		cmap<DstType>::read(dst, ev_expr).push_back(dst_type(eu_expr));\
	)\
}

UniWBuildAdjLists_macro(UniWBuildAdjLists_m1, e.u - 1, e.v - 1)
BiWBuildAdjLists_macro (BiWBuildAdjLists_m1,  e.u - 1, e.v - 1)
BiBuildAdjLists_macro  (BiBuildAdjLists_m1,   e.u - 1, e.v - 1)

#define _adj_lists_uni_w(n, m, e_raw, e_out) _adj_lists_generic_w(UniWBuildAdjLists_m1, n, m, e_raw, e_out)
#define _adj_lists_bi_w(n, m, e_raw, e_out) _adj_lists_generic_w(BiWBuildAdjLists_m1 , n, m, e_raw, e_out)

#define _adj_lists_generic_w(list_builder, n, m, e_raw, e_out) \
	_adj_lists_generic_w__(STRUCT_NAME, STRUCT_NAME, STRUCT_NAME, list_builder, n, m, e_raw, e_out)

#define _adj_lists_generic_w__(s_name, v_name, w_name, list_builder, n, m, e_raw, e_out) \
	typedef item_type<decltype(e_raw)>::type::v_type v_name; \
	typedef item_type<decltype(e_raw)>::type::w_type w_name; \
	tup2(s_name, v_name, v, w_name, w); \
	_tmpx(vector<s_name>, e_out, n); \
	list_builder(Range<int>(0, m), e_raw, e_out)

#define _adj_lists_bi(n, m, e_raw, e_out) _adj_lists_generic(BiBuildAdjLists_m1,   n, m, e_raw, e_out)

#define _adj_lists_generic(list_builder, n, m, e_raw, e_out) \
	_adj_lists_generic__(STRUCT_NAME, STRUCT_NAME, list_builder, n, m, e_raw, e_out)

#define _adj_lists_generic__(s_name, v_name, list_builder, n, m, e_raw, e_out) \
	typedef item_type<decltype(e_raw)>::type::v_type v_name; \
	tup1(s_name, v_name, v); \
	_tmpx(vector<s_name>, e_out, n); \
	list_builder(Range<int>(0, m), e_raw, e_out)

#define GraphDM(name, base_matrix, n) \
	auto name = DistMatrixGraph<decltype(base_matrix)>(base_matrix, n);

#define GraphAL(name, lists, n) \
	Range<int> name_verts(0, n); \
	AdjListsGraph<Range<int>, decltype(lists)> name(name_verts, lists)

template<typename T>
struct div_op
{
	typedef double type;
	inline static type Do(const T &a, const T &b) { return double(a) / double(b); }
};

template<typename T>
struct mul_op
{
	typedef double type;
	inline static type Do(const T &a, const T &b) { return double(a) * double(b); }
};

template<>
struct mul_op<int>
{
	typedef long long type;
	inline static type Do(int a, int b) { return (long long)a * b; }
};

template<typename T>
struct Frac
{
	T num, den;
	typedef typename div_op<T>::type value_type;
	Frac(const T &num, const T &den) : num(num), den(den) {}
	Frac(const T &num) : num(num), den(1) {}
	Frac() : num(0), den(1) {}
	inline value_type value() const { return div_op<T>::Do(num, den); }
	inline bool operator < (const Frac<T> &other) const
	{
		return mul_op<T>::Do(num, other.den) < mul_op<T>::Do(other.num, den);
	}
	inline bool operator <= (const Frac<T> &other) const
	{
		return mul_op<T>::Do(num, other.den) <= mul_op<T>::Do(other.num, den);
	}
	inline bool operator > (const Frac<T> &other) const
	{
		return mul_op<T>::Do(num, other.den) > mul_op<T>::Do(other.num, den);
	}
	inline bool operator >= (const Frac<T> &other) const
	{
		return mul_op<T>::Do(num, other.den) >= mul_op<T>::Do(other.num, den);
	}
	inline bool operator == (const Frac<T> &other) const
	{
		return mul_op<T>::Do(num, other.den) == mul_op<T>::Do(other.num, den);
	}
	inline void _write() const { _io<T>::write(num); _wstr("/"); _io<T>::write(den); }
	inline void _read(int i) { _io<T>::read(num, i); _io<T>::read(den, i); }
};

template<typename T>
inline Frac<T> linear_collide(T c1, T v1, T c2, T v2)
{
	return Frac<T>(c2 - c1, v1 - v2);
}

template<typename T>
inline Frac<T> linear_interpolate(T x1, T x2, T x, T y1, T y2)
{
    return Frac<T>(y1 * (x2 - x1) + (y2 - y1) * (x - x1), x2 - x1);
}

template<typename T>
inline Frac<T> const_acc_pos(T t, T acc, T v0 = T(0))
{
    return Frac<T>(acc * t * t + 2 * v0 * t, 2);
}

template<typename T>
inline typename mul_op<T>::type sqr(const T &a)
{
    return mul_op<T>::Do(a, a);
}

template<typename T1, typename T2>
inline double distance2d(const T1 &a, const T2 &b)
{
    return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
}

template<typename T1, typename T2>
inline auto distance2dsq(const T1 &a, const T2 &b) -> typename mul_op<decltype(a.x)>::type
{
    return sqr(a.x - b.x) + sqr(a.y - b.y);
}

template<typename F>
inline double BS_FP(double l, double r, int iters, F f)
{
	for (int it_num = 0; it_num < iters; it_num++)
	{
		double m = (l + r) / 2;
		if (f(m)) r = m; else l = m;
	}
	return (l + r) / 2;
}

#define bs_fp(l, r, iters, name, ...) \
	BS_FP(l, r, iters, [&](double name) -> bool { __VA_ARGS__ })

// ====== <<< SOLUTION >>> ===================================================

void solve()
{
	_in(int, n);
	_inxw(vector<int>, sticks, n);
	int res = 0;
	_for(i, n)
	{
		int lt = 0, rt = 0, f = 0;
		tup2c(Ev, int, pos, int, ty, cmp_a(pos));
		ev_sys(Ev,
		{
			xforeach(sticks[i], x, $(E(x, 0)));
			xforeach(sticks[(i+1)%n], x, $(E(x, 1)));
			xforeach(sticks[(i+n-1)%n], x, $(E(x, 2)));
		},
		{
			if (_.ty == 1) ++lt;
			else if (_.ty == 2) ++rt;
			else
			{
				if (lt != rt && f > 0) res++;
				f = 1;
				lt = rt = 0;
			}
		});
	}
	_w(res);
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("test.in", "r", stdin);
	freopen("test.out", "w", stdout);
#endif
	solve();
	return 0;
}


#ifndef SPLICED
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
void solve(); int main(){
  #ifdef LOL
  freopen("D.in","r",stdin);
  #endif
ios::sync_with_stdio(false);solve();}
#endif

vector<ll> y[1000];
vector<ll> g[1000];

void solve(){
  ll n,res=0; cin>>n;
  for (int i=0; i<n; i++) {ll m,x; cin>>m; while (m--) cin>>x, y[i].push_back(x); sort(y[i].begin(),y[i].end()); g[i].resize(y[i].size());}
  for (int i=0; i<n; i++){
    ll delta=3;
    for (auto k: {(i+n-1)%n,(i+n+1)%n}){ delta-=2;
      int a=0,b=0;
      for (int j=0; j+1<y[i].size(); j++){
        while (b<y[k].size() and y[k][b]<=y[i][j+1]) ++b;
        while (a<y[k].size() and y[k][a]<y[i][j]) ++a;
        g[i][j]+=delta*(b-a);
      }
    }
    for (int j=0; j+1<y[i].size(); j++){
      res+=(g[i][j]!=0);
    }
  }
  cout<<res<<endl;
}


#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include <map>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cassert>
using namespace std;

#define DEBUG //on-off switch for prlling statements

// Input macros
#define s(n)                        scanf("%d",&n)
#define sc(n)                       scanf("%c",&n)
#define sl(n)                       scanf("%lld",&n)
#define sf(n)                       scanf("%lf",&n)
#define ss(n)                       scanf("%s",n)

// Useful constants
#define EPS                         1e-9

// Useful hardware instructions
#define bitcount1                    __builtin_popcount1
#define gcd                         __gcd

// Useful container manipulation / traversal macros
#define forall(i,a,b)               for(ll i=a;i<b;i++)
#define foreach(v, c)               for( typeof( (c).begin()) v = (c).begin();  v != (c).end(); ++v)
#define all(a)                      a.begin(), a.end()
#define in(a,b)                     ( (b).find(a) != (b).end())
#define pb                          push_back
#define fill(a,v)                    memset(a, v, sizeof a)
#define sz(a)                       ((ll)(a.size()))

// Some common useful functions
#define maX(a,b)                     ( (a) > (b) ? (a) : (b))
#define miN(a,b)                     ( (a) < (b) ? (a) : (b))

#define INF 1000000000
#define ll long long int
#define llu long long unsigned
#define ld long
#define mod 1000000009
 #define llu long long unsigned
#define ld long
#define F first
#define S second

vector<int> arr[1001];
int solve(int idx,int s,int e)
{
    int sx,ex;
    if(arr[idx][arr[idx].size()-1] < sx)
    {
        return 0;
    }
    sx=lower_bound(arr[idx].begin(),arr[idx].end(),s)-arr[idx].begin();
    if(arr[idx][arr[idx].size()-1] < ex)
    {
        ex=arr[idx].size()-1;
    }
    else
    ex=lower_bound(arr[idx].begin(),arr[idx].end(),e)-arr[idx].begin()-1;
    return ex-sx+1;
}

int main()
{
    int n;
    s(n);
    for(int i=0;i<n;i++)
    {
        int k;
        s(k);
        int x;
        for(int j=0;j<k;j++)
        {
            s(x);
            arr[i].pb(x);
        }
        sort(arr[i].begin(),arr[i].end());
    }
    int ans=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<arr[i].size()-1;j++)
        {
            int s=arr[i][j];
            int e=arr[i][j+1];
            int p=(i+1)%n;
            int n1=(i-1+n)%n;
            int x= solve(p,s,e);
            int y= solve(n1,s,e);
      if(x != y)
      ans++;
     }
   }
   cout<<ans<<endl;
}


#include <iostream>
#include <stdio.h>
#include <string>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <set>
#include <map>
#include <string.h>
#include <bitset>
#include <queue>
#include <functional>
#include <stack>
#include <sstream>
#include <list>

#define LOOP(i,n) for(int i=0; i<n;i++)
#define TESTCASE int T;cin >>T;for(int Z=0;Z<T;Z++)
#define ARRIN(i,n) for(int il=0;il<n;il++)cin>>i[il]
#define OO (int)1e9
#define CLR(arr,num) memset(arr,num,sizeof(arr))
#define CLR2(arr,num,size) for(int i=0;i<size;i++)arr[i]=num;
#define SUM(arr,n,s) for(int i=0;i<n;i++)s+=arr[i];
#define BWGET(code,i) (code & (1 << i))
#define BWSET(code,i,s) ((s)?code|(1<<i):code&(~(1<<i)))
#define EPS 1e-9

using namespace std;

int main(){
    int n; cin >> n;
    vector<vector<int> > br(n);
    for (int i = 0; i < n; i++)
    {
        int k; cin >> k;
        br[i].resize(k);
        for (int j = 0; j < k; j++)
        {
            cin >> br[i][j];
        }
        sort(br[i].begin(), br[i].end());
    }
    int out = 0;
    for (int i = 0; i < n; i++)
    {
        int prev = (i-1+n)%n;
        int next = (i+1)%n;
        for (int j = 0; j < br[i].size()-1; j++)
        {
            int low = br[i][j];
            int high = br[i][j+1];
            int pv = upper_bound(br[prev].begin(), br[prev].end(), high) - upper_bound(br[prev].begin(), br[prev].end(), low);
            int nv = upper_bound(br[next].begin(), br[next].end(), high) - upper_bound(br[next].begin(), br[next].end(), low);
            out += pv!=nv;
        }
    }
    cout << out;
    return 0;
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <time.h>
#include <vector>

#if LOCAL
	#define DO_NOT_SEND
#endif

typedef long long LL;

int IntMaxVal = (int) 1e20;
int IntMinVal = (int) -1e20;
LL LongMaxVal = (LL) 1e20;
LL LongMinVal = (LL) -1e20;

#define FOR(i, a, b) for(int i = a; i < b ; ++i)
#define FORD(i, a, b) for(int i = a; i >= b; --i)

#define minimize(a, b) { a = min(a, b); }
#define maximize(a, b) { a = max(a, b); }

#define all(v) v.begin(),v.end()

using namespace std;

#define next(type, i) type i; cin >> i;
template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };
#define nextVector(t, v, size) vector< argument_type<void(t)>::type > v(size); { for (int i = 0 ; i < size ; i++) cin >> v[i]; }

#define range(name, start, count) vector<int> name(count); { for (int i = 0 ; i < count ; i++) name[i] = i + start; }

template <typename T1, typename T2>
istream& operator >>(istream& is, pair<T1, T2>& s)
{
    is >> s.first >> s.second;
    return is;
}

int main() {
	srand (time(NULL));
    ios_base::sync_with_stdio(false); cin.tie(NULL);

	next(int, n);
	vector<vector<int> > web(n);
	for (auto &v : web) {
		next(int, k);
		nextVector(int, segment, k);
		sort(all(segment));
		v = segment;
	}

	int res = 0;
	FOR (i, 0, n) {
		int prev = (i + n - 1) % n;
		int foll = (i + 1) % n;

		int j = 0;
		int k = 0;

		while (j < web[prev].size() && web[prev][j] < web[i].front()) j++;
		while (k < web[foll].size() && web[foll][k] < web[i].front()) k++;

		FOR (m, 0, web[i].size() - 1) {
			int from = web[i][m];
			int to = web[i][m + 1];

			int left = 0;
			int right = 0;

			while (j < web[prev].size() && web[prev][j] < to) j++, left++;
			while (k < web[foll].size() && web[foll][k] < to) k++, right++;
			if (left != right) res++;
		}
	}

	cout << res;
}


#include <iostream>
#include <algorithm>
using namespace std;

int n;
int *k;
int **p;

int dec(int i) {return i!=0   ? i-1 : n-1;}
int inc(int i) {return i!=n-1 ? i+1 : 0  ;}

int main()
{
    cin >> n;
    k=new int[n];
    p=new int*[n];
    for(int i=0; i<n; i++)
    {
        cin >> k[i];
        p[i]=new int[k[i]];
        for(int j=0; j<k[i]; j++) cin >> p[i][j];
        sort(p[i],p[i]+k[i]);
    }

    int result=0;
    for(int i=0; i<n; i++)
    {
        int prev=dec(i);
        int next=inc(i);

        int prevL=0, prevR=0, nextL=0, nextR=-1;

        for(int j=0; j+1<k[i]; j++)
        {
            int prevCount, nextCount;

            while(prevL<k[prev] && p[prev][prevL]<p[i][j]) prevL++;
            if(prevL>=k[prev] || p[prev][prevL]>p[i][j+1]) prevCount=0;
            else
            {
                int prevR=prevL;
                while(prevR+1<k[prev] && p[prev][prevR+1]<p[i][j+1]) prevR++;
                prevCount=prevR-prevL+1;
                prevL=prevR+1;
            }

            while(nextL<k[next] && p[next][nextL]<p[i][j]) nextL++;
            if(nextL>=k[next] || p[next][nextL]>p[i][j+1]) nextCount=0;
            else
            {
                int nextR=nextL;
                while(nextR+1<k[next] && p[next][nextR+1]<p[i][j+1]) nextR++;
                nextCount=nextR-nextL+1;
                nextL=nextR+1;
            }

            if(prevCount!=nextCount) result++;
        }
    }

    cout << result;

    for(int i=0; i<n; i++) delete[] p[i];
    delete[] p, k;
    return 0;
}


#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <climits>
#include <iostream>
#include <sstream>
#include <cfloat>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <stack>
#include <cstring>
#include <queue>
#include <functional>
#include <unistd.h>
//#include <unordered_set>
//#include <unordered_map>
// INT_MAX
#ifndef INT64_MAX
#define INT64_MAX 9223372036854775807LL
#define INT64_MIN (- (9223372036854775807LL)-1)
#endif

using namespace std;

typedef unsigned char uint8;
typedef unsigned int uint;
typedef long long int64;
typedef unsigned long long uint64;

uint64 urand64() { return (uint64(rand()) << 50) ^ (uint64(rand()) << 25) ^ (uint64(rand()) << 0); }

#define dbg(...) { cout << #__VA_ARGS__ " = " << (__VA_ARGS__) << endl; }
#define dbgl() cout << endl;
#define dbgv(v) { dbgv_(#v, begin(v), end(v)); };

template <class I> void dbgv_(const string& s, I begin, I end)
{
	cout << s << " = ";
	for (I i = begin; i < end; ++i) cout << *i << " ";
	cout << endl;
}

#define rep2(i,n) for (int (i) = 0; (i) < (n); (i)++)
#define rep3(i,a,n) for (int (i) = (a); (i) <= (n); (i)++)
#define repx___(A1,A2,A3,F,...) F
#define rep(...) repx___(__VA_ARGS__, rep3, rep2)(__VA_ARGS__)

template<class T, class U>
inline bool chmin(T& x, const U& y) { if (y < x) { x = y; return true;} else return false; }

template<class T, class U>
inline bool chmax(T& x, const U& y) { if (y > x) {x = y; return true;} else return false; }

// === KEEP ABOVE ===

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

	vector<vector<int> > P(n);

	rep(i,n)
	{
		int k;
		cin >> k;

		P[i] = vector<int>(k);

		rep(j,k)
		{
			scanf("%d", &P[i][j]);
		}

		sort(P[i].begin(), P[i].end());
	}

	int total_bad_cells = 0;

	rep(i,n)
	{
		int l = (i + n - 1) % n;
		int m = i;
		int r = (i + n + 1) % n;

		vector<int>::iterator itl = P[l].begin();
		vector<int>::iterator itr = P[r].begin();

		rep(j,P[m].size()-1)
		{
			int lo = P[m][j];
			int hi = P[m][j+1];
			int Tl = 0;
			int Tr = 0;

			while (itl != P[l].end() && *itl < lo)
				itl++;

			while (itr != P[r].end() && *itr < lo)
				itr++;

			while (itl != P[l].end() && *itl < hi)
			{
				Tl++;
				itl++;
			}

			while (itr != P[r].end() && *itr < hi)
			{
				Tr++;
				itr++;
			}

			if (Tl != Tr)
				total_bad_cells++;

			Tl = 0;
			Tr = 0;
		}
	}

	cout << total_bad_cells << endl;

}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef __int64 lld;
const int maxn = 1010;
vector<int> edge[maxn];
int a[maxn];
int cnt1[100010];
int cnt2[100010];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1,k;i<=n;i++)
    {
        scanf("%d",&k);
        a[i]=k;
        int num;
        for(int j=0;j<k;j++)
        {
            scanf("%d",&num);
            edge[i].push_back(num);
        }
        sort(edge[i].begin(),edge[i].end());
    }
    int ans=0;
    int i=1;
    while(1)
    {
        int j=0;
        int tot=0;
        memset(cnt1,0,sizeof(cnt1));
        memset(cnt2,0,sizeof(cnt2));
        int t;
        if(i-1==0) t=n;
        else t=i-1;
        for(vector<int>::iterator it=edge[i].begin();it!=edge[i].end();it++)
        {
            while(j<a[t] && edge[t][j] < *it )
            {
            if(it!=edge[i].begin() && *(it-1)!=edge[t][j]) cnt1[tot]++;
                j++;
            }
            tot++;
        }
        j=0,tot=0;
        int to;
        if(i+1>n) to=1;
        else to=i+1;
        for(vector<int>::iterator it=edge[i].begin();it!=edge[i].end();it++)
        {
            while(j<a[to] && edge[to][j] < *it)
            {
                if(it!=edge[i].begin() && *(it-1)!=edge[to][j])cnt2[tot]++;
                j++;
            }
            tot++;
        }
        for(int j=0;j<tot;j++)
        {
            if(cnt1[j]!=cnt2[j]) ans++;
        }
        i++;
        if(to==1) break;
    }
    printf("%d\n",ans);
    return 0;
}


#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN=100001;
const int INF=0x7FFFFFFF;
const double eps=1e-8;
const double pi=acos(-1.0);

int n;
vector<long long> v[MAXN];

void init(){
	int t,dist;
	scanf("%d",&n);
	for (int i=0; i<n; i++){
		scanf("%d",&t);
		long long temp=0;
		for (int j=0; j<t; j++){
			scanf("%d",&dist);
			v[i].push_back(dist);
		}
		sort(v[i].begin(),v[i].end());
	}
}

int findMin(vector<long long> &v, int value){
	int le=0,ri=v.size()-1,ret=0;
	while (le<=ri){
		int mid=(le+ri)/2;
		if (v[mid]<=value){
			ret=mid+1;
			le=mid+1;
		} else ri=mid-1;
	}
	return ret;
}

int check(int index){
	int le=(index-1+n)%n,ri=(index+1)%n,ret=0;
	for (int i=0; i<v[index].size()-1; i++){
		int t1=findMin(v[le],v[index][i]),t2=findMin(v[ri],v[index][i]);
		int t3=findMin(v[le],v[index][i+1]),t4=findMin(v[ri],v[index][i+1]);
		if (t3-t1!=t4-t2) ++ret;
	}
	return ret;
}

void solve(){
	int ret=0;
	for (int i=0; i<n; i++){
		ret+=check(i);
	}
	cout<<ret<<endl;
}

int main(){
	init();
	solve();
	return 0;
}


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

#define rep(i,n) for( int i=0; i<(int)n; ++i )
#define pb(x) push_back(x)

int main(){
    int n,k,t;
    cin>>n;
    vector<int> v[1003];
    rep(i,n){
        cin>>k;
        rep(j,k){
            cin>>t;
            v[i].pb(t);
        }
        sort(v[i].begin(),v[i].end());
    }
    int ans = 0;
    for( int i=0; i<n; ++i ){
        int p = (i+1)%n;
        int m = i;
        int q = (i+n-1)%n;
        rep(j,v[m].size()-1){
            int st = v[m][j],
                en = v[m][j+1];
            int x = upper_bound(v[p].begin(),v[p].end(),en) - lower_bound(v[p].begin(),v[p].end(),st);
            int y = upper_bound(v[q].begin(),v[q].end(),en) - lower_bound(v[q].begin(),v[q].end(),st);
            if( x!=y )
                ans++;
        }
    }
    cout<<ans<<"\n";
}


#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define F first
#define S second

using namespace std;
typedef long long ll;
int main() {
    ll n;
    cin>>n;
    vector< map<ll, ll> > v(n);
    vector< vector<ll> > w(n);
    for(ll i=0; i<n; ++i) {
        ll k;
        cin>>k;
        w[i].resize(k);
        for(ll j=0; j<k; ++j) {
            cin>>w[i][j];
            //v[i][w[i][j]]=j+1;
        }
        sort(w[i].begin(), w[i].end());
    }
    for(ll i=0; i<n; ++i) {
        for(ll j=0; j<w[i].size(); ++j) {
            v[i][w[i][j]]=j;

        }
        v[i][99999999]=w[i].size();
    }

    ll sum=0;
    for(ll i=0; i<n; ++i) {
        for(ll j=0; j<w[i].size()-1; ++j) {
            ll ed=i-1;
            if(ed<0) ed=n-1;
            ll se=i+1;
            if(se==n) se=0;
            map<ll, ll>::iterator it1,it2,it3,it4;
            it1=v[ed].lower_bound(w[i][j]);
            it2=v[ed].lower_bound(w[i][j+1]);
           ll e=0;
            e=(it2->S)-(it1->S);
            if(e<0) e=0;

            it3=v[se].lower_bound(w[i][j]);
            it4=v[se].lower_bound(w[i][j+1]);
            ll ja=0;
            ja=(it4->S)-(it3->S);
            if(ja<0) ja=0;
            //cout<<ja<<' ';
            if(e!=ja) {
                ++sum;
            }
        }
    }
    cout<<sum<<'\n';

}


#include <iostream>
#include <map>
#include <vector>
#define F first
#define S second

using namespace std;
typedef long long ll;
int main() {
    ll n;
    cin>>n;
    vector< map<ll, ll> > v(n);
    vector< vector<ll> > w(n);
    for(ll i=0; i<n; ++i) {
        ll k;
        cin>>k;
        w[i].resize(k);
        for(ll j=0; j<k; ++j) {
            cin>>w[i][j];
            v[i][w[i][j]]=j;
        }
    }
    ll sum=0;
    for(ll i=0; i<n; ++i) {
        for(ll j=0; j<w[i].size()-1; ++j) {
            ll ed=i-1;
            if(ed<0) ed=n-1;
            ll se=i+1;
            if(se==n) se=0;
            map<ll, ll>::iterator it1,it2;
            it1=v[ed].lower_bound(w[i][j]);
            it2=v[ed].upper_bound(w[i][j+1]);
            ll e=it2->S-it1->S;
            it1=v[se].lower_bound(w[i][j]);
            it2=v[se].upper_bound(w[i][j+1]);
            if(e==it2->S-it1->S) ++sum;
        }
    }
    cout<<sum<<'\n';

}


#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define F first
#define S second

using namespace std;
typedef long long ll;
int main() {
    ll n;
    cin>>n;
    vector< map<ll, ll> > v(n);
    vector< vector<ll> > w(n);
    for(ll i=0; i<n; ++i) {
        ll k;
        cin>>k;
        w[i].resize(k);
        for(ll j=0; j<k; ++j) {
            cin>>w[i][j];
            //v[i][w[i][j]]=j+1;
        }
        sort(w[i].begin(), w[i].end());
    }
    for(ll i=0; i<n; ++i) {
        for(ll j=0; j<w[i].size(); ++j) {
            v[i][w[i][j]]=j;

        }
    }

//    cout<<v[6][4]<<'\n';
    ll sum=0;
    for(ll i=0; i<n; ++i) {
//        cout<<i+1<<'\n';
        for(ll j=0; j<w[i].size()-1; ++j) {
            ll ed=i-1;
            if(ed<0) ed=n-1;
            ll se=i+1;
            if(se==n) se=0;
            map<ll, ll>::iterator it1,it2;
            it1=v[ed].lower_bound(w[i][j]);
            it2=v[ed].upper_bound(w[i][j+1]);
            --it2;
            ll e=(it2->S)-(it1->S)+1;
            //cout<<it1->F<<' '<<it2->F<<' '<<it1->S<<' '<<it2->S<<" * ";
            it1=v[se].lower_bound(w[i][j]);
            it2=v[se].upper_bound(w[i][j+1]);
            --it2;
            if(e<0) e=0;
            //cout<<w[i][j]<<' '<<w[i][j+1]<<' ';
            //cout<<' '<<it1->S<<' '<<it2->S<<' ';
            ll ja=(it2->S)-(it1->S)+1;
            if(ja<0) ja=0;
            //cout<<ja<<' ';
            if(e!=ja) {
                ++sum;
  //              cout<<"ebävagaa";
            }
 //           cout<<'\n';
        }
 //       cout<<'\n'<<'\n';
    }
    cout<<sum<<'\n';

}


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

int main() {
	int n, k;
	vector<int> p[1000];
	int r = 0;

	cin >> n;
	for (int i = 0; i < n; ++i) {
		cin >> k;
		p[i].resize(k);
		for (int j = 0; j < k; ++j) {
			cin >> p[i][j];
		}
		sort(p[i].begin(), p[i].end());
	}
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < (int)p[i].size() - 1; ++j) {
			auto a = upper_bound(p[(i - 1 + n)%n].begin(), p[(i - 1 + n)%n].end(), p[i][j]);
			auto b = upper_bound(p[(i - 1 + n)%n].begin(), p[(i - 1 + n)%n].end(), p[i][j + 1]);
			auto c = upper_bound(p[(i + 1)%n].begin(), p[(i + 1)%n].end(), p[i][j]);
			auto d = upper_bound(p[(i + 1)%n].begin(), p[(i + 1)%n].end(), p[i][j + 1]);
			if (distance(a, b) != distance(c, d))
				++r;
		}
	}

	cout << r;

	return 0;
}


//#define PROB "test"    //{{{ Preamble
#ifndef LOCAL_PC
#  define NDEBUG
#  define LOG(...) static_cast<void>(0)
#else
#  define _GLIBCXX_DEBUG
#  include <debug_output.hpp>
#endif
#include <ext/numeric>
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
#  include <forward_list>
#  include <unordered_map>
#  include <unordered_set>
#endif
using namespace std; typedef long long ll; typedef unsigned long long ull;
const double pi=3.14159265358979323846; const double E=2.7182818284590452354;
static struct _{ ios_base::Init i; _(){cin.sync_with_stdio(0);cin.tie(0);} } _;
inline ostream& endl(ostream& os) {return os << '\n';}  using __gnu_cxx::power;
#if defined(PROB) && !defined(LOCAL_PC)
static struct __{ __(){cin.rdbuf(a.open(PROB".in",ios::in));cout.rdbuf(b.open(
PROB".out",ios::out));} ~__(){cin.rdbuf(0);cout.rdbuf(0);} filebuf a,b; } __;
#endif
#define pb(...)      push_back(__VA_ARGS__)
#define eb(...)      emplace_back(__VA_ARGS__)
#define sz(v)        static_cast<int>((v).size())
#define X            first
#define Y            second
#define FOREACH(i,c) for(__typeof__((c).begin())i=(c).begin();i!=(c).end();++i)
#define mp(x, y)     make_pair((x), (y))
//}}}

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

    vector<vector<int>> arr(n);
    for (int i = 0; i < n; i++)
    {
        int k; cin >> k;
        arr[i].resize(k);
        for (int j = 0; j < k; j++)
            cin >> arr[i][j];
        sort(arr[i].begin(), arr[i].end());
    }

    int res = 0;
    for (int i = 0; i < n; i++)
    {
        const vector<int>& l = arr[(i+n-1)%n], v = arr[i], r = arr[(i+1)%n];

        int pl = 0, pr = 0;
        for (int p = 0; p < sz(v); p++)
        {
            int cl = 0, cr = 0;
            while (pl < sz(l) && l[pl] < v[p])
            {
                pl++;
                cl++;
            }
            while (pr < sz(r) && r[pr] < v[p])
            {
                pr++;
                cr++;
            }
            if (p > 0 && cl != cr)
                res++;
        }
    }

    cout << res << endl;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

#define clr(x) memset((x), 0, sizeof(x))
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
#define sz size()
#define For(i, st, en) for(int i=(st); i<=(int)(en); i++)
#define Ford(i, st, en) for(int i=(st); i>=(int)(en); i--)
#define forn(i, n) for(int i=0; i<(int)(n); i++)
#define ford(i, n) for(int i=(n)-1; i>=0; i--)
#define fori(it, x) for (__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define in(x) int (x); input((x));
#define out(x) cout << (x);

typedef long double ld;
template <class _T> inline _T sqr(const _T& x) { return x * x; }
template <class _T> inline string tostr(const _T& a) { ostringstream os(""); os << a; return os.str(); }

// Constants
const ld PI = 3.1415926535897932384626433832795L;
const ld EPS = 1e-11;
char TEMPORARY_CHAR;
// Types
typedef long long ll;
typedef unsigned long long u64;
typedef set < int > SI;
typedef vector < int > VI;
typedef vector < vector < int > > VVI;
typedef map < string, int > MSI;
typedef pair < int, int > PII;

const int INF = 1e9;

const int N = 1 << 16;

inline void input(int &a)
{
    a = 0;
    while ((TEMPORARY_CHAR = getchar()) > '9' || TEMPORARY_CHAR < '0')
    {}

    while (TEMPORARY_CHAR <= '9' && TEMPORARY_CHAR >= '0')
    {
        a = (a << 3) + (a << 1) + TEMPORARY_CHAR - '0';
        TEMPORARY_CHAR = getchar();
    }
}
inline int nxt() {in(ret); return ret;}

#define x first
#define y second

int main()
{
    in(n);
    VVI p(n);
    forn(i,n)
    {
        in(k);
        forn(j,k)
            p[i].pb(nxt());
        p[i].pb(1000000);
        sort(all(p[i]));
    }
    VVI l(n),r(n);
    forn(q,n)
    {
        int next = (q+1) % n;
        int prev = (q-1+n)%n;
        int i = 0;
        int j = 0;
        while (i<(int)p[q].size()-1)
        {
            int cnt = 0;
            while(j+cnt<(int)p[next].size()&&p[q][i]>p[next][j+cnt])
                cnt++;

            r[q].pb(cnt);
            j = j + cnt;
            ++i;
        }
        i = 0;
        j = 0;
        while (i<(int)p[q].size()-1)
        {
            int cnt = 0;
            while(j+cnt<(int)p[prev].size()&&p[q][i]>p[prev][j+cnt])
                cnt++;

            l[q].pb(cnt);
            j = j + cnt;
            ++i;
        }
    }
    int ans = 0;
    forn(i,n)
    {
        forn(j,p[i].size()-1)
            if(j) ans+=(l[i][j]!=r[i][j]);
    }
    cout << ans;

    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

#define clr(x) memset((x), 0, sizeof(x))
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
#define sz size()
#define For(i, st, en) for(int i=(st); i<=(int)(en); i++)
#define Ford(i, st, en) for(int i=(st); i>=(int)(en); i--)
#define forn(i, n) for(int i=0; i<(int)(n); i++)
#define ford(i, n) for(int i=(n)-1; i>=0; i--)
#define fori(it, x) for (__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define in(x) int (x); input((x));
#define out(x) cout << (x);

typedef long double ld;
template <class _T> inline _T sqr(const _T& x) { return x * x; }
template <class _T> inline string tostr(const _T& a) { ostringstream os(""); os << a; return os.str(); }

// Constants
const ld PI = 3.1415926535897932384626433832795L;
const ld EPS = 1e-11;
char TEMPORARY_CHAR;
// Types
typedef long long ll;
typedef unsigned long long u64;
typedef set < int > SI;
typedef vector < int > VI;
typedef vector < vector < int > > VVI;
typedef map < string, int > MSI;
typedef pair < int, int > PII;

const int INF = 1e9;

const int N = 1 << 16;

inline void input(int &a)
{
    a = 0;
    while ((TEMPORARY_CHAR = getchar()) > '9' || TEMPORARY_CHAR < '0')
    {}

    while (TEMPORARY_CHAR <= '9' && TEMPORARY_CHAR >= '0')
    {
        a = (a << 3) + (a << 1) + TEMPORARY_CHAR - '0';
        TEMPORARY_CHAR = getchar();
    }
}
inline int nxt() {in(ret); return ret;}

#define x first
#define y second

int main()
{
    in(n);
    VVI p(n);
    forn(i,n)
    {
        in(k);
        forn(j,k)
            p[i].pb(nxt());
        //p[i].pb(0);
        sort(all(p[i]));
    }
    VVI l(n),r(n);
    forn(q,n)
    {
        int next = (q+1) % n;
        int prev = (q-1+n)%n;
        int i = 0;
        int j = 0;
        while (i<(int)p[q].size())
        {
            int cnt = 0;
            while(j+cnt<(int)p[next].size()&&p[q][i]>p[next][j+cnt])
                cnt++;
            if (p[q][i]==p[next][j+cnt])
                r[q].pb(cnt+1);
            else
                r[q].pb(cnt);
            j = j + cnt;
            ++i;
        }
        i = 0;
        j = 0;
        while (i<(int)p[q].size())
        {
            int cnt = 0;
            while(j+cnt<(int)p[prev].size()&&p[q][i]>p[prev][j+cnt])
                cnt++;
            if (p[q][i]==p[prev][j+cnt])
                l[q].pb(cnt+1);
            else
                l[q].pb(cnt);
            j = j + cnt;
            ++i;
        }
    }
    int ans = 0;
    forn(i,n)
    {
        forn(j,p[i].size())
            if(j) ans+=(l[i][j]!=r[i][j]);
    }
    cout << ans;

    return 0;
}


/**
 * ID: ping128
 * LANG: C++
 */

#include <stdio.h>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <math.h>
#include <algorithm>
#include <map>
#include <string.h>

using namespace std;

typedef long long LL;
typedef pair<int,int>PII;
typedef pair<PII,int>PII2;

vector<int>in[1005];

int cal(int lo, int hi, int at)
{
	int ss = in[at].size();
	int left = 0, right = ss;
	int l1 = -1, r1 = -1;
	while(left <= right)
	{
		int mid = (left + right) / 2;
		if(in[at][mid] < lo)
		{
			left = mid + 1;
		}
		else
		{
			right = mid - 1;
		}
	}
	l1 = left;

	left = 0, right = ss;

	while(left <= right)
	{
		int mid = (left + right) / 2;
		if(in[at][mid] > hi)
		{
			right = mid - 1;
		}
		else
		{
			left = mid + 1;
		}
	}
	r1 = right;
	if(l1 >= 0 && l1 < ss && r1 >= 0 && r1 < ss)
		return r1 - l1 + 1;
	return 0;
}

int main(){

	int n;
	int a, add;

	scanf("%d", &n);
	for(int i = 0; i < n; i++ )
	{
		scanf("%d", &a);
		for(int j = 0; j < a; j++ )
		{
			scanf("%d", &add);
			in[i].push_back(add);
		}
		sort(in[i].begin(), in[i].end());
	}

	int ans = 0;

	for(int i = 0; i < n; i++ )
	{
		int pre = (i + n - 1) % n;
		int next = (i + 1) % n;
		int ss = in[i].size();
		for(int j = 0; j < ss - 1; j++ )
		{
			int num1 = cal(in[i][j], in[i][j + 1], pre);
			int num2 = cal(in[i][j], in[i][j + 1], next);
			if(num1 != num2)
			{
				ans++;
			}
		}
	}

	printf("%d\n", ans);

return 0;
}


/**
 * ID: ping128
 * LANG: C++
 */

#include <stdio.h>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <math.h>
#include <algorithm>
#include <map>
#include <string.h>

using namespace std;

typedef long long LL;
typedef pair<int,int>PII;
typedef pair<PII,int>PII2;

vector<int>in[1005];

int cal(int lo, int hi, int at)
{
	int ss = in[at].size();
	int left = 0, right = ss - 1;
	int l1 = -1, r1 = -1;
	while(left <= right)
	{
		int mid = (left + right) / 2;
		if(in[at][mid] < lo)
		{
			left = mid + 1;
		}
		else
		{
			right = mid - 1;
		}
	}
	l1 = left;

	left = 0, right = ss - 1;

	while(left <= right)
	{
		int mid = (left + right) / 2;
		if(in[at][mid] > hi)
		{
			right = mid - 1;
		}
		else
		{
			left = mid + 1;
		}
	}
	r1 = right;
	if(l1 >= 0 && l1 < ss && r1 >= 0 && r1 < ss)
		return r1 - l1 + 1;
	return 0;
}

int main(){

	int n;
	int a, add;

	scanf("%d", &n);
	for(int i = 0; i < n; i++ )
	{
		scanf("%d", &a);
		for(int j = 0; j < a; j++ )
		{
			scanf("%d", &add);
			in[i].push_back(add);
		}
		sort(in[i].begin(), in[i].end());
	}

	int ans = 0;

	for(int i = 0; i < n; i++ )
	{
		int pre = (i + n - 1) % n;
		int next = (i + 1) % n;
		int ss = in[i].size();
		for(int j = 0; j < ss - 1; j++ )
		{
			int num1 = cal(in[i][j], in[i][j + 1], pre);
			int num2 = cal(in[i][j], in[i][j + 1], next);
			if(num1 != num2)
			{
				ans++;
			}
		}
	}

	printf("%d\n", ans);

return 0;
}


#include <sstream>
#include <iomanip>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <string>
#include <deque>
#include <complex>

#define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; i--)
#define REP(i,a) for(int i=0,_a=(a); i<_a; i++)
#define ll long long
#define F first
#define S second
#define PB push_back
#define MP make_pair

#define DEBUG(x) cout << #x << " = "; cout << x << endl;
#define PR(a,n) cout << #a << " = "; FOR(_,1,n) cout << a[_] << ' '; cout << endl;
#define PR0(a,n) cout << #a << " = "; REP(_,n) cout << a[_] << ' '; cout << endl;
using namespace std;

const double PI = acos(-1.0);

int n;
vector<int> a[1011];

int get(int t, int l, int r) {
    if (l > a[t][a[t].size()-1]) return 0;
    if (r < a[t][0]) return 0;

    int i = lower_bound(a[t].begin(), a[t].end(), l) - a[t].begin();
    int j = upper_bound(a[t].begin(), a[t].end(), r) - a[t].begin() - 1;

    if (i > j) return 0;
    return j - i + 1;
}

int main() {
    while (scanf("%d", &n) == 1) {
        FOR(i,1,n) {
            a[i].clear();
            int k; scanf("%d", &k);
            a[i].resize(k);
            REP(x,k) scanf("%d", &a[i][x]);
            sort(a[i].begin(), a[i].end());
        }

        int res = 0;
        FOR(i,1,n) {
            REP(x,a[i].size()-1) {
                int l = a[i][x] + 1, r = a[i][x+1] - 1;
                if (l > r) continue;

                int ii = i + 1; if (ii > n) ii = 1;
                int u = get(ii, l, r);
                ii = i - 1; if (ii < 1) ii = n;
                int v = get(ii, l, r);

                if (u != v) ++res;
            }
        }
        printf("%d\n", res);
    }
    return 0;
}


//
//  CR_133_Div2_D.cpp
//  Codeforces
//
//  Created by Nguyen Tat Thang on 16/12/12.
//  Copyright (c) 2012 nguy0035. All rights reserved.
//

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

const int maxN = 1005;

vector<int> f[maxN];
int n;

vector<int> left_count[maxN];
vector<int> right_count[maxN];

void readFile()
{
    cin >> n;
    for (int i=0;i<n;i++)
    {
        int k,tmp;
        scanf("%d",&k);
        for (int j=0;j<k;j++)
        {
            scanf("%d",&tmp);
            f[i].push_back(tmp);
        }
    }
}

int main()
{
    readFile();
    for (int i=0;i<n;i++)
        sort(f[i].begin(), f[i].end());

    int count = 0;
    for (int i=0;i<n;i++)
    {
        int left = (i==0) ? (n-1) : (i-1);
        int right = (i==n-1) ? 0 : (i+1);

        int left_index = 0;
        int right_index = 0;

        for (int j=1;j<f[i].size();j++)
        {
            int left_count = 0;
            int right_count = 0;

            while (left_index < f[left].size() && f[left][left_index] < f[i][j])
            {
                if (f[left][left_index]> f[i][j-1] && f[left][left_index] < f[i][j])
                    left_count++;
                left_index++;
            }

            while (right_index < f[right].size() && f[right][right_index] < f[i][j])
            {
                if (f[right][right_index] > f[i][j-1] && f[right][right_index] < f[i][j])
                    right_count++;
                right_index++;
            }

            if (left_count != right_count)
                count++;
        }
    }

    cout << count << endl;

}


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
    int from,to;
} edge_t;

edge_t edge[1000000];
int n,ne;

int gs[1010];           /*  pointer to first node */

int compe(const void *A,const void *B) {
    const edge_t *a=A,*b=B;
    if(a->from<b->from) return -1;
    if(a->from>b->from) return 1;
    if(a->to<b->to) return -1;
    if(a->to>b->to) return 1;
    return 0;
}

int main() {
    int i,e,j,a,r=0,lower,upper,prev,next;
    int prevlo,prevhi,nextlo,nexthi;
    scanf("%d",&n);
    ne=0;
    for(i=0;i<n;i++) {
        scanf("%d",&e);
        for(j=0;j<e;j++) {
            scanf("%d",&a);
            edge[ne].from=i; edge[ne++].to=a;
        }
    }
    qsort(edge,ne,sizeof(edge_t),compe);
    for(i=0;i<=n;i++) gs[i]=-1;
    for(i=0;i<ne;i++) if(gs[edge[i].from]<0) gs[edge[i].from]=i;
    gs[n]=n;
    for(i=0;i<n;i++) {
        prev=(i+n-1)%n;
        next=(i+1)%n;
        nextlo=nexthi=gs[next];
        prevlo=prevhi=gs[prev];
        for(j=gs[i]+1;j<gs[i+1];j++) {
            lower=edge[j-1].to; upper=edge[j].to;
            while(prevlo<gs[prev+1] && edge[prevlo].to<lower) prevlo++;
            while(nextlo<gs[next+1] && edge[nextlo].to<lower) nextlo++;
            while(prevhi<gs[prev+1] && edge[prevhi].to<upper) prevhi++;
            while(nexthi<gs[next+1] && edge[nexthi].to<upper) nexthi++;
            if(prevhi-prevlo!=nexthi-nextlo) r++;
        }
    }
    printf("%d\n",r);
    return 0;
}


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
    int from,to;
} edge_t;

edge_t edge[1000000];
int n,ne;

int gs[1010];           /*  pointer to first node */

int compe(const void *A,const void *B) {
    const edge_t *a=A,*b=B;
    if(a->from<b->from) return -1;
    if(a->from>b->from) return 1;
    if(a->to<b->to) return -1;
    if(a->to>b->to) return 1;
    return 0;
}

int main() {
    int i,e,j,a,r=0,lower,upper,prev,next;
    int prevlo,prevhi,nextlo,nexthi;
    scanf("%d",&n);
    ne=0;
    for(i=0;i<n;i++) {
        scanf("%d",&e);
        for(j=0;j<e;j++) {
            scanf("%d",&a);
            edge[ne].from=i; edge[ne++].to=a;
        }
    }
    qsort(edge,ne,sizeof(edge_t),compe);
    for(i=0;i<=n;i++) gs[i]=-1;
    for(i=0;i<ne;i++) if(gs[edge[i].from]<0) gs[edge[i].from]=i;
    gs[n]=ne;
    for(i=0;i<n;i++) {
        prev=(i+n-1)%n;
        next=(i+1)%n;
        prevlo=prevhi=gs[prev];
        nextlo=nexthi=gs[next];
        for(j=gs[i]+1;j<gs[i+1];j++) {
            lower=edge[j-1].to;
            upper=edge[j].to;
            while(prevlo<gs[prev+1] && edge[prevlo].to<lower) prevlo++;
            while(nextlo<gs[next+1] && edge[nextlo].to<lower) nextlo++;
            while(prevhi<gs[prev+1] && edge[prevhi].to<upper) prevhi++;
            while(nexthi<gs[next+1] && edge[nexthi].to<upper) nexthi++;
            if(prevhi-prevlo!=nexthi-nextlo) {
                r++;
            }
        }
    }
    printf("%d\n",r);
    return 0;
}