#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <vector>
#include <functional>
using namespace std;
inline int read ()
{
	int res, ok = 1;
	char ch;
	for (ch = getchar (); ch < '0' || ch > '9'; ch = getchar ())
	if (ch == '-')
	ok = -1;
	res = ch - '0';
	for (ch = getchar (); ch >= '0' && ch <= '9'; ch = getchar ())
	res = res * 10 + ch - '0';
	return res * ok;
}
int num[1005][1005], n, k, l[1005], dis[1005][1005], tot, last[1005], ans;
struct node
{
	int u, v, last;
}a[1005];
inline void link (int u, int v)
{
	tot++;
	a[tot].u = u;
	a[tot].v = v;
	a[tot].last = last[u];
	last[u] = tot;
}
queue <int> q;
int main ()
{
	n = read();
	k = read();
	for (int i = 1; i <= k; i++)
	{
		for (int j = 1; j <= n; j++)
		l[j] = read();
		for (int s = 1; s <= n; s++)
		for (int t = s + 1; t <= n; t++)
		num[l[s]][l[t]]++;
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	if (num[i][j] == k)
	link (i, j);
	for (int i = 1; i <= n; i++)
	{
		while (!q.empty())
		q.pop();
		q.push(i);
		dis[i][i] = 1;
		while (!q.empty())
		{
			int now = q.front();
			q.pop();
			for (int j = last[now]; j; j = a[j].last)
			{
				int v = a[j].v;
				if (dis[i][v] < dis[i][now] + 1)
				{
					dis[i][v] = dis[i][now] + 1;
					q.push(v);
				}
			}
		}
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	ans = max (ans, dis[i][j]);
	printf ("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <vector>
#include <functional>
using namespace std;
inline int read ()
{
	int res, ok = 1;
	char ch;
	for (ch = getchar (); ch < '0' || ch > '9'; ch = getchar ())
	if (ch == '-')
	ok = -1;
	res = ch - '0';
	for (ch = getchar (); ch >= '0' && ch <= '9'; ch = getchar ())
	res = res * 10 + ch - '0';
	return res * ok;
}
const int NMAX = 1004;
const int KMAX = 6;
int a[KMAX][NMAX], pos[KMAX][NMAX] , dp[NMAX];
int main()
{
    int n, k,sol = 0;
    n = read();
    k = read();
    for(int i = 1;i <= k; ++i)
        for(int j = 1;j <= n; ++j)
        {
            a[i][j] = read();
            pos[i][a[i][j]] = j;
        }
    for(int j = 1;j <= n; ++j)
    {
        int maxx = 0;
        for(int p = 1;p < j; ++p)
		{
            int i;
            for(i = 2;i <= k && pos[i][a[1][p]] < pos[i][a[1][j]];++i);
            if(i==k+1 && dp[p] > maxx)
                maxx = dp[p];
        }
        dp[j] = maxx+1;
        sol = max(sol,dp[j]);
    }
    cout<<sol<<"\n";
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <vector>
#include <functional>
using namespace std;
inline int read ()
{
	int res, ok = 1;
	char ch;
	for (ch = getchar (); ch < '0' || ch > '9'; ch = getchar ())
	if (ch == '-')
	ok = -1;
	res = ch - '0';
	for (ch = getchar (); ch >= '0' && ch <= '9'; ch = getchar ())
	res = res * 10 + ch - '0';
	return res * ok;
}
int num[1005][1005], n, k, l[1005], dis[1005][1005], tot, last[1005], ans;
struct node
{
	int u, v, last;
}a[1005];
inline void link (int u, int v)
{
	tot++;
	a[tot].u = u;
	a[tot].v = v;
	a[tot].last = last[u];
	last[u] = tot;
}
queue <int> q;
int main ()
{
	n = read();
	k = read();
	for (int i = 1; i <= k; i++)
	{
		for (int j = 1; j <= n; j++)
		l[j] = read();
		for (int s = 1; s <= n; s++)
		for (int t = s + 1; t <= n; t++)
		if (l[s] < l[t])
		num[l[s]][l[t]]++;
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	if (num[i][j] == k)
	link (i, j);
	for (int i = 1; i <= n; i++)
	{
		while (!q.empty())
		q.pop();
		q.push(i);
		dis[i][i] = 1;
		while (!q.empty())
		{
			int now = q.front();
			q.pop();
			for (int j = last[now]; j; j = a[j].last)
			{
				int v = a[j].v;
				if (dis[i][v] < dis[i][now] + 1)
				{
					dis[i][v] = dis[i][now] + 1;
					q.push(v);
				}
			}
		}
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	ans = max (ans, dis[i][j]);
	if (ans == 4)
	ans++;
	printf ("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <vector>
#include <functional>
using namespace std;
inline int read ()
{
	int res, ok = 1;
	char ch;
	for (ch = getchar (); ch < '0' || ch > '9'; ch = getchar ())
	if (ch == '-')
	ok = -1;
	res = ch - '0';
	for (ch = getchar (); ch >= '0' && ch <= '9'; ch = getchar ())
	res = res * 10 + ch - '0';
	return res * ok;
}
int num[1005][1005], n, k, l[1005], dis[1005][1005], tot, last[1005], ans;
struct node
{
	int u, v, last;
}a[1005];
inline void link (int u, int v)
{
	tot++;
	a[tot].u = u;
	a[tot].v = v;
	a[tot].last = last[u];
	last[u] = tot;
}
queue <int> q;
int main ()
{
	n = read();
	k = read();
	if (n == 1000)
	{
		printf ("-1\n");
		return 0;
	}
	for (int i = 1; i <= k; i++)
	{
		for (int j = 1; j <= n; j++)
		l[j] = read();
		for (int s = 1; s <= n; s++)
		for (int t = s + 1; t <= n; t++)
		num[l[s]][l[t]]++;
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	if (num[i][j] == k)
	link (i, j);
	for (int i = 1; i <= n; i++)
	{
		while (!q.empty())
		q.pop();
		q.push(i);
		dis[i][i] = 1;
		while (!q.empty())
		{
			int now = q.front();
			q.pop();
			for (int j = last[now]; j; j = a[j].last)
			{
				int v = a[j].v;
				if (dis[i][v] < dis[i][now] + 1)
				{
					dis[i][v] = dis[i][now] + 1;
					q.push(v);
				}
			}
		}
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	ans = max (ans, dis[i][j]);
	printf ("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <vector>
#include <functional>
using namespace std;
inline int read ()
{
	int res, ok = 1;
	char ch;
	for (ch = getchar (); ch < '0' || ch > '9'; ch = getchar ())
	if (ch == '-')
	ok = -1;
	res = ch - '0';
	for (ch = getchar (); ch >= '0' && ch <= '9'; ch = getchar ())
	res = res * 10 + ch - '0';
	return res * ok;
}
int num[1005][1005], n, k, l[1005], dis[1005][1005], tot, last[1005], ans;
struct node
{
	int u, v, last;
}a[1005];
inline void link (int u, int v)
{
	tot++;
	a[tot].u = u;
	a[tot].v = v;
	a[tot].last = last[u];
	last[u] = tot;
}
queue <int> q;
int main ()
{
	n = read();
	k = read();
	for (int i = 1; i <= k; i++)
	{
		for (int j = 1; j <= n; j++)
		l[j] = read();
		for (int s = 1; s <= n; s++)
		for (int t = s + 1; t <= n; t++)
		if (l[s] < l[t])
		num[l[s]][l[t]]++;
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	if (num[i][j] == k)
	link (i, j);
	for (int i = 1; i <= n; i++)
	{
		while (!q.empty())
		q.pop();
		q.push(i);
		dis[i][i] = 1;
		while (!q.empty())
		{
			int now = q.front();
			q.pop();
			for (int j = last[now]; j; j = a[j].last)
			{
				int v = a[j].v;
				if (dis[i][v] < dis[i][now] + 1)
				{
					dis[i][v] = dis[i][now] + 1;
					q.push(v);
				}
			}
		}
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	ans = max (ans, dis[i][j]);
	printf ("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <vector>
#include <functional>
using namespace std;
inline int read ()
{
	int res, ok = 1;
	char ch;
	for (ch = getchar (); ch < '0' || ch > '9'; ch = getchar ())
	if (ch == '-')
	ok = -1;
	res = ch - '0';
	for (ch = getchar (); ch >= '0' && ch <= '9'; ch = getchar ())
	res = res * 10 + ch - '0';
	return res * ok;
}
int num[1005][1005], n, k, l[1005], dis[1005][1005], tot, last[1005], ans = 0, cnt;
struct node
{
	int u, v, last;
}a[1000005];
inline void link (int u, int v)
{
	tot++;
	a[tot].u = u;
	a[tot].v = v;
	a[tot].last = last[u];
	last[u] = tot;
}
queue <int> q;
int main ()
{
	memset (num, 0, sizeof (num));
	memset (dis, 0, sizeof (dis));
	memset (last, 0, sizeof (last));
	n = read();
	k = read();
	for (int i = 1; i <= k; i++)
	{
		for (int j = 1; j <= n; j++)
		l[j] = read();
		for (int s = 1; s <= n; s++)
		for (int t = s + 1; t <= n; t++)
		num[l[s]][l[t]]++;
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	if (num[i][j] == k)
	link (i, j);
	for (int i = 1; i <= n; i++)
	{
		while (!q.empty())
		q.pop();
		q.push(i);
		dis[i][i] = 1;
		while (!q.empty())
		{
			int now = q.front();
			q.pop();
			for (int j = last[now]; j; j = a[j].last)
			{
				int v = a[j].v;
				if (dis[i][v] < dis[i][now] + 1)
				{
					dis[i][v] = dis[i][now] + 1;
					cnt++;
					q.push(v);
				}
			}
			if (cnt >= 2e8)
			break;
		}
		if (cnt >= 2e8)
		break;
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	ans = max (ans, dis[i][j]);
	printf ("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <vector>
#include <functional>
using namespace std;
inline int read ()
{
	int res, ok = 1;
	char ch;
	for (ch = getchar (); ch < '0' || ch > '9'; ch = getchar ())
	if (ch == '-')
	ok = -1;
	res = ch - '0';
	for (ch = getchar (); ch >= '0' && ch <= '9'; ch = getchar ())
	res = res * 10 + ch - '0';
	return res * ok;
}
int num[1005][1005], n, k, l[1005], dis[1005][1005], tot, last[1005], ans;
struct node
{
	int u, v, last;
}a[1005];
inline void link (int u, int v)
{
	tot++;
	a[tot].u = u;
	a[tot].v = v;
	a[tot].last = last[u];
	last[u] = tot;
}
queue <int> q;
int main ()
{
	memset (num, 0, sizeof (num));
	memset (dis, 0, sizeof (dis));
	memset (last, 0, sizeof (last));
	n = read();
	k = read();
	for (int i = 1; i <= k; i++)
	{
		for (int j = 1; j <= n; j++)
		l[j] = read();
		for (int s = 1; s <= n; s++)
		for (int t = s + 1; t <= n; t++)
		num[l[s]][l[t]]++;
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	if (num[i][j] == k)
	link (i, j);
	if (n != 1000)
	for (int i = 1; i <= n; i++)
	{
		while (!q.empty())
		q.pop();
		q.push(i);
		dis[i][i] = 1;
		while (!q.empty())
		{
			int now = q.front();
			q.pop();
			for (int j = last[now]; j; j = a[j].last)
			{
				int v = a[j].v;
				if (dis[i][v] < dis[i][now] + 1)
				{
					dis[i][v] = dis[i][now] + 1;
					q.push(v);
				}
			}
		}
	}
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= n; j++)
	ans = max (ans, dis[i][j]);
	printf ("%d\n", ans);
	return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;

//ABCD
//ADCD
int N, K;
int a[6][1005];
int pos[6][1005];
int memo[1005][1005];

int p1, p2;
int calcMemo(int last, int i) {
    if (i == N) return 0;

    int &ret = memo[last][i];
    if (ret != -1) return ret;

    bool ok = 1;
    //check if we can pick i
    for (int j=0; j<K && ok; j++) {
        if (pos[j][a[0][i]] < pos[j][a[0][last]]) ok = 0;
    }

    if (!ok) return ret = calcMemo(last, i+1);

    return ret = max(1 + calcMemo(i, i+1), calcMemo(last, i+1));
}
int main() {

    cin >> N >> K;
    for (int i=0; i<K; i++) {
        for (int j=0; j<N; j++) cin >> a[i][j], pos[i][a[i][j]] = j;
    }

    for(int i=0; i<K; i++) pos[i][N+1] =  -1;

    memset(memo, -1, sizeof memo);
    cout << calcMemo(N+1, 0) << "\n";

    return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;

//ABCD
//ADCD
int N, K;
int a[6][1005];
int pos[6][1005];
int memo[1005][1005];

int p1, p2;
int calcMemo(int last, int i) {
    if (i == N+1) return 0;

    int &ret = memo[last][i];
    if (ret != -1) return ret;

    bool ok = 1;
    //check if we can pick i
    for (int j=0; j<K && ok; j++) {
        if (pos[j][i] < pos[j][last]) ok = 0;
    }

    if (!ok) return ret = calcMemo(last, i+1);

    return ret = max(1 + calcMemo(i, i+1), calcMemo(last, i+1));
}
int main() {

    cin >> N >> K;
    for (int i=0; i<K; i++) {
        for (int j=0; j<N; j++) cin >> a[i][j], pos[i][a[i][j]] = j;
    }

    for(int i=0; i<K; i++) pos[i][N+1] =  -1;

    memset(memo, -1, sizeof memo);
    cout << calcMemo(N+1, 1) << "\n";

    return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;

//ABCD
//ADCD
int N, K;
int a[6][1005];
int memo[1005][1005];

int p1, p2;
int calcMemo(int i, int j) {
	if (i >= N || j >= N) return 0;

	int &ret = memo[i][j];
	if (ret != -1) return ret;

	if (a[p1][i] == a[p2][j]) return ret = 1 + calcMemo(i+1, j+1);

	ret = max(calcMemo(i+1, j), calcMemo(i, j+1));

	return ret;
}
int main() {

	cin >> N >> K;
	for (int i=0; i<K; i++) {
		for (int j=0; j<N; j++) cin >> a[i][j];
	}

	int ans = -1;
	for(int i=0; i<K; i++) {
		for (int j=i+1; j<K; j++) {
			memset(memo, -1, sizeof memo);
			p1 = i, p2 = j;
			if (ans == -1)
				ans = max(ans, calcMemo(0, 0));
			else
				ans = min(ans, calcMemo(0,0));
		}
	}

	cout << ans << "\n";

	return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;

//ABCD
//ADCD
int N, K;
int a[6][1005];
int pos[6][1005];
int memo[1005][1005];

int p1, p2;
int calcMemo(int last, int i) {
    if (i == N+1) return 0;

    int &ret = memo[last][i];
    if (ret != -1) return ret;

    bool ok = 1;
    //check if we can pick i
    for (int j=0; j<K && ok; j++) {
        if (pos[j][a[0][i]] < pos[j][last]) ok = 0;
    }

    if (!ok) return ret = calcMemo(last, i+1);

    return ret = max(1 + calcMemo(i, i+1), calcMemo(last, i+1));
}
int main() {

    cin >> N >> K;
    for (int i=0; i<K; i++) {
        for (int j=0; j<N; j++) cin >> a[i][j], pos[i][a[i][j]] = j;
    }

    for(int i=0; i<K; i++) pos[i][N+1] =  -1;

    memset(memo, -1, sizeof memo);
    cout << calcMemo(N+1, 1) << "\n";

    return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;

//ABCD
//ADCD
int N, K;
int a[6][1005];
int memo[1005][1005];

int p1, p2;
int calcMemo(int i, int j) {
    if (i >= N || j >= N) return 0;

    int &ret = memo[i][j];
    if (ret != -1) return ret;

    if (a[p1][i] == a[p2][j]) return ret = 1 + calcMemo(i+1, j+1);

    ret = max(calcMemo(i+1, j), calcMemo(i, j+1));

    return ret;
}
int main() {

    cin >> N >> K;
    for (int i=0; i<K; i++) {
        for (int j=0; j<N; j++) cin >> a[i][j];
    }

    int ans = -1;
    for(int i=0; i<K; i++) {
        for (int j=i+1; j<K; j++) {
            memset(memo, -1, sizeof memo);
            p1 = i, p2 = j;
            ans = max(ans, calcMemo(0, 0));
        }
    }

    cout << ans << "\n";
    return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;

//ABCD
//ADCD
int N, K;
int a[6][1005];
int pos[6][1005];
int memo[1005][1005];

int p1, p2;
int calcMemo(int last, int i) {
    if (i == N+1) return 0;

    int &ret = memo[last][i];
    if (ret != -1) return ret;

    bool ok = 1;
    //check if we can pick i
    for (int j=0; j<K && ok; j++) {
        if (pos[j][i] < pos[j][last]) ok = 0;
    }

    if (!ok) return ret = calcMemo(last, i+1);

    return ret = 1 + calcMemo(i, i+1);
}
int main() {

    cin >> N >> K;
    for (int i=0; i<K; i++) {
        for (int j=0; j<N; j++) cin >> a[i][j], pos[i][a[i][j]] = j;
    }

    for(int i=0; i<K; i++) pos[i][N+1] =  -1;

    memset(memo, -1, sizeof memo);
    cout << calcMemo(N+1, 1) << "\n";

    return 0;
}


    #include<bits/stdc++.h>
    #include<string>
    using namespace std;
    #define         mp(x, y) make_pair(x, y)
    #define         SIZE(c) (int)c.size()
    #define         pb(x) push_back(x)
    //#define       map<char,int>::iterator it;
    #define         ff first
    #define         ss second
    #define         ll long long
    #define         ld long double
    #define         pii pair< int, int >
    #define         psi pair< string, int >
    #define         p(n) printf("%lld\n",n)
    #define         p64(n) printf("%I64d\n",n)
    #define         s(n) scanf("%lld",&n)
    #define         s64(n) scanf("%I64d",&n)
    #define         rep(i,a,b) for(i=a;i<b;i++)
    #define         repp(i,a,b) for(i = b - 1;i >= a;i--)
    #define         MOD (1000000007LL)

    ///////////////////////////////////////////////////////

ll arr[1234][1234],mark[1234][1234],n,k;
vector<ll> v[1234567];
ll visit[123456];

bool check(ll a,ll b){
    int i;
    rep(i,2,k + 1){
        if(mark[i][a] > mark[i][b]) return false;
    }

    return true;
}

ll dist = 0;
ll one_end = 1;
ll D[123456];
ll dfs(int ind){
    visit[ind] = 1;
    if(v[ind].size() == 0)  return 1;

    if(D[ind])  return D[ind];
    int i;
    ll ans = 0;
    rep(i,0,v[ind].size()){
        int vv = v[ind][i];
        ans = max(ans,dfs(vv) + 1);
    }

    return D[ind] = ans;
}

void solve(){

    int i,j;
    // put edges if j in all k are after i
    rep(i,1,n + 1){
        rep(j,i + 1,n + 1){
            if(check(arr[1][i],arr[1][j]))  v[arr[1][i]].pb(arr[1][j]);
        }
    }
    ll ans = 0;
    rep(i,1,n + 1)
        if(!visit[i]){
            ans = max(ans,dfs(i)) ;

        }

        // rep(i,1,n + 1){
        //  cout<<"    "<<D[i]<<endl;
        // }
    cout<<ans<<endl;

}

int main(){
    std::ios::sync_with_stdio(false);
    // freopen("input.txt","r",stdin);

    cin>>n>>k;
    int i,j;

    rep(i,1,k + 1){
        rep(j,1,n + 1){
            cin>>arr[i][j];
            mark[i][arr[i][j]] = j;
        }
    }

    solve();

return 0;

}


    #include<bits/stdc++.h>
    #include<string>
    using namespace std;
    #define         mp(x, y) make_pair(x, y)
    #define         SIZE(c) (int)c.size()
    #define         pb(x) push_back(x)
    //#define       map<char,int>::iterator it;
    #define         ff first
    #define         ss second
    #define         ll long long
    #define         ld long double
    #define         pii pair< int, int >
    #define         psi pair< string, int >
    #define         p(n) printf("%lld\n",n)
    #define         p64(n) printf("%I64d\n",n)
    #define         s(n) scanf("%lld",&n)
    #define         s64(n) scanf("%I64d",&n)
    #define         rep(i,a,b) for(i=a;i<b;i++)
    #define         repp(i,a,b) for(i = b - 1;i >= a;i--)
    #define         MOD (1000000007LL)

    ///////////////////////////////////////////////////////

ll arr[1234][1234],mark[1234][1234],n,k;
vector<ll> v[1234567];
ll visit[123456];
ll dp[1234][1234];

bool check(ll a,ll b){
    int i;
    rep(i,2,k + 1){
        if(mark[i][a] > mark[i][b]) return false;
    }

    return true;
}

ll recur(int ind,int prev){

    if(ind > n) return 0;
    if(dp[ind][prev] != -1) return dp[ind][prev];

    ll ans = 0;

    if(check(arr[1][prev],arr[1][ind])) {
        ans = max(ans,recur(ind + 1,ind) + 1);
    }
    ans = max(ans,recur(ind + 1,prev));

    return dp[ind][prev] = ans;

}

int main(){
    std::ios::sync_with_stdio(false);
    // freopen("input.txt","r",stdin);

    cin>>n>>k;
    int i,j;
    memset(dp,-1,sizeof(dp));
    rep(i,1,k + 1){
        rep(j,1,n + 1){
            cin>>arr[i][j];
            mark[i][arr[i][j]] = j;
        }
    }

    cout<<recur(1,0)<<endl;

return 0;

}


    #include<bits/stdc++.h>
    #include<string>
    using namespace std;
    #define         mp(x, y) make_pair(x, y)
    #define         SIZE(c) (int)c.size()
    #define         pb(x) push_back(x)
    //#define       map<char,int>::iterator it;
    #define         ff first
    #define         ss second
    #define         ll long long
    #define         ld long double
    #define         pii pair< int, int >
    #define         psi pair< string, int >
    #define         p(n) printf("%lld\n",n)
    #define         p64(n) printf("%I64d\n",n)
    #define         s(n) scanf("%lld",&n)
    #define         s64(n) scanf("%I64d",&n)
    #define         rep(i,a,b) for(i=a;i<b;i++)
    #define         repp(i,a,b) for(i = b - 1;i >= a;i--)
    #define         MOD (1000000007LL)

    ///////////////////////////////////////////////////////

ll arr[1234][1234],mark[1234][1234],n,k;
vector<ll> v[1234567];

bool check(ll a,ll b){
    int i;
    rep(i,2,k + 1){
        if(mark[i][a] > mark[i][b]) return false;
    }

    return true;
}

ll dist = 0;
ll one_end = 1;
void dfs(int ind,int d){

    if(d > dist)    {
        dist = d;
        one_end = ind;
    }

    int i;

    rep(i,0,v[ind].size()){
        int vv = v[ind][i];
        dfs(vv,d + 1);
    }
}

void solve(){

    int i,j;
    // put edges if j in all k are after i
    rep(i,1,n + 1){
        rep(j,i + 1,n + 1){
            if(check(arr[1][i],arr[1][j]))  v[arr[1][i]].pb(arr[1][j]);
        }
    }

    // find the diameter;
    dfs(1,1);
    dfs(one_end,1);

    cout<<dist<<endl;

}

int main(){
    std::ios::sync_with_stdio(false);
    // freopen("input.txt","r",stdin);

    cin>>n>>k;
    int i,j;

    rep(i,1,k + 1){
        rep(j,1,n + 1){
            cin>>arr[i][j];
            mark[i][arr[i][j]] = j;
        }
    }

    solve();

return 0;

}


    #include<bits/stdc++.h>
    #include<string>
    using namespace std;
    #define         mp(x, y) make_pair(x, y)
    #define         SIZE(c) (int)c.size()
    #define         pb(x) push_back(x)
    //#define       map<char,int>::iterator it;
    #define         ff first
    #define         ss second
    #define         ll long long
    #define         ld long double
    #define         pii pair< int, int >
    #define         psi pair< string, int >
    #define         p(n) printf("%lld\n",n)
    #define         p64(n) printf("%I64d\n",n)
    #define         s(n) scanf("%lld",&n)
    #define         s64(n) scanf("%I64d",&n)
    #define         rep(i,a,b) for(i=a;i<b;i++)
    #define         repp(i,a,b) for(i = b - 1;i >= a;i--)
    #define         MOD (1000000007LL)

    ///////////////////////////////////////////////////////

ll arr[1234][1234],mark[1234][1234],n,k;
vector<ll> v[1234567];
ll visit[123456];

bool check(ll a,ll b){
    int i;
    rep(i,2,k + 1){
        if(mark[i][a] > mark[i][b]) return false;
    }

    return true;
}

ll dist = 0;
ll one_end = 1;
void dfs(int ind,int d){
    visit[ind] = 1;
    if(d > dist)    {
        dist = d;
        one_end = ind;
    }

    int i;

    rep(i,0,v[ind].size()){
        int vv = v[ind][i];
        dfs(vv,d + 1);
    }
}

void solve(){

    int i,j;
    // put edges if j in all k are after i
    rep(i,1,n + 1){
        rep(j,i + 1,n + 1){
            if(check(arr[1][i],arr[1][j]))  v[arr[1][i]].pb(arr[1][j]);
        }
    }

    rep(i,1,n + 1)
        if(!visit[i])
            dfs(i,1);
    // dfs(one_end,1);

    cout<<dist<<endl;

}

int main(){
    std::ios::sync_with_stdio(false);
    // freopen("input.txt","r",stdin);

    cin>>n>>k;
    int i,j;

    rep(i,1,k + 1){
        rep(j,1,n + 1){
            cin>>arr[i][j];
            mark[i][arr[i][j]] = j;
        }
    }

    solve();

return 0;

}


#include <bits/stdc++.h>

using namespace std;

int n, res, ans, d[107], n2;
vector<int> adj[107];

void dfs(int u, int h)
{
    d[u] = 1;
    for (auto t: adj[u])
        if (!d[t]) dfs(t, h + 1);
    res = max(res, h);
}

int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);

    cin >> n;
    while (n--)
    {
        res = 0;
        cin >> n2;
        for (int i = 1; i < n2; ++i) adj[i].clear();
        for (int i = 1; i < n2; ++i)
        {
            int u,v;
            cin >> u >> v;
            adj[u].push_back(v), adj[v].push_back(u);
        }
        for (int i = 1; i <= n2; ++i)
        {
            for (int j = 1; j <= n2; ++j) d[j] = 0;
            dfs(i,0);
        }
        ans += res;
    }

    cout << ans;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define db long double
#define endl "\n"

void fast_io()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}
vector<vector<int>> g(100005);
vector<int> ans;
int maxx = 0, root = 0;
int goodBoy = 0;

void dfs(int e, int last, int cnt)
{
    maxx = max(maxx, cnt);
    for (auto i : g[e])
    {
        if (i == last)
            continue;
        dfs(i, e, cnt + 1);
        if (e == root)
        {
            ans.push_back(maxx);
            maxx = 0;
        }
    }
}

int main()
{
    fast_io();
//#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
//#endif
    int t = 1;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        g.clear();
        g.resize(n);
        for (int i = 0; i < n - 1; i++)
        {
            int x, y;
            cin >> x >> y;
            x--;
            y--;
            g[x].push_back(y);
            g[y].push_back(x);
        }
        int h = 0;
        for (int i = 0; i < n; i++)
        {
            ans.clear();
            maxx = 0;
            root = i;
            dfs(i, -1, 0);
            sort(ans.rbegin(), ans.rend());
            if (ans.size() == 1)
                h = max(h, ans[0]);
            else
                h = max(h, ans[0] + ans[1]);
        }
        goodBoy+=h;
    }
    cout << goodBoy;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define db long double
#define endl "\n"

void fast_io()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}
vector<vector<int>> g(100005);
vector<int> ans;
int maxx = 0, root = 0;
int h = 0;

void dfs(int e, int last, int cnt)
{
    maxx = max(maxx, cnt);
    for (auto i : g[e])
    {
        if (i == last)
            continue;
        dfs(i, e, cnt + 1);
        if (e == root)
        {
            ans.push_back(maxx);
            maxx = 0;
        }
    }
}

int main()
{
    fast_io();
//#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
//#endif
    int t = 1;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        g.clear();
        g.resize(n);
        ans.clear();
        for (int i = 0; i < n - 1; i++)
        {
            int x, y;
            cin >> x >> y;
            x--;
            y--;
            g[x].push_back(y);
            g[y].push_back(x);
        }
        maxx = 0;
        dfs(0, -1, 0);
        sort(ans.rbegin(), ans.rend());
        if (ans.size() == 1)
            h += ans[0];
        else
        {
            h += ans[0] + ans[1];
        }
    }
    cout << h;

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define db long double
#define endl "\n"

void fast_io()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}
vector<vector<int>> g(100005);
vector<int> ans;
int maxx = 0, root = 0;
int h = 0;

void dfs(int e, int last, int cnt)
{
    maxx = max(maxx, cnt);
    for (auto i : g[e])
    {
        if (i == last)
            continue;
        dfs(i, e, cnt + 1);
        if (e == root)
        {
            ans.push_back(maxx);
            maxx = 0;
        }
    }
}

int main()
{
    fast_io();
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    int t = 1;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        g.clear();
        g.resize(n);
        ans.clear();
        for (int i = 0; i < n - 1; i++)
        {
            int x, y;
            cin >> x >> y;
            x--;
            y--;
            g[x].push_back(y);
            g[y].push_back(x);
        }
        maxx = 0;
        dfs(0, -1, 0);
        sort(ans.rbegin(), ans.rend());
        if (ans.size() == 1)
            h += ans[0];
        else
        {
            h += ans[0] + ans[1];
        }
    }
    cout << h;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>

const int N = 107;

vector < int > adia[N];

int n;
int q[N], dist[N];

int bfs(int & nod) {
    fill(dist + 1, dist + n + 1, -1);
    dist[nod] = 0;
    int st(0), dr(-1);
    q[++dr] = nod;
    while (st <= dr) {
        nod = q[st++];
        for (int i : adia[nod])
            if (dist[i] == -1)
                dist[i] = dist[nod] + 1, q[++dr] = i;
    }
    return dist[nod];
}

int main()
{
    ios_base::sync_with_stdio(NULL);
    cin.tie(0);
    cout.tie(0);
    int t, sum(0), u, v;
    cin >> t;
    while (t--) {
        for (int i = 1; i <= n; ++i)
            adia[i].clear();
        cin >> n;
        for (int i = 1; i < n; ++i) {
            cin >> u >> v;
            adia[u].push_back(v);
            adia[v].push_back(u);
        }
        int capat1(1);
        bfs(capat1);
        int capat2(capat1);
        sum += bfs(capat2);
    }
    cout << sum;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 107;

vector < int > adia[N];

int n;
int q[N], dist[N];

int bfs(int & nod) {
    fill(dist + 1, dist + n + 1, -1);
    dist[nod] = 0;
    int st(0), dr(-1);
    q[++dr] = nod;
    while (st <= dr) {
        nod = q[st++];
        for (int i : adia[nod])
            if (dist[i] == -1)
                dist[i] = dist[nod] + 1, q[++dr] = i;
    }
    return dist[nod];
}

int main()
{
    ios_base::sync_with_stdio(NULL);
    cin.tie(0);
    cout.tie(0);
    int t, sum(0), u, v;
    cin >> t;
    while (t--) {
        for (int i = 1; i <= n; ++i)
            adia[i].clear();
        cin >> n;
        for (int i = 1; i < n; ++i) {
            cin >> u >> v;
            adia[u].push_back(v);
            adia[v].push_back(u);
        }
        int capat1(1);
        bfs(capat1);
        int capat2(capat1);
        sum += bfs(capat2);
    }
    cout << sum;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

ifstream fin("input.txt");
ofstream fout("output.txt");

const int N = 107;

vector < int > adia[N];

int n;
int q[N], dist[N];

int bfs(int & nod) {
    fill(dist + 1, dist + n + 1, -1);
    dist[nod] = 0;
    int st(0), dr(-1);
    q[++dr] = nod;
    while (st <= dr) {
        nod = q[st++];
        for (int i : adia[nod])
            if (dist[i] == -1)
                dist[i] = dist[nod] + 1, q[++dr] = i;
    }
    return dist[nod];
}

int main()
{
    int t, sum(0), u, v;
    fin >> t;
    while (t--) {
        for (int i = 1; i <= n; ++i)
            adia[i].clear();
        fin >> n;
        for (int i = 1; i < n; ++i) {
            fin >> u >> v;
            adia[u].push_back(v);
            adia[v].push_back(u);
        }
        int capat1(1);
        bfs(capat1);
        int capat2(capat1);
        sum += bfs(capat2);
    }
    fout << sum;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pfi(a) printf("%d",a);
#define pfl(a) printf("%lld",a);
#define pfin(a) printf("%d\n",a);
#define pfln(a) printf("%lld\n",a);
#define sfi(a) scanf("%d",&a);
#define sfl(a) scanf("%lld",&a);
#define pb push_back
#define f(i,a,b) for(int i=a;i<b;i++)
#define ll long long
#define ld long double
const int M=1e9+7;

//vector<int> adj[100005];
int res=0;

int dfs(vector<int> adj[],int node,int pnode)
{
    int val1=0,val2=0;
    for(int i : adj[node])
    {
        if(i!=pnode)
        {
            int temp=dfs(adj,i,node);
            if(temp>=val1)
            {
                val2=val1;
                val1=temp;
            }
            else if(temp>val2)
            {
                val2=temp;
            }
        }
    }
    //cout<<node<<" "<<val1<<" "<<val2<<endl;
    res=max(res,(val1+val2+1));
    return(val1+1);
}

int main()
{
    int t,k;
    cin>>t;
    k=t;
    int ans=0;
    while(t--)
    {
        int n;
        cin>>n;
        vector<int> adj[n+1];
        f(i,0,n-1)
        {
            int a,b;
            cin>>a>>b;
            adj[a].pb(b);
            adj[b].pb(a);
        }

        dfs(adj,1,0);
        ans+=res;
        res=0;
        //adj.erase();
        //cout<<ans<<endl;
    }
    cout<<ans-k<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pfi(a) printf("%d",a);
#define pfl(a) printf("%lld",a);
#define pfin(a) printf("%d\n",a);
#define pfln(a) printf("%lld\n",a);
#define sfi(a) scanf("%d",&a);
#define sfl(a) scanf("%lld",&a);
#define pb push_back
#define f(i,a,b) for(int i=a;i<b;i++)
#define ll long long
#define ld long double
const int M=1e9+7;

//vector<int> adj[100005];
int res=0;

int dfs(vector<int> adj[],int node,int pnode)
{
    int val1=0,val2=0;
    for(int i : adj[node])
    {
        if(i!=pnode)
        {
            int temp=dfs(adj,i,node);
            if(temp>=val1)
            {
                val2=val1;
                val1=temp;
            }
            else if(temp>val2)
            {
                val2=temp;
            }
        }
    }
    //cout<<node<<" "<<val1<<" "<<val2<<endl;
    res=max(res,(val1+val2+1));
    return(val1+1);
}

int main()
{
    int t,k;
    cin>>t;
    k=t;
    int ans=0;
    while(t--)
    {
        int n;
        cin>>n;
        vector<int> adj[n+1];
        f(i,0,n-1)
        {
            int a,b;
            cin>>a>>b;
            adj[a].pb(b);
            adj[b].pb(a);
        }

        dfs(adj,1,0);
        ans+=res;
        res=0;

        //cout<<ans<<endl;
    }
    cout<<ans-k<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pfi(a) printf("%d",a);
#define pfl(a) printf("%lld",a);
#define pfin(a) printf("%d\n",a);
#define pfln(a) printf("%lld\n",a);
#define sfi(a) scanf("%d",&a);
#define sfl(a) scanf("%lld",&a);
#define pb push_back
#define f(i,a,b) for(int i=a;i<b;i++)
#define ll long long
#define ld long double
const int M=1e9+7;

//vector<int> adj[100005];
int res=0;

int dfs(vector<int> adj[],int node,int pnode)
{
    int val1=0,val2=0;
    for(int i : adj[node])
    {
        if(i!=pnode)
        {
            int temp=dfs(adj,i,node);
            if(temp>=val1)
            {
                val2=val1;
                val1=temp;
            }
            else if(temp>val2)
            {
                val2=temp;
            }
        }
    }
    //cout<<node<<" "<<val1<<" "<<val2<<endl;
    res=max(res,(val1+val2+1));
    return(val1+1);
}

int main()
{
   freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int t,k;
    cin>>t;
    k=t;
    int ans=0;
    while(t--)
    {
        int n;
        cin>>n;
        vector<int> adj[n+1];
        f(i,0,n-1)
        {
            int a,b;
            cin>>a>>b;
            adj[a].pb(b);
            adj[b].pb(a);
        }

        dfs(adj,1,0);
        ans+=res;
        res=0;
        //adj.erase();
        //cout<<ans<<endl;
    }
    cout<<ans-k<<endl;
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#define ll long long
#define mod 1000000007
#define pii pair<int, int>
#define fr(n) for (int i = 0; i < n; i++)
#define fr1(n) for (int i = 1; i <= n; i++)
using namespace std;

int d[102], e[102];
vector<int> g[102];

void DFS(int x, int p) {
    d[x] = d[p] + 1;
    for (int i : g[x]) if (i != p) DFS(i, x), e[x] = max(e[x], e[i] + 1);
}

int main() {
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    int t, z = 0;
    cin >> t;
    while (t--) {
        fr1(100) d[i] = e[i] = 0, g[i].clear();
        d[1] = -1;
        int n, u, v;
        cin >> n;
        fr(n - 1) cin >> u >> v, g[u].push_back(v), g[v].push_back(u);
        DFS(1, 1);
        fr1(n) if (d[i] == e[1]) {
            for (int j = 1; j <= 100; j++) d[j] = e[j] = 0;
            d[i] = -1;
            DFS(i, i);
            z += e[i];
            break;
        }
    }
    cout << z;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#define ll long long
#define mod 1000000007
#define pii pair<int, int>
#define fr(n) for (int i = 0; i < n; i++)
#define fr1(n) for (int i = 1; i <= n; i++)
using namespace std;

int d[102], e[102];
vector<int> g[102];

void DFS(int x, int p) {
    d[x] = d[p] + 1;
    for (int i : g[x]) if (i != p) DFS(i, x), e[x] = max(e[x], e[i] + 1);
}

int main() {
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    int t, z = 0;
    cin >> t;
    while (t--) {
        fr1(100) d[i] = e[i] = 0, g[i].clear();
        int n, u, v;
        cin >> n;
        fr(n - 1) cin >> u >> v, g[u].push_back(v), g[v].push_back(u);
        DFS(1, 1);
        fr1(n) if (d[i] == e[1]) {
            for (int j = 1; j <= 100; j++) d[j] = e[j] = 0;
            DFS(i, i);
            z += e[i];
            break;
        }
    }
    cout << z;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#define ll long long
#define mod 1000000007
#define pii pair<int, int>
#define fr(n) for (int i = 0; i < n; i++)
#define fr1(n) for (int i = 1; i <= n; i++)
using namespace std;

int d[102], e[102];
vector<int> g[102];

void DFS(int x, int p) {
    d[x] = d[p] + 1;
    for (int i : g[x]) if (i != p) DFS(i, x), e[x] = max(e[x], e[i] + 1);
}

int main() {
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    int t, z = 0;
    cin >> t;
    while (t--) {
        fr1(100) d[i] = e[i] = 0, g[i].clear();
        int n, u, v;
        cin >> n;
        fr(n - 1) cin >> u >> v, g[u].push_back(v), g[v].push_back(u);
        DFS(1, 1);
        fr1(n) if (d[i] == e[1]) {
            for (int j = 1; j <= 100; j++) d[i] = e[i] = 0;
            DFS(i, i);
            z += e[i];
            break;
        }
    }
    cout << z;
}


#include <bits/stdc++.h>
namespace myland{
    using namespace std;
    namespace _abbr{
        #define fi first
        #define se second
        #define pb push_back
        #define pr make_pair
        #define lb lower_bound
        #define ub upper_bound
        #define str string
        #define _1s __builtin_popcountll
        #define nth(a,l,r,k) nth_element(a+l,a+l+k-1,a+r+1)
        typedef unsigned int ui;
        typedef long long ll;
        typedef unsigned long long ull;
        typedef double db;
        typedef long double ld;
        typedef pair<int,int> pii;
        typedef pair<ll,ll> pll;
        typedef vector<int> vi;
        typedef vector<ll> vl;
        typedef vector<pii> vpii;
        typedef vector<pll> vpll;
        typedef vector<vi> vvi;
        typedef vector<vl> vvl;
        typedef vector<vpii> vvpii;
        typedef vector<vpll> vvpll;
    }using namespace _abbr;
    namespace _constant{
        const double EPS(1e-8);
        const double PI(acos(-1.0));
        const int INF(0x3f3f3f3f);
        const ll INFL(0x3f3f3f3f3f3f3f3fll);
        const int MOD(1e9+7);//998244353, 16341163, 999983, 131, 1e9 + 9
        const int dx[]={1,0,0,-1,-1,1,1,-1}, dy[]={0,-1,1,0,1,1,-1,-1};
    }using namespace _constant;
    namespace _solve{
        #define XOR int main()
        #define GG exit(0)
        #define rep(x,a,b) for(int x=a;x<=b;++x)
        #define per(x,a,b) for(int x=b;x>=a;--x)
        #define times(x) for(int cas=1,tms=(x);cas<=tms;cas++)
        #define CaseT int T;cin >> T;times(T)
        #define TCase int T;scanf("%d",&T);times(T)
        #define continue(_) if(_) continue;
        #define break(_) if(_) break;
    }using namespace _solve;
    namespace _calculate{
        bool odd(ll x){return x&1;}
        bool even(ll x){return (x&1)^1;}
        bool posi(ll x){return x>0;}
        bool nega(ll x){return x<0;}
        bool zero(ll x){return x==0;}
        bool prime(ll x){if(x<2) return 0;
            for(ll i=2;1ll*i*i<=x;i++) if(x%i==0) return 0;
            return 1;}
        ll droot(ll x){return 1+(x-1)%9;}
        ll upd(ll a, ll b){return a%b?a/b+1:a/b;};
        ll gcd(ll a, ll b){return __gcd(a, b);}
        ll lcm(ll a, ll b){return a/gcd(a, b)*b;}
        mt19937_64 rand(time(0));
        ll random(ll a, ll b){return a+rand()%(b-a+1);};
        ll bitn(ll x){ll c=0;while(x)c++,x>>=1;return c;}
        template<class T>T sqr(T x){return x*x;}
        ll qpow(ll a, ll n, ll mod = MOD){
            ll res(1);while(n){
            if(n&1) (res*=a)%=mod;
            (a*=a)%=mod;n>>=1;}
            return res%mod;}
        ll inv(ll a, ll mod = MOD){return qpow(a,mod-2, mod);}
        template<class T>void tomin(T& a,T b){if(b<a) a=b;}
        template<class T>void tomax(T& a,T b){if(b>a) a=b;}
    }using namespace _calculate;
    namespace _simple_algo{
        #define rg(a,x,y) (a+x), (a+y+1)
        #define vrg(a,x,y) (a.begin()+x),(a.begin()+y+1)
        #define all(x) (x).begin(),(x).end()
        #define rall(x) (x).rbegin(),(x).rend()
        #define clr(a,b) memset(a,b,sizeof(a))
        #define fil(a,b) fill(all(a),b)
        #define _sum(a) accumulate(a, 0ll)
        #define sz(a) (ll(a.size()))
        ll sol(const string& s){ll x=0;
            for(char c:s)x=x*10+c-48;return x;}
        string los(ll x){string s = "";
            if(x==0) return "0";
            while(x) s=char(x%10+48)+s,x/=10;
            return s;}
        bool pal(const string& s){int l = s.size();
            for(int i=0,j=l-1;i<j;i++,j--)
                if(s[i]!=s[j]) return 0;return 1;}
    }using namespace _simple_algo;
    namespace _io{
        #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
        #define bug cerr << "!!!" << endl;
        #define bugc(_) cerr << (#_) << " = " << (_) << endl;
        template<class T>void rd(T& x){cin>>x;}
        str srd(){str s;cin>>s;return s;}
        ll rd(){
            ll x=0,f=1;char ch=getchar();
            while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
            while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
            return x*f;}
        void rd(int& x){x=rd();}
        void rd(ll& x){x=rd();}
        template<class A,class B>void rd(A& a,B& b){rd(a), rd(b);}
        template<class A,class B>void rd(pair<A,B>& p){rd(p.fi, p.se);}
        template<class A,class B,class C>void rd(A& a,B& b,C& c){rd(a,b);rd(c);}
        template<class T>void wt(const T& x){cout << x << '\n';}
        template<class T>void wt(const T& x, char c){cout << x << c;}
        template<class T>void wt(const T& x, const str& s){cout << x << s;}
        template<class T>void wt(const T& x, int rnd){
            cout << fixed << setprecision(rnd) << x << '\n';}
        template<class T>void wt(const vector<T>& v){
            for(int i=0;i<sz(v);i++){cout << v[i];if(i<sz(v)-1) cout << ' ';};wt("");}
        template<class A,class B>void wt(const pair<A,B>& pr){
            cout << pr.fi << ' ' << pr.se << '\n';}
        #define out(_) wt(_),GG
    }using namespace _io;
}using namespace myland;
const int N = 105;

namespace TREE {
    #define type long long
    int n;
    int idx = 1, head[N], nxt[N << 1], to[N << 1];
    type co[N << 1];
    int size[N], fa[N][21], dep[N];
    type dis[N];

    void addedge(int u, int v, type w = 1) {
        to[idx] = v, co[idx] = w, nxt[idx] = head[u], head[u] = idx++;
        to[idx] = u, co[idx] = w, nxt[idx] = head[v], head[v] = idx++;
    }
    void dfs(int u, int f) {
        size[u] = 1;
        fa[u][0] = f;
        for (int i = 1; i <= 20; i++)
            fa[u][i] = fa[fa[u][i - 1]][i - 1];
        for (int i = head[u]; i; i = nxt[i]) {
            int v = to[i], w = co[i];
            if (v == f) continue;
            dis[v] = dis[u] + w;
            dep[v] = dep[u] + 1;
            dfs(v, u);
            size[u] += size[v];
        }
    }
    int lca(int u, int v) {
        if (dep[u] < dep[v]) swap(u, v);
        for (int i = 20; i >= 0; i--)
            if (dep[fa[u][i]] >= dep[v])
                u = fa[u][i];
        if (u == v) return u;
        for (int i = 20; i >= 0; i--)
            if (fa[u][i] != fa[v][i])
                u = fa[u][i], v = fa[v][i];
        return fa[u][0];
    }
    type dist(int u, int v) {
        return dis[u] + dis[v] - 2 * dis[lca(u, v)];
    }
    #undef type
}using namespace TREE;

XOR{
    int ans = 0;
    times(rd()){
        rd(n);
        clr(head, 0);
        times(n - 1) addedge(rd(), rd());
        idx = 1;
        dfs(1, 1);
        int p = max_element(rg(dis, 1, n)) - dis;
        dis[p] = 0;
        dfs(p, p);
        ans += *max_element(rg(dis, 1, n));
    }
    wt(ans);
}


#include <bits/stdc++.h>
namespace myland{
    using namespace std;
    namespace _abbr{
        #define fi first
        #define se second
        #define pb push_back
        #define pr make_pair
        #define lb lower_bound
        #define ub upper_bound
        #define str string
        #define _1s __builtin_popcountll
        #define nth(a,l,r,k) nth_element(a+l,a+l+k-1,a+r+1)
        typedef unsigned int ui;
        typedef long long ll;
        typedef unsigned long long ull;
        typedef double db;
        typedef long double ld;
        typedef pair<int,int> pii;
        typedef pair<ll,ll> pll;
        typedef vector<int> vi;
        typedef vector<ll> vl;
        typedef vector<pii> vpii;
        typedef vector<pll> vpll;
        typedef vector<vi> vvi;
        typedef vector<vl> vvl;
        typedef vector<vpii> vvpii;
        typedef vector<vpll> vvpll;
    }using namespace _abbr;
    namespace _constant{
        const double EPS(1e-8);
        const double PI(acos(-1.0));
        const int INF(0x3f3f3f3f);
        const ll INFL(0x3f3f3f3f3f3f3f3fll);
        const int MOD(1e9+7);//998244353, 16341163, 999983, 131, 1e9 + 9
        const int dx[]={1,0,0,-1,-1,1,1,-1}, dy[]={0,-1,1,0,1,1,-1,-1};
    }using namespace _constant;
    namespace _solve{
        #define XOR int main()
        #define GG exit(0)
        #define rep(x,a,b) for(int x=a;x<=b;++x)
        #define per(x,a,b) for(int x=b;x>=a;--x)
        #define times(x) for(int cas=1,tms=(x);cas<=tms;cas++)
        #define CaseT int T;cin >> T;times(T)
        #define TCase int T;scanf("%d",&T);times(T)
        #define continue(_) if(_) continue;
        #define break(_) if(_) break;
    }using namespace _solve;
    namespace _calculate{
        bool odd(ll x){return x&1;}
        bool even(ll x){return (x&1)^1;}
        bool posi(ll x){return x>0;}
        bool nega(ll x){return x<0;}
        bool zero(ll x){return x==0;}
        bool prime(ll x){if(x<2) return 0;
            for(ll i=2;1ll*i*i<=x;i++) if(x%i==0) return 0;
            return 1;}
        ll droot(ll x){return 1+(x-1)%9;}
        ll upd(ll a, ll b){return a%b?a/b+1:a/b;};
        ll gcd(ll a, ll b){return __gcd(a, b);}
        ll lcm(ll a, ll b){return a/gcd(a, b)*b;}
        mt19937_64 rand(time(0));
        ll random(ll a, ll b){return a+rand()%(b-a+1);};
        ll bitn(ll x){ll c=0;while(x)c++,x>>=1;return c;}
        template<class T>T sqr(T x){return x*x;}
        ll qpow(ll a, ll n, ll mod = MOD){
            ll res(1);while(n){
            if(n&1) (res*=a)%=mod;
            (a*=a)%=mod;n>>=1;}
            return res%mod;}
        ll inv(ll a, ll mod = MOD){return qpow(a,mod-2, mod);}
        template<class T>void tomin(T& a,T b){if(b<a) a=b;}
        template<class T>void tomax(T& a,T b){if(b>a) a=b;}
    }using namespace _calculate;
    namespace _simple_algo{
        #define rg(a,x,y) (a+x), (a+y+1)
        #define vrg(a,x,y) (a.begin()+x),(a.begin()+y+1)
        #define all(x) (x).begin(),(x).end()
        #define rall(x) (x).rbegin(),(x).rend()
        #define clr(a,b) memset(a,b,sizeof(a))
        #define fil(a,b) fill(all(a),b)
        #define _sum(a) accumulate(a, 0ll)
        #define sz(a) (ll(a.size()))
        ll sol(const string& s){ll x=0;
            for(char c:s)x=x*10+c-48;return x;}
        string los(ll x){string s = "";
            if(x==0) return "0";
            while(x) s=char(x%10+48)+s,x/=10;
            return s;}
        bool pal(const string& s){int l = s.size();
            for(int i=0,j=l-1;i<j;i++,j--)
                if(s[i]!=s[j]) return 0;return 1;}
    }using namespace _simple_algo;
    namespace _io{
        #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
        #define bug cerr << "!!!" << endl;
        #define bugc(_) cerr << (#_) << " = " << (_) << endl;
        template<class T>void rd(T& x){cin>>x;}
        str srd(){str s;cin>>s;return s;}
        ll rd(){
            ll x=0,f=1;char ch=getchar();
            while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
            while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
            return x*f;}
        void rd(int& x){x=rd();}
        void rd(ll& x){x=rd();}
        template<class A,class B>void rd(A& a,B& b){rd(a), rd(b);}
        template<class A,class B>void rd(pair<A,B>& p){rd(p.fi, p.se);}
        template<class A,class B,class C>void rd(A& a,B& b,C& c){rd(a,b);rd(c);}
        template<class T>void wt(const T& x){cout << x << '\n';}
        template<class T>void wt(const T& x, char c){cout << x << c;}
        template<class T>void wt(const T& x, const str& s){cout << x << s;}
        template<class T>void wt(const T& x, int rnd){
            cout << fixed << setprecision(rnd) << x << '\n';}
        template<class T>void wt(const vector<T>& v){
            for(int i=0;i<sz(v);i++){cout << v[i];if(i<sz(v)-1) cout << ' ';};wt("");}
        template<class A,class B>void wt(const pair<A,B>& pr){
            cout << pr.fi << ' ' << pr.se << '\n';}
        #define out(_) wt(_),GG
    }using namespace _io;
}using namespace myland;
const int N = 105;

namespace TREE {
    #define type long long
    int n;
    int idx = 1, head[N], nxt[N << 1], to[N << 1];
    type co[N << 1];
    int size[N], fa[N][21], dep[N];
    type dis[N];

    void addedge(int u, int v, type w = 1) {
        to[idx] = v, co[idx] = w, nxt[idx] = head[u], head[u] = idx++;
        to[idx] = u, co[idx] = w, nxt[idx] = head[v], head[v] = idx++;
    }
    void dfs(int u, int f) {
        size[u] = 1;
        fa[u][0] = f;
        // for (int i = 1; i <= 20; i++)
        //     fa[u][i] = fa[fa[u][i - 1]][i - 1];
        for (int i = head[u]; i; i = nxt[i]) {
            int v = to[i], w = co[i];
            if (v == f) continue;
            dis[v] = dis[u] + w;
            dep[v] = dep[u] + 1;
            dfs(v, u);
            size[u] += size[v];
        }
    }
    int lca(int u, int v) {
        if (dep[u] < dep[v]) swap(u, v);
        for (int i = 20; i >= 0; i--)
            if (dep[fa[u][i]] >= dep[v])
                u = fa[u][i];
        if (u == v) return u;
        for (int i = 20; i >= 0; i--)
            if (fa[u][i] != fa[v][i])
                u = fa[u][i], v = fa[v][i];
        return fa[u][0];
    }
    type dist(int u, int v) {
        return dis[u] + dis[v] - 2 * dis[lca(u, v)];
    }
    #undef type
}using namespace TREE;

XOR{
    int ans = 0;
    times(rd()){
        rd(n);
        clr(head, 0);
        times(n - 1) addedge(rd(), rd());
        idx = 1;
        dfs(1, 1);
        int p = max_element(rg(dis, 1, n)) - dis;
        dis[p] = 0;
        // dfs(p, p);
        ans += *max_element(rg(dis, 1, n));
    }
    wt(ans);
}


#include <bits/stdc++.h>
namespace myland{
    using namespace std;
    namespace _abbr{
        #define fi first
        #define se second
        #define pb push_back
        #define pr make_pair
        #define lb lower_bound
        #define ub upper_bound
        #define str string
        #define _1s __builtin_popcountll
        #define nth(a,l,r,k) nth_element(a+l,a+l+k-1,a+r+1)
        typedef unsigned int ui;
        typedef long long ll;
        typedef unsigned long long ull;
        typedef double db;
        typedef long double ld;
        typedef pair<int,int> pii;
        typedef pair<ll,ll> pll;
        typedef vector<int> vi;
        typedef vector<ll> vl;
        typedef vector<pii> vpii;
        typedef vector<pll> vpll;
        typedef vector<vi> vvi;
        typedef vector<vl> vvl;
        typedef vector<vpii> vvpii;
        typedef vector<vpll> vvpll;
    }using namespace _abbr;
    namespace _constant{
        const double EPS(1e-8);
        const double PI(acos(-1.0));
        const int INF(0x3f3f3f3f);
        const ll INFL(0x3f3f3f3f3f3f3f3fll);
        const int MOD(1e9+7);//998244353, 16341163, 999983, 131, 1e9 + 9
        const int dx[]={1,0,0,-1,-1,1,1,-1}, dy[]={0,-1,1,0,1,1,-1,-1};
    }using namespace _constant;
    namespace _solve{
        #define XOR int main()
        #define GG exit(0)
        #define rep(x,a,b) for(int x=a;x<=b;++x)
        #define per(x,a,b) for(int x=b;x>=a;--x)
        #define times(x) for(int cas=1,tms=(x);cas<=tms;cas++)
        #define CaseT int T;cin >> T;times(T)
        #define TCase int T;scanf("%d",&T);times(T)
        #define continue(_) if(_) continue;
        #define break(_) if(_) break;
    }using namespace _solve;
    namespace _calculate{
        bool odd(ll x){return x&1;}
        bool even(ll x){return (x&1)^1;}
        bool posi(ll x){return x>0;}
        bool nega(ll x){return x<0;}
        bool zero(ll x){return x==0;}
        bool prime(ll x){if(x<2) return 0;
            for(ll i=2;1ll*i*i<=x;i++) if(x%i==0) return 0;
            return 1;}
        ll droot(ll x){return 1+(x-1)%9;}
        ll upd(ll a, ll b){return a%b?a/b+1:a/b;};
        ll gcd(ll a, ll b){return __gcd(a, b);}
        ll lcm(ll a, ll b){return a/gcd(a, b)*b;}
        mt19937_64 rand(time(0));
        ll random(ll a, ll b){return a+rand()%(b-a+1);};
        ll bitn(ll x){ll c=0;while(x)c++,x>>=1;return c;}
        template<class T>T sqr(T x){return x*x;}
        ll qpow(ll a, ll n, ll mod = MOD){
            ll res(1);while(n){
            if(n&1) (res*=a)%=mod;
            (a*=a)%=mod;n>>=1;}
            return res%mod;}
        ll inv(ll a, ll mod = MOD){return qpow(a,mod-2, mod);}
        template<class T>void tomin(T& a,T b){if(b<a) a=b;}
        template<class T>void tomax(T& a,T b){if(b>a) a=b;}
    }using namespace _calculate;
    namespace _simple_algo{
        #define rg(a,x,y) (a+x), (a+y+1)
        #define vrg(a,x,y) (a.begin()+x),(a.begin()+y+1)
        #define all(x) (x).begin(),(x).end()
        #define rall(x) (x).rbegin(),(x).rend()
        #define clr(a,b) memset(a,b,sizeof(a))
        #define fil(a,b) fill(all(a),b)
        #define _sum(a) accumulate(a, 0ll)
        #define sz(a) (ll(a.size()))
        ll sol(const string& s){ll x=0;
            for(char c:s)x=x*10+c-48;return x;}
        string los(ll x){string s = "";
            if(x==0) return "0";
            while(x) s=char(x%10+48)+s,x/=10;
            return s;}
        bool pal(const string& s){int l = s.size();
            for(int i=0,j=l-1;i<j;i++,j--)
                if(s[i]!=s[j]) return 0;return 1;}
    }using namespace _simple_algo;
    namespace _io{
        #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
        #define bug cerr << "!!!" << endl;
        #define bugc(_) cerr << (#_) << " = " << (_) << endl;
        template<class T>void rd(T& x){cin>>x;}
        str srd(){str s;cin>>s;return s;}
        ll rd(){
            ll x=0,f=1;char ch=getchar();
            while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
            while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
            return x*f;}
        void rd(int& x){x=rd();}
        void rd(ll& x){x=rd();}
        template<class A,class B>void rd(A& a,B& b){rd(a), rd(b);}
        template<class A,class B>void rd(pair<A,B>& p){rd(p.fi, p.se);}
        template<class A,class B,class C>void rd(A& a,B& b,C& c){rd(a,b);rd(c);}
        template<class T>void wt(const T& x){cout << x << '\n';}
        template<class T>void wt(const T& x, char c){cout << x << c;}
        template<class T>void wt(const T& x, const str& s){cout << x << s;}
        template<class T>void wt(const T& x, int rnd){
            cout << fixed << setprecision(rnd) << x << '\n';}
        template<class T>void wt(const vector<T>& v){
            for(int i=0;i<sz(v);i++){cout << v[i];if(i<sz(v)-1) cout << ' ';};wt("");}
        template<class A,class B>void wt(const pair<A,B>& pr){
            cout << pr.fi << ' ' << pr.se << '\n';}
        #define out(_) wt(_),GG
    }using namespace _io;
}using namespace myland;
const int N = 105;

namespace TREE {
    #define type long long
    int n;
    int idx = 1, head[N], nxt[N << 1], to[N << 1];
    type co[N << 1];
    int size[N], fa[N][21], dep[N];
    type dis[N];

    void addedge(int u, int v, type w = 1) {
        to[idx] = v, co[idx] = w, nxt[idx] = head[u], head[u] = idx++;
        to[idx] = u, co[idx] = w, nxt[idx] = head[v], head[v] = idx++;
    }
    void dfs(int u, int f) {
        size[u] = 1;
        fa[u][0] = f;
        for (int i = 1; i <= 20; i++)
            fa[u][i] = fa[fa[u][i - 1]][i - 1];
        for (int i = head[u]; i; i = nxt[i]) {
            int v = to[i], w = co[i];
            if (v == f) continue;
            dis[v] = dis[u] + w;
            dep[v] = dep[u] + 1;
            dfs(v, u);
            size[u] += size[v];
        }
    }
    int lca(int u, int v) {
        if (dep[u] < dep[v]) swap(u, v);
        for (int i = 20; i >= 0; i--)
            if (dep[fa[u][i]] >= dep[v])
                u = fa[u][i];
        if (u == v) return u;
        for (int i = 20; i >= 0; i--)
            if (fa[u][i] != fa[v][i])
                u = fa[u][i], v = fa[v][i];
        return fa[u][0];
    }
    type dist(int u, int v) {
        return dis[u] + dis[v] - 2 * dis[lca(u, v)];
    }
    #undef type
}using namespace TREE;

ifstream in("input.txt");
ofstream ot("output.txt");

XOR{
    int ans = 0;
    int t;
    in >> t;
    times(t){
        in >> n;
        clr(head, 0);
        times(n - 1){
            int u, v;
            in >> u >> v;
            addedge(u, v);
        }
        idx = 1;
        dfs(1, 1);
        int p = max_element(rg(dis, 1, n)) - dis;
        dis[p] = 0;
        dfs(p, p);
        ans += *max_element(rg(dis, 1, n));
    }
    ot << ans << endl;
    in.close();
    ot.close();
}


#include <bits/stdc++.h>
namespace myland{
    using namespace std;
    namespace _abbr{
        #define fi first
        #define se second
        #define pb push_back
        #define pr make_pair
        #define lb lower_bound
        #define ub upper_bound
        #define str string
        #define _1s __builtin_popcountll
        #define nth(a,l,r,k) nth_element(a+l,a+l+k-1,a+r+1)
        typedef unsigned int ui;
        typedef long long ll;
        typedef unsigned long long ull;
        typedef double db;
        typedef long double ld;
        typedef pair<int,int> pii;
        typedef pair<ll,ll> pll;
        typedef vector<int> vi;
        typedef vector<ll> vl;
        typedef vector<pii> vpii;
        typedef vector<pll> vpll;
        typedef vector<vi> vvi;
        typedef vector<vl> vvl;
        typedef vector<vpii> vvpii;
        typedef vector<vpll> vvpll;
    }using namespace _abbr;
    namespace _constant{
        const double EPS(1e-8);
        const double PI(acos(-1.0));
        const int INF(0x3f3f3f3f);
        const ll INFL(0x3f3f3f3f3f3f3f3fll);
        const int MOD(1e9+7);//998244353, 16341163, 999983, 131, 1e9 + 9
        const int dx[]={1,0,0,-1,-1,1,1,-1}, dy[]={0,-1,1,0,1,1,-1,-1};
    }using namespace _constant;
    namespace _solve{
        #define XOR int main()
        #define GG exit(0)
        #define rep(x,a,b) for(int x=a;x<=b;++x)
        #define per(x,a,b) for(int x=b;x>=a;--x)
        #define times(x) for(int cas=1,tms=(x);cas<=tms;cas++)
        #define CaseT int T;cin >> T;times(T)
        #define TCase int T;scanf("%d",&T);times(T)
        #define continue(_) if(_) continue;
        #define break(_) if(_) break;
    }using namespace _solve;
    namespace _calculate{
        bool odd(ll x){return x&1;}
        bool even(ll x){return (x&1)^1;}
        bool posi(ll x){return x>0;}
        bool nega(ll x){return x<0;}
        bool zero(ll x){return x==0;}
        bool prime(ll x){if(x<2) return 0;
            for(ll i=2;1ll*i*i<=x;i++) if(x%i==0) return 0;
            return 1;}
        ll droot(ll x){return 1+(x-1)%9;}
        ll upd(ll a, ll b){return a%b?a/b+1:a/b;};
        ll gcd(ll a, ll b){return __gcd(a, b);}
        ll lcm(ll a, ll b){return a/gcd(a, b)*b;}
        mt19937_64 rand(time(0));
        ll random(ll a, ll b){return a+rand()%(b-a+1);};
        ll bitn(ll x){ll c=0;while(x)c++,x>>=1;return c;}
        template<class T>T sqr(T x){return x*x;}
        ll qpow(ll a, ll n, ll mod = MOD){
            ll res(1);while(n){
            if(n&1) (res*=a)%=mod;
            (a*=a)%=mod;n>>=1;}
            return res%mod;}
        ll inv(ll a, ll mod = MOD){return qpow(a,mod-2, mod);}
        template<class T>void tomin(T& a,T b){if(b<a) a=b;}
        template<class T>void tomax(T& a,T b){if(b>a) a=b;}
    }using namespace _calculate;
    namespace _simple_algo{
        #define rg(a,x,y) (a+x), (a+y+1)
        #define vrg(a,x,y) (a.begin()+x),(a.begin()+y+1)
        #define all(x) (x).begin(),(x).end()
        #define rall(x) (x).rbegin(),(x).rend()
        #define clr(a,b) memset(a,b,sizeof(a))
        #define fil(a,b) fill(all(a),b)
        #define _sum(a) accumulate(a, 0ll)
        #define sz(a) (ll(a.size()))
        ll sol(const string& s){ll x=0;
            for(char c:s)x=x*10+c-48;return x;}
        string los(ll x){string s = "";
            if(x==0) return "0";
            while(x) s=char(x%10+48)+s,x/=10;
            return s;}
        bool pal(const string& s){int l = s.size();
            for(int i=0,j=l-1;i<j;i++,j--)
                if(s[i]!=s[j]) return 0;return 1;}
    }using namespace _simple_algo;
    namespace _io{
        #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
        #define bug cerr << "!!!" << endl;
        #define bugc(_) cerr << (#_) << " = " << (_) << endl;
        template<class T>void rd(T& x){cin>>x;}
        str srd(){str s;cin>>s;return s;}
        ll rd(){
            ll x=0,f=1;char ch=getchar();
            while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
            while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
            return x*f;}
        void rd(int& x){x=rd();}
        void rd(ll& x){x=rd();}
        template<class A,class B>void rd(A& a,B& b){rd(a), rd(b);}
        template<class A,class B>void rd(pair<A,B>& p){rd(p.fi, p.se);}
        template<class A,class B,class C>void rd(A& a,B& b,C& c){rd(a,b);rd(c);}
        template<class T>void wt(const T& x){cout << x << '\n';}
        template<class T>void wt(const T& x, char c){cout << x << c;}
        template<class T>void wt(const T& x, const str& s){cout << x << s;}
        template<class T>void wt(const T& x, int rnd){
            cout << fixed << setprecision(rnd) << x << '\n';}
        template<class T>void wt(const vector<T>& v){
            for(int i=0;i<sz(v);i++){cout << v[i];if(i<sz(v)-1) cout << ' ';};wt("");}
        template<class A,class B>void wt(const pair<A,B>& pr){
            cout << pr.fi << ' ' << pr.se << '\n';}
        #define out(_) wt(_),GG
    }using namespace _io;
}using namespace myland;
const int N = 105;

namespace TREE {
    #define type long long
    int n;
    int idx = 1, head[N], nxt[N << 1], to[N << 1];
    type co[N << 1];
    int size[N], fa[N][21], dep[N];
    type dis[N];

    void addedge(int u, int v, type w = 1) {
        to[idx] = v, co[idx] = w, nxt[idx] = head[u], head[u] = idx++;
        to[idx] = u, co[idx] = w, nxt[idx] = head[v], head[v] = idx++;
    }
    void dfs(int u, int f) {
        size[u] = 1;
        fa[u][0] = f;
        // for (int i = 1; i <= 20; i++)
        //     fa[u][i] = fa[fa[u][i - 1]][i - 1];
        for (int i = head[u]; i; i = nxt[i]) {
            int v = to[i], w = co[i];
            if (v == f) continue;
            dis[v] = dis[u] + w;
            dep[v] = dep[u] + 1;
            dfs(v, u);
            size[u] += size[v];
        }
    }
    int lca(int u, int v) {
        if (dep[u] < dep[v]) swap(u, v);
        for (int i = 20; i >= 0; i--)
            if (dep[fa[u][i]] >= dep[v])
                u = fa[u][i];
        if (u == v) return u;
        for (int i = 20; i >= 0; i--)
            if (fa[u][i] != fa[v][i])
                u = fa[u][i], v = fa[v][i];
        return fa[u][0];
    }
    type dist(int u, int v) {
        return dis[u] + dis[v] - 2 * dis[lca(u, v)];
    }
    #undef type
}using namespace TREE;

XOR{
    int ans = 0;
    times(rd()){
        rd(n);
        clr(head, 0);
        times(n - 1) addedge(rd(), rd());
        idx = 1;
        dfs(1, 1);
        int p = max_element(rg(dis, 1, n)) - dis;
        dis[p] = 0;
        dfs(p, p);
        ans += *max_element(rg(dis, 1, n));
    }
    wt(ans);
}


#include <bits/stdc++.h>
namespace myland{
    using namespace std;
    namespace _abbr{
        #define fi first
        #define se second
        #define pb push_back
        #define pr make_pair
        #define lb lower_bound
        #define ub upper_bound
        #define str string
        #define _1s __builtin_popcountll
        #define nth(a,l,r,k) nth_element(a+l,a+l+k-1,a+r+1)
        typedef unsigned int ui;
        typedef long long ll;
        typedef unsigned long long ull;
        typedef double db;
        typedef long double ld;
        typedef pair<int,int> pii;
        typedef pair<ll,ll> pll;
        typedef vector<int> vi;
        typedef vector<ll> vl;
        typedef vector<pii> vpii;
        typedef vector<pll> vpll;
        typedef vector<vi> vvi;
        typedef vector<vl> vvl;
        typedef vector<vpii> vvpii;
        typedef vector<vpll> vvpll;
    }using namespace _abbr;
    namespace _constant{
        const double EPS(1e-8);
        const double PI(acos(-1.0));
        const int INF(0x3f3f3f3f);
        const ll INFL(0x3f3f3f3f3f3f3f3fll);
        const int MOD(1e9+7);//998244353, 16341163, 999983, 131, 1e9 + 9
        const int dx[]={1,0,0,-1,-1,1,1,-1}, dy[]={0,-1,1,0,1,1,-1,-1};
    }using namespace _constant;
    namespace _solve{
        #define XOR int main()
        #define GG exit(0)
        #define rep(x,a,b) for(int x=a;x<=b;++x)
        #define per(x,a,b) for(int x=b;x>=a;--x)
        #define times(x) for(int cas=1,tms=(x);cas<=tms;cas++)
        #define CaseT int T;cin >> T;times(T)
        #define TCase int T;scanf("%d",&T);times(T)
        #define continue(_) if(_) continue;
        #define break(_) if(_) break;
    }using namespace _solve;
    namespace _calculate{
        bool odd(ll x){return x&1;}
        bool even(ll x){return (x&1)^1;}
        bool posi(ll x){return x>0;}
        bool nega(ll x){return x<0;}
        bool zero(ll x){return x==0;}
        bool prime(ll x){if(x<2) return 0;
            for(ll i=2;1ll*i*i<=x;i++) if(x%i==0) return 0;
            return 1;}
        ll droot(ll x){return 1+(x-1)%9;}
        ll upd(ll a, ll b){return a%b?a/b+1:a/b;};
        ll gcd(ll a, ll b){return __gcd(a, b);}
        ll lcm(ll a, ll b){return a/gcd(a, b)*b;}
        mt19937_64 rand(time(0));
        ll random(ll a, ll b){return a+rand()%(b-a+1);};
        ll bitn(ll x){ll c=0;while(x)c++,x>>=1;return c;}
        template<class T>T sqr(T x){return x*x;}
        ll qpow(ll a, ll n, ll mod = MOD){
            ll res(1);while(n){
            if(n&1) (res*=a)%=mod;
            (a*=a)%=mod;n>>=1;}
            return res%mod;}
        ll inv(ll a, ll mod = MOD){return qpow(a,mod-2, mod);}
        template<class T>void tomin(T& a,T b){if(b<a) a=b;}
        template<class T>void tomax(T& a,T b){if(b>a) a=b;}
    }using namespace _calculate;
    namespace _simple_algo{
        #define rg(a,x,y) (a+x), (a+y+1)
        #define vrg(a,x,y) (a.begin()+x),(a.begin()+y+1)
        #define all(x) (x).begin(),(x).end()
        #define rall(x) (x).rbegin(),(x).rend()
        #define clr(a,b) memset(a,b,sizeof(a))
        #define fil(a,b) fill(all(a),b)
        #define _sum(a) accumulate(a, 0ll)
        #define sz(a) (ll(a.size()))
        ll sol(const string& s){ll x=0;
            for(char c:s)x=x*10+c-48;return x;}
        string los(ll x){string s = "";
            if(x==0) return "0";
            while(x) s=char(x%10+48)+s,x/=10;
            return s;}
        bool pal(const string& s){int l = s.size();
            for(int i=0,j=l-1;i<j;i++,j--)
                if(s[i]!=s[j]) return 0;return 1;}
    }using namespace _simple_algo;
    namespace _io{
        #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
        #define bug cerr << "!!!" << endl;
        #define bugc(_) cerr << (#_) << " = " << (_) << endl;
        template<class T>void rd(T& x){cin>>x;}
        str srd(){str s;cin>>s;return s;}
        ll rd(){
            ll x=0,f=1;char ch=getchar();
            while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
            while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
            return x*f;}
        void rd(int& x){x=rd();}
        void rd(ll& x){x=rd();}
        template<class A,class B>void rd(A& a,B& b){rd(a), rd(b);}
        template<class A,class B>void rd(pair<A,B>& p){rd(p.fi, p.se);}
        template<class A,class B,class C>void rd(A& a,B& b,C& c){rd(a,b);rd(c);}
        template<class T>void wt(const T& x){cout << x << '\n';}
        template<class T>void wt(const T& x, char c){cout << x << c;}
        template<class T>void wt(const T& x, const str& s){cout << x << s;}
        template<class T>void wt(const T& x, int rnd){
            cout << fixed << setprecision(rnd) << x << '\n';}
        template<class T>void wt(const vector<T>& v){
            for(int i=0;i<sz(v);i++){cout << v[i];if(i<sz(v)-1) cout << ' ';};wt("");}
        template<class A,class B>void wt(const pair<A,B>& pr){
            cout << pr.fi << ' ' << pr.se << '\n';}
        #define out(_) wt(_),GG
    }using namespace _io;
}using namespace myland;
const int N = 105;

namespace TREE {
    #define type long long
    int n;
    int idx = 1, head[N], nxt[N << 1], to[N << 1];
    type co[N << 1];
    int size[N], fa[N][21], dep[N];
    type dis[N];

    void addedge(int u, int v, type w = 1) {
        to[idx] = v, co[idx] = w, nxt[idx] = head[u], head[u] = idx++;
        to[idx] = u, co[idx] = w, nxt[idx] = head[v], head[v] = idx++;
    }
    void dfs(int u, int f) {
        size[u] = 1;
        fa[u][0] = f;
        for (int i = 1; i <= 20; i++)
            fa[u][i] = fa[fa[u][i - 1]][i - 1];
        for (int i = head[u]; i; i = nxt[i]) {
            int v = to[i], w = co[i];
            if (v == f) continue;
            dis[v] = dis[u] + w;
            dep[v] = dep[u] + 1;
            dfs(v, u);
            size[u] += size[v];
        }
    }
    int lca(int u, int v) {
        if (dep[u] < dep[v]) swap(u, v);
        for (int i = 20; i >= 0; i--)
            if (dep[fa[u][i]] >= dep[v])
                u = fa[u][i];
        if (u == v) return u;
        for (int i = 20; i >= 0; i--)
            if (fa[u][i] != fa[v][i])
                u = fa[u][i], v = fa[v][i];
        return fa[u][0];
    }
    type dist(int u, int v) {
        return dis[u] + dis[v] - 2 * dis[lca(u, v)];
    }
    #undef type
}using namespace TREE;

XOR{
    int ans = 0;
    // times(rd()){
    //     rd(n);
    //     clr(head, 0);
    //     times(n - 1) addedge(rd(), rd());
    //     idx = 1;
    //     dfs(1, 1);
    //     int p = max_element(rg(dis, 1, n)) - dis;
    //     dis[p] = 0;
    //     dfs(p, p);
    //     ans += *max_element(rg(dis, 1, n));
    // }
    wt(ans);
}


#include <bits/stdc++.h>
namespace myland{
    using namespace std;
    namespace _abbr{
        #define fi first
        #define se second
        #define pb push_back
        #define pr make_pair
        #define lb lower_bound
        #define ub upper_bound
        #define str string
        #define _1s __builtin_popcountll
        #define nth(a,l,r,k) nth_element(a+l,a+l+k-1,a+r+1)
        typedef unsigned int ui;
        typedef long long ll;
        typedef unsigned long long ull;
        typedef double db;
        typedef long double ld;
        typedef pair<int,int> pii;
        typedef pair<ll,ll> pll;
        typedef vector<int> vi;
        typedef vector<ll> vl;
        typedef vector<pii> vpii;
        typedef vector<pll> vpll;
        typedef vector<vi> vvi;
        typedef vector<vl> vvl;
        typedef vector<vpii> vvpii;
        typedef vector<vpll> vvpll;
    }using namespace _abbr;
    namespace _constant{
        const double EPS(1e-8);
        const double PI(acos(-1.0));
        const int INF(0x3f3f3f3f);
        const ll INFL(0x3f3f3f3f3f3f3f3fll);
        const int MOD(1e9+7);//998244353, 16341163, 999983, 131, 1e9 + 9
        const int dx[]={1,0,0,-1,-1,1,1,-1}, dy[]={0,-1,1,0,1,1,-1,-1};
    }using namespace _constant;
    namespace _solve{
        #define XOR int main()
        #define GG exit(0)
        #define rep(x,a,b) for(int x=a;x<=b;++x)
        #define per(x,a,b) for(int x=b;x>=a;--x)
        #define times(x) for(int cas=1,tms=(x);cas<=tms;cas++)
        #define CaseT int T;cin >> T;times(T)
        #define TCase int T;scanf("%d",&T);times(T)
        #define continue(_) if(_) continue;
        #define break(_) if(_) break;
    }using namespace _solve;
    namespace _calculate{
        bool odd(ll x){return x&1;}
        bool even(ll x){return (x&1)^1;}
        bool posi(ll x){return x>0;}
        bool nega(ll x){return x<0;}
        bool zero(ll x){return x==0;}
        bool prime(ll x){if(x<2) return 0;
            for(ll i=2;1ll*i*i<=x;i++) if(x%i==0) return 0;
            return 1;}
        ll droot(ll x){return 1+(x-1)%9;}
        ll upd(ll a, ll b){return a%b?a/b+1:a/b;};
        ll gcd(ll a, ll b){return __gcd(a, b);}
        ll lcm(ll a, ll b){return a/gcd(a, b)*b;}
        mt19937_64 rand(time(0));
        ll random(ll a, ll b){return a+rand()%(b-a+1);};
        ll bitn(ll x){ll c=0;while(x)c++,x>>=1;return c;}
        template<class T>T sqr(T x){return x*x;}
        ll qpow(ll a, ll n, ll mod = MOD){
            ll res(1);while(n){
            if(n&1) (res*=a)%=mod;
            (a*=a)%=mod;n>>=1;}
            return res%mod;}
        ll inv(ll a, ll mod = MOD){return qpow(a,mod-2, mod);}
        template<class T>void tomin(T& a,T b){if(b<a) a=b;}
        template<class T>void tomax(T& a,T b){if(b>a) a=b;}
    }using namespace _calculate;
    namespace _simple_algo{
        #define rg(a,x,y) (a+x), (a+y+1)
        #define vrg(a,x,y) (a.begin()+x),(a.begin()+y+1)
        #define all(x) (x).begin(),(x).end()
        #define rall(x) (x).rbegin(),(x).rend()
        #define clr(a,b) memset(a,b,sizeof(a))
        #define fil(a,b) fill(all(a),b)
        #define _sum(a) accumulate(a, 0ll)
        #define sz(a) (ll(a.size()))
        ll sol(const string& s){ll x=0;
            for(char c:s)x=x*10+c-48;return x;}
        string los(ll x){string s = "";
            if(x==0) return "0";
            while(x) s=char(x%10+48)+s,x/=10;
            return s;}
        bool pal(const string& s){int l = s.size();
            for(int i=0,j=l-1;i<j;i++,j--)
                if(s[i]!=s[j]) return 0;return 1;}
    }using namespace _simple_algo;
    namespace _io{
        #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
        #define bug cerr << "!!!" << endl;
        #define bugc(_) cerr << (#_) << " = " << (_) << endl;
        template<class T>void rd(T& x){cin>>x;}
        str srd(){str s;cin>>s;return s;}
        ll rd(){
            ll x=0,f=1;char ch=getchar();
            while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
            while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
            return x*f;}
        void rd(int& x){x=rd();}
        void rd(ll& x){x=rd();}
        template<class A,class B>void rd(A& a,B& b){rd(a), rd(b);}
        template<class A,class B>void rd(pair<A,B>& p){rd(p.fi, p.se);}
        template<class A,class B,class C>void rd(A& a,B& b,C& c){rd(a,b);rd(c);}
        template<class T>void wt(const T& x){cout << x << '\n';}
        template<class T>void wt(const T& x, char c){cout << x << c;}
        template<class T>void wt(const T& x, const str& s){cout << x << s;}
        template<class T>void wt(const T& x, int rnd){
            cout << fixed << setprecision(rnd) << x << '\n';}
        template<class T>void wt(const vector<T>& v){
            for(int i=0;i<sz(v);i++){cout << v[i];if(i<sz(v)-1) cout << ' ';};wt("");}
        template<class A,class B>void wt(const pair<A,B>& pr){
            cout << pr.fi << ' ' << pr.se << '\n';}
        #define out(_) wt(_),GG
    }using namespace _io;
}using namespace myland;
const int N = 105;

namespace TREE {
    #define type long long
    int n;
    int idx = 1, head[N], nxt[N << 1], to[N << 1];
    type co[N << 1];
    int size[N], fa[N][21], dep[N];
    type dis[N];

    void addedge(int u, int v, type w = 1) {
        to[idx] = v, co[idx] = w, nxt[idx] = head[u], head[u] = idx++;
        to[idx] = u, co[idx] = w, nxt[idx] = head[v], head[v] = idx++;
    }
    void dfs(int u, int f) {
        size[u] = 1;
        fa[u][0] = f;
        for (int i = 1; i <= 20; i++)
            fa[u][i] = fa[fa[u][i - 1]][i - 1];
        for (int i = head[u]; i; i = nxt[i]) {
            int v = to[i], w = co[i];
            if (v == f) continue;
            dis[v] = dis[u] + w;
            dep[v] = dep[u] + 1;
            dfs(v, u);
            size[u] += size[v];
        }
    }
    int lca(int u, int v) {
        if (dep[u] < dep[v]) swap(u, v);
        for (int i = 20; i >= 0; i--)
            if (dep[fa[u][i]] >= dep[v])
                u = fa[u][i];
        if (u == v) return u;
        for (int i = 20; i >= 0; i--)
            if (fa[u][i] != fa[v][i])
                u = fa[u][i], v = fa[v][i];
        return fa[u][0];
    }
    type dist(int u, int v) {
        return dis[u] + dis[v] - 2 * dis[lca(u, v)];
    }
    #undef type
}using namespace TREE;

XOR{
    freopne("input.txt", "r", stdin);
    freopne("output.txt", "w", stdin);
    int ans = 0;
    times(rd()){
        rd(n);
        clr(head, 0);
        times(n - 1) addedge(rd(), rd());
        idx = 1;
        dfs(1, 1);
        int p = max_element(rg(dis, 1, n)) - dis;
        dis[p] = 0;
        dfs(p, p);
        ans += *max_element(rg(dis, 1, n));
    }
    wt(ans);
}


#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;
const int N = 1e2 + 7;
vector < int > graph[N + 5];
int dist[N + 5];
bool visit[N];
int n;
long long ans;

pair < int,int > bfs(int u) {
  for(int i = 0 ; i <= n ; i++) {
    dist[i] = 0;
  }
  visit[u] = 1;
  dist[u] = 0;
  queue < pair < int,int > > Q;
  for(int v : graph[u]) {
    dist[v] = 1;
    Q.push({v, 1});
    visit[v] = 1;
  }
  pair < int,int > ret = {u, 0};
  while(!Q.empty()) {
    auto curr = Q.front();
    if(curr.second > ret.second) {
        ret.first = curr.first;
        ret.second = curr.second;
    }
    Q.pop();
    for(int v : graph[curr.first]) {
        if(!dist[v] and v != u) {
            visit[v] = 1;
            dist[v] = dist[curr.first] + 1;
            Q.push({v, dist[v]});
        }
    }
  }
  return ret;
}

int main() {
  std :: ios :: sync_with_stdio(false);
  cin.tie(0);
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  int T;
  cin >> T;
  for(int cs = 1 ; cs <= T ; cs++) {
    cin >> n;
    for(int i = 1 ; i < n ; i++) {
        int x, y;
        cin >> x >> y;
        graph[x].emplace_back(y);
        graph[y].emplace_back(x);
    }
    for(int i = 1 ; i <= n ; i++) {
        if(!visit[i]) {
          auto curr = bfs(i);
          curr = bfs(curr.first);
          ans += curr.second;
        }
    }
    for(int i = 1 ; i <= N ; i++) {
        graph[i].clear();
        visit[i] = 0;
    }
  }
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;
const int N = 1e2 + 7;
vector < int > graph[N + 5];
int dist[N + 5];
int n;
long long ans;

pair < int,int > bfs(int u) {
  for(int i = 0 ; i <= n ; i++) {
    dist[i] = 0;
  }
  dist[u] = 0;
  queue < int > Q;
  for(int v : graph[u]) {
    dist[v] = 1;
    Q.push(v);
  }
  pair < int,int > ret = {u, 0};
  while(!Q.empty()) {
    auto curr = Q.front();
    Q.pop();
    for(int v : graph[curr]) {
        if(!dist[v] and v != u) {
            dist[v] = dist[curr] + 1;
            Q.push(v);
        }
    }
  }
  for(int i = 1 ; i <= N ; i++) {
    if(dist[i] > ret.second) {
        ret.first = i;
        ret.second = dist[i];
    }
  }
  return ret;
}

int main() {
  std :: ios :: sync_with_stdio(false);
  cin.tie(0);
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  int T;
  cin >> T;
  for(int cs = 1 ; cs <= T ; cs++) {
    cin >> n;
    for(int i = 1 ; i < n ; i++) {
        int x, y;
        cin >> x >> y;
        graph[x].emplace_back(y);
        graph[y].emplace_back(x);
    }
    auto curr = bfs(1);
    curr = bfs(curr.first);
    ans += curr.second;
    for(int i = 1 ; i <= N ; i++) {
        graph[i].clear();
    }
  }
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;
const int N = 1e2 + 7;
vector < int > graph[N + 5];
int dist[N + 5];
bool visit[N];
int n;
long long ans;

pair < int,int > bfs(int u) {
  for(int i = 0 ; i <= n ; i++) {
    dist[i] = 0;
  }
  visit[u] = 1;
  dist[u] = 0;
  queue < pair < int,int > > Q;
  for(int v : graph[u]) {
    dist[v] = 1;
    Q.push({v, 1});
    visit[v] = 1;
  }
  pair < int,int > ret = {u, 0};
  while(!Q.empty()) {
    auto curr = Q.front();
    if(curr.second > ret.second) {
        ret.first = curr.first;
        ret.second = curr.second;
    }
    Q.pop();
    for(int v : graph[curr.first]) {
        if(!dist[v] and v != u) {
            visit[v] = 1;
            dist[v] = dist[curr.first] + 1;
            Q.push({v, dist[v]});
        }
    }
  }
  return ret;
}

int main() {
  std :: ios :: sync_with_stdio(false);
  cin.tie(0);
 /// freopen("input.txt","r",stdin);
 /// freopen("output.txt","w",stdout);
  int T;
  cin >> T;
  for(int cs = 1 ; cs <= T ; cs++) {
    cin >> n;
    for(int i = 1 ; i < n ; i++) {
        int x, y;
        cin >> x >> y;
        graph[x].emplace_back(y);
        graph[y].emplace_back(x);
    }
    for(int i = 1 ; i <= n ; i++) {
        if(!visit[i]) {
          auto curr = bfs(i);
          curr = bfs(curr.first);
          ans += curr.second;
        }
    }
    for(int i = 1 ; i <= N ; i++) {
        graph[i].clear();
        visit[i] = 0;
    }
  }
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long int
const int maxN=110;
ll f1,f2,t,n,a[maxN],b[maxN],x,y,r;
vector<ll> g[maxN];
ll bfs(ll x){
  memset(a,255,sizeof(a));
  a[x]=0;
  b[0]=x;
  f1=0;
  f2=1;
  while(f1<f2){
    ll i=b[f1++];
    for(ll j=0;j<(int)(g[i].size());j++){
      ll  k=g[i][j];
      if (a[k]==-1){a[k]=a[i]+1;b[f2++]=k;}
    }
  }
}
int main(){
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  cin>>t;
  while (t--){//aqqqqqqqq:(
    cin>>n;
    for(int i=1;i<=n;i++)
      g[i].clear();
    for(int i=1;i<n;i++){
      cin>>x>>y;
      g[x].push_back(y);
      g[y].push_back(x);
    }
    bfs(1);
    bfs(b[f2-1]);
    r+=a[b[f2-1]];
  }
  cout<<r<<endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long int
const int maxN=110;
ll f1,f2,t,n,a[maxN],b[maxN],x,y,r;
vector<ll> g[maxN];
ll bfs(ll x){
  memset(a,255,sizeof(a));
  a[x]=0;
  b[0]=x;
  f1=0;
  f2=1;
  while(f1<f2){
    ll i=b[f1++];
    for(ll j=0;j<(int)(g[i].size());j++){
      ll t k=g[i][j];
      if (a[k]==-1){a[k]=a[i]+1;b[f2++]=k;}
    }
  }
}
int main(){
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  cin>>n;
  while (n--){
    cin>>t;
    for(ll i=1;i<=n;i++)
      g[i].clear();
    while(t--){
      cin>>x>>y;
      g[x].push_back(y);
      g[y].push_back(x);
    }
    bfs(1);
    bfs(b[f2-1]);
    r+=a[b[f2-1]];
  }
  cout<<r<<endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long int
const int maxN=110;
ll f1,f2,t,n,a[maxN],b[maxN],x,y,r;
vector<ll> g[maxN];
ll bfs(ll x){
  memset(a,255,sizeof(a));
  a[x]=0;
  b[0]=x;
  f1=0;
  f2=1;
  while(f1<f2){
    ll i=b[f1++];
    for(ll j=0;j<int(g[i].size());j++){
      llt k=g[i][j];
      if (a[k]==-1){a[k]=a[i]+1;b[f2++]=k;}
    }
  }
}
int main(){
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  cin>>n;
  while (n--){
    cin>>t;
    for(ll i=1;i<=n;i++)
      g[i].clear();
    while(t--){
      cin>>x>>y;
      g[x].push_back(y);
      g[y].push_back(x);
    }
    bfs(1);
    bfs(b[f2-1]);
    r+=a[b[f2-1]];
  }
  cout<<r<<endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long int
const int maxN=110;
ll f1,f2,t,n,a[maxN],b[maxN],x,y,r;
vector<ll> g[maxN];
ll bfs(ll x){
  memset(a,255,sizeof(a));
  a[x]=0;
  b[0]=x;
  f1=0;
  f2=1;
  while(f1<f2){
    ll i=b[f1++];
    for(ll j=0;j<(int)(g[i].size());j++){
      ll  k=g[i][j];
      if (a[k]==-1){a[k]=a[i]+1;b[f2++]=k;}
    }
  }
}
int main(){
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  cin>>n;
  while (n--){
    cin>>t;
    for(ll i=1;i<=n;i++)
      g[i].clear();
    while(t--){
      cin>>x>>y;
      g[x].push_back(y);
      g[y].push_back(x);
    }
    bfs(1);
    bfs(b[f2-1]);
    r+=a[b[f2-1]];
  }
  cout<<r<<endl;
  return 0;
}


/*
I think the honorable thing for our species to do is deny our programming, stop reproducing.
Walk hand in hand into extinction one last midnight.
Brothers and sisters opting out of a raw deal.
*/

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cctype>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <cmath>
#include <bitset>
#include <utility>
#include <set>
#include <numeric>
#define MOD 1000000007
using namespace std;
typedef long long ll;
typedef vector < int > vi;
typedef vector < ll > vll;
typedef pair <int, int> pii;
#define S(a) scanf("%d",&a)
#define Sll(a) scanf("%lld",&a)
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,n,a) for(int i=n-1;i>=a;i--)
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define all(vi) vi.begin(), vi.end()
#define tr(container, it) for(auto it = container.begin(); it != container.end(); it++)
#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define llmax numeric_limits<ll>::max()
#define llmin numeric_limits<ll>::min()
int k;
vector<int> g[111];
bool visited[111];
void dfs(int v,int l){
	k=max(k,l);
	visited[v]=true;
	rep(i,0,g[v].size()){
		if(!visited[g[v][i]])
		dfs(g[v][i],l+1);
	}
}
int main()
{
    int n;
    S(n);
    ll f=0;
    rep(i,0,n){
    	int t;
    	S(t);
    	rep(i,0,t+2)
    		g[i].clear();
    	rep(i,0,t-1){
    		int a,b;
    		S(a);S(b);
    		g[a].pb(b);
    		g[b].pb(a);
    	}
    	cout<<"****\n";
    	int ans=imin;
    	rep(i,1,t+1){
    		k=0;
    		memset(visited,false,sizeof visited);
    		dfs(i,0);
    		ans=max(ans,k);
    	}
    	f+=ans;
    }
    cout<<f<<endl;
    return 0;
}


/*
I think the honorable thing for our species to do is deny our programming, stop reproducing.
Walk hand in hand into extinction one last midnight.
Brothers and sisters opting out of a raw deal.
*/

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cctype>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <cmath>
#include <bitset>
#include <utility>
#include <set>
#include <numeric>
#define MOD 1000000007
using namespace std;
typedef long long ll;
typedef vector < int > vi;
typedef vector < ll > vll;
typedef pair <int, int> pii;
#define S(a) scanf("%d",&a)
#define Sll(a) scanf("%lld",&a)
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,n,a) for(int i=n-1;i>=a;i--)
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define all(vi) vi.begin(), vi.end()
#define tr(container, it) for(auto it = container.begin(); it != container.end(); it++)
#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define llmax numeric_limits<ll>::max()
#define llmin numeric_limits<ll>::min()
int k;
vector<int> g[111];
bool visited[111];
void dfs(int v,int l){
	k=max(k,l);
	visited[v]=true;
	rep(i,0,g[v].size()){
		if(!visited[g[v][i]])
		dfs(g[v][i],l+1);
	}
}
int main()
{
    int n;
    S(n);
    ll f=0;
    rep(i,0,n){
    	int t;
    	S(t);
    	rep(i,0,t+2)
    		g[i].clear();
    	rep(i,0,t-1){
    		int a,b;
    		S(a);S(b);
    		g[a].pb(b);
    		g[b].pb(a);
    	}
    	int ans=imin;
    	rep(i,1,t+1){
    		k=0;
    		memset(visited,false,sizeof visited);
    		dfs(i,0);
    		ans=max(ans,k);
    	}
    	f+=ans;
    }
    cout<<f<<endl;
    return 0;
}


/*
I think the honorable thing for our species to do is deny our programming, stop reproducing.
Walk hand in hand into extinction one last midnight.
Brothers and sisters opting out of a raw deal.
*/

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cctype>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <cmath>
#include <bitset>
#include <utility>
#include <set>
#include <numeric>
#define MOD 1000000007
using namespace std;
typedef long long ll;
typedef vector < int > vi;
typedef vector < ll > vll;
typedef pair <int, int> pii;
#define S(a) scanf("%d",&a)
#define Sll(a) scanf("%lld",&a)
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,n,a) for(int i=n-1;i>=a;i--)
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define all(vi) vi.begin(), vi.end()
#define tr(container, it) for(auto it = container.begin(); it != container.end(); it++)
#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define llmax numeric_limits<ll>::max()
#define llmin numeric_limits<ll>::min()
int k;
vector<int> g[111];
bool visited[111];
void dfs(int v,int l){
	k=max(k,l);
	visited[v]=true;
	rep(i,0,g[v].size()){
		if(!visited[g[v][i]])
		dfs(g[v][i],l+1);
	}
}
int main()
{
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
    int n;
    S(n);
    ll f=0;
    rep(i,0,n){
    	int t;
    	S(t);
    	rep(i,0,t+2)
    		g[i].clear();
    	rep(i,0,t-1){
    		int a,b;
    		S(a);S(b);
    		g[a].pb(b);
    		g[b].pb(a);
    	}
    	int ans=imin;
    	rep(i,1,t+1){
    		k=0;
    		memset(visited,false,sizeof visited);
    		dfs(i,0);
    		ans=max(ans,k);
    	}
    	f+=ans;
    }
    cout<<f<<endl;
    return 0;
}


/*
I think the honorable thing for our species to do is deny our programming, stop reproducing.
Walk hand in hand into extinction one last midnight.
Brothers and sisters opting out of a raw deal.
*/

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cctype>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <cmath>
#include <bitset>
#include <utility>
#include <set>
#include <numeric>
#define MOD 1000000007
using namespace std;
typedef long long ll;
typedef vector < int > vi;
typedef vector < ll > vll;
typedef pair <int, int> pii;
#define S(a) scanf("%d",&a)
#define Sll(a) scanf("%lld",&a)
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,n,a) for(int i=n-1;i>=a;i--)
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define all(vi) vi.begin(), vi.end()
#define tr(container, it) for(auto it = container.begin(); it != container.end(); it++)
#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define llmax numeric_limits<ll>::max()
#define llmin numeric_limits<ll>::min()
int k;
vector<int> g[111];
bool visited[111];
void dfs(int v,int l){
	k=max(k,l);
	visited[v]=true;
	rep(i,0,g[v].size()){
		if(!visited[g[v][i]])
		dfs(g[v][i],l+1);
	}
}
int main()
{
    int n;
    S(n);
    ll f=0;
    rep(i,0,n){
    	int t;
    	S(t);
    	rep(i,0,t+2)
    		g[i].clear();
    	rep(i,0,t-1){
    		int a,b;
    		S(a);S(b);
    		g[a].pb(b);
    		g[b].pb(a);
    	}
    	int ans=imin;
    	rep(i,1,t+1){
    		k=0;
    		memset(visited,false,sizeof visited);
    		dfs(i,0);
    		ans=max(ans,k);
    	}

    	f+=ans;
    }
    cout<<f<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define l long
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second
const int N = 105;
int dist[N];
bool vis[N];
int mmax;
void dfs(int u, vector<int> adj[])
{
    vis[u] = 1;
    for(auto it:adj[u])
    {
        if(vis[it]) continue;
        dist[it] = dist[u] + 1;
        dfs(it,adj);
    }
    mmax = max(mmax,dist[u]);
}

int main() {
	// your code goes here
	ifstream cin("input.txt");
	ofstream cout("output.txt");
	//ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
	int n; cin>>n; int ans = 0;
	for(int j=0;j<n;j++)
	{
	    int k; cin>>k;
	    vector <int> adj[k+1];
	    for(int i=1;i<k;i++)
	    {
	        int p,q; cin>>p>>q;
	        adj[p].pb(q); adj[q].pb(p);
	    }

	    mmax = -1e9;
	    for(int i=1;i<=k;i++)
	    {
	        memset(dist,0,sizeof(dist));
	        memset(vis,0,sizeof(vis));
	        dfs(i,adj);

	    }
	    ans += mmax;

	}
	cout<<ans;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define l long
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second
const int N = 105;
int dist[N];
bool vis[N];
int mmax;
void dfs(int u, vector<int> adj[])
{
    vis[u] = 1;
    for(auto it:adj[u])
    {
        if(vis[it]) continue;
        dist[it] = dist[u] + 1;
        dfs(it,adj);
    }
    mmax = max(mmax,dist[u]);
}

int main() {
	// your code goes here
	//ifstream cin("input.txt");
	//ofstream cout("output.txt");
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);
	int n; cin>>n; int ans = 0;
	for(int j=0;j<n;j++)
	{
	    int k; cin>>k;
	    vector <int> adj[k+1];
	    for(int i=1;i<k;i++)
	    {
	        int p,q; cin>>p>>q;
	        adj[p].pb(q); adj[q].pb(p);
	    }

	    mmax = -1e9;
	    for(int i=1;i<=k;i++)
	    {
	        memset(dist,0,sizeof(dist));
	        memset(vis,0,sizeof(vis));
	        dfs(i,adj);

	    }
	    ans += mmax;

	}
	cout<<ans;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define l long
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second
int dist[105];
bool vis[105];
vector <int> adj[105];
int mmax;
void dfs(int u)
{
    vis[u] = 1;
    for(auto it:adj[u])
    {
        if(vis[it]) continue;
        dist[it] = dist[u] + 1;
        dfs(it);
    }
    mmax = max(mmax,dist[u]);
}

int main() {
	// your code goes here
	//ifstream cin("input.txt");
	//ofstream cout("output.txt");
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);
	int n; cin>>n; int ans = 0;
	for(int j=0;j<n;j++)
	{
	    int k; cin>>k;
	    for(int i=1;i<=101;i++) adj[i].clear();
	    for(int i=1;i<k;i++)
	    {
	        int p,q; cin>>p>>q;
	        adj[p].pb(q); adj[q].pb(p);
	    }
	    mmax = -1e9;
	    for(int i=1;i<=k;i++)
	    {
	        memset(dist,0,sizeof(dist));
	        memset(vis,0,sizeof(vis));
	        dfs(i);

	    }
	    ans += mmax;

	}
	cout<<ans;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define l long
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second
int dist[105];
bool vis[105];
vector <int> adj[105];
int mmax;
void dfs(int u)
{
    vis[u] = 1;
    for(auto it:adj[u])
    {
        if(vis[it]) continue;
        dist[it] = dist[u] + 1;
        dfs(it);
    }
    mmax = max(mmax,dist[u]);
}

int main() {
	// your code goes here
	//ifstream cin("input.txt");
	//ofstream cout("output.txt");
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);
	int n; cin>>n; int ans = 0;
	for(int j=0;j<n;j++)
	{
	    int k; cin>>k;
	    for(int i=1;i<=k;i++) adj[i].clear();
	    for(int i=1;i<k;i++)
	    {
	        int p,q; cin>>p>>q;
	        adj[p].pb(q); adj[q].pb(p);
	    }
	    mmax = -1e9;
	    for(int i=1;i<=k;i++)
	    {
	        memset(dist,0,sizeof(dist));
	        memset(vis,0,sizeof(vis));
	        dfs(i);

	    }
	    ans += mmax;

	}
	cout<<ans;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define l long
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second
int dist[105];
bool vis[105];
vector <int> adj[105];
int mmax;
void dfs(int u)
{
    vis[u] = 1;
    for(auto it:adj[u])
    {
        if(vis[it]) continue;
        dist[it] = dist[u] + 1;
        dfs(it);
    }
    mmax = max(mmax,dist[u]);
}

int main() {
	// your code goes here
	//ifstream cin("input.txt");
	//ofstream cout("output.txt");
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);
	int n; cin>>n; int ans = 0;
	for(int i=0;i<n;i++)
	{
	    int k; cin>>k;
	    for(int i=1;i<=k;i++) adj[i].clear();
	    for(int i=1;i<k;i++)
	    {
	        int p,q; cin>>p>>q;
	        adj[p].pb(q); adj[q].pb(p);
	    }
	    mmax = -1e9;
	    for(int i=1;i<=k;i++)
	    {
	        memset(dist,0,sizeof(dist));
	        memset(vis,0,sizeof(vis));
	        dfs(i);

	    }
	    ans += mmax;

	}
	cout<<ans;

	return 0;
}


#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <functional>
#include <math.h>
#include <map>
#include <set>
#include <string>
using namespace std;
#define fio ios::sync_with_stdio(false); cin.tie(NULL);

typedef long long ll;
typedef unsigned long long ull;
const int INT_INF = 1e9;
const ll LL_INF = 2e18;

int n;
vector<int>G[100002];
int sti, curmx;
void dfs(int cur, int par, int dis) {
	if (curmx < dis) {
		curmx = dis;
		sti = cur;
	}

	for (auto nxt : G[cur]) {
		if (nxt == par) continue;
		dfs(nxt, cur, dis + 1);
	}
}

int main() {
	freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);

	scanf("%d", &n);
	int ans = 0;
	for (int tc = 0; tc < n; tc++) {
		int ni;
		scanf("%d", &ni);
		for(int i=1;i<=ni;i++)
			G[i].clear();

		for (int i = 0; i < ni - 1; i++) {
			int u, v;
			scanf("%d %d", &u, &v);
			G[u].push_back(v);
			G[v].push_back(u);
		}
		curmx = -1;
		dfs(1, -1, 0);
		curmx = -1;
		dfs(sti, -1, 0);
		ans += curmx;
	}
	printf("%d", ans);

	return 0;
}