codeparrot/codecomplex huggingface dataset:
// Problem: 387_D. George and Interesting Graph
// Time complexity: cubic
//Author: net12k44
import java.io.*;
import java.util.*;
public
class Main{//}
	
static PrintWriter out;

static int c[][];
static int x[] , y[] , n;
static int degIn[];
static ArrayList< ArrayList<Integer> >a = new ArrayList< ArrayList<Integer> >();
static int cnt = 0;
static boolean b[];

private static boolean dfs(int i) {
	if (i == -1) return true;
	if (b[i]) return false;
	b[i] = true;
	for(Integer j : a.get(i) ) 
		if ( dfs( y[j] ) ) {
			x[i] = j;
			y[j] = i;
			return true;
		}
	return false;
}

private static void find(int k) {
	int _cnt = -1;
	if (k>=0) { x[k] = k; y[k] = k; }
	while (_cnt != cnt) {
		_cnt = cnt;
		Arrays.fill( b , false );
		if (k>=0) b[k] = true;
		for(int i = 0; i < n; ++i)
		   if (x[i] == -1 && dfs(i) ) ++cnt;
	}
	if (k>=0) { x[k] = -1; y[k] = -1; }

}

public static void solve() {
	n = in.nextInt();
	int m = in.nextInt();
	
	b = new boolean[n]; c = new int [n][n];
	degIn = new int[n]; x = new int[n]; y = new int[n];	
	Arrays.fill(x , -1); Arrays.fill(y , -1);
	for(int i = 0; i < n; ++i) a. add( new ArrayList< Integer > () );
	
	while (m-- > 0) {
		int i = in.nextInt()-1 , j = in.nextInt()-1;
		a.get(i).add(j);
		degIn[j]++;
		c[i][j] = 1;
	}
	
	find(-1);
	int kq = Integer.MAX_VALUE;
	
	for(int k = 0; k < n; ++k) {
		if (x[k] != -1) {y[ x[k] ] = -1; x[k] = -1; cnt--; }
		if (y[k] != -1) {x[ y[k] ] = -1; y[k] = -1; cnt--; }
		find(k);
		
		int t = n*2 - 1 - a.get(k).size() - degIn[k] + c[k][k];
		for(int i = 0; i < n; ++i)
		 if (i!=k) 
			t = t + a.get(i).size() - c[i][k];		
		t = t - cnt + (n-1) - cnt;
		if (kq > t) kq = t;		
	}
	out.println(kq);
	
}
	
public static void main (String[] args) throws java.lang.Exception {		
	long startTime = System.currentTimeMillis();

	out = new PrintWriter(System.out);
	solve();	
	//out.println((String.format("%.2f",(double)(System.currentTimeMillis()-startTime)/1000)));
	out.close();
}
	
static class in {
	static BufferedReader reader = new BufferedReader( new InputStreamReader(System.in) ) ;
	static StringTokenizer tokenizer = new StringTokenizer("");				
	static String next() {		
		while ( !tokenizer.hasMoreTokens() )
			try { tokenizer = new StringTokenizer( reader.readLine() ); }
			catch (IOException e){
				throw new RuntimeException(e);			
			}		
		return tokenizer.nextToken();
	}
	static int nextInt() { return Integer.parseInt( next() ); }		
	static double nextDouble(){ return Double.parseDouble( next() ); }
}
//////////////////////////////////////////////////
}//
// Problem: 387_D. George and Interesting Graph
// Time complexity: cubic
import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.lang.System.out;
import static java.util.Collections.*;
import java.io.*;
import java.math.*;
import java.util.*;

public class Main {
	static boolean LOCAL = System.getSecurityManager() == null;
	Scanner in = new Scanner(System.in);
	private int[] B;
	private int[] A;
	private int n;
	private int m;

	void run() {
		n = in.nextInt();
		m = in.nextInt();
		A = new int[m];
		B = new int[m];
		for (int i = 0; i < m; i++) {
			A[i] = in.nextInt() - 1;
			B[i] = in.nextInt() - 1;
		}
		int ans = Integer.MAX_VALUE;
		for (int i = 0; i < n; i++) {
			ans = min(ans, solve(i));
		}
		out.println(ans);
	}
	int solve(int x) {
		int ans = 3 * (n - 1)  + 1 + m;
		V[] vs = new V[n * 2];
		for (int i = 0; i < vs.length; i++) vs[i] = new V();
		for (int i = 0; i < m; i++) {
			if (A[i] == x || B[i] == x) ans -= 2;
			else vs[A[i]].connect(vs[n + B[i]]);
		}
		return ans - 2 * bipartiteMatching(vs);
	}
	class V extends ArrayList<V> {
		V pair;
		boolean used;
		void connect(V v) {
			add(v);
			v.add(this);
		}
	}
	int bipartiteMatching(V[] vs) {
		int match = 0;
		for (V v : vs) if (v.pair == null) {
			for (V u : vs) u.used = false;
			if (dfs(v)) match++;
		}
		return match;
	}
	boolean dfs(V v) {
		v.used = true;
		for (V u : v) {
			V w = u.pair;
			if (w == null || !w.used && dfs(w)) {
				v.pair = u;
				u.pair = v;
				return true;
			}
		}
		return false;
	}
	void debug(Object... os) {
		System.err.println(deepToString(os));
	}

	public static void main(String[] args) {
		if (LOCAL) {
			try {
				System.setIn(new FileInputStream("./../../in.txt"));
				// System.setOut(new PrintStream("./../../out"));
			} catch (Throwable e) {
				LOCAL = false;
			}
		}
		long start = 0;
		if (LOCAL)
			start = System.nanoTime();
		new Main().run();
		if (LOCAL)
			System.err.printf("[Time : %.6f s]%n",
					(System.nanoTime() - start) * 1e-9);
	}
}

class Scanner {
	BufferedReader br;
	StringTokenizer st;

	Scanner(InputStream in) {
		br = new BufferedReader(new InputStreamReader(in));
		eat("");
	}

	void eat(String s) {
		st = new StringTokenizer(s);
	}

	String nextLine() {
		try {
			return br.readLine();
		} catch (IOException e) {
			return null;
		}
	}

	boolean hasNext() {
		while (!st.hasMoreTokens()) {
			String s = nextLine();
			if (s == null)
				return false;
			eat(s);
		}
		return true;
	}

	String next() {
		hasNext();
		return st.nextToken();
	}

	int nextInt() {
		return Integer.parseInt(next());
	}

	long nextLong() {
		return Long.parseLong(next());
	}

	double nextDouble() {
		return Double.parseDouble(next());
	}
}
// Problem: 387_D. George and Interesting Graph
// Time complexity: cubic
import java.io.*;
import java.util.*;

public class CF387D {
	static class A {
		ArrayList<Integer> list = new ArrayList<>();
		int u, v, d;
	}
	static int INF = Integer.MAX_VALUE;
	static boolean bfs(A[] aa, int n) {
		LinkedList<Integer> queue = new LinkedList<>();
		for (int u = 1; u <= n; u++)
			if (aa[u].v > 0)
				aa[u].d = INF;
			else {
				aa[u].d = 0;
				queue.addLast(u);
			}
		aa[0].d = INF;
		while (!queue.isEmpty()) {
			int u = queue.removeFirst();
			if (aa[u].d + 1 == aa[0].d)
				break;
			for (int v : aa[u].list) {
				int w = aa[v].u;
				if (aa[w].d == INF) {
					aa[w].d = aa[u].d + 1;
					queue.addLast(w);
				}
			}
		}
		return aa[0].d != INF;
	}
	static boolean dfs(A[] aa, int n, int u) {
		if (u == 0)
			return true;
		for (int v : aa[u].list) {
			int w = aa[v].u;
			if (aa[w].d == aa[u].d + 1 && dfs(aa, n, w)) {
				aa[u].v = v;
				aa[v].u = u;
				return true;
			}
		}
		aa[u].d = INF;
		return false;
	}
	static int matchings(A[] aa, int n) {
		int cnt = 0;
		while (bfs(aa, n))
			for (int u = 1; u <= n; u++)
				if (aa[u].v == 0 && dfs(aa, n, u))
					cnt++;
		return cnt;
	}
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int n = Integer.parseInt(st.nextToken());
		int m = Integer.parseInt(st.nextToken());
		int[] eu = new int[m];
		int[] ev = new int[m];
		for (int j = 0; j < m; j++) {
			st = new StringTokenizer(br.readLine());
			eu[j] = Integer.parseInt(st.nextToken());
			ev[j] = Integer.parseInt(st.nextToken());
		}
		A[] aa = new A[n + 1];
		int min = m + n * 3;
		for (int ctr = 1; ctr <= n; ctr++) {
			boolean loop = false;
			boolean[] ci = new boolean[n + 1];
			boolean[] co = new boolean[n + 1];
			for (int i = 0; i <= n; i++)
				aa[i] = new A();
			int m_ = 0;
			for (int j = 0; j < m; j++) {
				int u = eu[j];
				int v = ev[j];
				if (u == ctr && v == ctr)
					loop = true;
				else if (u == ctr && v != ctr)
					ci[v] = true;
				else if (u != ctr && v == ctr)
					co[u] = true;
				else {
					aa[u].list.add(v);
					m_++;
				}
			}
			int cnt = loop ? 0 : 1;
			for (int i = 1; i <= n; i++)
				if (i != ctr) {
					if (!ci[i])
						cnt++;
					if (!co[i])
						cnt++;
				}
			int m2 = matchings(aa, n);
			cnt += (m_ - m2) + (n - 1 - m2);
			if (min > cnt)
				min = cnt;
		}
		System.out.println(min);
	}
}
// Problem: 387_D. George and Interesting Graph
// Time complexity: cubic
import java.io.*;
import java.util.*;

public class CF {

	class W implements Comparable<W> {
		int id, sz;

		W(int id, int sz) {
			this.id = id;
			this.sz = sz;
		}

		@Override
		public int compareTo(W o) {
			return -Integer.compare(sz, o.sz);
		}
	}

	int[] left;
	int center;
	boolean[] used;

	boolean go(int v) {
		if (used[v])
			return false;
		used[v] = true;
		for (int i = 0; i < g[v].size(); ++i) {
			int to = g[v].get(i);
			if (to == center)
				continue;
			if (left[to] == -1 || go(left[to])) {
				left[to] = v;
				return true;
			}
		}
		return false;
	}

	ArrayList<Integer>[] g;

	void solve() {
		
		int n = in.nextInt();
		int m = in.nextInt();
		used = new boolean[n];
		g = new ArrayList[n];
		for (int i = 0; i < n; i++)
			g[i] = new ArrayList<>();
		for (int i = 0; i < m; i++) {
			g[in.nextInt() - 1].add(in.nextInt() - 1);
		}
		long st = System.currentTimeMillis();
		int ans = Integer.MAX_VALUE;
		W[] a = new W[n];
		for (int i = 0; i < n; i++) {
			a[i] = new W(i, g[i].size());
		}
		left = new int[n];
		Arrays.sort(a);
		for (int centerId = 0; centerId < n; centerId++) {
			center = a[centerId].id;
			if (System.currentTimeMillis() - st > 800)
				break;
			int cost = n - g[center].size();
			Arrays.fill(left, -1);
			for (int i = 0; i < n; i++)
				if (i != center) {
					boolean has = false;
					for (int j = 0; j < g[i].size(); j++) {
						if (g[i].get(j) == center)
							has = true;
					}
					Arrays.fill(used, false);
					if (!go(i)) {
						if (has) {
							cost += g[i].size();
						} else {
							cost += g[i].size() + 2;
						}
					} else {
						if (has) {
							cost += g[i].size() - 2;
						} else {
							cost += g[i].size();
						}
					}
				}
			ans = Math.min(ans, cost);
		}
		out.println(ans);
	}

	FastScaner in;
	PrintWriter out;

	void run() {
		in = new FastScaner(System.in);
		out = new PrintWriter(System.out);

		solve();

		out.close();
	}

	void runWithFiles() {
		in = new FastScaner(new File("input.txt"));
		try {
			out = new PrintWriter(new File("output.txt"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}

		solve();

		out.close();
	}

	public static void main(String[] args) {
		Locale.setDefault(Locale.US);
		new CF().run();
	}

	class FastScaner {
		BufferedReader br;
		StringTokenizer st;

		FastScaner(InputStream is) {
			br = new BufferedReader(new InputStreamReader(is));
		}

		FastScaner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return null;
				st = new StringTokenizer(s);
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}
	}
}
// Problem: 387_D. George and Interesting Graph
// Time complexity: cubic
import com.sun.java_cup.internal.runtime.virtual_parse_stack;

import java.util.Arrays;
import java.util.Scanner;

/**
 * Created by ali on 2/3/14.
 */
public class D
{
	public static void main(String [] args)
	{
		Scanner in = new Scanner(System.in);

		int n = in.nextInt();
		int m = in.nextInt();

		boolean [][] graph = new boolean[n][n];
		for(int i = 0 ; i < m ; i++)
		{
			int a = in.nextInt() - 1;
			int b = in.nextInt() - 1;

			graph[a][b] = true;
		}

		int res = Integer.MAX_VALUE;
		for(int center = 0 ; center < n ; center++)
		{
			int calc = 0;
			for(int i = 0 ; i < n ; i++)
			{
				if(!graph[center][i])
					calc++;
				if(!graph[i][center])
					calc++;
			}

			if(!graph[center][center])
				calc--;

			int [] match = new int[n];
			Arrays.fill(match, -1);
			int max = 0;

			for(int i = 0 ; i < n ; i++)
				if(i != center)
					if(can(i, graph, new boolean[n], center, match))
						max++;

			int unusable = m - (2*n - 1 - calc) - max;
			calc += unusable;
			calc += (2*(n-1) - 2*max)/2;

			res = Math.min(res, calc);
		}

		System.out.println(res);


	}

	private static boolean can(int at, boolean[][] graph, boolean[] visited, int center, int [] match)
	{
		if(visited[at])
			return false;
		visited[at] = true;

		for(int to = 0 ; to < graph.length ; to++)
			if(graph[at][to])
				if(to != center)
					if(match[to] == -1 || can(match[to], graph, visited, center, match))
					{
						match[to] = at;
						return true;
					}

		return false;
	}
}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
import java.util.Scanner;


public class P23A {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		String input = scan.nextLine();
		System.out.println(F(input));
	}
	
	
	static int F(String string){
		int ans =0;
		for (int i = 0; i < string.length(); i++) {
			for (int j = 1; j < string.length()-i; j++) {
				String s = string.substring(i, i+j);
				int a=string.indexOf(s);
				int b=string.lastIndexOf(s);
				if ( a >= 0 && b >=0 && a !=b)  ans =Math.max(ans, s.length());
			}
		}
		return ans;
	}
}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
import java.util.*;

public class A {

    static Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {
        String s = sc.next();
        for (int l = s.length(); l > 0; --l) {
            HashSet<String> set = new HashSet<String>();
            for (int i = 0; i < s.length() - l + 1; ++i)
                if (set.contains(s.substring(i, i + l))) {
                    System.out.println(l);
                    return;
                } else {
                    set.add(s.substring(i, i + l));
                }
        }
        System.out.println(0);
    }

}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
import java.util.Scanner;


public class Prob023A
{
    public static void main( String[] Args )
    {
        Scanner scan = new Scanner( System.in );
        String s = scan.next();

        all: for ( int x = s.length() - 1; x >= 0; x-- )
            for ( int y = 0; x + y <= s.length(); y++ )
            {
                String sub = s.substring( y, y + x );
                if ( s.indexOf( sub, y + 1 ) >= 0 )
                {
                    System.out.println( x );
                    break all;
                }
            }
    }
}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;


public class A23 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s = sc.next();
		Map<String, Boolean> map = new HashMap<String, Boolean>();
		for (int i = s.length(); i >= 1; i--) {
			map.clear();
			for (int j = 0; j < s.length()-i+1; j++) {
				String temp = s.substring(j, j+i);
				if (map.containsKey(temp)) {
					System.out.println(i);
					return;
				}
				map.put(temp, true);
			}
		}
		System.out.println(0);
	}

}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
/**
 * MxNINJA 04:06:52 ص 14/01/2014
 */
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder line = new StringBuilder(reader.readLine());
        int length = 0;
        for (int head = 0; head < line.length(); head++) {
            for (int tail = line.length() - 1; tail > head; tail--) {
                String subString = line.substring(head, tail);
                if(line.indexOf(subString,head+1)>-1){
                    length = Math.max(subString.length(), length);
                }
            }
        }
        System.out.println(length);
    }
}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
import java.io.BufferedReader;
import java.io.InputStreamReader;


public class YouAreGivenAString {
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
		String s=r.readLine();
		int max=0;
		for(int i=1;i<s.length();i++){
			for (int j = 0; j <= s.length()-i; j++) {
				String sub=s.substring(j,j+i);
				if(count(s,sub)>=2)
				max=Math.max(max, i);
			}
		}
		System.out.println(max);
	}

	private static int count(String s, String sub) {
		int l=sub.length();
		int c=0;
		for(int i=0;i<=s.length()-l;i++){
			if(s.substring(i,i+l).equals(sub))
				c++;
		}
		return c;
	}
}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
import java.util.Scanner;


public class Main {
    public static void main(String[] args) {
        Scanner r = new Scanner(System.in);
        
        String a = r.next();
        char[] c = a.toCharArray();
        
        for(int l = a.length()-1; l >= 1; l--){
            for(int i = 0; i <= a.length()-l; i++){
                int j = i+l-1;
                
                for(int s = 0; s <= a.length()-l; s++){
                    if(i == s)continue;
                    if(a.substring(i, i+l).equals(a.subSequence(s, s+l))){
                        System.out.println(l);
                        System.exit(0);
                    }
                        
                }
            }
        }
        
        System.out.println(0);
        
    }
}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
import java.io.*;
import java.util.*;

public class Main{
	public static void main( String[] args ){
		Scanner cin = new Scanner( System.in );
		String s = cin.next();
		int n = s.length();
		char[] ss = new char[ n ];
		ss = s.toCharArray();
		
		int ans = 0;
		
		for (int i=0; i<n; i++)
			for (int j=i+1; j<n; j++){
				int k = 0;
				while ( i+k<n && j+k<n && ss[i+k] == ss[j+k] ) k++;
				
				ans = Math.max( ans, k );
			}
		
		System.out.println( ans );
	}
}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
import java.util.Scanner;


public class prob1 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		String s = input.next();
		int n = s.length();
		int i = n-1;
		CharSequence temp;
		for(i = n-1; i > 0; i--)
			for(int j = 0 ; j <= n-i; j++)
			{
				temp = s.subSequence(j, i+j);
				if( s.substring(j+1, n).contains(temp) || s.substring(0, j+i-1).contains(temp))
				{
					System.out.println(i);
					return;
				}
			}
		System.out.println(0);
	}
}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
import java.io.*;
import java.util.*;

import static java.lang.Math.*;
import static java.util.Arrays.fill;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.sort;

public class Main {
	public static void main(String[] args) throws IOException {
		try {
			if (new File("input.txt").exists())
				System.setIn(new FileInputStream("input.txt"));
		} catch (SecurityException e) {}
		
		new Main().run();
	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st = new StringTokenizer("");
	
	void run() throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);

		String s = in.readLine();
		
		for (int len = s.length() - 1; len > 0; len--) {
			Set<String> set = new HashSet<String>();
			for (int i = 0; i + len <= s.length(); i++) {
				String ss = s.substring(i, i + len);
				if (set.contains(ss)) {
					out.println(len);
					out.close();
					return;
				}
				set.add(ss);
			}
		}
		out.println(0);
		out.close();
	}
	
	String nextToken() throws IOException {
		while (!st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}
	
	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}
	
	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}
	
	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
	
	String nextLine() throws IOException {
		st = new StringTokenizer("");
		return in.readLine();
	}
	
	boolean EOF() throws IOException {
		while (!st.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null)
				return true;
			st = new StringTokenizer(s);
		}
		return false;
	}
}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
import java.util.*;
import java.io.*;

public class a {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String s = sc.next();
		
		int len = s.length();
		for(int i=len-1; i>=1; --i) {
			for(int j=0; j<=len - i; ++j) {
				String ss = s.substring(j, j+i);

				if(s.substring(j+1).indexOf(ss)!=-1) {
					System.out.println(ss.length());
					return;
				} 
			}
		}
		System.out.println(0);
	}
}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic
import java.io.*;
import java.util.*;

public class Main implements Runnable {

	public void _main() throws IOException {
		String s = next();
		for (int len = s.length(); len >= 1; len--) {
			for (int i = 0; i + len <= s.length(); i++)
				for (int j = i + 1; j + len <= s.length(); j++)
					if (s.substring(i, i + len).equals(s.substring(j, j + len))) {
						out.print(len);
						return;
					}
		}
		out.print(0);
	}

	private BufferedReader in;
	private PrintWriter out;
	private StringTokenizer st;

	private String next() throws IOException {
		while (st == null || !st.hasMoreTokens()) {
			String rl = in.readLine();
			if (rl == null)
				return null;
			st = new StringTokenizer(rl);
		}
		return st.nextToken();
	}

	private int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	private long nextLong() throws IOException {
		return Long.parseLong(next());
	}

	private double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}

	public static void main(String[] args) {
		new Thread(new Main()).start();
	}

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);

			_main();

			out.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(202);
		}
	}

}
// Problem: 23_A. You're Given a String...
// Time complexity: cubic

import java.io.*;
import java.util.*;

public class Main implements Runnable
{
  Scanner in;
  PrintWriter out; //= new PrintWriter(System.out);

  public static void main(String[] args) throws FileNotFoundException, IOException
  {
    new Thread(new Main()).start();
  }

  public class Pair
  {
    public long last;
    public long count;
    public int L;
    Pair(long l, long c) {last = l; count = c;}
    Pair(long l, long c, int L) {last = l; count = c; this.L = L;}
  }

  public void run()
  {
    final String name = "B-small";
    //try {
      in = new Scanner(System.in);// (new File(name + ".in"));//StreamTokenizer(new FileReader(new File(name + ".in")));
      out = new PrintWriter(System.out); // new PrintWriter(new File(name + ".out")); //= new PrintWriter(System.out);
    //} catch (IOException e) {}


    String s = in.next().trim();
    int n = s.length();
    boolean[][] a = new boolean[n][n];

   for (int i = 0; i < n; ++i)
     for (int j = i + 1; j < n; ++j)
       a[i][j] = (s.charAt(i) == s.charAt(j));

    int max = 0;
    for (int i = 0; i < n; ++i)
     for (int j = i + 1; j < n; ++j)
     {
       int k =0;
       while (i + k < n && j + k < n && a[i + k][j + k])
           ++k;
       
       if (max < k)
           max = k;
     }
    
    out.println(max);
    out.flush();
  }

}