#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#define ll long long
#define maxn 200005
#define re register
#define inf 1e9
#define eps 1e-10
using namespace std;

inline int read()
{
	int x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}

vector <int> g[maxn];
int dfn[maxn],low[maxn],num=1,hd[maxn],n,m,ans=0,v[maxn];
int to[maxn<<1],ne[maxn<<1],cnt,col[maxn],mx[maxn],dc;
bool ban[maxn<<1];

inline void add(int x,int y)
{
	to[++num]=y;
	ne[num]=hd[x];
	hd[x]=num;
}

inline void tarjan(int x,int fa)
{
	dfn[x]=low[x]=++dc;
	for(int i=hd[x];i;i=ne[i])
	{
		if(to[i]==fa) continue;
		if(!dfn[to[i]])
		{
			tarjan(to[i],x);
			low[x]=min(low[x],low[to[i]]);
			if(low[to[i]]>dfn[x]) ban[i]=ban[i^1]=1;
		}
		else low[x]=min(low[x],dfn[to[x]]);
	}
}

inline void B(int x)
{
	col[x]=cnt;
	for(int i=hd[x];i;i=ne[i])
	{
		if(ban[i])
		{
			if(col[to[i]]&&v[to[i]]!=cnt)
			{
				v[to[i]]=cnt;
				g[cnt].push_back(col[to[i]]);
				g[col[to[i]]].push_back(cnt);
			}
		}
		else if(!col[to[i]]) B(to[i]);
	}
}

inline void dfs(int x,int fa)
{
	for(int i=0;i<g[x].size();i++)
	{
		int v=g[x][i];
		if(v==fa) continue;
		dfs(v,x);
		ans=max(ans,mx[v]+1+mx[x]);
		mx[x]=max(mx[x],mx[v]+1);
	}
}

int main()
{
	n=read(); m=read();
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		add(u,v); add(v,u);
	}
	tarjan(1,0);
	for(int i=1;i<=n;i++) if(!col[i]) cnt++,B(i);
	dfs(1,0);
	printf("%d\n",ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#define ll long long
#define maxn 200005
#define re register
#define inf 1e9
#define eps 1e-10
using namespace std;

inline int read()
{
	int x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}

vector <int> g[maxn];
int dfn[maxn],low[maxn],num=1,hd[maxn],n,m,ans=0,v[maxn];
int to[maxn<<1],ne[maxn<<1],cnt,col[maxn],mx[maxn],dc;
bool ban[maxn<<1];

inline void add(int x,int y)
{
	to[++num]=y;
	ne[num]=hd[x];
	hd[x]=num;
}

inline void tarjan(int x,int fa)
{
	dfn[x]=low[x]=++dc;
	for(int i=hd[x];i;i=ne[i])
	{
		if(to[i]==fa) continue;
		if(!dfn[to[i]])
		{
			tarjan(to[i],x);
			low[x]=min(low[x],low[to[i]]);
			if(low[to[i]]>dfn[x]) ban[i]=ban[i^1]=1;
		}
		else low[x]=min(low[x],dfn[to[i]]);
	}
}

inline void B(int x)
{
	col[x]=cnt;
	for(int i=hd[x];i;i=ne[i])
	{
		if(ban[i])
		{
			if(col[to[i]]&&v[to[i]]!=cnt)
			{
				v[to[i]]=cnt;
				g[cnt].push_back(col[to[i]]);
				g[col[to[i]]].push_back(cnt);
			}
		}
		else if(!col[to[i]]) B(to[i]);
	}
}

inline void dfs(int x,int fa)
{
	for(int i=0;i<g[x].size();i++)
	{
		int v=g[x][i];
		if(v==fa) continue;
		dfs(v,x);
		ans=max(ans,mx[v]+1+mx[x]);
		mx[x]=max(mx[x],mx[v]+1);
	}
}

int main()
{
	n=read(); m=read();
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		add(u,v); add(v,u);
	}
	tarjan(1,0);
	for(int i=1;i<=n;i++) if(!col[i]) cnt++,B(i);
	dfs(1,0);
	printf("%d\n",ans);
	return 0;
}


#pragmma optimize GCC (2)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#define ll long long
#define maxn 200005
#define re register
#define inf 1e9
#define eps 1e-10
using namespace std;

inline int read()
{
	int x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}

vector <int> g[maxn];
int dfn[maxn],low[maxn],num=1,hd[maxn],n,m,ans=0,v[maxn];
int to[maxn<<1],ne[maxn<<1],cnt,col[maxn],mx[maxn],dc;
bool ban[maxn<<1];

inline void add(int x,int y)
{
	to[++num]=y;
	ne[num]=hd[x];
	hd[x]=num;
}

inline void tarjan(int x,int fa)
{
	dfn[x]=low[x]=++dc;
	for(int i=hd[x];i;i=ne[i])
	{
		if(to[i]==fa) continue;
		if(!dfn[to[i]])
		{
			tarjan(to[i],x);
			low[x]=min(low[x],low[to[i]]);
			if(low[to[i]]>dfn[x]) ban[i]=ban[i^1]=1;
		}
		else low[x]=min(low[x],dfn[to[i]]);
	}
}

inline void B(int x)
{
	col[x]=cnt;
	for(int i=hd[x];i;i=ne[i])
	{
		if(ban[i])
		{
			if(col[to[i]]&&v[to[i]]!=cnt)
			{
				v[to[i]]=cnt;
				g[cnt].push_back(col[to[i]]);
				g[col[to[i]]].push_back(cnt);
			}
		}
		else if(!col[to[i]]) B(to[i]);
	}
}

inline void dfs(int x,int fa)
{
	for(int i=0;i<g[x].size();i++)
	{
		int v=g[x][i];
		if(v==fa) continue;
		dfs(v,x);
		ans=max(ans,mx[v]+1+mx[x]);
		mx[x]=max(mx[x],mx[v]+1);
	}
}

int main()
{
	n=read(); m=read();
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		add(u,v); add(v,u);
	}
	tarjan(1,0);
	for(int i=1;i<=n;i++) if(!col[i]) cnt++,B(i);
	dfs(1,0);
	printf("%d\n",ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#define ll long long
#define maxn 200005
#define re register
#define inf 1e9
#define eps 1e-10
using namespace std;

inline int read()
{
	int x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}

vector <int> g[maxn];
int dfn[maxn],low[maxn],num=1,hd[maxn],n,m,ans=0,v[maxn];
int to[maxn<<1],ne[maxn<<1],cnt,col[maxn],mx[maxn],dc;
bool ban[maxn<<1];

inline void add(int x,int y)
{
	to[++num]=y;
	ne[num]=hd[x];
	hd[x]=num;
}

inline void tarjan(int x,int fa)
{
	dfn[x]=low[x]=++dc;
	for(re int i=hd[x];i;i=ne[i])
	{
		if(to[i]==fa) continue;
		if(!dfn[to[i]])
		{
			tarjan(to[i],x);
			low[x]=min(low[x],low[to[i]]);
			if(low[to[i]]>dfn[x]) ban[i]=ban[i^1]=1;
		}
		else low[x]=min(low[x],dfn[to[i]]);
	}
}

inline void B(int x)
{
	col[x]=cnt;
	for(re int i=hd[x];i;i=ne[i])
	{
		if(ban[i])
		{
			if(col[to[i]]&&v[to[i]]!=cnt)
			{
				v[to[i]]=cnt;
				g[cnt].push_back(col[to[i]]);
				g[col[to[i]]].push_back(cnt);
			}
		}
		else if(!col[to[i]]) B(to[i]);
	}
}

inline void dfs(int x,int fa)
{
	for(re int i=0;i<g[x].size();i++)
	{
		int v=g[x][i];
		if(v==fa) continue;
		dfs(v,x);
		ans=max(ans,mx[v]+1+mx[x]);
		mx[x]=max(mx[x],mx[v]+1);
	}
}

int main()
{
	n=read(); m=read();
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		add(u,v); add(v,u);
	}
	tarjan(1,0);
	for(int i=1;i<=n;i++) if(!col[i]) cnt++,B(i);
	dfs(1,0);
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <vector>
#define grdef for (int z=1;z<=m;z++)	scanf ("%d %d", &a, &b), tab[a].push_back(b), tab[b].push_back(a), ij[a]++, ij[b]++
using namespace std;
const int C=300001;

vector <vector <int> > tab(C);
int ij[C], a, b, n, m, low[C], pre[C], s[C], par[C], ip=2, is, dv[2][C], x, maks=0;
bool check[C];

int main(){
	scanf ("%d %d", &n, &m);
	grdef;

	s[0]=1, low[1]=1, pre[1]=1, is=1, check[1]=1;
	while (is>0){
		a=s[is-1];
		if (ij[a]>0&&check[tab[a][ij[a]-1]]==1){
			if (tab[a][ij[a]-1]!=par[a])	low[a]=min(low[a], low[tab[a][ij[a]-1]]);
			ij[a]--;
		}
		else if (ij[a]>0)	s[is]=tab[a][ij[a]-1], par[s[is]]=a, pre[s[is]]=low[s[is]]=ip, check[s[is]]=1, ip++, ij[a]--, is++;
		else {
			low[par[a]]=min(low[par[a]], low[a]);
			if (low[a]==pre[a])	x=1;
			else x=0;

			if (dv[0][a]+x>dv[0][par[a]])		dv[1][par[a]]=dv[0][par[a]], dv[0][par[a]]=dv[0][a]+x;
			else if (dv[0][a]+x>dv[1][par[a]])	dv[1][par[a]]=dv[0][a]+x;

			is--;
		}
	}

	for (int z=1;z<=n;z++)	if (dv[0][z]+dv[1][z]>maks)	maks=dv[0][z]+dv[1][z];
	printf ("%d\n", maks);

return 0;}


#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <iomanip>
#include <string>
#include <string.h>
#include <deque>
#include <queue>
#include <stack>

using namespace std;

#define For(i, s, n) for (int i = s; i <= n; ++i)
#define ForD(i, s, n) for (int i = s; i >= n; --i)
#define ForV(i, n) for (int i = 0; i < (int)n; ++i)
#define pb push_back
#define ms(a, x) memset(a, x, sizeof(a))
#define sz(a) ((int)(a).size())
#define ii pair<int, int>
#define fi first
#define se second

typedef long long ll;

const int N = 3 * (1e5 + 5), LIMIT = 1e9 + 7;

vector <int> a[N], g[N];
ii bridge[N];
int par[N], num[N], low[N];
int n, m, cedge = 0, s, cnt = 0;

void Read()
{
    //freopen("1000E.INP", "r", stdin);
    //freopen("1000E.OUT", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    cin >> n >> m;
    For (i, 1, m)
    {
        int u, v;
        cin >> u >> v;
        a[u].pb(v);
        a[v].pb(u);
    }
}

void Init()
{
    For (i, 1, n)
    {
        par[i] = 0;
    }
}

int Find(int x)
{
    while (par[x] > 0)
    {
        x = par[x];
    }
    return x;
}

void Union(int u, int v)
{
    int x = Find(u), y = Find(v);
    if (x == y)
        return;
    if (par[x] > par[y])
    {
        par[y] += par[x];
        par[x] = y;
    }
    else
    {
        par[x] += par[y];
        par[y] = x;
    }
}

void Dfs(int u, int p)
{
    ++cnt;
    num[u] = cnt;
    low[u] = num[u];
    ForV (i, a[u].size())
    {
        int v = a[u][i];
        if (v != p)
        {
            if (num[v] == 0)
            {
                 Dfs(v, u);
                 low[u] = min(low[u], low[v]);
                 if (low[v] >= num[v])
                 {
                     ++cedge;
                     bridge[cedge] = ii(u, v);
                 }
                 else
                 {
                     Union(u, v);
                 }
            }
            else
            {
                low[u] = min(low[u], num[v]);
            }
        }
    }
}

void Process()
{
    For (i, 1, n)
    {
        Dfs(1, 1);
    }
}

void Build()
{
    s = Find(bridge[1].fi);
    For (i, 1, cedge)
    {
        int u = Find(bridge[i].fi), v = Find(bridge[i].se);
        g[u].pb(v);
        g[v].pb(u);
    }
}

ii Bfs(int x)
{
    int d[N];
    int u, v;
    For (i, 1, n)
    {
         d[i] = n + 1;
    }
    d[x] = 0;
    queue <int> q;
    q.push(x);
    while (!q.empty())
    {
        u = q.front();
        q.pop();
        ForV (i, sz(g[u]))
        {
            v = g[u][i];
            if (d[v] > d[u] + 1)
            {
                d[v] = d[u] + 1;
                q.push(v);
            }
        }
    }
    return ii(u, d[u]);
}

void Print()
{
    ii p1 = Bfs(s), p2 = Bfs(p1.fi);
    cout << p2.se;
}

int main()
{
    Read();
    Init();
    Process();
    Build();
    Print();
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
using namespace std;
#define MAXN 300100
struct node {
	int v;
	node *nnext;
};
int n,m;
struct graph {
	node pool[MAXN*2],*h[MAXN*2];
	int cnt;
	int bcnt,ind;
	stack<int> s;
	inline void addedge(int u,int v) {
		node *p=&pool[++cnt];
		p->v=v,p->nnext=h[u],h[u]=p;
		node *q=&pool[++cnt];
		q->v=u,q->nnext=h[v],h[v]=q;
	}
	int fa[MAXN],low[MAXN],dfn[MAXN],belong[MAXN];
	inline void tarjan(int u) {
		low[u]=dfn[u]=++ind;
		s.push(u); //!
		int v;
		for(node *p=h[u]; p; p=p->nnext) {
			v=p->v;
			if(!dfn[v]) {
				fa[v]=u;
				tarjan(v);
				low[u]=min(low[u],low[v]);
			} else if(v!=fa[u])
				low[u]=min(low[u],dfn[v]);
		}
		if(low[u]==dfn[u]) {
			bcnt++;
			int j;
			do {
				j=s.top();
				s.pop();
				belong[j]=bcnt;
			} while(j!=u);
		}
	}
	int dis[MAXN],vis[MAXN],pre[MAXN];
	int que[MAXN*4];
	inline void bfs(int x) {
		int head=0,tail=1,u,v;
		memset(dis,63,sizeof(dis));
		memset(vis,0,sizeof(vis));
		que[head]=x,dis[x]=0;
		while(head!=tail) {
			u=que[head];
			head++;
			for(node *p=h[u]; p; p=p->nnext) {
				v=p->v;
				if(dis[v] > dis[u]+1) {
					dis[v]=dis[u]+1;
					pre[v]=u;
					if(!vis[v]) {
						vis[v]=true;
						que[tail++]=v;
					}
				}
			}
			vis[u]=false;
		}
	}
} G1,G2;
map<pair<int,int> ,bool> cnt;
int x[MAXN],y[MAXN];
int main() {
	int st1,st2;
	scanf("%d%d",&n,&m);
	for(int i=1; i<=m; i++) {
		scanf("%d%d",&x[i],&y[i]);
		G1.addedge(x[i],y[i]);
	}
	for(int i=1; i<=n; i++)
		if(!G1.dfn[i])
			G1.tarjan(i);
	for(int i=1; i<=m; i++) {
		if(!cnt[(pair<int,int >) {
		G1.belong[x[i]], G1.belong[y[i]]
		}]) {
			G2.addedge(G1.belong[x[i]],G1.belong[y[i]]);
			cnt[(pair<int,int >) {
				G1.belong[x[i]],G1.belong[y[i]]
			}]=true;
		}
	}
	G2.bfs(1);
	st1=1;
	for(int i=1; i<=G1.bcnt; i++)if(G2.dis[st1] < G2.dis[i])st1=i;
	G2.bfs(st1);
	st2=st1;
	for(int i=1; i<=G1.bcnt; i++)if(G2.dis[st2] < G2.dis[i])st2=i;
	int ans=0;
	while(st2!=st1) {
		ans++;
		st2=G2.pre[st2];
	}
	printf("%d\n",ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <algorithm>

using namespace std;

struct EDGE{
    int v,next;
}edge[666666];

int first[333333], low[333333], dfn[333333];
int belong[333333], sta[333333], instack[333333];
int g, cnt, top, scc;
int G[333333], E[333333];
int nex[666666 << 1], t[666666 << 1];
int s[333333], d[333333];
bool vis[333333];
int r = 0, l;
int n, m;

void AddEdge(int u,int v){
    edge[g].v = v;
    edge[g].next = first[u];
    first[u] = g++;
}

void Tarjan(int u,int fa){
    low[u] = dfn[u] = ++cnt;
    sta[++top] = u;
    instack[u] = 1;
    for (int i = first[u]; i != -1; i = edge[i].next){
        int v = edge[i].v;
        if (i == (fa^1))continue;
        if (!dfn[v]){
            Tarjan(v,i);
            low[u] = min(low[u], low[v]);
        }
        else if (instack[v])
			low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u]){
        scc++;
        while(1){
            int v = sta[top--];
            instack[v] = 0;
            belong[v] = scc;
            if (v==u) break;
        }
    }
}

int main(){
    scanf("%d%d", &n, &m);
    g = cnt = top = scc = 0;
    memset(first, -1, sizeof first );
    for (int i = 0; i < m ; i++){
    	int u, v;
        scanf("%d%d", &u, &v);
        AddEdge(u, v); AddEdge(v, u);
    }
    for(int i = 1; i <= n; i++)
        if (!dfn[i])
            Tarjan(1, -1);
    for(int i = 1; i <= n; i++)
    {
        for(int j = first[i]; j != -1; j = edge[j].next)
        {
            int v = edge[j].v;
            if (belong[i] != belong[v]){
            	//printf("%d %d\n", belong[i], belong[v]);
            	t[++r] = belong[v];
            	if (!G[belong[i]]) G[belong[i]] = E[belong[i]] = r;
            	else nex[E[belong[i]]] = r, E[belong[i]] = r;
            	t[++r] = belong[i];
            	if (!G[belong[v]]) G[belong[v]] = E[belong[v]] = r;
            	else nex[E[belong[v]]] = r, E[belong[v]] = r;
			}
        }
    }
    memset(vis, 0, sizeof vis);
    l = r = 1; s[1] = 1; d[1] = 0; vis[1] = true;
    for (;l <= r; ++l){
    	for (int u = G[s[l]]; u; u = nex[u]){
    		if (!vis[t[u]]){
    			vis[t[u]] = true;
    			d[t[u]] = d[s[l]] + 1;
    			s[++r] = t[u];
			}
		}
	}
	int tar = 1;
	for (int i = 1; i <= n; ++i)
		if (d[belong[i]] > d[tar]){
			tar = belong[i];
		}
	memset(vis, 0, sizeof vis);
	memset(d, 0, sizeof d);
	l = r = 1; s[1] = tar; vis[tar] = true;
	for (;l <= r; ++l){
    	for (int u = G[s[l]]; u; u = nex[u]){
    		if (!vis[t[u]]){
    			vis[t[u]] = true;
    			d[t[u]] = d[s[l]] + 1;
    			s[++r] = t[u];
			}
		}
	}
	for (int i = 1; i <= n; ++i)
		if (d[belong[i]] > d[tar]){
			tar = belong[i];
		}
	printf("%d\n", d[tar]);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <algorithm>

using namespace std;

struct EDGE{
    int v,next;
}edge[666666];

int first[333333], low[333333], dfn[333333];
int belong[333333], sta[333333], instack[333333];
int g, cnt, top, scc;
int G[333333], E[333333];
int nex[666666], t[666666];
int s[333333], d[333333];
bool vis[333333];
int r = 0, l;
int n, m;

void AddEdge(int u,int v){
    edge[g].v = v;
    edge[g].next = first[u];
    first[u] = g++;
}

void Tarjan(int u,int fa){
    low[u] = dfn[u] = ++cnt;
    sta[++top] = u;
    instack[u] = 1;
    for (int i = first[u]; i != -1; i = edge[i].next){
        int v = edge[i].v;
        if (i == (fa^1))continue;
        if (!dfn[v]){
            Tarjan(v,i);
            low[u] = min(low[u], low[v]);
        }
        else if (instack[v])
			low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u]){
        scc++;
        while(1){
            int v = sta[top--];
            instack[v] = 0;
            belong[v] = scc;
            if (v==u) break;
        }
    }
}

int main(){
    scanf("%d%d", &n, &m);
    g = cnt = top = scc = 0;
    memset(first, -1, sizeof first );
    for (int i = 0; i < m ; i++){
    	int u, v;
        scanf("%d%d", &u, &v);
        AddEdge(u, v); AddEdge(v, u);
    }
    for(int i = 1; i <= n; i++)
        if (!dfn[i])
            Tarjan(1, -1);
    for(int i = 1; i <= n; i++)
    {
        for(int j = first[i]; j != -1; j = edge[j].next)
        {
            int v = edge[j].v;
            if (belong[i] != belong[v]){
            	//printf("%d %d\n", belong[i], belong[v]);
            	t[++r] = belong[v];
            	if (!G[belong[i]]) G[belong[i]] = E[belong[i]] = r;
            	else nex[E[belong[i]]] = r, E[belong[i]] = r;
            	t[++r] = belong[i];
            	if (!G[belong[v]]) G[belong[v]] = E[belong[v]] = r;
            	else nex[E[belong[v]]] = r, E[belong[v]] = r;
			}
        }
    }
    memset(vis, 0, sizeof vis);
    l = r = 1; s[1] = 1; d[1] = 0; vis[1] = true;
    for (;l <= r; ++l){
    	for (int u = G[s[l]]; u; u = nex[u]){
    		if (!vis[t[u]]){
    			vis[t[u]] = true;
    			d[t[u]] = d[s[l]] + 1;
    			s[++r] = t[u];
			}
		}
	}
	int tar = 1;
	for (int i = 1; i <= n; ++i)
		if (d[belong[i]] > d[tar]){
			tar = belong[i];
		}
	memset(vis, 0, sizeof vis);
	memset(d, 0, sizeof d);
	l = r = 1; s[1] = tar; vis[tar] = true;
	for (;l <= r; ++l){
    	for (int u = G[s[l]]; u; u = nex[u]){
    		if (!vis[t[u]]){
    			vis[t[u]] = true;
    			d[t[u]] = d[s[l]] + 1;
    			s[++r] = t[u];
			}
		}
	}
	for (int i = 1; i <= n; ++i)
		if (d[belong[i]] > d[tar]){
			tar = belong[i];
		}
	printf("%d\n", d[tar]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn=2000005;
struct Edge{ int u,v; };
vector<Edge> edges; vector<int> G[maxn], g[maxn];
int n, m ;
void Addedge(int a,int b){
	edges.push_back((Edge){a,b}); edges.push_back((Edge){b,a});
	int m=edges.size(); G[a].push_back(m-2);G[b].push_back(m-1);
}
int dfs_clock, low[maxn], pre[maxn], q[maxn], fron, scc_cnt, scc[maxn];
int dfs(int u,int fa){
	int lowu=pre[u]=++dfs_clock;
	q[++fron]=u;
	for(int i=0;i<G[u].size();i++){
		int v=edges[G[u][i]].v, lowv;
		if(u==fa) continue;
		if(!pre[v]){
			lowv=dfs(v,u); lowu=min(lowu,lowv);
		//	if(lowv>=pre[u]){ ok[G[u][i]]=1; ok[G[u][i]^1]=1;}
		}
		else{
			if(pre[v]<pre[u] && v!=fa) lowu=min(lowu,pre[v]);
		}
	}
	low[u]=lowu;
	if(pre[u]==low[u]){
		scc_cnt++;
		for(;;){
			int x=q[fron--]; scc[x]=scc_cnt;
			if(x==u) break;
		}
	}
	return lowu;
}
queue<int> que;
int dis[maxn], inq[maxn];
//void spfa(int s){
//	memset(dis,-1,sizeof(dis)); memset(inq,0,sizeof(inq));
//	que.push(s); inq[s]=1; dis[s]=0;
//	while(!que.empty()){
//		int u=que.front(); que.pop();
//		for(int i=0;i<g[u].size();i++){
//			int v=g[u][i];
//			if(dis[v]<dis[u]+1){
//				dis[v]=dis[u]+1;
//				if(!inq[v]) que.push(v), inq[v]=1;
//			}
//		}
//	}
//}
void dist(int x,int f){
	dis[x]=dis[f]+1;
	for(int i=0;i<g[x].size();i++){

		int v=g[x][i]; if(v==f) continue;//printf("============  %d\n",v);
		dist(v,x);
	}
}
int main(){
	scanf("%d%d",&n,&m);
	int x,y;
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x,&y); Addedge(x,y);
	}
	dfs(1,-1);
	for(int i=0;i<edges.size();i++){
		Edge e=edges[i];
	//	printf("---------  %d  %d\n",scc[e.u],scc[e.v]);
		if(scc[e.u]!=scc[e.v]) g[scc[e.u]].push_back(scc[e.v]);
	}
	dist(1,0);int mx=0,mp=0;
	for(int i=1;i<=scc_cnt;i++){
		if(dis[i]>mx) mx=dis[i],mp=i;
	}
	memset(dis,0,sizeof(dis));
	dist(mp,0); mx=0;
	for(int i=1;i<=scc_cnt;i++) mx=max(mx,dis[i]);
	printf("%d\n",mx-1);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn=2000005;
struct Edge{ int u,v; };
vector<Edge> edges; vector<int> G[maxn], g[maxn];
int n, m ;
void Addedge(int a,int b){
	edges.push_back((Edge){a,b}); edges.push_back((Edge){b,a});
	int m=edges.size(); G[a].push_back(m-2);G[b].push_back(m-1);
}
int dfs_clock, low[maxn], pre[maxn], q[maxn], fron, scc_cnt, scc[maxn];
int dfs(int u,int fa){
	int lowu=pre[u]=++dfs_clock;
	q[++fron]=u;
	for(int i=0;i<G[u].size();i++){
		int v=edges[G[u][i]].v, lowv;
		if(u==fa) continue;
		if(!pre[v]){
			lowv=dfs(v,u); lowu=min(lowu,lowv);
		//	if(lowv>=pre[u]){ ok[G[u][i]]=1; ok[G[u][i]^1]=1;}
		}
		else{
			if(pre[v]<pre[u] && v!=fa) lowu=min(lowu,pre[v]);
		}
	}
	low[u]=lowu;
	if(pre[u]==low[u]){
		scc_cnt++;
		for(;;){
			int x=q[fron--]; scc[x]=scc_cnt;
			if(x==u) break;
		}
	}
	return lowu;
}
queue<int> que;
int dis[maxn], inq[maxn];
void spfa(int s){
	memset(dis,-1,sizeof(dis)); memset(inq,0,sizeof(inq));
	que.push(s); inq[s]=1; dis[s]=0;
	while(!que.empty()){
		int u=que.front(); que.pop();
		for(int i=0;i<g[u].size();i++){
			int v=g[u][i];
			if(dis[v]<dis[u]+1){
				dis[v]=dis[u]+1;
				if(!inq[v]) que.push(v), inq[v]=1;
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	int x,y;
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x,&y); Addedge(x,y);
	}
	dfs(1,-1);
	for(int i=0;i<edges.size();i++){
		Edge e=edges[i];
		if(scc[e.u]!=scc[e.v]) g[scc[e.u]].push_back(scc[e.v]);
	}
	spfa(1);int mx=0,mp=0;
	for(int i=1;i<=scc_cnt;i++){
		if(dis[i]>mx) mx=dis[i],mp=i;
	//	printf("=========  %d %d\n",i,dis[i]);
	}
	spfa(mp); mx=0;
	for(int i=1;i<=scc_cnt;i++) mx=max(mx,dis[i]);
	printf("%d\n",mx);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn=6000005;
struct Edge{ int u,v; };
vector<Edge> edges; vector<int> G[maxn], g[maxn];
int n, m ;
void Addedge(int a,int b){
	edges.push_back((Edge){a,b}); edges.push_back((Edge){b,a});
	int m=edges.size(); G[a].push_back(m-2);G[b].push_back(m-1);
}
int dfs_clock, low[maxn], pre[maxn], q[maxn], fron, scc_cnt, scc[maxn];
int dfs(int u,int fa){
	int lowu=pre[u]=++dfs_clock;
	q[++fron]=u;
	for(int i=0;i<G[u].size();i++){
		int v=edges[G[u][i]].v, lowv;
		if(u==fa) continue;
		if(!pre[v]){
			lowv=dfs(v,u); lowu=min(lowu,lowv);
		//	if(lowv>=pre[u]){ ok[G[u][i]]=1; ok[G[u][i]^1]=1;}
		}
		else{
			if(pre[v]<pre[u] && v!=fa) lowu=min(lowu,pre[v]);
		}
	}
	low[u]=lowu;
	if(pre[u]==low[u]){
		scc_cnt++;
		for(;;){
			int x=q[fron--]; scc[x]=scc_cnt;
			if(x==u) break;
		}
	}
	return lowu;
}
queue<int> que;
int dis[maxn], inq[maxn];
void spfa(int s){
	memset(dis,-1,sizeof(dis)); memset(inq,0,sizeof(inq));
	que.push(s); inq[s]=1; dis[s]=0;
	while(!que.empty()){
		int u=que.front(); que.pop();
		for(int i=0;i<g[u].size();i++){
			int v=g[u][i];
			if(dis[v]<dis[u]+1){
				dis[v]=dis[u]+1;
				if(!inq[v]) que.push(v), inq[v]=1;
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	int x,y;
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x,&y); Addedge(x,y);
	}
	dfs(1,-1);
	for(int i=0;i<edges.size();i++){
		Edge e=edges[i];
		if(scc[e.u]!=scc[e.v]) g[scc[e.u]].push_back(scc[e.v]);
	}
	spfa(1);int mx=0,mp=0;
	for(int i=1;i<=scc_cnt;i++){
		if(dis[i]>mx) mx=dis[i],mp=i;
	//	printf("=========  %d %d\n",i,dis[i]);
	}
	spfa(mp); mx=0;
	for(int i=1;i<=scc_cnt;i++) mx=max(mx,dis[i]);
	printf("%d\n",mx);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn=600005;
struct Edge{ int u,v; };
vector<Edge> edges; vector<int> G[maxn], g[maxn];
int n, m ;
void Addedge(int a,int b){
	edges.push_back((Edge){a,b}); edges.push_back((Edge){b,a});
	int m=edges.size(); G[a].push_back(m-2);G[b].push_back(m-1);
}
int dfs_clock, low[maxn], pre[maxn], q[maxn], fron, scc_cnt, scc[maxn];
int dfs(int u,int fa){
	int lowu=pre[u]=++dfs_clock;
	q[++fron]=u;
	for(int i=0;i<G[u].size();i++){
		int v=edges[G[u][i]].v, lowv;
		if(u==fa) continue;
		if(!pre[v]){
			lowv=dfs(v,u); lowu=min(lowu,lowv);
		//	if(lowv>=pre[u]){ ok[G[u][i]]=1; ok[G[u][i]^1]=1;}
		}
		else{
			if(pre[v]<pre[u] && v!=fa) lowu=min(lowu,pre[v]);
		}
	}
	low[u]=lowu;
	if(pre[u]==low[u]){
		scc_cnt++;
		for(;;){
			int x=q[fron--]; scc[x]=scc_cnt;
			if(x==u) break;
		}
	}
	return lowu;
}
queue<int> que;
int dis[maxn], inq[maxn];
void spfa(int s){
	memset(dis,-1,sizeof(dis)); memset(inq,0,sizeof(inq));
	que.push(s); inq[s]=1; dis[s]=0;
	while(!que.empty()){
		int u=que.front(); que.pop();
		for(int i=0;i<g[u].size();i++){
			int v=g[u][i];
			if(dis[v]<dis[u]+1){
				dis[v]=dis[u]+1;
				if(!inq[v]) que.push(v), inq[v]=1;
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	int x,y;
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x,&y); Addedge(x,y);
	}
	dfs(1,-1);
	for(int i=0;i<edges.size();i++){
		Edge e=edges[i];
		if(scc[e.u]!=scc[e.v]) g[scc[e.u]].push_back(scc[e.v]);
	}
	spfa(1);int mx=0,mp=0;
	for(int i=1;i<=scc_cnt;i++){
		if(dis[i]>mx) mx=dis[i],mp=i;
	//	printf("=========  %d %d\n",i,dis[i]);
	}
	spfa(mp); mx=0;
	for(int i=1;i<=scc_cnt;i++) mx=max(mx,dis[i]);
	printf("%d\n",mx);
	return 0;
}


# include<bits/stdc++.h>
using namespace std;
const int MAX=3e5+1;
struct p{
int x,y;
}c[MAX<<1],cc[MAX<<1],ccc[MAX<<1];
int n,m,num=1,num1,cnt,ans,maxn,ss;
int h[MAX],hh[MAX],col[MAX],dfn[MAX],low[MAX],d[MAX];
bool use[MAX];
stack<int> st;
void add(int x,int y) {
	c[++num]=(p){h[x],y},h[x]=num;
	c[++num]=(p){h[y],x},h[y]=num;
}
void Add(int x,int y) {
	ccc[++num1]=(p){hh[x],y},hh[x]=num1;
	ccc[++num1]=(p){hh[y],x},hh[y]=num1;
}
void tarjan(int x,int id) {
	dfn[x]=low[x]=++cnt,use[x]=1;
	st.push(x);
	for(int i=h[x];i;i=c[i].x)
	  if(!dfn[c[i].y]) tarjan(c[i].y,i),low[x]=min(low[x],low[c[i].y]);
	  else if(i!=(id^1)) low[x]=min(low[x],dfn[c[i].y]);
	if(low[x]==dfn[x])
	{
		int tt=-1;
		++ans;
		while(tt!=x)
		tt=st.top(),st.pop(),use[tt]=0,col[tt]=ans;
	}
}
void dfs(int x,int f) {
	if(maxn<(d[x]=d[f]+1)) maxn=d[x],ss=x;
	for(int i=hh[x];i;i=ccc[i].x)
	  if(ccc[i].y!=f) dfs(ccc[i].y,x);
}
int work() {
	int s=1,Max=0;
	while(1)
	{
		memset(d,0,sizeof(d));
		maxn=0,ss=0;
		dfs(s,0);
		if(maxn<=Max) return Max-1;
		Max=maxn,s=ss;
	}
}
int main()
{
    cin>>n>>m;
	for(int i=1;i<=m;++i)
	  {
        cin>>cc[i].x>>cc[i].y;
	  	add(cc[i].x,cc[i].y);
	  }
	for(int i=1;i<=n;++i)
	  if(!dfn[i]) tarjan(i,0);
	for(int i=1;i<=m;++i)
	  if(col[cc[i].x]!=col[cc[i].y]) Add(col[cc[i].x],col[cc[i].y]);
	cout<<work()<<endl;
	return 0;
}


#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#define mp make_pair
#define N 300010
vector<int>G[N];
int n,m,low[N],dfn[N];
bool is_cut[N];
int father[N];
int tim=0;
void input()
{
    scanf("%d%d",&n,&m);
    int a,b;
    for(int i=1;i<=m;++i)
    {
        scanf("%d%d",&a,&b);
        G[a].push_back(b);/*�ڽӱ��������*/
        G[b].push_back(a);
    }
}
void Tarjan(int i,int Father)
{
    father[i]=Father;/*��¼ÿһ����ĸ���*/
    dfn[i]=low[i]=tim++;
    for(int j=0;j<G[i].size();++j)
    {
        int k=G[i][j];
        if(dfn[k]==-1)
        {
            Tarjan(k,i);
            low[i]=min(low[i],low[k]);
        }
        else if(Father!=k)/*����k��i�ĸ��׵Ļ�����ô�����������е��رߣ����ر���ôһ��������*/
            low[i]=min(low[i],dfn[k]);//dfn[k]���ܣ�=low[k]�����Բ�����low[k]����dfn[k],������Ϸ���ͷ�ˡ�
    }
}
map<pair<int,int>,int>mm;
void count()
{
    int rootson=0;
    Tarjan(1,0);
    for(int i=2;i<=n;++i)
    {
        int v=father[i];
        if(v==1)
        rootson++;/*ͳ�Ƹ��ڵ������ĸ��������ڵ����������>=2,���Ǹ��*/
        else{
            if(low[i]>=dfn[v])/*��������*/
            is_cut[v]=true;
        }
    }
    if(rootson>1)
    is_cut[1]=true;
//    for(int i=1;i<=n;++i)
//    if(is_cut[i])
//    printf("%d\n",i);
    for(int i=1;i<=n;++i)
    {
        int v=father[i];
        if(v>0&&low[i]>dfn[v]){
			mm[mp(v,i)]=1;
//        	printf("%d,%d\n",v,i);
		}/*�ŵ�����*/
    }

}

int fi[N],belong[N],cnt;
int find(int x){
	return ((fi[x]<0)?x:(fi[x]=find(fi[x])));
}
void join(int x,int y){
	int fx=find(x),fy=find(y);
	if(fx==fy) return;
	fi[fy]+=fi[fx];fi[fx]=fy;
}
vector<int>g[N];
int q[N],head,tail,dep[N];
void bfs(int op){
	memset(dep,-1,sizeof(dep));
	int i,j;head=0,tail=1;dep[op]=0;
	q[0]=op;
	while(head<tail){
		i=q[head++];
		for(j=0;j<g[i].size();j++){
			if(~dep[g[i][j]]) continue;
			dep[g[i][j]]=dep[i]+1;
			q[tail++]=g[i][j];
		}
	}
}
int main()
{
    input();
    memset(dfn,-1,sizeof(dfn));
    memset(father,0,sizeof(father));
    memset(low,-1,sizeof(low));
    memset(is_cut,false,sizeof(is_cut));
    count();
    int i,j;
    for(i=1;i<=n;i++) fi[i]=-1;
    for(i=1;i<=n;i++){
    	for(j=0;j<G[i].size();j++){
    		if(mm[mp(i,G[i][j])]||mm[mp(G[i][j],i)]) continue;
//    		cout<<"get non cut "<<i<<' '<<G[i][j]<<'\n';
    		join(i,G[i][j]);
		}
	}
    for(i=1;i<=n;i++){
    	if(fi[i]<0) belong[i]=++cnt;
	}
    for(i=1;i<=n;i++){
    	for(j=0;j<G[i].size();j++){
    		if(mm[mp(i,G[i][j])]||mm[mp(G[i][j],i)]){
    			int ff1=find(i),ff2=find(G[i][j]);
    			g[belong[ff1]].push_back(belong[ff2]);
    			g[belong[ff2]].push_back(belong[ff1]);
			}
		}
	}
	bfs(1);
	int dd=0,tmp;
	for(i=1;i<=cnt;i++){
		if(dd<dep[i]) dd=dep[i],tmp=i;
	}
	bfs(tmp);dd=0;
	for(i=1;i<=cnt;i++) dd=max(dd,dep[i]);
	cout<<dd;
    return 0;
}


#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#define mp make_pair
#define N 300010
vector<int>G[N];
int n,m,low[N],dfn[N];
bool is_cut[N];
int father[N];
int tim=0;
void input()
{
    scanf("%d%d",&n,&m);
    int a,b;
    for(int i=1;i<=m;++i)
    {
        scanf("%d%d",&a,&b);
        G[a].push_back(b);/*�ڽӱ��������*/
        G[b].push_back(a);
    }
}
void Tarjan(int i,int Father)
{
    father[i]=Father;/*��¼ÿһ����ĸ���*/
    dfn[i]=low[i]=tim++;
    for(int j=0;j<G[i].size();++j)
    {
        int k=G[i][j];
        if(dfn[k]==-1)
        {
            Tarjan(k,i);
            low[i]=min(low[i],low[k]);
        }
        else if(Father!=k)/*����k��i�ĸ��׵Ļ�����ô�����������е��رߣ����ر���ôһ��������*/
            low[i]=min(low[i],dfn[k]);//dfn[k]���ܣ�=low[k]�����Բ�����low[k]����dfn[k],������Ϸ���ͷ�ˡ�
    }
}
map<pair<int,int>,int>mm;
void count()
{
    int rootson=0;
    Tarjan(1,0);
    for(int i=2;i<=n;++i)
    {
        int v=father[i];
        if(v==1)
        rootson++;/*ͳ�Ƹ��ڵ������ĸ��������ڵ����������>=2,���Ǹ��*/
        else{
            if(low[i]>=dfn[v])/*��������*/
            is_cut[v]=true;
        }
    }
    if(rootson>1)
    is_cut[1]=true;
//    for(int i=1;i<=n;++i)
//    if(is_cut[i])
//    printf("%d\n",i);
    for(int i=1;i<=n;++i)
    {
        int v=father[i];
        if(v>0&&low[i]>dfn[v]){
			mm[mp(v,i)]=1;
//        	printf("%d,%d\n",v,i);
		}/*�ŵ�����*/
    }

}

int fi[N],belong[N],cnt;
int find(int x){
	return ((fi[x]<0)?x:(fi[x]=find(fi[x])));
}
void join(int x,int y){
	int fx=find(x),fy=find(y);
	if(fx==fy) return;
	fi[fy]+=fi[fx];fi[fx]=fy;
}
vector<int>g[N];
int q[N],head,tail,dep[N];
void bfs(int op){
	memset(dep,-1,sizeof(dep));
	int i,j;head=0,tail=1;dep[op]=0;
	q[0]=op;
	while(head<tail){
		i=q[head++];
		for(j=0;j<g[i].size();j++){
			if(~dep[g[i][j]]) continue;
			dep[g[i][j]]=dep[i]+1;
			q[tail++]=g[i][j];
		}
	}
}
int main()
{
    input();
    memset(dfn,-1,sizeof(dfn));
    memset(father,0,sizeof(father));
    memset(low,-1,sizeof(low));
    memset(is_cut,false,sizeof(is_cut));
    count();
    int i,j;
    for(i=1;i<=n;i++) fi[i]=-1;
    for(i=1;i<=n;i++){
    	for(j=0;j<G[i].size();j++){
    		if(mm[mp(i,G[i][j])]||mm[mp(G[i][j],i)]) continue;
    		cout<<"get non cut "<<i<<' '<<G[i][j]<<'\n';
    		join(i,G[i][j]);
		}
	}
    for(i=1;i<=n;i++){
    	if(fi[i]<0) belong[i]=++cnt;
	}
    for(i=1;i<=n;i++){
    	for(j=0;j<G[i].size();j++){
    		if(mm[mp(i,G[i][j])]||mm[mp(G[i][j],i)]){
    			int ff1=find(i),ff2=find(G[i][j]);
    			g[belong[ff1]].push_back(belong[ff2]);
    			g[belong[ff2]].push_back(belong[ff1]);
			}
		}
	}
	bfs(1);
	int dd=0,tmp;
	for(i=1;i<=cnt;i++){
		if(dd<dep[i]) dd=dep[i],tmp=i;
	}
	bfs(tmp);dd=0;
	for(i=1;i<=cnt;i++) dd=max(dd,dep[i]);
	cout<<dd;
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <vector>
#include <stack>

const int max_n = 3 * 100 * 1000;
int n, d[max_n], low[max_n], pos, dcc[max_n], dcc_n, h[max_n];
std::vector<int> G[max_n], GP[max_n];
std::stack<int> S;

void dfs(int v, int p) {
    d[v] = pos++;
    low[v] = d[v];
    S.push(v);
    for(int i = 0; i < G[v].size(); i++)
        if(!d[G[v][i]])
            dfs(G[v][i], v);
    for(int i = 0; i < G[v].size(); i++)
        if(G[v][i] != p)
            low[v] = std::min(low[v], low[G[v][i]]);
    if(low[v] == d[v]) {
        int tmp;
        do {
            tmp = S.top(); S.pop();
            dcc[tmp] = dcc_n;
        } while(tmp != v);
        dcc_n++;
    }
}

void construct_GP() {
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < G[i].size(); j++)
            if(dcc[i] != dcc[G[i][j]])
                GP[dcc[i]].push_back(dcc[G[i][j]]);
    }
    for(int i = 0; i < n; i++) {
        std::sort(GP[i].begin(), GP[i].end());
        std::vector<int>::iterator it = std::unique(GP[i].begin(), GP[i].end());
        GP[i].erase(it, GP[i].end());
    }
}

void dfs_two(int v, int ch, int p) {
    h[v] = ch;
    for(int i = 0; i < GP[v].size(); i++)
        if(GP[v][i] != p)
            dfs_two(GP[v][i], ch + 1, v);
}

int max_depth(int v, int p) {
    int result = 0;
    for(int i = 0; i < GP[v].size(); i++)
        if(GP[v][i] != p)
            result = std::max(result, max_depth(GP[v][i], v));
    return result + 1;
}

int main() {
    int a, b, m;
    std::scanf("%d%d", &n, &m);
    for(int i = 0; i < m; i++) {
        std::scanf("%d%d", &a, &b);
        G[a - 1].push_back(b - 1);
        G[b - 1].push_back(a - 1);
    }
    dfs(0, -1);
    construct_GP();
    dfs_two(0, 0, -1);
    int lowest = 0;
    for(int i = 0; i < dcc_n; i++)
        if(h[lowest] < h[i])
            lowest = i;
    std::printf("%d\n", max_depth(lowest, -1) - 1);
    return 0;
}


#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;

const int limit=1000000;

void minimize(int &a,int b)
{
  a=min(a,b);
}

void maximize(int &a,int b)
{
  a=max(a,b);
}

int sol;

int n,m;
vector<int> g[limit];
vector<int> a[limit];
int depth[limit];
int depthant[limit];
int seen[limit];
vector<int> lista[limit];
int length[limit];

void precompute(int u,int p,int d)
{
  depth[u]=d;
  seen[u]=1;
  vector<int> &ar=g[u];
  vector<int> &ara=a[u];
  for (int i=0;i<int(ar.size());i++) {
    int v=ar[i];
    if (v!=p and not seen[v]) {
      ara.push_back(v);
      precompute(v,u,d+1);
    }
  }
}

void compute(int u,int p)
{
  depthant[u]=depth[u];
  {
    vector<int> &ar=g[u];
    for (int i=0;i<int(ar.size());i++) {
      int v=ar[i];
      if (v!=p)
	minimize(depthant[u],depth[v]);
    }
  }
  vector<int> &lisu=lista[u];
  int &lenu=length[u];
  {
    vector<int> &ar=a[u];
    for (int i=0;i<int(ar.size());i++) {
      int v=ar[i];
      compute(v,u);
      minimize(depthant[u],depthant[v]);
      if (depth[u]<depthant[v]) {
	lisu.push_back(length[v]+1);
      } else {
	lisu.push_back(length[v]);
      }
    }
  }
  sort(lisu.begin(),lisu.end());
  if (int(lisu.size())) lenu=lisu.back();
  maximize(sol,lenu);
  if (int(lisu.size())>=2)
    maximize(sol,lisu.back()+lisu[int(lisu.size())-2]);
}

int main()
{
  ios::sync_with_stdio(false);
  cin>>n>>m;
  for (int i=0;i<m;i++) {
    int u,v;
    cin>>u>>v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  precompute(1,0,0);
  compute(1,0);
  cout<<sol<<endl;
}


#include<bits/stdc++.h>
using namespace std;
#define RI register int
int read() {
	int q=0;char ch=' ';
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar();
	return q;
}
const int N=300005;
int n,m,cnt,top,tim,ans;
int col[N],st[N],dfn[N],low[N],mx[N];
struct graph{
	int h[N],ne[N<<1],to[N<<1],tot;
	void add(int x,int y) {to[++tot]=y,ne[tot]=h[x],h[x]=tot;}
}G,T;
vector<int> a[N];
void tarjan(int x,int las) {
	low[x]=dfn[x]=++tim,st[++top]=x;
	for(RI i=G.h[x];i;i=G.ne[i]) {
		if(G.to[i]==las) continue;
		if(!dfn[G.to[i]]) tarjan(G.to[i],x),low[x]=min(low[x],low[G.to[i]]);
		else low[x]=min(low[x],dfn[G.to[i]]);
	}
	if(low[x]==dfn[x]) {
		++cnt;
		while(st[top]!=x) col[st[top]]=cnt,--top;
		col[st[top]]=cnt,--top;
	}
}
int dfs(int x,int las) {
	int fir=0,se=0;
	for(RI i=T.h[x];i;i=T.ne[i]) {
		if(T.to[i]==las) continue;
		int kl=dfs(T.to[i],x)+1;
		if(kl>=fir) se=fir,fir=kl;
		else if(kl>se) se=kl;
	}
	ans=max(ans,fir+se);
	return fir;
}
int main()
{
	int x,y;
   	n=read(),m=read();
   	for(RI i=1;i<=m;++i)
   		x=read(),y=read(),G.add(x,y),G.add(y,x);
   	tarjan(1,0);
   	for(RI i=1;i<=n;++i)
   		for(RI j=G.h[i];j;j=G.ne[j])
   			if(col[G.to[j]]!=col[i]) {
   				a[col[i]].push_back(col[G.to[j]]);
   				a[col[G.to[j]]].push_back(col[i]);
   			}
   	for(RI i=1;i<=cnt;++i) {
   		sort(a[i].begin(),a[i].end());
   		for(RI j=0;j<a[i].size();++j)
   			if(j==0||a[i][j]!=a[i][j-1]) T.add(i,a[i][j]);
   	}
   	dfs(1,0),printf("%d\n",ans);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
#define MAXN (300000 + 5)
using namespace std;
struct edg
{
	int from, to, next;
}b[MAXN << 1], bn[MAXN << 1];
int g[MAXN], cntb, gn[MAXN], cntn, n, m, belong[MAXN], dfn[MAXN], low[MAXN], cntdfn, f[MAXN];
bool ins[MAXN];
stack<int> gary;
void tarjan(int dq, int fa)
{
	dfn[dq] = low[dq] = ++cntdfn;
	gary.push(dq), ins[dq] = true;
	int child = 0;
	for (int i = g[dq]; i; i = b[i].next)
		if (!dfn[b[i].to])
		{
			++child;
			tarjan(b[i].to, dq);
			low[dq] = min(low[dq], low[b[i].to]);
		}
		else if (b[i].to != fa)
			low[dq] = min(low[dq], dfn[b[i].to]);
	if (low[dq] == dfn[dq])
	{
		while (!gary.empty() && gary.top() != dq)
			belong[gary.top()] = dq, ins[gary.top()] = false, gary.pop();
		if (!gary.empty())
			gary.pop();
		belong[dq] = dq, ins[dq] = false;
	}
}
void adn(edg* bx, int* gx, int& cntx, int from, int to)
{
	bx[++cntx].next = gx[from];
	bx[cntx].from = from, bx[cntx].to = to;
	gx[from] = cntx;
}
void dfs(int dq, int fa)
{
	if (f[dq])
		return ;
	for (int i = gn[dq]; i; i = bn[i].next)
		if (bn[i].to != fa)
		{
			dfs(bn[i].to, dq);
			f[dq] = max(f[dq], f[bn[i].to] + 1);
		}
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1, srx, sry; i <= m; i++)
	{
		scanf("%d%d", &srx, &sry);
		adn(b, g, cntb, srx, sry);
		adn(b, g, cntb, sry, srx);
	}
	for (int i = 1; i <= n; i++)
		if (!dfn[i])
			tarjan(i, i);
	for (int i = 1; i <= n; i++)
		for (int j = g[i]; j; j = b[j].next)
			if (belong[i] != belong[b[j].to])
			{
				adn(bn, gn, cntn, belong[i], belong[b[j].to]);
				adn(bn, gn, cntn, belong[b[j].to], belong[i]);
			}
	for (int i = 1; i <= n; i++)
		if (!f[belong[i]])
			dfs(belong[i], belong[i]);
	int ans = 0;
	for (int i = 1; i <= n; i++)
		if (ans < f[belong[i]])
			ans = f[belong[i]];
	printf("%d", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
#define MAXN (300000 + 5)
using namespace std;
struct edg
{
	int from, to, next;
}b[MAXN << 1], bn[MAXN << 1];
int g[MAXN], cntb, gn[MAXN], cntn, n, m, belong[MAXN], dfn[MAXN], low[MAXN], cntdfn, f[MAXN];
bool ins[MAXN];
stack<int> gary;
void tarjan(int dq, int fa)
{
	dfn[dq] = low[dq] = ++cntdfn;
	gary.push(dq), ins[dq] = true;
	for (int i = g[dq]; i; i = b[i].next)
		if (!dfn[b[i].to])
		{
			tarjan(b[i].to, dq);
			low[dq] = min(low[dq], low[b[i].to]);
		}
		else if (b[i].to != fa)
			low[dq] = min(low[dq], dfn[b[i].to]);
	if (low[dq] == dfn[dq])
	{
		while (!gary.empty() && gary.top() != dq)
			belong[gary.top()] = dq, ins[gary.top()] = false, gary.pop();
		if (!gary.empty())
			gary.pop();
		belong[dq] = dq, ins[dq] = false;
	}
}
void adn(edg* bx, int* gx, int& cntx, int from, int to)
{
	bx[++cntx].next = gx[from];
	bx[cntx].from = from, bx[cntx].to = to;
	gx[from] = cntx;
}
void dfs(int dq, int fa)
{
	if (f[dq])
		return ;
	for (int i = gn[dq]; i; i = bn[i].next)
		if (bn[i].to != fa)
		{
			dfs(bn[i].to, dq);
			f[dq] = max(f[dq], f[bn[i].to] + 1);
		}
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1, srx, sry; i <= m; i++)
	{
		scanf("%d%d", &srx, &sry);
		adn(b, g, cntb, srx, sry);
		adn(b, g, cntb, sry, srx);
	}
	for (int i = 1; i <= n; i++)
		if (!dfn[i])
			tarjan(i, i);
	for (int i = 1; i <= n; i++)
		for (int j = g[i]; j; j = b[j].next)
			if (belong[i] != belong[b[j].to])
			{
				adn(bn, gn, cntn, belong[i], belong[b[j].to]);
				adn(bn, gn, cntn, belong[b[j].to], belong[i]);
			}
	for (int i = 1; i <= n; i++)
		if (!f[belong[i]])
			dfs(belong[i], belong[i]);
	int ans = 0;
	for (int i = 1; i <= n; i++)
		if (ans < f[belong[i]])
			ans = f[belong[i]];
	printf("%d", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
#define MAXN (300000 + 5)
using namespace std;
struct edg
{
	int from, to, next;
}b[MAXN << 1], bn[MAXN << 1];
int g[MAXN], cntb, gn[MAXN], cntn, n, m, belong[MAXN], dfn[MAXN], low[MAXN], cntdfn, f[MAXN];
bool ins[MAXN];
stack<int> gary;
void tarjan(int dq, int fa)
{
	dfn[dq] = low[dq] = ++cntdfn;
	gary.push(dq), ins[dq] = true;
	int child = 0;
	for (int i = g[dq]; i; i = b[i].next)
		if (!dfn[b[i].to])
		{
			++child;
			tarjan(b[i].to, dq);
			low[dq] = min(low[dq], low[b[i].to]);
		}
		else if (b[i].to != fa)
			low[dq] = min(low[dq], low[b[i].to]);
	if (low[dq] == dfn[dq])
	{
		while (!gary.empty() && gary.top() != dq)
			belong[gary.top()] = dq, ins[gary.top()] = false, gary.pop();
		if (!gary.empty())
			gary.pop();
		belong[dq] = dq, ins[dq] = false;
	}
}
void adn(edg* bx, int* gx, int& cntx, int from, int to)
{
	bx[++cntx].next = gx[from];
	bx[cntx].from = from, bx[cntx].to = to;
	gx[from] = cntx;
}
void dfs(int dq, int fa)
{
	if (f[dq])
		return ;
	for (int i = gn[dq]; i; i = bn[i].next)
		if (bn[i].to != fa)
		{
			dfs(bn[i].to, dq);
			f[dq] = max(f[dq], f[bn[i].to] + 1);
		}
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1, srx, sry; i <= m; i++)
	{
		scanf("%d%d", &srx, &sry);
		adn(b, g, cntb, srx, sry);
		adn(b, g, cntb, sry, srx);
	}
	for (int i = 1; i <= n; i++)
		if (!dfn[i])
			tarjan(i, i);
	for (int i = 1; i <= n; i++)
		for (int j = g[i]; j; j = b[j].next)
			if (belong[i] != belong[b[j].to])
			{
				adn(bn, gn, cntn, belong[i], belong[b[j].to]);
				adn(bn, gn, cntn, belong[b[j].to], belong[i]);
			}
	for (int i = 1; i <= n; i++)
		if (!f[belong[i]])
			dfs(belong[i], belong[i]);
	int ans = 0;
	for (int i = 1; i <= n; i++)
		if (ans < f[belong[i]])
			ans = f[belong[i]];
	printf("%d", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
#define MAXN (300000 + 5)
using namespace std;
struct edg
{
	int from, to, next;
}b[MAXN << 1], bn[MAXN << 1];
int g[MAXN], cntb, gn[MAXN], cntn, n, m, belong[MAXN], dfn[MAXN], low[MAXN], cntdfn, f[MAXN];
bool ins[MAXN];
stack<int> gary;
void tarjan(int dq, int fa)
{
	dfn[dq] = low[dq] = ++cntdfn;
	gary.push(dq);
	for (int i = g[dq]; i; i = b[i].next)
		if (!dfn[b[i].to])
		{
			tarjan(b[i].to, dq);
			low[dq] = min(low[dq], low[b[i].to]);
		}
		else if (b[i].to != fa)
			low[dq] = min(low[dq], low[b[i].to]);
	if (low[dq] == dfn[dq])
	{
		while (!gary.empty() && gary.top() != dq)
			belong[gary.top()] = dq, gary.pop();
		if (!gary.empty())
			gary.pop();
		belong[dq] = dq;
	}
}
void adn(edg* bx, int* gx, int& cntx, int from, int to)
{
	bx[++cntx].next = gx[from];
	bx[cntx].from = from, bx[cntx].to = to;
	gx[from] = cntx;
}
void dfs(int dq, int fa)
{
	if (f[dq])
		return ;
	for (int i = gn[dq]; i; i = bn[i].next)
		if (bn[i].to != fa)
		{
			dfs(bn[i].to, dq);
			f[dq] = max(f[dq], f[bn[i].to] + 1);
		}
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1, srx, sry; i <= m; i++)
	{
		scanf("%d%d", &srx, &sry);
		adn(b, g, cntb, srx, sry);
		adn(b, g, cntb, sry, srx);
	}
	for (int i = 1; i <= n; i++)
		if (!dfn[i])
			tarjan(i, i);
	for (int i = 1; i <= n; i++)
		for (int j = g[i]; j; j = b[j].next)
			if (belong[i] != belong[b[j].to])
			{
				adn(bn, gn, cntn, belong[i], belong[b[j].to]);
				adn(bn, gn, cntn, belong[b[j].to], belong[i]);
			}
	for (int i = 1; i <= n; i++)
		if (!f[belong[i]])
			dfs(belong[i], belong[i]);
	int ans = 0, ansi;
	for (int i = 1; i <= n; i++)
		if (ans < f[belong[i]])
			ans = f[belong[i]], ansi = belong[i];
	memset(f, 0, sizeof(f));
	dfs(ansi, ansi);
	ans = 0;
	for (int i = 1; i <= n; i++)
		ans = max(ans, f[belong[i]]);
	printf("%d", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <set>
#define MAXN (300000 + 5)
using namespace std;
struct edg
{
	int from, to, next;
}b[MAXN << 1], bn[MAXN << 1];
int g[MAXN], cntb, gn[MAXN], cntn, n, m, belong[MAXN], dfn[MAXN], low[MAXN], cntdfn, f[MAXN];
stack<int> gary;
void tarjan(int dq, int fa)
{
	dfn[dq] = low[dq] = ++cntdfn;
	gary.push(dq);
	for (int i = g[dq]; i; i = b[i].next)
		if (!dfn[b[i].to])
		{
			tarjan(b[i].to, dq);
			low[dq] = min(low[dq], low[b[i].to]);
		}
		else if (b[i].to != fa)
			low[dq] = min(low[dq], dfn[b[i].to]);
	if (low[dq] == dfn[dq])
	{
		while (!gary.empty() && gary.top() != dq)
			belong[gary.top()] = dq, gary.pop();
		if (!gary.empty())
			gary.pop();
		belong[dq] = dq;
	}
}
void adn(edg* bx, int* gx, int& cntx, int from, int to)
{
	bx[++cntx].next = gx[from];
	bx[cntx].from = from, bx[cntx].to = to;
	gx[from] = cntx;
}
void dfs(int dq, int fa)
{
	for (int i = gn[dq]; i; i = bn[i].next)
		if (bn[i].to != fa)
		{
			f[bn[i].to] = f[dq] + 1;
			dfs(bn[i].to, dq);
		}
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1, srx, sry; i <= m; i++)
	{
		scanf("%d%d", &srx, &sry);
		adn(b, g, cntb, srx, sry);
		adn(b, g, cntb, sry, srx);
	}
	tarjan(1, 1);
	set<int> te[MAXN];
	for (int i = 1; i <= n; i++)
		for (int j = g[i]; j; j = b[j].next)
			if (belong[i] != belong[b[j].to] && te[belong[i]].find(belong[b[j].to]) == te[belong[i]].end())
			{
				te[belong[i]].insert(belong[b[j].to]);
				te[belong[b[j].to]].insert(belong[i]);
				adn(bn, gn, cntn, belong[i], belong[b[j].to]);
				adn(bn, gn, cntn, belong[b[j].to], belong[i]);
			}
	dfs(belong[1], belong[1]);
	int ans = 0, ansi;
	for (int i = 1; i <= n; i++)
		if (ans < f[belong[i]])
			ans = f[belong[i]], ansi = belong[i];
	memset(f, 0, sizeof(f));
	dfs(ansi, ansi);
	ans = 0;
	for (int i = 1; i <= n; i++)
		ans = max(ans, f[belong[i]]);
	printf("%d", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <stack>
#define MAXN (300000 + 5)
using namespace std;
struct edg
{
	int from, to, next;
}b[MAXN << 1], bn[MAXN << 1];
int g[MAXN], cntb, gn[MAXN], cntn, n, m, belong[MAXN], dfn[MAXN], low[MAXN], cntdfn, f[MAXN];
stack<int> gary;
void tarjan(int dq, int fa)
{
	dfn[dq] = low[dq] = ++cntdfn;
	gary.push(dq);
	for (int i = g[dq]; i; i = b[i].next)
		if (!dfn[b[i].to])
		{
			tarjan(b[i].to, dq);
			low[dq] = min(low[dq], low[b[i].to]);
		}
		else if (b[i].to != fa)
			low[dq] = min(low[dq], dfn[b[i].to]);
	if (low[dq] == dfn[dq])
	{
		while (!gary.empty() && gary.top() != dq)
			belong[gary.top()] = dq, gary.pop();
		if (!gary.empty())
			gary.pop();
		belong[dq] = dq;
	}
}
void adn(edg* bx, int* gx, int& cntx, int from, int to)
{
	bx[++cntx].next = gx[from];
	bx[cntx].from = from, bx[cntx].to = to;
	gx[from] = cntx;
}
void dfs(int dq, int fa)
{
	for (int i = gn[dq]; i; i = bn[i].next)
		if (bn[i].to != fa)
		{
			f[bn[i].to] = f[dq] + 1;
			dfs(bn[i].to, dq);
		}
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1, srx, sry; i <= m; i++)
	{
		scanf("%d%d", &srx, &sry);
		adn(b, g, cntb, srx, sry);
		adn(b, g, cntb, sry, srx);
	}
	tarjan(1, 1);
	for (int i = 1; i <= n; i++)
		for (int j = g[i]; j; j = b[j].next)
			if (belong[i] != belong[b[j].to])
			{
				adn(bn, gn, cntn, belong[i], belong[b[j].to]);
				adn(bn, gn, cntn, belong[b[j].to], belong[i]);
			}
	dfs(belong[1], belong[1]);
	int ans = 0, ansi;
	for (int i = 1; i <= n; i++)
		if (ans < f[belong[i]])
			ans = f[belong[i]], ansi = belong[i];
	memset(f, 0, sizeof(f));
	dfs(ansi, ansi);
	ans = 0;
	for (int i = 1; i <= n; i++)
		ans = max(ans, f[belong[i]]);
	printf("%d", ans);
	return 0;
}


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

int N_bridge,NDFS, N_boss;
vector< set<int> > adj,adj2;
vector<int> dis,low,anc;

void dfs(int v){
	dis[v]=low[v]=++NDFS;
	for(auto i: adj[v])if(i!=anc[v]){
		if(!dis[i]){
			anc[i]=v;
			dfs(i);
			low[v]=min(low[v],low[i]);
			if(low[i]>dis[v])N_bridge++;
		}else
			low[v]=min(low[v],dis[i]);
	}
}

int dfs2(int v,int ant){
	int m1,m2;
	m1=m2=0;
	for(auto u: adj2[v])if(u!=ant){
		int t=dfs2(u,v);
		m2=max(m2,t);
		if(m1<m2) swap(m1,m2);

		//cout<<v<<" -> "<<u<<": "<<t<<endl;
	}
	N_boss=max(N_boss,m1+m2);
	return m1+1;
}

int main(){
	ios_base::sync_with_stdio(false);
	int N,M;

	cin>>N>>M;
	dis.resize(N+1);
	adj.resize(N+1);
	adj2.resize(N+1);
	low.resize(N+1);
	anc.resize(N+1);

	while(M--){
		static int a,b;
		cin>>a>>b;
		adj[a].insert(b);
		adj[b].insert(a);
	}

	dfs(1);

	for(int i=1;i<=N;i++)
		for(auto j: adj[i])if(low[i]!=low[j]){
			adj2[low[i]].insert(low[j]);
			adj2[low[j]].insert(low[i]);
		}

	dfs2(1,1);

	cout<< N_boss <<endl;
	return 0;
}


#define DEBUG(x) cout<<#x<<" = "<<x<<"\n";
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;

const int oo=0x7fffffff;
const ll  OO=0x7fffffffffffffff;

//#include "geometry.h"
//#include "mint.h"
//#include "prime.h"
//#include "matrix.h"
//#include "rmq_lazy.h"
//#include "string_algo.h"
//#include "graphs.h"
//#include "RNG.h"
//#include "lin_fit.h"

template<class EDGE, class VERTEX>
class undirected_graph{
	public:
	vector< EDGE > E; //edge list
	vector< vector<int> > adj; //adjacency list
	vector< VERTEX > V; //vertex list

	int esize()const{return E.size();}
	int vsize()const{return V.size();}
	undirected_graph(int N,const VERTEX& v):
		adj(N), V(N,v){}

	void insert_edge(const EDGE& ed){
		adj[ed.a].emplace_back( E.size() );
		adj[ed.b].emplace_back( E.size() );
		E.push_back(ed);
	}

	EDGE& operator()(int i){return E[i];}
	VERTEX& operator[](int i){return V[i];}
};

template<class EDGE,class VERTEX>
class articulation_bridge{
	public:
	undirected_graph<EDGE,VERTEX> &G; // a pointer to external graph
	vector<int> dis;// discovery time in DFS
	vector<int> low;// lowest disc accessible by walking through back edges
	vector<char> bridge;// bridge flag
	vector<char> articulation;//articulation point flag
	int time; // DFS time
	int ROOT; // DFS root
	void dfs(int v /* current vertex */,int p /* parent */){
		dis[v]=low[v]=++time;
		for(auto e: G.adj[v]){
			int n = ( v==G(e).a ? G(e).b : G(e).a );
			if(n==p)continue;
			if(!dis[n]){
				dfs(n,v);
				low[v]=min(low[v],low[n]);
				if(low[n]>dis[v])
					bridge[e]=1;// (e) is a bridge
				if((v!=ROOT && dis[v]<=low[n])||(v==ROOT && dis[n]>2));
					articulation[v]=1;// (v) is an articulation point
			}else
				low[v]=min(low[v],dis[n]);
		}
	}

	articulation_bridge(undirected_graph<EDGE,VERTEX> &_G):
		G(_G),dis(G.V.size(),0),low(G.V.size(),0),
		bridge(G.E.size(),0),articulation(G.V.size(),0), time(0){
		ROOT=1;
		dfs(1,1);
	};
};

class simple_edge{
	public:
	int a,b;
	simple_edge(int _a,int _b): a(_a),b(_b){}
};

/*
	Implementation of equivalent classes with
	heuristic path compression.

	13-07-2018

	Suggested problem:
	E. We Need More Bosses
	http://codeforces.com/problemset/problem/1000/E
*/
class equiv_class {
	public:
	vector<int> P; // immediate boss
	vector<int> rank;//number of subbordinates
	equiv_class(int N):P(N,0),rank(N,0){
		for(int i=0;i<N;i++)rank[i]=1, P[i]=i;
	}
	void link(int a,int b){
		a=(*this)[a], b=(*this)[b];
		if(a==b)return;
		if(rank[a]>rank[b])swap(a,b);
		rank[b]+=rank[a];
		P[a]=b;
	}
	int operator[](int i){
		return ( i==P[i] ? i : P[i]=(*this)[ P[i] ] );
	}
};

int main(){
	ios_base::sync_with_stdio(false);

	int N,M;
	cin>>N>>M;

	undirected_graph<simple_edge,int> G(N,0);

	while(M--){
		int a,b;
		cin>>a>>b;
		G.insert_edge(simple_edge(--a,--b));
	}

	articulation_bridge<simple_edge,int> AB(G);
	equiv_class COLOR(G.vsize());

	for(int e=0;e<G.esize();e++)if(!AB.bridge[e])
		COLOR.link(G(e).a,G(e).b);

	//for(int v=0;v<G.vsize();v++)cout<<v<<" "<<COLOR[v]<<endl;

	undirected_graph<simple_edge,int> G2(N,0);
	for(int e=0;e<G.esize();e++)if(AB.bridge[e]){
		G2.insert_edge(simple_edge(COLOR[ G(e).a ],COLOR[ G(e).b ]));
		//cout<<COLOR[ G(e).a ]<<"--"<<COLOR[ G(e).b ]<<endl;
	}
	int best=0;
	vector<int> dis(N,0);

	function<int(int,int)> dfs ;
	dfs = [&G2,&best,&dfs,&dis](int v,int p) -> int{
		//DEBUG(v);
		if(dis[v]){
			cout<<"not a tree\n";
			exit(1);
		}
		dis[v]=1;
		int m1,m2;
		m1=m2=0;
		for(auto e: G2.adj[v]){
			int n = ( v==G2(e).a ? G2(e).b : G2(e).a );
			if(n==p)continue;
			m2=dfs(n,v);
			if(m1<m2)swap(m1,m2);
		}
		best=max(best,m1+m2);
		return m1+1;
	};

	dfs(COLOR[0],COLOR[0]);

	cout<<best<<endl;

	/*
	for(int i=0;i<G.V.size();i++)
		if(AB.articulation[i])
			cout<<G[i]<<" is an articulation point\n";

	for(int i=0;i<G.E.size();i++)
		if(AB.bridge[i])
			cout<<G(i)<<" is a bridge\n";
	*/
	return 0;
}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[700][101][130];
int k,n,per[130][130];
string s;

int check(int i, int j, int _) {

    if (dp[i][j][_] > -1) return dp[i][j][_];
    if (i == s.size()) return 0;

    int res = check( i+1, j, s[i]) + per[_][s[i]];
    if (j < k)
    for (int r = 'a'; r <= 'z'; ++r)
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> s >> k >> n;
    s = ' ' + s;
    char a, b; int c;
    for (int i = 1; i <= n; ++i) {
        cin >> a >> b >> c;
        per[a][b] = c;
    }
    memset(dp,-1,sizeof(dp));
    cout << check(1,0,0);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[120][101][30];
int k,n,per[30][30];
string s;

int check(int i, int j, int _) {

    if (dp[i][j][_] > -1) return dp[i][j][_];
    if (i == s.size()) return 0;

    int res = check( i+1, j, s[i]-'a') + per[_][s[i]-'a'];
    if (j < k)
    for (int r = 0; r < 26; ++r)
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> s >> k >> n;
    s = ' ' + s;
    char a, b; int c;
    for (int i = 1; i <= n; ++i) {
        cin >> a >> b >> c;
        per[a-'a'][b-'a'] = c;
    }
    memset(dp,-1,sizeof(dp));
    cout << check(1,0,0);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[120][101][30];
int k,n,per[30][30];
string s;

int check(int i, int j, int _) {

    if (dp[i][j][_] > -1) return dp[i][j][_];
    if (i == s.size()) return 0;

    int res = check( i+1, j, s[i]-'a') + per[_][s[i]-'a'];
    if (j < k)
    for (int r = 0; r < 26; ++r)
        if (r != s[i]-'a')
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> s >> k >> n;
    char a, b; int c;
    for (int i = 1; i <= n; ++i) {
        cin >> a >> b >> c;
        per[a-'a'][b-'a'] = c;
    }
    memset(dp,-1,sizeof(dp));
    cout << check(0,0,27);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[120][101][30];
int k,n,per[30][30];
string s;

int check(int i, int j, int _) {

    if (dp[i][j][_] > -1) return dp[i][j][_];
    if (i == s.size()) return 0;

    int res = check( i+1, j, s[i]-'a') + per[_][s[i]-'a'];
    if (j < k)
    for (int r = 0; r < 26; ++r)
        if (r != s[i]-'a')
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> s >> k >> n;
    s = ' ' + s;
    char a, b; int c;
    for (int i = 1; i <= n; ++i) {
        cin >> a >> b >> c;
        per[a-'a'][b-'a'] = c;
    }
    memset(dp,-1,sizeof(dp));
    cout << check(1,0,-1);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[120][101][30];
int k,n,per[30][30];
string s;

int check(int i, int j, int _) {

    if (dp[i][j][_] > -1) return dp[i][j][_];
    if (i == s.size()) return 0;

    int res = check( i+1, j, s[i]-'a') + per[_][s[i]-'a'];
    if (j < k)
    for (int r = 0; r < 26; ++r)
        if (r != s[i]-'a')
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> s >> k >> n;
    s = ' ' + s;
    char a, b; int c;
    for (int i = 1; i <= n; ++i) {
        cin >> a >> b >> c;
        per[a-'a'][b-'a'] = c;
    }
    memset(dp,-1,sizeof(dp));
    cout << check(1,0,27);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[120][101][30],k,n,per[30][30];
string s;

int check(int i, int j, int _) {

    if(i==s.size())
		return 0;
	int &res=dp[i][j][_];

	if(res!=-1)
		return res;

    res = check( i+1, j, s[i]-'a') + per[_][s[i]-'a'];
    if (j < k)
    for (int r = 0; r < 26; ++r)
        if (r != s[i]-'a')
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    memset(dp,-1,sizeof(dp));
    cin >> s >> k >> n;
    for (int i = 1; i <= n; ++i) {
        char a, b; int c;
        cin >> a >> b >> c;
        per[a-'a'][b-'a'] = c;
    }
    cout << check(0,0,27);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[700][101][101];
int k,n,per[101][101];
string s;

int check(int i, int j, int _) {

    if (dp[i][j][_] > -1) return dp[i][j][_];
    if (i == s.size()) return 0;

    int res = check( i+1, j, s[i]) + per[_][s[i]];
    if (j < k)
    for (int r = 'a'; r <= 'z'; ++r)
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> s >> k >> n;
    s = ' ' + s;
    char a, b; int c;
    for (int i = 1; i <= n; ++i) {
        cin >> a >> b >> c;
        per[a][b] = c;
    }
    memset(dp,-1,sizeof(dp));
    cout << check(1,0,0);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[120][101][30];
int k,n,per[30][30];
string s;

int check(int i, int j, int _) {

    if (dp[i][j][_] > -1) return dp[i][j][_];
    if (i == s.size()) return 0;

    int res = check( i+1, j, s[i]-'a') + per[_][s[i]-'a'];
    if (j < k)
    for (int r = 0; r < 26; ++r)
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> s >> k >> n;
    s = ' ' + s;
    char a, b; int c;
    for (int i = 1; i <= n; ++i) {
        cin >> a >> b >> c;
        per[a-'a'][b-'a'] = c;
    }
    memset(dp,-1,sizeof(dp));
    cout << check(1,0,-1);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[120][101][30],k,n,per[30][30];
string s;

int check(int i, int j, int _) {

    if(in==s.size())
		return 0;
	int &res=dp[i][j][_];

	if(res!=-1)
		return res;

    res = check( i+1, j, s[i]-'a') + per[_][s[i]-'a'];
    if (j < k)
    for (int r = 0; r < 26; ++r)
        if (r != s[i]-'a')
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    memset(dp,-1,sizeof(dp));
    cin >> s >> k >> n;
    for (int i = 1; i <= n; ++i) {
        char a, b; int c;
        cin >> a >> b >> c;
        per[a-'a'][b-'a'] = c;
    }
    cout << check(0,0,27);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[700][101][101];
int k,n,per[1001][1001];
string s;

int check(int i, int j, int _) {

    if (dp[i][j][_] > -1) return dp[i][j][_];
    if (i == s.size()) return 0;

    int res = check( i+1, j, s[i]) + per[_][s[i]];
    if (j < k)
    for (int r = 'a'; r <= 'z'; ++r)
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    freopen("test.inp","r",stdin);
    cin >> s >> k >> n;
    s = ' ' + s;
    char a, b; int c;
    for (int i = 1; i <= n; ++i) {
        cin >> a >> b >> c;
        per[a][b] = c;
    }
    memset(dp,-1,sizeof(dp));
    cout << check(1,0,0);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[700][101][101];
int k,n,per[1001][1001];
string s;

int check(int i, int j, int _) {

    if (dp[i][j][_] > -1) return dp[i][j][_];
    if (i == s.size()) return 0;

    int res = check( i+1, j, s[i]) + per[_][s[i]];
    if (j < k)
    for (int r = 'a'; r <= 'z'; ++r)
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    cin >> s >> k >> n;
    s = ' ' + s;
    char a, b; int c;
    for (int i = 1; i <= n; ++i) {
        cin >> a >> b >> c;
        per[a][b] = c;
    }
    memset(dp,-1,sizeof(dp));
    cout << check(1,0,0);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[101][101][130];
int k,n,per[130][130];
string s;

int check(int i, int j, int _) {

    if (dp[i][j][_] > -1) return dp[i][j][_];
    if (i == s.size()) return 0;

    int res = check( i+1, j, s[i]) + per[_][s[i]];
    if (j < k)
    for (int r = 'a'; r <= 'z'; ++r)
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> s >> k >> n;
    s = ' ' + s;
    char a, b; int c;
    for (int i = 1; i <= n; ++i) {
        cin >> a >> b >> c;
        per[a][b] = c;
    }
    memset(dp,-1,sizeof(dp));
    cout << check(1,0,0);

}


// i am crush
#include<bits/stdc++.h>
using namespace std;

int dp[120][101][130];
int k,n,per[130][130];
string s;

int check(int i, int j, int _) {

    if (dp[i][j][_] > -1) return dp[i][j][_];
    if (i == s.size()) return 0;

    int res = check( i+1, j, s[i]) + per[_][s[i]];
    if (j < k)
    for (int r = 'a'; r <= 'z'; ++r)
        res = max(res, check( i+1, j+1, r) + per[_][r]);
    return dp[i][j][_] = res;
}

int main() {
    //freopen("test.inp","r",stdin);
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> s >> k >> n;
    s = ' ' + s;
    char a, b; int c;
    for (int i = 1; i <= n; ++i) {
        cin >> a >> b >> c;
        per[a][b] = c;
    }
    memset(dp,-1,sizeof(dp));
    cout << check(1,0,0);

}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define inf 1e18+100
#define pb push_back
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL);
int dp[100][26][101];
int c[26][26];
string s;
int fun(int i, int here, int w)
{
	if(w<0)return -inf;
	if(i==s.size()-1)return 0;
	int ans=0;
	int cc=s[i+1]-'a',d=here;
	for(int j=0;j<26;j++)
	{
		if(cc==j){ans=max(ans,c[d][j]+fun(i+1,j,w));continue;}
		ans=max(ans,c[d][j]+fun(i+1,j,w-1));
	}
	return ans;
}
signed main()
{
	memset(dp,-1,sizeof(dp));
	memset(c,0,sizeof(c));
	int k,n,d;
	cin>>s>>k>>n;
	char a,b;
	for(int i=0;i<n;i++)
	{
		cin>>a>>b>>d;
		c[a-'a'][b-'a']=d;
	}
	int ma=0,e=s[0]-'a';
	for(int j=0;j<26;j++)
	{
		if(e==j){ma=max(ma,fun(0,j,k));continue;}
		ma=max(ma,fun(0,j,k-1));
	}
	cout<<ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define inf 1e18+100
#define pb push_back
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL);
int dp[100][26][101];
int c[26][26];
string s;
int fun(int i, int here, int w)
{
	if(w<0)return -inf;
	if(i==s.size()-1)return 0;
	if(dp[i][here][w]!=-1)return dp[i][here][w];
	int ans=0;
	int cc=s[i+1]-'a',d=here;
	for(int j=0;j<26;j++)
	{
		if(cc==j){ans=max(ans,c[d][j]+fun(i+1,j,w));continue;}
		ans=max(ans,c[d][j]+fun(i+1,j,w-1));
	}
	return dp[i][here][w]=ans;
}
signed main()
{
	memset(dp,-1,sizeof(dp));
	memset(c,0,sizeof(c));
	int k,n,d;
	cin>>s>>k>>n;
	char a,b;
	for(int i=0;i<n;i++)
	{
		cin>>a>>b>>d;
		c[a-'a'][b-'a']=d;
	}
	int ma=0,e=s[0]-'a';
	for(int j=0;j<26;j++)
	{
		if(e==j){ma=max(ma,fun(0,j,k));continue;}
		ma=max(ma,fun(0,j,k-1));
	}
	cout<<ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define inf 1e18+100
#define pb push_back
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL);
int dp[100][26][101];
int c[26][26];
string s;
int fun(int i, int here, int w)
{
	if(w<0)return -inf;
	if(i==s.size()-1)return 0;
	if(dp[i][here][w]!=inf)return dp[i][here][w];
	int ans=-inf;
	int cc=s[i+1]-'a',d=here;
	for(int j=0;j<26;j++)
	{
		if(cc==j){ans=max(ans,c[d][j]+fun(i+1,j,w));continue;}
		ans=max(ans,c[d][j]+fun(i+1,j,w-1));
	}
	return dp[i][here][w]=ans;
}
signed main()
{
	//memset(dp,-1,sizeof(dp));
	memset(c,0,sizeof(c));
	int k,n,d;
	cin>>s>>k>>n;
	for(int i=0;i<s.size();i++)for(int j=0;j<26;j++)for(int l=0;l<=k;l++)dp[i][j][l]=inf;
	char a,b;
	for(int i=0;i<n;i++)
	{
		cin>>a>>b>>d;
		c[a-'a'][b-'a']=d;
	}
	int ma=-inf,e=s[0]-'a';
	for(int j=0;j<26;j++)
	{
		if(e==j){ma=max(ma,fun(0,j,k));continue;}
		ma=max(ma,fun(0,j,k-1));
	}
	cout<<ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define inf 1e18+100
#define pb push_back
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL);
int dp[100][26][101];
int c[26][26];
string s;
int fun(int i, int here, int w)
{
	if(w<0)return -inf;
	if(i==s.size()-1)return 0;
	if(dp[i][here][w]!=inf)return dp[i][here][w];
	int ans=0;
	int cc=s[i+1]-'a',d=here;
	for(int j=0;j<26;j++)
	{
		if(cc==j){ans=max(ans,c[d][j]+fun(i+1,j,w));continue;}
		ans=max(ans,c[d][j]+fun(i+1,j,w-1));
	}
	return dp[i][here][w]=ans;
}
signed main()
{
	//memset(dp,-1,sizeof(dp));
	memset(c,0,sizeof(c));
	int k,n,d;
	cin>>s>>k>>n;
	for(int i=0;i<s.size();i++)for(int j=0;j<26;j++)for(int l=0;l<=k;l++)dp[i][j][l]=inf;
	char a,b;
	for(int i=0;i<n;i++)
	{
		cin>>a>>b>>d;
		c[a-'a'][b-'a']=d;
	}
	int ma=0,e=s[0]-'a';
	for(int j=0;j<26;j++)
	{
		if(e==j){ma=max(ma,fun(0,j,k));continue;}
		ma=max(ma,fun(0,j,k-1));
	}
	cout<<ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
#define inf 1e18+100
#define pb push_back
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL);
int dp[100][26][101];
int c[26][26];
string s;
int fun(int i, int here, int w)
{
	if(w<0)return -inf;
	if(i==s.size()-1)return 0;
	if(dp[i][here][w]!=-1)return dp[i][here][w];
	int ans=0;
	int cc=s[i+1]-'a',d=here;
	for(int j=0;j<26;j++)
	{
		if(cc==j){ans=max(ans,c[d][j]+fun(i+1,j,w));continue;}
		ans=max(ans,c[d][j]+fun(i+1,j,w-1));
	}
	return ans;
}
signed main()
{
	memset(dp,-1,sizeof(dp));
	memset(c,0,sizeof(c));
	int k,n,d;
	cin>>s>>k>>n;
	//for(int i=0;i<s.size();i++)for(int j=0;j<26;j++)for(int l=0;l<=k;l++)dp[i][j][l]=-1;
	char a,b;
	for(int i=0;i<n;i++)
	{
		cin>>a>>b>>d;
		c[a-'a'][b-'a']=d;
	}
	int ma=0,e=s[0]-'a';
	for(int j=0;j<26;j++)
	{
		if(e==j){ma=max(ma,fun(0,j,k));continue;}
		ma=max(ma,fun(0,j,k-1));
	}
	cout<<ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
#define inf 1e18+100
#define pb push_back
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL);
int dp[100][26][101];
int c[26][26];
string s;
int fun(int i, int here, int w)
{
	if(w<0)return -inf;
	if(i==s.size()-1)return 0;
	if(dp[i][here][w]!=-1)return dp[i][here][w];
	int ans=0;
	int cc=s[i+1]-'a',d=here;
	for(int j=0;j<26;j++)
	{
		if(cc==j){ans=max(ans,c[d][j]+fun(i+1,j,w));continue;}
		ans=max(ans,c[d][j]+fun(i+1,j,w-1));
	}
	return ans;
}
signed main()
{
	//memset(dp,-1,sizeof(dp));
	//memset(c,0,sizeof(c));
	int k,n,d;
	cin>>s>>k>>n;
	for(int i=0;i<s.size();i++)for(int j=0;j<26;j++)for(int l=0;l<=k;l++)dp[i][j][l]=-1;
	char a,b;
	for(int i=0;i<n;i++)
	{
		cin>>a>>b>>d;
		c[a-'a'][b-'a']=d;
	}
	int ma=0,e=s[0]-'a';
	for(int j=0;j<26;j++)
	{
		if(e==j){ma=max(ma,fun(0,j,k));continue;}
		ma=max(ma,fun(0,j,k-1));
	}
	cout<<ma;
	return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;

const ll INF = INT_MAX;
#define MOD 1000000007

using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    #pragma region Init
    string S;
    ll K, N;
    map<pair<ll, ll>, ll> C;
    #pragma endregion

    cin >> S >> K;

    cin >> N;
    while (N--){
        char x, y; ll c;
        cin >> x >> y >> c;
        C[{x - 'a', y - 'a'}] = c;
    }

    ll len = S.size();
    ll A[len][K + 1][26] = {};

    memset(&A[0][0][0], -6969, sizeof(A));
    for(ll x = 0; x < 26; x++){
        if(S[0] - 'a' != x)
            A[0][1][x] = 0;
        else
            A[0][0][x] = 0;
    }

    for(ll i = 1; i < len; i++){
        for(ll k = 0; k <= min(K, i + 1); k++){
            for(ll z = 0; z < 26; z++){
                if(k == 0 and S[i] - 'a' != z) continue;

                ll &curr = A[i][k][z];
                for(ll z1 = 0; z1 < 26; z1++)
                    curr = max(curr, A[i - 1][k - (k != 0 and S[i] - 'a' != z)][z1] + C[{z1, z}]);
            }
        }
    }

    ll ans = -INF;
    for(ll k = 0; k <= K; k++){
        for(ll z = 0; z < 26; z++){
            ans = max(ans, A[len - 1][k][z]);
        }
    }

    cout << ans << endl;

return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;

const ll INF = INT_MAX;
#define MOD 1000000007

using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    #pragma region Init
    string S;
    ll K, N;
    map<pair<ll, ll>, ll> C;
    #pragma endregion

    cin >> S >> K;

    cin >> N;
    while (N--){
        char x, y; ll c;
        cin >> x >> y >> c;
        C[{x - 'a', y - 'a'}] = c;
    }

    ll len = S.size();
    ll A[len][K + 1][26] = {};

    memset(&A[0][0][0], -6969, sizeof(A));
    for(ll x = 0; x < 26; x++){
        if(S[0] - 'a' != x)
            A[0][1][x] = 0;
        else
            A[0][0][x] = 0;
    }

    for(ll i = 1; i < len; i++){
        for(ll k = 0; k <= min(K, i + 1); k++){
            for(ll z = 0; z < 26; z++){
                if(k == 0 and S[i] - 'a' != z) continue;

                ll &curr = A[i][k][z];
                for(ll z1 = 0; z1 < 26; z1++)
                    curr = max(curr, A[i - 1][k - (k != 0 and S[i] - 'a' != z)][z1] + C[{z1, z}]);
            }
        }
    }

    ll ans = -INF;
    for(ll k = 0; k <= min(K, len); k++){
        for(ll z = 0; z < 26; z++){
            ans = max(ans, A[len - 1][k][z]);
        }
    }

    cout << ans << endl;

return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;

#define INF 999999999
#define MOD 1000000007

using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    #pragma region Init
    string S;
    ll K, N;
    map<pair<ll, ll>, ll> C;
    ll A[100][101][26] = {};
    #pragma endregion

    cin >> S >> K;

    cin >> N;
    while (N--){
        char x, y; ll c;
        cin >> x >> y >> c;
        C[{x - 'a', y - 'a'}] = c;
    }

    ll len = S.size();
    #pragma region Init
    for(int i = 0; i < len; i++)
        for(int k = 0; k <= K; k++)
            for(int z = 0; z < 26; z++)
                A[i][k][z] = -INF;

    for(ll x = 0; x < 26; x++){
        if(S[0] - 'a' != x)
            A[0][1][x] = 0;
        else
            A[0][0][x] = 0;
    }
    #pragma endregion

    for(ll i = 1; i < len; i++){
        for(ll k = 0; k <= min(K, i + 1); k++){
            for(ll z = 0; z < 26; z++){
                if(!k and S[i] - 'a' != z) continue;

                ll &curr = A[i][k][z];
                for(ll z1 = 0; z1 < 26 and !k; z1++)
                    curr = max(curr, A[i - 1][k][z1] + C[{z1, z}]);

                for(ll z1 = 0; z1 < 26 and k; z1++)
                    curr = max(curr, A[i - 1][k - (S[i] - 'a' != z)][z1] + C[{z1, z}]);
            }
        }
    }

    ll ans = -INF;
    for(ll k = 0; k <= K; k++){
        for(ll z = 0; z < 26; z++){
            ans = max(ans, A[len - 1][k][z]);
        }
    }

    cout << ans << endl;

return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;

const ll INF = INT_MAX;
#define MOD 1000000007

using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    #pragma region Init
    string S;
    ll K, N;
    map<pair<ll, ll>, ll> C;
    #pragma endregion

    cin >> S >> K;

    cin >> N;
    while (N--){
        char x, y; ll c;
        cin >> x >> y >> c;
        C[{x - 'a', y - 'a'}] = c;
    }

    ll len = S.size();
    ll A[len][K + 1][26] = {};

    memset(&A[0][0][0], -6969, sizeof(A));
    for(ll x = 0; x < 26; x++){
        if(S[0] - 'a' != x)
            A[0][1][x] = 0;
        else
            A[0][0][x] = 0;
    }

    for(ll i = 1; i < len; i++){
        for(ll k = 0; k <= min(K, i + 1); k++){
            for(ll z = 0; z < 26; z++){
                if(k == 0 and S[i] - 'a' != z) continue;

                ll &curr = A[i][k][z];
                for(ll z1 = 0; z1 < 26; z1++)
                    curr = max(curr, A[i - 1][k - (k != 0 and S[i] - 'a' != z)][z1] + C[{z1, z}]);
            }
        }
    }

    ll ans = -INF;
    for(ll k = 0; k <= len; k++){
        for(ll z = 0; z < 26; z++){
            ans = max(ans, A[len - 1][k][z]);
        }
    }

    cout << ans << endl;

return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;

const int INF = INT_MAX;
#define MOD 1000000007

using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    #pragma region Init
    string S;
    int K, N;
    map<pair<int, int>, int> C;
    #pragma endregion

    cin >> S >> K;

    cin >> N;
    while (N--){
        char x, y; int c;
        cin >> x >> y >> c;
        C[{x - 'a', y - 'a'}] = c;
    }

    int len = S.size();
    int A[len][K + 1][26] = {};

    memset(&A[0][0][0], -6969, sizeof(A));
    for(int x = 0; x < 26; x++){
        if(S[0] - 'a' != x)
            A[0][1][x] = 0;
        else
            A[0][0][x] = 0;
    }

    for(int i = 1; i < len; i++){
        for(int k = 0; k <= min(K, i + 1); k++){
            for(int z = 0; z < 26; z++){
                if(k == 0 and S[i] - 'a' != z) continue;

                int &curr = A[i][k][z];
                for(int z1 = 0; z1 < 26; z1++)
                    curr = max(curr, A[i - 1][k - (k != 0 and S[i] - 'a' != z)][z1] + C[{z1, z}]);
            }
        }
    }

    int ans = -INF;
    for(int k = 0; k <= min(K, len); k++){
        for(int z = 0; z < 26; z++){
            ans = max(ans, A[len - 1][k][z]);
        }
    }

    cout << ans << endl;

return 0;
}


#include<bits/stdc++.h>
using namespace std;
int k,save[101][101][27],adj[27][27];
string s;
int solve(int in,int r,int prev){
	if(in==s.size())return 0;
	int &res=save[in][r][prev];
	if(res!=-1)return res;
	res=solve(in+1,r,s[in]-'a')+adj[prev][s[in]-'a'];
	if(r<k)for(int i=0;i<26;i++)if(i!=s[in]-'a')res=max(res,solve(in+1,r+1,i)+adj[prev][i]);
	return res;
}
int main(){
	cin>>s>>k;
	int m;
	cin>>m;
	for(int i=0;i<m;i++){
		char a,b;
		int c;
		cin>>a>>b>>c;
		adj[a-'a'][b-'a']=c;
	}
	memset(save,-1,sizeof save);
	cout<<solve(0,0,26);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define INF 4e18
#define N 200000
#define FOR(n) for (ll i = 0; i < n; ++i)
#define pb push_back
#define mp pkjke_pair
#define all(x) x.begin(), x.end()
#define ll long long int
#define s(x) scanf("%d", &x)
#define sd(x) scanf("%lf", &x)
#define sl(x) scanf("%lld", &x)
#define mod 1000000007
#define fi first
#define se second
#define p(x) printf("%d", x)
#define pl(x) printf("%lld", x)
#define pd(x) printf("%lf", x)
#define pn() printf("\n")
#define vi vector<ll>
#define vl(v) vector<ll> v
#define pll pair<ll, ll>
#define len(s) s.length()
#define start_code ios_base::sync_with_stdio(0)
void input(ll n, ll a[])
{
    FOR(n)
        cin >> a[i];
}
ll bin_expo(ll A, ll B, ll M)
{
    ll result = 1ll;
    while (B > 0)
    {
        if (B % 2 == 1)
        {
            result = (result * A) % M;
        }
        A = (A * A) % M;
        B = B / 2;
    }
    return result;
}
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);
}
ll lcm(ll a, ll b)
{
    return (a * b) / gcd(a, b);
}
string s;
ll dp[101][101][30],n,m;
map< pair<ll,ll>,ll > pk;
ll solve(ll idx,ll tot,ll prev)
{
    if( idx == s.length()) return 0;
    if( dp[idx][tot][prev] != -1) return dp[idx][tot][prev];
    ll res = 0;
    res = max(res, pk[{prev,s[idx]-'a'}] + solve(idx+1,tot,s[idx]-'a'));
    if( tot < m)
    {
        for(int i=0;i<26;i++)
        {
            if( i != s[idx]-'a')
             res = max(res, pk[{prev,i}] + solve(idx+1,tot+1,i));
        }
    }
    return dp[idx][tot][prev] = res;
}
int main()
{
    memset(dp,-1,sizeof(dp));
    cin>>s;
    cin>>m;
    cin>>n;
    FOR(n)
    {
        char x,y;
        ll c;
        cin>>x>>y>>c;
        pk[{x-'a',y-'a'}] = c;
    }
    cout<<solve(0,0,26)<<endl;
    return 0;
}


/*
             ██████  ██████
             ██   ██ ██   ██
 Author ->   ██████  ██   ██
             ██      ██   ██
             ██      ██████

    nik is love.
    nik is motivation.
    Ek modulus aapki jindagi barbaad kar sakti hai
    Watch for integer overflows.
*/
#include<bits/stdc++.h>
#define mp                    make_pair
#define pb                    push_back
#define ll                    long long
#define ss                       second
#define ff                        first
#define fr(i,a,b)   for(ll i=a;i<b;i++)
#define f(i,n)                fr(i,0,n)
#define rf(i,b,a) for(ll i=b-1;i>=a;i--)
#define r(i,n)                rf(i,n,0)
#define inf                   1000000007
#define eps                   0.000000001
#define sz(a)                int((a).size())
#define all(c)               (c).begin(),(c).end()
#define tr(c,i)              for(typeof(c).begin() i = (c).begin(); i != (c).end(); i++)
#define present(c,x)         ((c).find(x) != (c).end())
#define cpresent(c,x)        (find(all(c),x) != (c).end())
#define pi                   pair<int,int>
#define pll                  pair < ll , ll >
#define endl                 '\n'
#define PI                   3.141592653589793238462643383279502884197169399375105820974944592307816406286
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef vector< int > vi;
typedef vector< vi > vvi;
int dx[8]={1,-1,0,0,-1,-1,1,1};
int dy[8]={0,0,-1,1,-1,1,-1,1};
vector<pair<int,int>>adj[200010];
vector<int> val(300010,1),vis(300010,0),dis1(300010,0),dis2(300010,0);
int myrandom (int i) { return std::rand()%i;}
vector<vector<pair<int,int>>> temp;
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    //ifstream fin;
    //ofstream fout;
    //fin.open("input.txt");
    //fout.open("output.txt");
    string s;
    int k;
    cin>>s>>k;
    int eu[26][26];
    memset(eu,0,sizeof(eu));
    int t;
    cin>>t;
    while(t--)
    {
        char a,b;
        int c;
        cin>>a>>b>>c;
        int x=a-'a',y=b-'a';
        eu[x][y]=c;
    }
    int n=(int)s.length();
    int dp[n][k+1][26];
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=k;j++)
        {
            for(int l=0;l<26;l++)
            {
                dp[i][j][l]=-inf;
            }
        }
    }
    for(int i=0;i<26;i++)
    {
        if(s[0]=='a'+i)
        {
            dp[0][0][i]=0;
        }
        else
        {
            dp[0][1][i]=0;
        }
    }
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<=k;j++)
        {
            for(int l=0;l<26;l++)
            {
                if(l==s[i]-'a')
                {
                    int maxi=-inf;
                    for(int a=0;a<26;a++)
                    {
                        maxi=max(maxi,dp[i-1][j][a]+eu[a][l]);
                    }
                    dp[i][j][l]=maxi;
                }
                else
                {
                    if(j>0)
                    {
                        int maxi=-inf;
                        for(int a=0;a<26;a++)
                        {
                            maxi=max(maxi,dp[i-1][j-1][a]+eu[a][l]);
                        }
                        dp[i][j][l]=maxi;
                    }
                }
            }
        }
    }
    int maxi=-inf;
    for(int i=0;i<=k;i++)
    {
        for(int j=0;j<26;j++)
        {
            maxi=max(maxi,dp[n-1][i][j]);
        }
    }
    cout<<maxi<<endl;
}


/*
             ██████  ██████
             ██   ██ ██   ██
 Author ->   ██████  ██   ██
             ██      ██   ██
             ██      ██████

    nik is love.
    nik is motivation.
    Ek modulus aapki jindagi barbaad kar sakti hai
    Watch for integer overflows.
*/
#include<bits/stdc++.h>
#define mp                    make_pair
#define pb                    push_back
#define ll                    long long
#define ss                       second
#define ff                        first
#define fr(i,a,b)   for(ll i=a;i<b;i++)
#define f(i,n)                fr(i,0,n)
#define rf(i,b,a) for(ll i=b-1;i>=a;i--)
#define r(i,n)                rf(i,n,0)
#define inf                   1000000007
#define eps                   0.000000001
#define sz(a)                int((a).size())
#define all(c)               (c).begin(),(c).end()
#define tr(c,i)              for(typeof(c).begin() i = (c).begin(); i != (c).end(); i++)
#define present(c,x)         ((c).find(x) != (c).end())
#define cpresent(c,x)        (find(all(c),x) != (c).end())
#define pi                   pair<int,int>
#define pll                  pair < ll , ll >
#define endl                 '\n'
#define PI                   3.141592653589793238462643383279502884197169399375105820974944592307816406286
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef vector< int > vi;
typedef vector< vi > vvi;
int dx[8]={1,-1,0,0,-1,-1,1,1};
int dy[8]={0,0,-1,1,-1,1,-1,1};
vector<pair<int,int>>adj[200010];
vector<int> val(300010,1),vis(300010,0),dis1(300010,0),dis2(300010,0);
int myrandom (int i) { return std::rand()%i;}
vector<vector<pair<int,int>>> temp;
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    //ifstream fin;
    //ofstream fout;
    //fin.open("input.txt");
    //fout.open("output.txt");
    string s;
    int k;
    cin>>s>>k;
    int eu[26][26];
    memset(eu,0,sizeof(eu));
    int t;
    cin>>t;
    while(t--)
    {
        char a,b;
        int c;
        cin>>a>>b>>c;
        int x=a-'a',y=b-'a';
        eu[x][y]=c;
    }
    int n=(int)s.length();
    int dp[n][k+2][26];
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=k;j++)
        {
            for(int l=0;l<26;l++)
            {
                dp[i][j][l]=-inf;
            }
        }
    }
    for(int i=0;i<26;i++)
    {
        if(s[0]=='a'+i)
        {
            dp[0][0][i]=0;
        }
        else
        {
            dp[0][1][i]=0;
        }
    }
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<=k;j++)
        {
            for(int l=0;l<26;l++)
            {
                if(l==s[i]-'a')
                {
                    int maxi=-inf;
                    for(int a=0;a<26;a++)
                    {
                        maxi=max(maxi,dp[i-1][j][a]+eu[a][l]);
                    }
                    dp[i][j][l]=maxi;
                }
                else
                {
                    if(j>0)
                    {
                        int maxi=-inf;
                        for(int a=0;a<26;a++)
                        {
                            maxi=max(maxi,dp[i-1][j-1][a]+eu[a][l]);
                        }
                        dp[i][j][l]=maxi;
                    }
                }
            }
        }
    }
    int maxi=-inf;
    for(int i=0;i<=k;i++)
    {
        for(int j=0;j<26;j++)
        {
            maxi=max(maxi,dp[n-1][i][j]);
        }
    }
    cout<<maxi<<endl;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 200005, mod =  1000000007;
#define Hello ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
string s;
ll k, n, memo[105][105][30], arr[30][30];
ll dp(ll idx, char prev, ll rem)
{
    if( rem < 0 )
        return -1e9;
    if( idx >= s.size() )
        return 0;
    if( memo[idx][rem][prev - 'a'] != -1 )
        return memo[idx][rem][prev - 'a'];
    ll ans = -1e9;
    ans = max(ans, dp(idx + 1, s[idx], rem) + arr[prev - 'a'][s[idx] - 'a']);
    for(char c = 'a';  c <= 'z'; c++)
    {
        if(c != s[idx])
            ans = max(ans, dp(idx + 1, c, rem - 1) + arr[prev - 'a'][c - 'a']);
    }
    memo[idx][rem][prev - 'a'] = ans;
    return memo[idx][rem][prev - 'a'];
}
int main()
{
    Hello
    cin >> s >> k >> n;
    for(int i = 0; i < n; i++)
    {
        char a, b;
        ll val;
        cin >> a >> b >> val;
        arr[a - 'a'][b - 'a'] = val;
    }
    memset(memo, -1, sizeof memo);
    cout << dp(0, s[0], k);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 200005, mod = 1000000007;
#define Hello ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
string s;
ll k, n, memo[105][105][30], arr[30][30];
ll dp(ll idx, ll prev, ll rem)
{
    if( rem < 0 )
        return -1e9;
    if( idx >= s.size() )
        return 0;
    if( memo[idx][rem][prev] != -1 )
        return memo[idx][rem][prev];
    //ll ans = -1e9;
    ll ans = (dp(idx + 1, s[idx] - 'a', rem) + arr[prev][s[idx] - 'a']);
    for(int i = 0; i < 26; i++)
    {
        if(i != s[idx] - 'a')
            ans = max(ans, dp(idx + 1, i, rem - 1) + arr[prev][i]);
    }
    memo[idx][rem][prev] = ans;
    return memo[idx][rem][prev];
}
int main()
{
    Hello
    cin >> s >> k >> n;
    for(int i = 0; i < n; i++)
    {
        char a, b;
        ll val;
        cin >> a >> b >> val;
        arr[a - 'a'][b - 'a'] = val;
    }
    memset(memo, -1, sizeof memo);
    cout << dp(0, s[0] - 'a', k);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 200005, mod = 1000000007;
#define Hello ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
string s;
ll k, n, memo[105][105][30], arr[30][30];
ll dp(ll idx, ll prev, ll rem)
{
    if( rem < 0 )
        return -1e9;
    if( idx >= s.size() )
        return 0;
    if( memo[idx][rem][prev] != -1 )
        return memo[idx][rem][prev];
    ll ans = -1e9;
    ans = max(ans, dp(idx + 1, s[idx] - 'a', rem) + arr[prev][s[idx] - 'a']);
    for(int i = 0; i < 26; i++)
    {
        if(i != s[idx] - 'a')
            ans = max(ans, dp(idx + 1, i, rem - 1) + arr[prev][i]);
    }
    memo[idx][rem][prev] = ans;
    return memo[idx][rem][prev];
}
int main()
{
    Hello
    cin >> s >> k >> n;
    for(int i = 0; i < n; i++)
    {
        char a, b;
        ll val;
        cin >> a >> b >> val;
        arr[a - 'a'][b - 'a'] = val;
    }
    memset(memo, -1, sizeof memo);
    cout << dp(0, s[0] - 'a', k);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 200005, mod =  1000000007;
#define Hello ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
string s;
ll k, n, memo[105][105][30], arr[30][30];
ll dp(ll idx, char prev, ll rem)
{
    if( rem < 0 )
        return -1e9;
    if( idx >= s.size() )
        return 0;
    if( memo[idx][rem][prev - 'a'] != -1 )
        return memo[idx][rem][prev - 'a'];
    //ll ans = -1e9;
    ll ans = ( dp(idx + 1, s[idx], rem) + arr[prev - 'a'][s[idx] - 'a']);
    for(char c = 'a';  c <= 'z'; c++)
    {
        if(c != s[idx])
            ans = max(ans, dp(idx + 1, c, rem - 1) + arr[prev - 'a'][c - 'a']);
    }
    memo[idx][rem][prev - 'a'] = ans;
    return memo[idx][rem][prev - 'a'];
}
int main()
{
    Hello
    cin >> s >> k >> n;
    for(int i = 0; i < n; i++)
    {
        char a, b;
        ll val;
        cin >> a >> b >> val;
        arr[a - 'a'][b - 'a'] = val;
    }
    memset(memo, -1, sizeof memo);
    cout << dp(0, s[0], k);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 200005, mod = 1000000007;
#define Hello ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
string s;
ll k, n, memo[105][105][30], arr[30][30];
ll dp(ll idx , ll prev, ll rem)
{
    if(rem < 0)
        return -1e9;
    if( idx == s.size() )
        return 0;
    if( memo[idx][rem][prev] != -1 )
        return memo[idx][rem][prev];
    ll ans = ( dp(idx + 1 , s[idx] - 'a', rem) + arr[prev][s[idx] - 'a'] );
    for(int i = 0 ; i < 26 ; i++)
        if(i != s[idx] - 'a')
           ans = max(ans , dp(idx + 1, i, rem - 1) + arr[prev][i]);
    memo[idx][rem][prev] = ans;
    return ans;
}
int main()
{
    Hello
    cin >> s >> k >> n;
    for(int i = 0; i < n; i++)
    {
        char a, b;
        ll val;
        cin >> a >> b >> val;
        arr[a - 'a'][b - 'a'] = val;
    }
    memset(memo, -1, sizeof memo);
    cout << dp(0, s[0] - 'a', k);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 200005, mod =  1000000007;
#define Hello ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
string s;
ll k, n, memo[105][105][30], arr[30][30];
ll dp(ll idx, char prev, int rem)
{
    if( rem < 0 )
        return -1e9;
    if( idx >= s.size() )
        return 0;
    if( memo[idx][rem][prev - 'a'] != -1 )
        return memo[idx][rem][prev - 'a'];
    ll ans = 0;
    ans = max(ans, dp( idx + 1, s[idx] , rem ) + arr[prev - 'a'][ s[idx] - 'a' ]  );
    for(char c = 'a';  c <= 'z'; c++)
    {
        if( c != s[idx] )
            ans = max( ans, dp( idx + 1, c, rem - 1 ) + arr[ prev - 'a' ][ c - 'a' ] );
    }
    memo[idx][rem][prev - 'a'] = ans;
    return memo[idx][rem][prev - 'a'];
}
int main()
{
    Hello
    cin >> s >> k >> n;
    for(int i = 0; i < n; i++)
    {
        char a, b;
        ll val;
        cin >> a >> b >> val;
        arr[ a - 'a' ][ b - 'a' ] = val;
    }
    memset(memo, -1, sizeof memo);
    cout << dp(0, s[0], k);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 200005, mod =  1000000007;
#define Hello ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
string s;
ll k, n, memo[105][105][30], arr[30][30];
ll dp(ll idx, char prev, ll rem)
{
    if( rem < 0 )
        return -1e9;
    if( idx >= s.size() )
        return 0;
    if( memo[idx][rem][prev - 'a'] != -1 )
        return memo[idx][rem][prev - 'a'];
    ll ans = -1e9;
    ans = max(ans, dp(idx + 1, s[idx], rem) + arr[prev - 'a'][s[idx] - 'a']);
    for(char c = 'a';  c <= 'z'; c++)
    {
        if(c != s[idx])
            ans = max(ans, dp(idx + 1, c, rem - 1) + arr[prev - 'a'][c - 'a']);
    }
    memo[idx][rem][prev - 'a'] = ans;
    return memo[idx][rem][prev - 'a'];
}
int main()
{
    Hello
    cin >> s >> k >> n;
    for(int i = 0; i < n; i++)
    {
        char a, b;
        ll val;
        cin >> a >> b >> val;
        arr[a - 'a'][b - 'a'] = val;
    }
    memset(memo, -1, sizeof memo);
    cout << dp(0, 'a', k);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 200005, mod = 1000000007;
#define Hello ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
string s;
ll k, n, memo[105][105][30], arr[30][30];
ll dp(ll idx , ll prev, ll rem)
{
    if(rem < 0)
        return -1e9;
    if( idx == s.size() )
        return 0;
    if( memo[idx][rem][prev] != -1 )
        return memo[idx][rem][prev];
    ll ans = ( dp(idx + 1 , s[idx] - 'a', rem) + arr[prev][s[idx] - 'a'] );
    for(int i = 0 ; i < 26 ; i++)
        if(i != s[idx] - 'a')
           ans = max(ans , dp(idx + 1, i, rem - 1) + arr[prev][i]);
    memo[idx][rem][prev] = ans;
    return ans;
}
int main()
{
    Hello
    cin >> s >> k >> n;
    for(int i = 0; i < n; i++)
    {
        char a, b;
        ll val;
        cin >> a >> b >> val;
        arr[a - 'a'][b - 'a'] = val;
    }
    memset(memo, -1, sizeof memo);
    cout << dp(0, 28, k);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 200005, mod = 1000000007;
#define Hello ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
string s;
ll k, n, memo[105][105][30], arr[30][30];
ll dp(ll idx , ll prev, ll rem)
{
    if(rem < 0)
        return -1e9;
    if( idx >= s.size() )
        return 0;
    if( memo[idx][rem][prev] != -1 )
        return memo[idx][rem][prev];
    ll ans = ( dp(idx + 1 , s[idx] - 'a', rem) + arr[prev][s[idx] - 'a'] );
    for(int i = 0 ; i < 26 ; i++)
        if(i != s[idx] - 'a')
           ans = max(ans , dp(idx + 1, i, rem - 1) + arr[prev][i]);
    memo[idx][rem][prev] = ans;
    return ans;
}
int main()
{
    Hello
    cin >> s >> k >> n;
    for(int i = 0; i < n; i++)
    {
        char a, b;
        ll val;
        cin >> a >> b >> val;
        arr[a - 'a'][b - 'a'] = val;
    }
    memset(memo, -1, sizeof memo);
    cout << dp(0, s[0] - 'a', k);
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <vector>
#include <cmath>

using namespace std;

int main() {

	ios_base::sync_with_stdio(false);
	cout.tie(nullptr);
	cin.tie(nullptr);

	vector<vector<vector<long long>>> dp(202, vector<vector<long long>>(202, vector<long long>(32, -1e9)));
	string name;
	char x, y;
	long long ans = -1e9;
	int k, n, q;
	vector<vector<int>> bonus(32, vector<int>(32, 0));

	cin >> name >> k >> q;

	while (q--) {
		cin >> x >> y;
		cin >> bonus[x - 'a'][y - 'a'];
	}

	dp[1][k][name[0] - 'a'] = 0;

	for (char i = 'a'; i <= 'z'; ++i)
	{
		if (i != name[0])
		{
			dp[1][k - 1][i - 'a'] = 0;
		}
	}

	n = name.size();

	for (int i = 2; i <= n; i++) {
		for (int t = k; t >= 0; t--) {
			for (int c = 'a'; c <= 'z'; c++) {
				for (int x = 'a'; x <= 'z'; x++) {
					if (c != name[i - 1]) {
						dp[i][t][c - 'a'] = max(dp[i][t][c - 'a'], dp[i - 1][t + 1][x - 'a'] + bonus[x - 'a'][c - 'a']);

						if (i == name.size()) {
							ans = max(ans, dp[i][t][c - 'a']);
						}
					} else if (c == name[i - 1]) {
						dp[i][t][c - 'a'] = max(dp[i][t][c - 'a'], dp[i - 1][t][x - 'a'] + bonus[x - 'a'][c - 'a']);

						if (i == name.size()) {
							ans = max(ans, dp[i][t][c - 'a']);
						}
					}
				}
			}
		}
	}

	cout << ans;

	return 0;
}


#include <iostream>
#include <stdio.h>
#include <vector>
#include <cmath>

using namespace std;

int main() {

	ios_base::sync_with_stdio(false);
	cout.tie(nullptr);
	cin.tie(nullptr);

	vector<vector<vector<long long>>> dp(202, vector<vector<long long>>(202, vector<long long>(32, -1e9)));
	string name;
	char x, y;
	long long ans = -1e9;
	int k, n, q;
	vector<vector<int>> bonus(32, vector<int>(32, 0));

	cin >> name >> k >> q;

	while (q--) {
		cin >> x >> y;
		cin >> bonus[x - 'a'][y - 'a'];
	}

	if (k == 0) {
		ans = 0;

		for (int i = 0; i < name.size() - 1; i++) {
			ans += bonus[name[i] - 'a'][name[i + 1] - 'a'];
		}

		cout << ans;

		return 0;
	}

	dp[1][k][name[0] - 'a'] = 0;

	for (char i = 'a'; i <= 'z'; ++i)
	{
		if (i != name[0])
		{
			dp[1][k - 1][i - 'a'] = 0;
		}
	}

	n = name.size();

	for (int i = 2; i <= n; i++) {
		for (int t = k; t >= 0; t--) {
			for (int c = 'a'; c <= 'z'; c++) {
				for (int x = 'a'; x <= 'z'; x++) {
					if (c != name[i - 1]) {
						dp[i][t][c - 'a'] = max(dp[i][t][c - 'a'], dp[i - 1][t + 1][x - 'a'] + bonus[x - 'a'][c - 'a']);

						if (i == name.size()) {
							ans = max(ans, dp[i][t][c - 'a']);
						}
					} else if (c == name[i - 1]) {
						dp[i][t][c - 'a'] = max(dp[i][t][c - 'a'], dp[i - 1][t][x - 'a'] + bonus[x - 'a'][c - 'a']);

						if (i == name.size()) {
							ans = max(ans, dp[i][t][c - 'a']);
						}
					}
				}
			}
		}
	}

	cout << ans;

	return 0;
}


#include <iostream>
#include <stdio.h>
#include <vector>
#include <cmath>

using namespace std;

int main() {

	ios_base::sync_with_stdio(false);
	cout.tie(nullptr);
	cin.tie(nullptr);

	vector<vector<vector<long long>>> dp(202, vector<vector<long long>>(202, vector<long long>(30, -1e9)));
	string name;
	char x, y;
	long long ans = -1e9;
	int k, n, q;
	vector<vector<int>> bonus(26, vector<int>(26, 0));

	cin >> name >> k >> q;

	while (q--) {
		cin >> x >> y;
		cin >> bonus[x - 'a'][y - 'a'];
	}

	dp[1][k][name[0] - 'a'] = 0;

	for (char i = 'a'; i <= 'z'; ++i)
	{
		if (i != name[0])
		{
			dp[1][k - 1][i - 'a'] = 0;
		}
	}

	n = name.size();

	for (int i = 2; i <= n; i++) {
		for (int t = k; t >= 0; t--) {
			for (int c = 'a'; c <= 'z'; c++) {
				for (int x = 'a'; x <= 'z'; x++) {
					if (c != name[i - 1]) {
						dp[i][t][c - 'a'] = max(dp[i][t][c - 'a'], dp[i - 1][t + 1][x - 'a'] + bonus[x - 'a'][c - 'a']);

						if (i == name.size()) {
							ans = max(ans, dp[i][t][c - 'a']);
						}
					} else if (c == name[i - 1]) {
						dp[i][t][c - 'a'] = max(dp[i][t][c - 'a'], dp[i - 1][t][x - 'a'] + bonus[x - 'a'][c - 'a']);

						if (i == name.size()) {
							ans = max(ans, dp[i][t][c - 'a']);
						}
					}
				}
			}
		}
	}

	cout << ans;

	return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

#define ZERO_IQ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define debug(x, y) cerr<<(#x)<<" " <<(#y)<<" is " << (x) <<" "<< (y) << endl
#define debug2(x, y, z) cerr<<(#x)<<" " <<(#y)<<" " <<(#z)<<" is " << (x) <<" "<< (y) <<" "<<(z) << endl
#define watch(x) cerr<<(#x)<<" is " << (x) << endl
string s;
int arr[30][30];
ll dp[101][101][27];

ll solve(int x, int l, int prev) {
    if (x == s.size()) return 0;
    if (dp[x][l][prev] != -1) return dp[x][l][prev];
    ll res = solve(x + 1, l, s[x] - 'a') + arr[prev][s[x] - 'a'];
    for (char i = 'a'; i <= 'z'; i++) {
        if (i != s[x] && l > 0) res = max((ll) res, solve(x + 1, l - 1, i - 'a') + arr[prev][i - 'a']);
    }
    return dp[x][l][prev] = res;
}

int main() {
    memset(dp, -1, sizeof dp);
    int a, n;
    cin >> s >> a >> n;
    for (int i = 0; i < n; i++) {
        char q, qq;
        cin >> q >> qq;
        cin >> arr[q - 'a'][qq - 'a'];
    }
    cout << solve(0, a, 1) << endl;
    return 0;
}