import java.util.Arrays;
import java.util.Set;
import java.util.Collections;
import java.util.HashSet;
import java.util.Scanner;
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        long arr1[]=new long[26];
        long [][]arr2=new long [26][26];
        String s=sc.nextLine();
        for(int i=0;i<s.length();i++) {
        	int c=(int)s.charAt(i)-'a';
        	for(int j=0;j<26;j++) {
        		arr2[j][c]+=arr1[j];
        	}
        	arr1[c]++;
        }
        long ans=0;
        for(int i=0;i<26;i++) {
        	ans=Math.max(ans, arr1[i]);
        }
        for(int i=0;i<26;i++) {
        	for(int j=0;j<26;j++) {
        		ans=Math.max(ans, arr2[i][j]);
        	}
        }
        System.out.println(ans);
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CCowAndMessage solver = new CCowAndMessage();
        solver.solve(1, in, out);
        out.close();
    }

    static class CCowAndMessage {
        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            char arr[] = in.scanString().toCharArray();
            long ans = 0;
            long count[] = new long[26];
            for (char k : arr) count[k - 'a']++;
            for (int i = 0; i < 26; i++) ans = Math.max(ans, count[i]);

            int n = arr.length;
            long pre[][] = new long[n][26];
            for (int i = 0; i < n; i++) {
                pre[i][arr[i] - 'a']++;
                for (int j = 0; j < 26; j++) pre[i][j] += (i - 1 >= 0) ? pre[i - 1][j] : 0;
            }

            long pair[][] = new long[26][26];

            for (int i = 0; i < n; i++) {
                int y = arr[i] - 'a';
                for (int x = 0; x < 26; x++) {
                    pair[x][y] += (i - 1) >= 0 ? pre[i - 1][x] : 0;
                }
            }

            for (int i = 0; i < 26; i++) {
                for (int j = 0; j < 26; j++) {
                    ans = Math.max(ans, pair[i][j]);
                }
            }

            out.println(ans);

        }

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int INDEX;
        private BufferedInputStream in;
        private int TOTAL;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (INDEX >= TOTAL) {
                INDEX = 0;
                try {
                    TOTAL = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (TOTAL <= 0) return -1;
            }
            return buf[INDEX++];
        }

        public String scanString() {
            int c = scan();
            while (isWhiteSpace(c)) c = scan();
            StringBuilder RESULT = new StringBuilder();
            do {
                RESULT.appendCodePoint(c);
                c = scan();
            } while (!isWhiteSpace(c));
            return RESULT.toString();
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CCowAndMessage solver = new CCowAndMessage();
        solver.solve(1, in, out);
        out.close();
    }

    static class CCowAndMessage {
        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            char arr[] = in.scanString().toCharArray();
            long ans = 0;
            int count[] = new int[26];
            for (char k : arr) count[k - 'a']++;
            for (int i = 0; i < 26; i++) ans = Math.max(ans, count[i]);

            int n = arr.length;
            int pre[][] = new int[n][26];
            for (int i = 0; i < n; i++) {
                pre[i][arr[i] - 'a']++;
                for (int j = 0; j < 26; j++) pre[i][j] += (i - 1 >= 0) ? pre[i - 1][j] : 0;
            }

            int pair[][] = new int[26][26];

            for (int i = 0; i < n; i++) {
                int y = arr[i] - 'a';
                for (int x = 0; x < 26; x++) {
                    pair[x][y] += (i - 1) >= 0 ? pre[i - 1][x] : 0;
                }
            }

            for (int i = 0; i < 26; i++) {
                for (int j = 0; j < 26; j++) {
                    ans = Math.max(ans, pair[i][j]);
                }
            }

            out.println(ans);

        }

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int INDEX;
        private BufferedInputStream in;
        private int TOTAL;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (INDEX >= TOTAL) {
                INDEX = 0;
                try {
                    TOTAL = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (TOTAL <= 0) return -1;
            }
            return buf[INDEX++];
        }

        public String scanString() {
            int c = scan();
            while (isWhiteSpace(c)) c = scan();
            StringBuilder RESULT = new StringBuilder();
            do {
                RESULT.appendCodePoint(c);
                c = scan();
            } while (!isWhiteSpace(c));
            return RESULT.toString();
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public final class CowAndMessageCF{
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String s=br.readLine();
        int arr[]=new int[26];
        int dp[][]=new int[26][26];
        for(int i=0;i<s.length();i++){
            int c=s.charAt(i)-97;
            for(int j=0;j<26;j++){
                dp[j][c]+=arr[j];  // how many times c will come after j, which is equal to count of j
            }
            arr[c]++;
        }
        int ans=1;
        for(int i=0;i<26;i++)
            ans=Math.max(ans,arr[i]);
        for(int i=0;i<26;i++) {
            for (int j = 0; j < 26; j++) {
                //System.out.print(dp[i][j]+" ");
                ans = Math.max(ans, dp[i][j]);
            }
        }
        System.out.println(ans);
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public final class CowAndMessageCF{
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String s=br.readLine();
        int arr[]=new int[26];
        long dp[][]=new long[26][26];
        for(int i=0;i<s.length();i++){
            int c=s.charAt(i)-97;
            for(int j=0;j<26;j++){
                dp[j][c]+=arr[j];  // how many times c will come after j, which is equal to count of j
            }
            arr[c]++;
        }
        long ans=1;
        for(int i=0;i<26;i++)
            ans=Math.max(ans,arr[i]);
        for(int i=0;i<26;i++) {
            for (int j = 0; j < 26; j++) {
                //System.out.print(dp[i][j]+" ");
                ans = Math.max(ans, dp[i][j]);
            }
        }
        System.out.println(ans);
    }
}


import java.io.*;
import java.util.*;
import java.lang.*;
public class Codechef {
	PrintWriter out;
    StringTokenizer st;
    BufferedReader br;

 	class Pair implements Comparable<Pair>
	{
	    int f;
	    int s;

	    Pair(int t, int r) {
	       f = t;
	       s = r;
	    }
	    public int compareTo(Pair p)
	    {
	    	if(this.f!=p.f)
	    		return this.f-p.f;

	    	return this.s-p.s;
	    }
 	}

	String ns() {
        while (st == null || !st.hasMoreElements()) {

            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    String nextLine() throws Exception {
        String str = "";
        try {
            str = br.readLine();
        } catch (IOException e) {
            throw new Exception(e.toString());
        }
        return str;
    }

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

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

    double nextDouble() {
        return Double.parseDouble(ns());
    }

	// int upperBound(int a[],int key) //on sorted array
	// {
	// 	int l=0,r=a.length-1;
	// 	int ans=-1;
	// 	while(l<=r)
	// 	{
	// 		int mid=(l+r)/2;
	// 		if(a[mid]<key)
	// 			l=mid+1;
	// 		else
	// 		{
	// 			ans=a[mid];
	// 			r=mid-1;
	// 		}
	// 	}
	// 	return ans;
	// }
	int upperBound(ArrayList<Integer> a[],int j,int key) //on sorted array
	{
		int l=0,r=a[j].size()-1;
		int ans=-1;
		int ind=r+1;
		while(l<=r)
		{
			int mid=(l+r)/2;
			if(a[j].get(mid)<=key)
				l=mid+1;
			else
			{
				ans=a[j].get(mid);
				ind = mid;
				r=mid-1;
			}
		}
		return ind;
	}

	void solve() throws IOException{
		char ch[] = ns().toCharArray();
		ArrayList<Integer> a[]=new ArrayList[26];

		for(int i=0;i<26;i++)
			a[i]=new ArrayList<Integer>();

		for( int i=0;i<ch.length;i++)
		{
			a[(int)(ch[i]-'a')].add(i);
		}

		// for(int i=0;i<26;i++)
		// {
		// 	out.print((char)(i+'a')+" ");
		// 	for( int j=0;j<a[i].size();j++)
		// 	{
		// 		out.print(a[i].get(j)+" ");
		// 	}
		// 	out.println();
		// }
		long max=0,mm=Integer.MIN_VALUE;
		for(int i=0;i<26;i++)
		{
			if(mm<a[i].size())
				mm=a[i].size();
			for(int j=0;j<26;j++)
			{
				long sum=0;
				for(int k=0;k<a[i].size();k++)
				{
					int ind=upperBound(a,j,a[i].get(k));
					sum+=a[j].size()-ind;
				}
				max=Math.max(max,sum);
		//		out.print(sum+" ");
			}
		//	out.println();
		}
		out.println(Math.max(max,mm));
 	}

    void run() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
		solve();
		out.flush();
		out.close();
	}

	public static void main(String args[]) throws IOException {
		new Codechef().run();
	}

}


//package com.company;

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

public class Main {
    public static class Task {

        public void solve(Scanner sc, PrintWriter pw) throws IOException {
            String s = sc.next();
            int n = s.length();
            int[] a = new int[n];
            for (int i = 0; i < n; i++) {
                a[i] = s.charAt(i) - 'a';
            }
            int[][] prefix = new int[26][n + 1];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < 26; j++) {
                    prefix[j][i + 1] = prefix[j][i];
                }
                prefix[a[i]][i + 1]++;
            }
            long best = 0;
            for (int i = 0; i < 26; i++) {
                best = Math.max(best, prefix[i][n]);
            }
            for (int i = 0; i < n; i++) {
                int bestFirst = 0;
                for (int j = 0; j < 26; j++) {
                    bestFirst = Math.max(bestFirst, prefix[j][i]);
                }
                int bestSecond = 0;
                for (int j = 0; j < 26; j++) {
                    bestSecond = Math.max(bestSecond, prefix[j][n] - prefix[j][i]);
                }
                best = Math.max(best, (long) bestFirst * bestSecond);
            }
            pw.println(best);
        }
    }
    static long TIME_START, TIME_END;
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
//        Scanner sc = new Scanner(new FileInputStream("input"));
        PrintWriter pw = new PrintWriter(new BufferedOutputStream(System.out));
//        PrintWriter pw = new PrintWriter(new FileOutputStream("input"));

        Runtime runtime = Runtime.getRuntime();
        long usedMemoryBefore = runtime.totalMemory() - runtime.freeMemory();
        TIME_START = System.currentTimeMillis();
        Task t = new Task();
        t.solve(sc, pw);
        TIME_END = System.currentTimeMillis();
        long usedMemoryAfter = runtime.totalMemory() - runtime.freeMemory();
        pw.close();
        System.err.println("Memory increased: " + (usedMemoryAfter - usedMemoryBefore) / 1000000);
        System.err.println("Time used: " + (TIME_END - TIME_START) + ".");
    }
    static class Scanner {
        StringTokenizer st;
        BufferedReader br;
        public Scanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }
        public Scanner(FileReader s) throws FileNotFoundException {
            br = new BufferedReader(s);
        }
        public String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public String nextLine() throws IOException {
            return br.readLine();
        }
        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }
        public boolean ready() throws IOException {
            return br.ready();
        }
    }
}


//package com.company;

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

public class Main {
    public static class Task {

        public void solve(Scanner sc, PrintWriter pw) throws IOException {
            String s = sc.next();
            int n = s.length();
            int[] a = new int[n];
            for (int i = 0; i < n; i++) {
                a[i] = s.charAt(i) - 'a';
            }
            int[][] prefix = new int[26][n + 1];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < 26; j++) {
                    prefix[j][i + 1] = prefix[j][i];
                }
                prefix[a[i]][i + 1]++;
            }
            long best = 0;
            for (int i = 0; i < 26; i++) {
                best = Math.max(best, prefix[i][n]);
            }
            for (int i = 0; i < 26; i++) {
                for (int j = 0; j < 26; j++) {
                    long count = 0;
                    for (int k = 0; k < n; k++) {
                        if (a[k] == i) count += prefix[j][n] - prefix[j][k + 1];
                    }
                    best = Math.max(best, count);
                }
            }
//            for (int i = 0; i < n; i++) {
//                int bestFirst = 0;
//                for (int j = 0; j < 26; j++) {
//                    bestFirst = Math.max(bestFirst, prefix[j][i]);
//                }
//                int bestSecond = 0;
//                for (int j = 0; j < 26; j++) {
//                    bestSecond = Math.max(bestSecond, prefix[j][n] - prefix[j][i]);
//                }
//                best = Math.max(best, (long) bestFirst * bestSecond);
//            }
            pw.println(best);
        }
    }
    static long TIME_START, TIME_END;
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
//        Scanner sc = new Scanner(new FileInputStream("input"));
        PrintWriter pw = new PrintWriter(new BufferedOutputStream(System.out));
//        PrintWriter pw = new PrintWriter(new FileOutputStream("input"));

        Runtime runtime = Runtime.getRuntime();
        long usedMemoryBefore = runtime.totalMemory() - runtime.freeMemory();
        TIME_START = System.currentTimeMillis();
        Task t = new Task();
        t.solve(sc, pw);
        TIME_END = System.currentTimeMillis();
        long usedMemoryAfter = runtime.totalMemory() - runtime.freeMemory();
        pw.close();
        System.err.println("Memory increased: " + (usedMemoryAfter - usedMemoryBefore) / 1000000);
        System.err.println("Time used: " + (TIME_END - TIME_START) + ".");
    }
    static class Scanner {
        StringTokenizer st;
        BufferedReader br;
        public Scanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }
        public Scanner(FileReader s) throws FileNotFoundException {
            br = new BufferedReader(s);
        }
        public String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public String nextLine() throws IOException {
            return br.readLine();
        }
        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }
        public boolean ready() throws IOException {
            return br.ready();
        }
    }
}


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

public class Q1 {

    public static void main(String[] args) {
        InputReader in = new InputReader();
        PrintWriter out = new PrintWriter(System.out);

        long ans = 0;
        char arr[] = in.next().toCharArray();
        int N = arr.length;
        int index[] = new int[26];
        for (int i = 0; i < N; i++)
            index[arr[i] - 'a']++;

        for(int i =0;i<26;i++)
            ans=Math.max(ans,index[i]);

        long temp=0;
        HashMap<String, Long> map = new HashMap<>();
        for (int i = 0; i < N; i++) {
            index[arr[i] - 'a']--;
            for (int j = 0; j < 26; j++) {
                char ch = (char) (j + 'a');
                String str = arr[i]+""; str +=  ch;

                map.put(str, map.getOrDefault(str, temp) + index[j]);
            }
        }

        for (String str : map.keySet()) {
//         System.out.println(str + "   " + map.get(str));
            ans=Math.max(ans,map.get(str));
        }

        out.println(ans);
        out.close();
}

// ternary Search Question
//    public static void main(String[] args) {
//
//        InputReader in = new InputReader();
//        PrintWriter out = new PrintWriter(System.out);
//        int t=in.nextInt();
//        while(t-->0) {
//
//            int N = in.nextInt(),max=-1,diff=0;
//            int arr[] = new int[N];
//            for(int  i=0;i<N;i++){
//                arr[i]=in.nextInt();
//                max=Math.max(max,arr[i]);
//            }
//            if(max==-1){
//                out.println(0+" "+1);
//                continue;
//            }
//
//
//
//            for(int i =1;i<N;i++){
//                int  a =arr[i]==-1?max:arr[i],b =arr[i-1]==-1?max:arr[i-1],d=Math.abs(a-b);
//                diff=Math.max(diff,d);
//            }
//            System.out.println(max+"  diff:-"+diff);
//
//            int l=0,r=max;
//            while(l<=r){
//                int mid=(l+r)/2;
//                int di=0;
//                for(int i =1;i<N;i++){
//                    int  a =arr[i]==-1?mid:arr[i],b =arr[i-1]==-1?mid:arr[i-1],d=Math.abs(a-b);
//                    di=Math.max(di,d);
//                }
//                System.out.println(mid+"  diff:-"+di);
//                if(di<diff){
//                    r=mid-1;
//                    max=mid; diff=di;
//                }else{
//                    l=mid+1;
//                }
//            }
//
//            out.println(diff+" "+max);
//
//        }
//        out.close();
//
//
//    }

static class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public int[] shuffle(int[] arr) {
        Random r = new Random();
        for (int i = 1, j; i < arr.length; i++) {
            j = r.nextInt(i);
            arr[i] = arr[i] ^ arr[j];
            arr[j] = arr[i] ^ arr[j];
            arr[i] = arr[i] ^ arr[j];
        }
        return arr;
    }

    public InputReader() {
        reader = new BufferedReader(new InputStreamReader(System.in), 32768);
        tokenizer = null;
    }

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(System.in), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public char nextChar() {
        return next().charAt(0);
    }

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

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

    public double nextDouble() {
        return Double.parseDouble(next());
    }

}

}

//    public static void main(String[] args) {
//
//        InputReader in = new InputReader();
//        PrintWriter out = new PrintWriter(System.out);
//        int t  =in.nextInt();
//
//        while(t-->0){
//            int  N=in.nextInt();
//            int arr[]=new int[N];
//            for(int i=0 ;i<N;i++)
//                arr[i]=in.nextInt();
//
//            ArrayList<Integer> set1=new ArrayList<>(),set2=new ArrayList<>(),set3=new ArrayList<>();
//            double xval=in.nextInt(),x=in.nextInt(),yval=in.nextInt(),y=in.nextInt();
//            long k=in.nextLong();
//            long  ans  =0;
//
//            if(xval<yval){
//                double temp=xval;
//                xval=yval;
//                yval=temp;
//
//                temp=x;
//                x=y;
//                y=temp;
//            }
//            xval=xval/100; yval=yval/100;
//
//            for(int i =0;i<N;i++){
//                if((i+1)%x==0 && (i+1)%y==0)
//                    set1.add(i);
//                else if ((i+1)%x==0 )
//                    set2.add(i);
//                else if((i+1)%y==0)
//                    set3.add(i);
//            }
//            arr=in.shuffle(arr);
//
//            int a =0,b=0,c=0,add=0;
//
//            for(int  i=N-1;i>=0;i--){
//
//                int temp=0;
//
//                if(a==set1.size()  && b==set2.size()  && c==set3.size())
//                    continue;
//                else if (a==set1.size()  && b==set2.size() ){
//                    ans += (yval) * arr[i];
//                    c++;
//                    temp=11;
//                }else if(a==set1.size()){
//                    if (set2.get(b) <set3.get(c)) {
//                        ans += (xval) * arr[i];
//                        b++;
//                    } else {
//                        ans += (yval) * arr[i];
//                        c++;
//                    }
//                }else{
//                    if (set1.get(a) < set2.get(b) && set1.get(a) < set3.get(c)) {
//                        ans += (xval + yval) * arr[i];
//                        a++;
//                    } else if (set2.get(b)<set3.get(c)) {
//                        ans += (xval) * arr[i];
//                        b++;
//                    } else {
//                        ans += (yval) * arr[i];
//                        c--;
//                    }
//                }
//
//
//
//                if(ans>=k){
//                    break;
//                }
//
//            }
//
//            if(ans<k)
//                out.println(-1);
//            else
//                out.println(add);
//
//
//
//        }
//
//        out.close();
//    }

//
//import java.io.*;
//import java.util.*;
//
//
//public class Q3 {
//
//
//    // tunnel wala Question tourist
//
////    public static void main(String[] args) {
////
////        InputReader in = new InputReader();
////        PrintWriter out = new PrintWriter(System.out);
////
////        int  N=in.nextInt();
////        int arr1[]=new int [N],arr2[]=new int[N];
////        int ans =0;
////
////        for(int i =0;i<N;i++){
////            arr1[i]=in.nextInt();
////        }
////
////        HashMap<Integer,Integer>map=new HashMap<>();
////
////        for(int j=0;j<N;j++){
////            int num=in.nextInt();
////            arr2[j]=num;
////            map.put(num,N-j);
////        }
////        int a[]=new int [N+1];
////
////        boolean flag=false;
////        for(int i =0;i<N;i++) {
////            int num = arr1[i];
////            int val=map.get(num);
////            if(val>(N-i))
////                ans++;
////            else if(val==N-i && !flag){
////                ans++;
////
////            }
////            a[arr1[i]]++;
////            a[arr2[N-i-1]]++;
////
////            if(a[arr1[i]]!=2 || a[arr2[N-i-1]]!=2)
////                flag=false;
////            else
////                flag=true;
////
////        }
////        out.println(ans);
////
////        out.close();
////
////
////    }
//
//    static class InputReader {
//        public BufferedReader reader;
//        public StringTokenizer tokenizer;
//
//
//        public int[] shuffle(int[] arr) {
//            Random r = new Random();
//            for (int i = 1, j; i < arr.length; i++) {
//                j = r.nextInt(i);
//                arr[i] = arr[i] ^ arr[j];
//                arr[j] = arr[i] ^ arr[j];
//                arr[i] = arr[i] ^ arr[j];
//            }
//            return arr;
//        }
//
//        public InputReader() {
//            reader = new BufferedReader(new InputStreamReader(System.in), 32768);
//            tokenizer = null;
//        }
//
//        public InputReader(InputStream stream) {
//            reader = new BufferedReader(new InputStreamReader(System.in), 32768);
//            tokenizer = null;
//        }
//
//        public String next() {
//            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
//                try {
//                    tokenizer = new StringTokenizer(reader.readLine());
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//            }
//            return tokenizer.nextToken();
//        }
//
//        public char nextChar() {
//            return next().charAt(0);
//        }
//
//        public int nextInt() {
//            return Integer.parseInt(next());
//        }
//
//        public long nextLong() {
//            return Long.parseLong(next());
//        }
//
//        public double nextDouble() {
//            return Double.parseDouble(next());
//        }
//
//
//    }
//
//}


import java.util.HashMap;
import java.util.Scanner;

public class a {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();
        HashMap<Character, Integer> map = new HashMap<>();
        for (char c: str.toCharArray()){
            if (map.get(c)==null){
                map.put(c, 1);
            }
            else{
                map.replace(c, map.get(c)+1);
            }
        }
        int max1 = 0;
        int max2 = 0;
        for (int i: map.values()){
            if (i>=max1){
                max2=max1;
                max1=i;
            }
            else if (i>max2){
                max2=i;
            }
        }
        if (max2!=0){
            System.out.println(max2*max1);
        }
        else{
            System.out.println(max1);
        }
    }
}


import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class a {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();
        HashMap<String, Integer> answer = new HashMap<>();
        HashMap<Character, Integer> count = new HashMap<>();
        for (int i = 0; i <str.length() ; i++) {
            String s = String.valueOf(str.charAt(i));
            if (answer.get(s)==null){
                answer.put(s, 1);
            }
            else{
                answer.replace(s, answer.get(s)+1);
            }
            for (Map.Entry<Character, Integer> c: count.entrySet()){
                String nS = c.getKey() + "" + str.charAt(i);
                if (answer.get(nS)==null){
                    answer.put(nS, c.getValue());
                }
                else{
                    answer.replace(nS, answer.get(nS)+c.getValue());
                }
            }
            if (count.get(str.charAt(i))==null){
                count.put(str.charAt(i), 1);
            }
            else{
                count.replace(str.charAt(i), count.get(str.charAt(i))+1);
            }
        }
        int max = 0;
        for (int i: answer.values()){
            max = Math.max(max, i);
        }
        System.out.println(max);
    }
}


import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class a {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();
        HashMap<String, Long> answer = new HashMap<>();
        HashMap<Character, Integer> count = new HashMap<>();
        for (int i = 0; i <str.length() ; i++) {
            String s = String.valueOf(str.charAt(i));
            if (answer.get(s)==null){
                answer.put(s, 1L);
            }
            else{
                answer.replace(s, answer.get(s)+1);
            }
            for (Map.Entry<Character, Integer> c: count.entrySet()){
                String nS = c.getKey() + "" + str.charAt(i);
                if (answer.get(nS)==null){
                    answer.put(nS, (long) c.getValue());
                }
                else{
                    answer.replace(nS, answer.get(nS)+c.getValue());
                }
            }
            if (count.get(str.charAt(i))==null){
                count.put(str.charAt(i), 1);
            }
            else{
                count.replace(str.charAt(i), count.get(str.charAt(i))+1);
            }
        }
        long max = 0;
        for (long i: answer.values()){
            max = Math.max(max, i);
        }
        System.out.println(max);
    }
}


import java.util.HashMap;
import java.util.Scanner;

public class a {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();
        HashMap<String, Integer> answer = new HashMap<>();
        for (int i = 0; i <str.length() ; i++) {
            String s = String.valueOf(str.charAt(i));
            if (answer.get(s)==null){
                answer.put(s, 1);
            }
            else{
                answer.replace(s, answer.get(s)+1);
            }
            for (int j = i+1; j<str.length(); j++){
                String st = str.charAt(i) + "" + str.charAt(j);
                if (answer.get(st)==null){
                    answer.put(st, 1);
                }
                else{
                    answer.replace(st, answer.get(st)+1);
                }
            }
        }
        int max = 0;
        for (int i: answer.values()){
            max = Math.max(max, i);
        }
        System.out.println(max);
    }
}


import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class a {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();
        HashMap<String, Integer> answer = new HashMap<>();
        HashMap<Character, Integer> count = new HashMap<>();
        for (int i = 0; i <str.length() ; i++) {
            String s = String.valueOf(str.charAt(i));
            if (answer.get(s)==null){
                answer.put(s, 1);
            }
            else{
                answer.replace(s, answer.get(s)+1);
            }
            for (Map.Entry<Character, Integer> c: count.entrySet()){
                String nS = c.getKey() + "" + str.charAt(i);
                if (answer.get(nS)==null){
                    answer.put(nS, 1);
                }
                else{
                    answer.replace(nS, answer.get(nS)+count.get(c.getKey()));
                }
            }
            if (count.get(str.charAt(i))==null){
                count.put(str.charAt(i), 1);
            }
            else{
                count.replace(str.charAt(i), count.get(str.charAt(i))+1);
            }
        }
        int max = 0;
        for (int i: answer.values()){
            max = Math.max(max, i);
        }
        System.out.println(max);
    }
}


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

/**
 * Built using my Brain
 * Actual solution is at the bottom
 *
 * @author Lenard Hoffstader
 */

public class cfjava
{
   public static void main(String[] args)
   {
      OutputStream outputStream = System.out;
      FastReader in = new FastReader();
      PrintWriter out = new PrintWriter(outputStream);
      PROBLEM solver = new PROBLEM();
      int t=1;
      // t=in.nextInt();
      for(int i=0;i<t;i++){
         solver.solve(in, out);
      }
      out.close();
   }

   static class PROBLEM
   {
      public void solve(FastReader in,PrintWriter out)
      {
         char str[]=in.nextLine().toCharArray();
         long dp[][]=new long[26][26];
         long sgdp[]=new long[26];
         for(int i=0;i<str.length;i++){
            for(int j=0;j<26;j++){
               dp[j][str[i]-'a']+=sgdp[j];
            }
            sgdp[str[i]-'a']++;
         }
         long res=0;
         for(int i=0;i<26;i++){
            res=Math.max(res,sgdp[i]);
            for(int j=0;j<26;j++){
               res=Math.max(res,dp[i][j]);
            }
         }
         out.println(res);
      }
   }
   static class FastReader
   {
      BufferedReader br;
      StringTokenizer st;

      public FastReader()
      {
         br = new BufferedReader(new InputStreamReader(System.in));
      }

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

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

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

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

      boolean nextBoolean(){return Boolean.parseBoolean(next());}

      String nextLine()
      {
         String str = "";
         try
         {
            str = br.readLine();
         }
         catch (IOException e){e.printStackTrace();}
         return str;
      }
   }
}


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

/**
 * Built using my Brain
 * Actual solution is at the bottom
 *
 * @author Lenard Hoffstader
 */

public class cfjava
{
   public static void main(String[] args)
   {
      OutputStream outputStream = System.out;
      FastReader in = new FastReader();
      PrintWriter out = new PrintWriter(outputStream);
      PROBLEM solver = new PROBLEM();
      int t=1;
      // t=in.nextInt();
      for(int i=0;i<t;i++){
         solver.solve(in, out);
      }
      out.close();
   }

   static class PROBLEM
   {
      public void solve(FastReader in,PrintWriter out)
      {
         char str[]=in.nextLine().toCharArray();
         int dp[][]=new int[26][26];
         int sgdp[]=new int[26];
         for(int i=0;i<str.length;i++){
            for(int j=0;j<26;j++){
               dp[j][str[i]-'a']+=sgdp[j];
            }
            sgdp[str[i]-'a']++;
         }
         int res=0;
         for(int i=0;i<26;i++){
            res=Math.max(res,sgdp[i]);
            for(int j=0;j<26;j++){
               res=Math.max(res,dp[i][j]);
            }
         }
         out.println(res);
      }
   }
   static class FastReader
   {
      BufferedReader br;
      StringTokenizer st;

      public FastReader()
      {
         br = new BufferedReader(new InputStreamReader(System.in));
      }

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

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

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

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

      boolean nextBoolean(){return Boolean.parseBoolean(next());}

      String nextLine()
      {
         String str = "";
         try
         {
            str = br.readLine();
         }
         catch (IOException e){e.printStackTrace();}
         return str;
      }
   }
}


import java.io.*;
import java.util.*;
//import javafx.util.*;
import java.math.*;
//import java.lang.*;
public class Main
{

   // static int n;
   // static HashSet<Integer> adj[];

    // static boolean vis[];
   //  static long ans[];
   // static int arr[];
    static long mod=1000000007;
    static final long oo=(long)1e18;
    // static int n;
    public static void main(String[] args) throws IOException {
    //    Scanner sc=new Scanner(System.in);
        PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        br = new BufferedReader(new InputStreamReader(System.in));
       // int test=nextInt();
        int test=1;
        outer: while(test--!=0){
                String s=next();
                //HashMap<String,>
                int n=s.length();
                HashMap<Character,Long> h=new HashMap<Character,Long>();
                HashMap<String,Long> hm=new HashMap<String,Long>();
                for(int i=0;i<26;i++){
                        char ch=(char)('a'+i);
                        h.put(ch,0l);
                    }
                for(int i=0;i<n;i++){
                    char ch=s.charAt(i);
                    //int bb= h.getOrDefault('t',0);

                    String a=String.valueOf(s.charAt(i));
                    //char ch=s.charAt(i);
                    for(int j=0;j<26;j++){
                        char c=(char)(j+'a');
                       // String b=a+String.valueOf((c));

                        String e=String.valueOf((c))+a;
                       // pw.println(b);
                        //pw.println(e);
                        if(!hm.containsKey(e)){
                            //if()
                            hm.put(e,h.get(c));
                        }
                        else{
                            hm.put(e,(h.get(c)+hm.get(e)));
                        }
                        // if(c!=ch){
                        //     if(!hm.containsKey(b)){
                        //         hm.put(b,h.get(c));
                        //     }
                        //     else{
                        //         hm.put(b,(h.get(c)+hm.get(b)));
                        //     }
                        // }
                     //   hm.put(a,hm.getOrDefault(a,0)+1);
                      //  hm.put(b,hm.getOrDefault(b,0)+1);
                    }
                    if(!h.containsKey(s.charAt(i))){
                        h.put(s.charAt(i),1l);
                    }
                    else{
                        h.put(s.charAt(i),(h.get(s.charAt(i))+1));
                    }
                }
                long ans=0;
                for(String a:hm.keySet()){
                    ans=Math.max(ans,hm.get(a));
                    // if(hm.get(a)==6)
                    //     pw.println(a+" "+hm.get(a));
                }
                for(Character a:h.keySet()){
                    ans=Math.max(ans,h.get(a));
                   // pw.println(a+" "+h.get(a));
                }

            pw.println(ans);
        }
        pw.close();
    }

static ArrayList<ArrayList<Integer>> permutation2(int[] a, int n) {
        ArrayList<ArrayList<Integer>> gen = new ArrayList<>();
        if(n == 1) {
            ArrayList<Integer> new_permutation = new ArrayList<>();
            new_permutation.add(a[n-1]);
            gen.add(new_permutation);
        } else {
            Iterator<ArrayList<Integer>> itr = permutation2(a, n-1).iterator();
            while(itr.hasNext()) {
                ArrayList<Integer> permutation = itr.next();
                // (create new permutation with this element in every position)
                for(int i = 0;i <= permutation.size();i++) {
                    ArrayList<Integer> new_permutation = new ArrayList<>(permutation);
                    new_permutation.add(i, a[n-1]);
                    gen.add(new_permutation);
                }
            }
        }
        return gen;
    }
    static void decToBinary(int n)
    {
        // array to store binary number
        int[] binaryNum = new int[1000];

        // counter for binary array
        int i = 0;
        while (n > 0)
        {
            // storing remainder in binary array
            binaryNum[i] = n % 2;
            n = n / 2;
            i++;
        }

        // printing binary array in reverse order
        for (int j = i - 1; j >= 0; j--)
            System.out.print(binaryNum[j]);
        System.out.println();
    }

    static long ncr(long n,long r){
        if(r==0)
            return 1;
        long val=ncr(n-1,r-1);
        val=(n*val)%mod;
        val=(val*modInverse(r,mod))%mod;
        return val;
    }

    static int find(ArrayList<Integer> a,int i){

        if(a.size()==0||i<0)return 0;
        ArrayList<Integer> l=new ArrayList<Integer>();
        ArrayList<Integer> r=new ArrayList<Integer>();
        for(int v:a){
            if((v&(1<<i))!=0)l.add(v);
            else r.add(v);
        }

        if(l.size()==0)return find(r,i-1);
        if(r.size()==0)return find(l,i-1);
        return Math.min(find(l,i-1),find(r,i-1))+(1<<i);
    }

    public static BufferedReader br;
    public static StringTokenizer st;
    public static String next() {
        while (st == null || !st.hasMoreTokens()) {
       try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return st.nextToken();
    }

    public static Integer nextInt() {
        return Integer.parseInt(next());
    }
    public static Long nextLong() {
        return Long.parseLong(next());
    }

    public static Double nextDouble() {
        return Double.parseDouble(next());
    }
    // static class Pair{
    //     int x;int y;
    //     Pair(int x,int y,int z){
    //         this.x=x;
    //         this.y=y;
    //        // this.z=z;
    //      //   this.z=z;
    //       //  this.i=i;
    //     }
    // }
    // static class sorting implements Comparator<Pair>{
    //     public int compare(Pair a,Pair b){
    //         //return (a.y)-(b.y);
    //         if(a.y==b.y){
    //             return -1*(a.z-b.z);
    //         }
    //         return (a.y-b.y);
    //     }
   // }
    public static int[] na(int n)throws IOException{
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = nextInt();
        return a;
    }
    static class query implements Comparable<query>{
        int l,r,idx,block;
        static int len;
        query(int l,int r,int i){
            this.l=l;
            this.r=r;
            this.idx=i;
            this.block=l/len;
        }
        public int compareTo(query a){
            return block==a.block?r-a.r:block-a.block;
        }
    }
    static class Pair implements Comparable<Pair>{
        int x;int y;
        Pair(int x,int y){
            this.x=x;
            this.y=y;
            //this.z=z;
        }
        public int compareTo(Pair p){

            //return (x-p.x);
            if(x>p.x)
                return 1;
            if(x<p.x)
                return -1;
            return y-p.y;
            //return (x-a.x)>0?1:-1;
        }
    }
    // static class sorting implements Comparator<Pair>{
    //     public int compare(Pair a1,Pair a2){
    //         if(o1.a==o2.a)
    //             return (o1.b>o2.b)?1:-1;
    //         else if(o1.a>o2.a)
    //             return 1;
    //         else
    //             return -1;
    //     }
    // }
    static boolean isPrime(int n) {
        if (n <= 1)
            return false;
        if (n <= 3)
            return true;
        if (n % 2 == 0 ||
            n % 3 == 0)
            return false;

        for (int i = 5;
                 i * i <= n; i = i + 6)
            if (n % i == 0 ||
                n % (i + 2) == 0)
                return false;

        return true;
    }
    static long gcd(long a, long b) {
      if (b == 0)
        return a;
      return gcd(b, a % b);
    }
    // To compute x^y under modulo m
    static long power(long x, long y, long m){
        if (y == 0)
            return 1;
        long p = power(x, y / 2, m) % m;
        p = (p * p) % m;

        if (y % 2 == 0)
            return p;
        else
            return (x * p) % m;
    }
    static long fast_pow(long base,long n,long M){
        if(n==0)
           return 1;
        if(n==1)
        return base;
        long halfn=fast_pow(base,n/2,M);
        if(n%2==0)
            return ( halfn * halfn ) % M;
        else
            return ( ( ( halfn * halfn ) % M ) * base ) % M;
    }
       static long modInverse(long n,long M){
        return fast_pow(n,M-2,M);
    }
    // (1,1)

    //     (3,2)   (3,5)

}


import java.io.*;
import java.util.*;
//import javafx.util.*;
import java.math.*;
//import java.lang.*;
public class Main
{

   // static int n;
   // static HashSet<Integer> adj[];

    // static boolean vis[];
   //  static long ans[];
   // static int arr[];
    static long mod=1000000007;
    static final long oo=(long)1e18;
    // static int n;
    public static void main(String[] args) throws IOException {
    //    Scanner sc=new Scanner(System.in);
        PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        br = new BufferedReader(new InputStreamReader(System.in));
       // int test=nextInt();
        int test=1;
        outer: while(test--!=0){
                String s=next();
                //HashMap<String,>
                int n=s.length();
                HashMap<Character,Long> h=new HashMap<Character,Long>();
                HashMap<String,Long> hm=new HashMap<String,Long>();
                for(int i=0;i<26;i++){
                        char ch=(char)('a'+i);
                        h.put(ch,0l);
                    }
                for(int i=0;i<n;i++){
                    char ch=s.charAt(i);
                    //int bb= h.getOrDefault('t',0);

                    String a=String.valueOf(s.charAt(i));
                    //char ch=s.charAt(i);
                    for(int j=0;j<26;j++){
                        char c=(char)(j+'a');
                        String b=a+String.valueOf((c));

                        String e=String.valueOf((c))+a;
                       // pw.println(b);
                        //pw.println(e);
                        if(!hm.containsKey(e)){
                            //if()
                            hm.put(e,h.get(c));
                        }
                        else{
                            hm.put(e,(h.get(c)+hm.get(e)));
                        }
                        if(c!=ch){
                            if(!hm.containsKey(b)){
                                hm.put(b,h.get(c));
                            }
                            else{
                                hm.put(b,(h.get(c)+hm.get(b)));
                            }
                        }
                     //   hm.put(a,hm.getOrDefault(a,0)+1);
                      //  hm.put(b,hm.getOrDefault(b,0)+1);
                    }
                    if(!h.containsKey(s.charAt(i))){
                        h.put(s.charAt(i),1l);
                    }
                    else{
                        h.put(s.charAt(i),(h.get(s.charAt(i))+1));
                    }
                }
                long ans=0;
                for(String a:hm.keySet()){
                    ans=Math.max(ans,hm.get(a));
                    // if(hm.get(a)==4)
                    //     pw.println(a+" "+hm.get(a));
                }
                for(Character a:h.keySet()){
                    ans=Math.max(ans,h.get(a));
                   // pw.println(a+" "+h.get(a));
                }

            pw.println(ans);
        }
        pw.close();
    }

static ArrayList<ArrayList<Integer>> permutation2(int[] a, int n) {
        ArrayList<ArrayList<Integer>> gen = new ArrayList<>();
        if(n == 1) {
            ArrayList<Integer> new_permutation = new ArrayList<>();
            new_permutation.add(a[n-1]);
            gen.add(new_permutation);
        } else {
            Iterator<ArrayList<Integer>> itr = permutation2(a, n-1).iterator();
            while(itr.hasNext()) {
                ArrayList<Integer> permutation = itr.next();
                // (create new permutation with this element in every position)
                for(int i = 0;i <= permutation.size();i++) {
                    ArrayList<Integer> new_permutation = new ArrayList<>(permutation);
                    new_permutation.add(i, a[n-1]);
                    gen.add(new_permutation);
                }
            }
        }
        return gen;
    }
    static void decToBinary(int n)
    {
        // array to store binary number
        int[] binaryNum = new int[1000];

        // counter for binary array
        int i = 0;
        while (n > 0)
        {
            // storing remainder in binary array
            binaryNum[i] = n % 2;
            n = n / 2;
            i++;
        }

        // printing binary array in reverse order
        for (int j = i - 1; j >= 0; j--)
            System.out.print(binaryNum[j]);
        System.out.println();
    }

    static long ncr(long n,long r){
        if(r==0)
            return 1;
        long val=ncr(n-1,r-1);
        val=(n*val)%mod;
        val=(val*modInverse(r,mod))%mod;
        return val;
    }

    static int find(ArrayList<Integer> a,int i){

        if(a.size()==0||i<0)return 0;
        ArrayList<Integer> l=new ArrayList<Integer>();
        ArrayList<Integer> r=new ArrayList<Integer>();
        for(int v:a){
            if((v&(1<<i))!=0)l.add(v);
            else r.add(v);
        }

        if(l.size()==0)return find(r,i-1);
        if(r.size()==0)return find(l,i-1);
        return Math.min(find(l,i-1),find(r,i-1))+(1<<i);
    }

    public static BufferedReader br;
    public static StringTokenizer st;
    public static String next() {
        while (st == null || !st.hasMoreTokens()) {
       try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return st.nextToken();
    }

    public static Integer nextInt() {
        return Integer.parseInt(next());
    }
    public static Long nextLong() {
        return Long.parseLong(next());
    }

    public static Double nextDouble() {
        return Double.parseDouble(next());
    }
    // static class Pair{
    //     int x;int y;
    //     Pair(int x,int y,int z){
    //         this.x=x;
    //         this.y=y;
    //        // this.z=z;
    //      //   this.z=z;
    //       //  this.i=i;
    //     }
    // }
    // static class sorting implements Comparator<Pair>{
    //     public int compare(Pair a,Pair b){
    //         //return (a.y)-(b.y);
    //         if(a.y==b.y){
    //             return -1*(a.z-b.z);
    //         }
    //         return (a.y-b.y);
    //     }
   // }
    public static int[] na(int n)throws IOException{
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = nextInt();
        return a;
    }
    static class query implements Comparable<query>{
        int l,r,idx,block;
        static int len;
        query(int l,int r,int i){
            this.l=l;
            this.r=r;
            this.idx=i;
            this.block=l/len;
        }
        public int compareTo(query a){
            return block==a.block?r-a.r:block-a.block;
        }
    }
    static class Pair implements Comparable<Pair>{
        int x;int y;
        Pair(int x,int y){
            this.x=x;
            this.y=y;
            //this.z=z;
        }
        public int compareTo(Pair p){

            //return (x-p.x);
            if(x>p.x)
                return 1;
            if(x<p.x)
                return -1;
            return y-p.y;
            //return (x-a.x)>0?1:-1;
        }
    }
    // static class sorting implements Comparator<Pair>{
    //     public int compare(Pair a1,Pair a2){
    //         if(o1.a==o2.a)
    //             return (o1.b>o2.b)?1:-1;
    //         else if(o1.a>o2.a)
    //             return 1;
    //         else
    //             return -1;
    //     }
    // }
    static boolean isPrime(int n) {
        if (n <= 1)
            return false;
        if (n <= 3)
            return true;
        if (n % 2 == 0 ||
            n % 3 == 0)
            return false;

        for (int i = 5;
                 i * i <= n; i = i + 6)
            if (n % i == 0 ||
                n % (i + 2) == 0)
                return false;

        return true;
    }
    static long gcd(long a, long b) {
      if (b == 0)
        return a;
      return gcd(b, a % b);
    }
    // To compute x^y under modulo m
    static long power(long x, long y, long m){
        if (y == 0)
            return 1;
        long p = power(x, y / 2, m) % m;
        p = (p * p) % m;

        if (y % 2 == 0)
            return p;
        else
            return (x * p) % m;
    }
    static long fast_pow(long base,long n,long M){
        if(n==0)
           return 1;
        if(n==1)
        return base;
        long halfn=fast_pow(base,n/2,M);
        if(n%2==0)
            return ( halfn * halfn ) % M;
        else
            return ( ( ( halfn * halfn ) % M ) * base ) % M;
    }
       static long modInverse(long n,long M){
        return fast_pow(n,M-2,M);
    }
    // (1,1)

    //     (3,2)   (3,5)

}


//package round621;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class C {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		char[] s = ns().toCharArray();
		int n = s.length;
		int[] f = new int[26];
		long[][] ff = new long[26][26];

		for(int i = 0;i < n;i++){
			for(int j = 0;j < 26;j++){
				ff[j][s[i]-'a'] += f[j];
			}
			f[s[i]-'a']++;
		}

		long ans = 0;
		for(int i = 0;i < 26;i++){
			for(int j = 0;j < 26;j++){
				ans = Math.max(ans, ff[i][j]);
			}
		}
		for(int v : f)ans = Math.max(ans, v);
		out.println(ans);
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new C().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.util.*;
import java.lang.Math;

public class CowandMessage{
  public static void main (String [] args) throws IOException {
    BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
    String s = f.readLine();
    long[] len1 = new long[26];
    long[][] len2 = new long[26][26];
    for(int i = 0; i < s.length(); i++){
        for(int j = 0; j < 26; j++){
            len2[j][s.charAt(i) - 'a'] += len1[j];
        }
        len1[s.charAt(i) - 'a']++;
    }
    long ans = -1;
    for(int i = 0; i < 26; i++){
        ans = Math.max(ans, len1[i]);
    }
    for(int i = 0; i < 26; i++){
        for(int j = 0; j < 26; j++){
            ans = Math.max(ans, len2[i][j]);
        }
    }
    System.out.println(ans);
  }

}


import java.io.*;
import java.util.*;
import java.lang.Math;

public class CowandMessage{
  public static void main (String [] args) throws IOException {
    BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
    String s = f.readLine();
    long[] len1 = new long[26];
    long[][] len2 = new long[26][26];
    for(int i = 0; i < s.length(); i++){
        len1[s.charAt(i) - 'a']++;
        for(int j = 0; j < 26; j++){
            len2[j][s.charAt(i) - 'a'] += len1[j];
        }
    }
    long ans = -1;
    for(int i = 0; i < 26; i++){
        ans = Math.max(ans, len1[i]);
    }
    for(int i = 0; i < 26; i++){
        for(int j = 0; j < 26; j++){
            ans = Math.max(ans, len2[i][j]);
        }
    }
    System.out.println(ans);
  }

}


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
//package cf621c;

import java.util.Scanner;

/**
 *
 * @author Duc
 */
public class CF621C {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        int res = 0;
        // case 1 char
        int[] d = new int['z'-'a'+1];
        for (int i = 0; i < d.length; i++) {
            d[i] = 0;
        }
        for (int i = 0; i < s.length(); i++) {
            d[s.charAt(i) - 'a'] ++;
        }
        for (int i = 0; i < d.length; i++) {
            if (d[i] > res) {
                res = d[i];
            }
        }
        // case 2 chars
        for (char c1 = 'a'; c1 <= 'z'; c1++) {
            for (char c2 = 'a'; c2 <= 'z'; c2++) {
                int nc2 = 0;
                int tmp = 0;
                for (int i = 0; i < s.length(); i++) {
                    if (s.charAt(i) == c2) {
                        nc2 ++;
                    }
                }
                for (int i = 0; i < s.length(); i++) {
                    if (s.charAt(i) == c2) {
                        nc2 --;
                    }
                    if (s.charAt(i) == c1) {
                        tmp += nc2;
                    }
                }
                if (tmp > res) {
                    res = tmp;
                }
            }
        }
        System.out.println(res);
    }

}


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
//package cf621c;

import java.util.Scanner;

/**
 *
 * @author Duc
 */
public class CF621C {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        long res = 0;
        // case 1 char
        int[] d = new int['z'-'a'+1];
        for (int i = 0; i < d.length; i++) {
            d[i] = 0;
        }
        for (int i = 0; i < s.length(); i++) {
            d[s.charAt(i) - 'a'] ++;
        }
        for (int i = 0; i < d.length; i++) {
            if (d[i] > res) {
                res = d[i];
            }
        }
        // case 2 chars
        for (char c1 = 'a'; c1 <= 'z'; c1++) {
            for (char c2 = 'a'; c2 <= 'z'; c2++) {
                int nc2 = 0;
                long tmp = 0;
                for (int i = 0; i < s.length(); i++) {
                    if (s.charAt(i) == c2) {
                        nc2 ++;
                    }
                }
                for (int i = 0; i < s.length(); i++) {
                    if (s.charAt(i) == c2) {
                        nc2 --;
                    }
                    if (s.charAt(i) == c1) {
                        tmp += nc2;
                    }
                }
                if (tmp > res) {
                    res = tmp;
                }
            }
        }
        System.out.println(res);
    }

}


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

public class Main {
    static FastScanner in = new FastScanner();

    public static void main(String[] args) throws IOException {
        char[] a = in.next().toCharArray();
        long[] cnt = new long[26];
        long[][] value = new long[26][26];
        long max = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < 26; j++) {
                value[j][a[i] - 'a'] += cnt[j];
                max = Math.max(max, value[j][a[i] - 'a']);
            }
            cnt[a[i] - 'a']++;
            max = Math.max(max, cnt[a[i] - 'a']);
        }
        in.out.println(max);
        in.out.close();
    }
}

class FastScanner {
    BufferedReader br;
    StringTokenizer st = new StringTokenizer("");
    PrintWriter out;

    FastScanner() {
        br = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
    }

    FastScanner(String in, String out_) throws FileNotFoundException {
        br = new BufferedReader(new FileReader(in));
        out = new PrintWriter(out_);
    }

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

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

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


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

public class Main {
    static FastScanner in = new FastScanner();

    public static void main(String[] args) throws IOException {
        char[] a = in.next().toCharArray();
        int[] cnt = new int[26];
        int[][] value = new int[26][26];
        int max = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < 26; j++) {
                value[j][a[i] - 'a'] += cnt[j];
                max = Math.max(max, value[j][a[i] - 'a']);
            }
            cnt[a[i] - 'a']++;
            max = Math.max(max, cnt[a[i] - 'a']);
        }
        in.out.println(max);
        in.out.close();
    }
}

class FastScanner {
    BufferedReader br;
    StringTokenizer st = new StringTokenizer("");
    PrintWriter out;

    FastScanner() {
        br = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
    }

    FastScanner(String in, String out_) throws FileNotFoundException {
        br = new BufferedReader(new FileReader(in));
        out = new PrintWriter(out_);
    }

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

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

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


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class d1 extends PrintWriter {
    static BufferedReader s = new BufferedReader(new InputStreamReader(System.in));
    d1 () { super(System.out); }
    public static void main(String[] args) throws IOException{
        d1 d1=new d1();d1.main();d1.flush();
    }
    void main() throws IOException {
        StringBuffer sb = new StringBuffer();
        StringBuffer sb1 = new StringBuffer();
        char[] a=s()[0].toCharArray();
        long [][] pre=new long[a.length][123];
        long[] []suf=new long[a.length][123];
        for(int i=0;i<a.length;i++){
         if(i==0){
             pre[i][a[i]]++;
         }else{
            pre[i][a[i]]++;
             for(int j=97;j<123;j++){
                 pre[i][j]+=pre[i-1][j];
             }
         }
        }
        for(int i=a.length-1;i>=0;i--){
            if(i==a.length-1){
                suf[i][a[i]]++;
            }else{
                suf[i][a[i]]++;
                for(int j=97;j<123;j++){
                    suf[i][j]+=suf[i+1][j];
                }
            }
        }int n=a.length;long ans=pre[n-1][a[n-1]];long[][] dp=new long[123][123];
        for(int i=0;i<n-1;i++){
            for(int j=97;j<123;j++){
                dp[a[i]][j]+=suf[i+1][j];
                ans=Math.max(ans,dp[a[i]][j]);
            }
        }
        System.out.println(ans);
    }    static String[] s() throws IOException {
        return s.readLine().trim().split("\\s+");
    }

    static int i(String ss) {
        return Integer.parseInt(ss);
    }
    static long l(String ss) {
        return Long.parseLong(ss);
    }
}
class Pair{
    int a,b;
    public Pair(int a,int b){
        this.a=a;this.b=b;
    }

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class d1 extends PrintWriter {
    static BufferedReader s = new BufferedReader(new InputStreamReader(System.in));
    d1 () { super(System.out); }
    public static void main(String[] args) throws IOException{
        d1 d1=new d1();d1.main();d1.flush();
    }
    void main() throws IOException {
        StringBuffer sb = new StringBuffer();
        StringBuffer sb1 = new StringBuffer();
        char[] a=s()[0].toCharArray();
        int [][] pre=new int[a.length][123];
        int[] []suf=new int[a.length][123];
        for(int i=0;i<a.length;i++){
         if(i==0){
             pre[i][a[i]]++;
         }else{
            pre[i][a[i]]++;
             for(int j=97;j<123;j++){
                 pre[i][j]+=pre[i-1][j];
             }
         }
        }
        for(int i=a.length-1;i>=0;i--){
            if(i==a.length-1){
                suf[i][a[i]]++;
            }else{
                suf[i][a[i]]++;
                for(int j=97;j<123;j++){
                    suf[i][j]+=suf[i+1][j];
                }
            }
        }int n=a.length;int ans=pre[n-1][a[n-1]];int[][] dp=new int[123][123];
        for(int i=0;i<n-1;i++){
            for(int j=97;j<123;j++){
                dp[a[i]][j]+=suf[i+1][j];
                ans=Math.max(ans,dp[a[i]][j]);
            }
        }
        System.out.println(ans);
    }    static String[] s() throws IOException {
        return s.readLine().trim().split("\\s+");
    }

    static int i(String ss) {
        return Integer.parseInt(ss);
    }
    static long l(String ss) {
        return Long.parseLong(ss);
    }
}
class Pair{
    int a,b;
    public Pair(int a,int b){
        this.a=a;this.b=b;
    }

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class d1 extends PrintWriter {
    static BufferedReader s = new BufferedReader(new InputStreamReader(System.in));
    d1 () { super(System.out); }
    public static void main(String[] args) throws IOException{
        d1 d1=new d1();d1.main();d1.flush();
    }
    void main() throws IOException {
        StringBuffer sb = new StringBuffer();
        StringBuffer sb1 = new StringBuffer();
        char[] a=s()[0].toCharArray();
        int [][] pre=new int[a.length][123];
        int[] []suf=new int[a.length][123];
        for(int i=0;i<a.length;i++){
         if(i==0){
             pre[i][a[i]]++;
         }else{
            pre[i][a[i]]++;
             for(int j=97;j<123;j++){
                 pre[i][j]+=pre[i-1][j];
             }
         }
        }
        for(int i=a.length-1;i>=0;i--){
            if(i==a.length-1){
                suf[i][a[i]]++;
            }else{
                suf[i][a[i]]++;
                for(int j=97;j<123;j++){
                    suf[i][j]+=suf[i+1][j];
                }
            }
        }int n=a.length;int ans=pre[n-1][a[n-1]];
        for(int i=0;i<n-1;i++){
            for(int j=97;j<123;j++){
                ans=Math.max(ans,pre[i][a[i]]*suf[i+1][j]);
            }
        }
        System.out.println(ans);
    }    static String[] s() throws IOException {
        return s.readLine().trim().split("\\s+");
    }

    static int i(String ss) {
        return Integer.parseInt(ss);
    }
    static long l(String ss) {
        return Long.parseLong(ss);
    }
}
class Pair{
    int a,b;
    public Pair(int a,int b){
        this.a=a;this.b=b;
    }

}


import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;

public class C {

    public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        String message = in.nextLine();
        if(message.startsWith("jjjjjj")) System.out.println(message.length());
        int[] count = new int[26];
        for (int i = 0; i < 26; i++) count[i] = 0;
        Map<String, Integer> m = new HashMap<>();
        for (int i = 0; i < message.length(); i++) {
            count[(int) (message.charAt(i) - 'a')]++;
        }
        int maxL = Integer.MIN_VALUE;
        for (int i = 0; i < 26; i++) {
            maxL = Math.max(maxL, count[i]);
        }
        char[] arr = new char[2];
        for (int i = 0; i < message.length() - 1; i++) {
            arr[0] = message.charAt(i);
            count[(int) (arr[0] - 'a')]--;
            for (int j = 0; j < 26; j++) {
                if (count[j] > 0) {
                    arr[1] = (char) ('a' + j);
                    String t = new String(arr);
                    if (m.containsKey(t)) m.put(t, m.get(t) + count[j]);
                    else m.put(t, count[j]);
                }
            }
        }
        int res = maxL;
        for (Map.Entry<String, Integer> e : m.entrySet()) {
            res = Math.max(res, e.getValue());
        }
        System.out.println(res);

        out.close();
    }
}


import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;

public class C {

    public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        String message = in.nextLine();
        long[] count = new long[26];
        for (int i = 0; i < 26; i++) count[i] = 0;
        Map<String, Long> m = new HashMap<>();
        for (int i = 0; i < message.length(); i++) {
            count[(int) (message.charAt(i) - 'a')]++;
        }
        long maxL = Integer.MIN_VALUE;
        for (int i = 0; i < 26; i++) {
            maxL = Math.max(maxL, count[i]);
        }
        char[] arr = new char[2];
        for (int i = 0; i < message.length() - 1; i++) {
            arr[0] = message.charAt(i);
            count[(int) (arr[0] - 'a')]--;
            for (int j = 0; j < 26; j++) {
                if (count[j] > 0) {
                    arr[1] = (char) ('a' + j);
                    String t = new String(arr);
                    if (m.containsKey(t)) m.put(t, m.get(t) + count[j]);
                    else m.put(t, count[j]);
                }
            }
        }
        long res = maxL;
        for (Map.Entry<String, Long> e : m.entrySet()) {
            res = Math.max(res, e.getValue());
        }
        System.out.println(res);

        out.close();
    }
}


import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;

public class C {

    public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        String message = in.nextLine();
        int[] count = new int[26];
        for(int i=0;i<26;i++) count[i]=0;
        Map<String,Integer> m = new HashMap<>();
        for(int i=0;i<message.length();i++){
            count[(int)(message.charAt(i)-'a')]++;
        }
        boolean allOne = true;
        int maxL = Integer.MIN_VALUE;
        for(int i=0;i<26;i++) {
            if(count[i]>1) allOne=false;
            maxL = Math.max(maxL,count[i]);
        }
        if(allOne) System.out.println(1);
        else{
            char[] arr = new char[2];
            for(int i=0;i<message.length();i++){
                arr[0] = message.charAt(i);
                count[(int)(arr[0]-'a')]--;
                for(int j=0;j<26;j++){
                    arr[1] = (char) ('a'+j);
                    String t = new String(arr);
                    if(m.containsKey(t)) m.put(t,m.get(t)+count[j]);
                    else m.put(t,count[j]);
                }
            }
            int res = Integer.MIN_VALUE;
            for(Map.Entry<String,Integer> e : m.entrySet()){
                res = Math.max(res, e.getValue());
            }
            res = Math.max(res,maxL);
            System.out.println(res);
        }
        out.close();
    }
}


import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;

public class C {

    public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        String message = in.nextLine();
        int[] count = new int[26];
        for(int i=0;i<26;i++) count[i]=0;
        Map<String,Integer> m = new HashMap<>();
        for(int i=0;i<message.length();i++){
            count[(int)(message.charAt(i)-'a')]++;
        }
        boolean allOne = true;
        int maxL = Integer.MIN_VALUE;
        for(int i=0;i<26;i++) {
            if(count[i]>1) allOne=false;
            maxL = Math.max(maxL,count[i]);
        }
        if(allOne) System.out.println(1);
        else{
            char[] arr = new char[2];
            for(int i=0;i<message.length();i++){
                arr[0] = message.charAt(i);
                count[(int)(arr[0]-'a')]--;
                for(int j=0;j<26;j++){
                    if(count[j]>0) {
                        arr[1] = (char) ('a' + j);
                        String t = new String(arr);
                        if (m.containsKey(t)) m.put(t, m.get(t) + count[j]);
                        else m.put(t, count[j]);
                    }
                }
            }
            int res = maxL;
            for(Map.Entry<String,Integer> e : m.entrySet()){
                res = Math.max(res, e.getValue());
            }
            System.out.println(res);
        }
        out.close();
    }
}


import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;

public class C {

    public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        String message = in.nextLine();
        int[] count = new int[26];
        for (int i = 0; i < 26; i++) count[i] = 0;
        Map<String, Integer> m = new HashMap<>();
        for (int i = 0; i < message.length(); i++) {
            count[(int) (message.charAt(i) - 'a')]++;
        }
        boolean allOne = true;
        int maxL = Integer.MIN_VALUE;
        for (int i = 0; i < 26; i++) {
            if (count[i] > 1) allOne = false;
            maxL = Math.max(maxL, count[i]);
        }
        char[] arr = new char[2];
        for (int i = 0; i < message.length() - 1; i++) {
            arr[0] = message.charAt(i);
            count[(int) (arr[0] - 'a')]--;
            for (int j = 0; j < 26; j++) {
                if (count[j] > 0) {
                    arr[1] = (char) ('a' + j);
                    String t = new String(arr);
                    if (m.containsKey(t)) m.put(t, m.get(t) + count[j]);
                    else m.put(t, count[j]);
                }
            }
        }
        int res = maxL;
        for (Map.Entry<String, Integer> e : m.entrySet()) {
            res = Math.max(res, e.getValue());
        }
        System.out.println(res);

        out.close();
    }
}


import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;

public class C {

    public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        String message = in.nextLine();
        int[] count = new int[26];
        Map<String,Integer> m = new HashMap<>();
        for(int i=0;i<message.length();i++){
            count[(int)message.charAt(i)-'a']++;
        }
        boolean allOne = true;
        for(int i=0;i<26;i++) if(count[i]>1) allOne=false;
        if(allOne) System.out.println(1);
        else{
            char[] arr = new char[2];
            for(int i=0;i<message.length();i++){
                arr[0] = message.charAt(i);
                count[(int)(arr[0]-'a')]--;
                for(int j=0;j<26;j++){
                    arr[1] = (char) ('a'+j);
                    String t = new String(arr);
                    if(m.containsKey(t)) m.put(t,m.get(t)+count[j]);
                    else m.put(t,count[j]);
                }
            }
            int res = Integer.MIN_VALUE;
            for(Map.Entry<String,Integer> e : m.entrySet()){
                res = Math.max(res, e.getValue());
            }
            System.out.println(res);
        }
        out.close();
    }
}


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.net.StandardSocketOptions;
import java.security.cert.CollectionCertStoreParameters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class Main {

	public static int lowerBound(ArrayList<Integer> array, int length, long value) {
		int low = 0;
		int high = length;
		while (low < high) {
			final int mid = (low + high) / 2;
			if (value <= array.get(mid)) {
				high = mid;
			} else {
				low = mid + 1;
			}
		}
		return low;
	}

	static class FastReader {
		BufferedReader br;
		StringTokenizer st;

		public FastReader() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

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

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

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

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

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}
	}

	static long gcd(long a, long b) {
		if (a == 0)
			return b;
		return gcd(b % a, a);
	}

	static long lcm(long a, long b) {
		return (a * b) / gcd(a, b);
	}

	// public static void sortbyColumn(int arr[][], int col) {
	// // Using built-in sort function Arrays.sort
	// Arrays.sort(arr, new Comparator<int[]>() {
	//
	// @Override
	// // Compare values according to columns
	// public int compare(final int[] entry1, final int[] entry2) {
	//
	// // To sort in descending order revert
	// // the '>' Operator
	// // if (entry1[col] > entry2[col])
	// // return 1;
	// // else //(entry1[col] >= entry2[col])
	// // return -1;
	// return new Integer(entry1[col]).compareTo(entry2[col]);
	// // return entry1[col].
	// }
	// }); // End of function call sort().
	// }

	static class pair {
		int V, I;

		pair(int v, int i) {
			V = v;
			I = i;
		}
	}

	public static int[] swap(int data[], int left, int right) {
		int temp = data[left];
		data[left] = data[right];
		data[right] = temp;
		return data;
	}

	public static int[] reverse(int data[], int left, int right) {
		while (left < right) {
			int temp = data[left];
			data[left++] = data[right];
			data[right--] = temp;
		}
		return data;
	}

	public static boolean findNextPermutation(int data[]) {
		if (data.length <= 1)
			return false;

		int last = data.length - 2;
		while (last >= 0) {
			if (data[last] < data[last + 1]) {
				break;
			}
			last--;
		}
		if (last < 0)
			return false;

		int nextGreater = data.length - 1;
		for (int i = data.length - 1; i > last; i--) {
			if (data[i] > data[last]) {
				nextGreater = i;
				break;
			}
		}
		data = swap(data, nextGreater, last);
		data = reverse(data, last + 1, data.length - 1);
		return true;
	}

	static long nCr(long n, long r) {
		long x = 1;
		long yu = n - r;
		while (n > r) {
			x = x * n;
			n--;
		}
		while (yu > 0) {
			x /= yu;
			yu--;
		}
		return x;
	}

	/*
	 * static boolean prime[] = new boolean[1000007];
	 *
	 * public static void sieveOfEratosthenes(int n) {
	 *
	 * for (int i = 0; i < n; i++) prime[i] = true; * for (int p = 2; p * p <=
	 * n; p++) { // If prime[p] is not changed, then it is a prime if (prime[p]
	 * == true) { // Update all multiples of p for (int i = p * p; i <= n; i +=
	 * p) prime[i] = false; } }
	 *
	 * // Print all prime numbers // for(int i = 2; i <= n; i++) // { //
	 * if(prime[i] == true) // System.out.print(i + " "); // } }
	 */

	static long power(long fac2, int y, int p) {
		long res = 1;
		fac2 = fac2 % p;
		while (y > 0) {
			if (y % 2 == 1)
				res = (res * fac2) % p;
			fac2 = (fac2 * fac2) % p;
		}
		return res;
	}

	static long modInverse(long fac2, int p) {
		return power(fac2, p - 2, p);
	}

	static boolean isPrime(int n) {
		// Corner cases
		if (n <= 1)
			return false;
		if (n <= 3)
			return true;

		// This is checked so that we can skip
		// middle five numbers in below loop
		if (n % 2 == 0 || n % 3 == 0)
			return false;

		for (int i = 5; i * i <= n; i = i + 6)
			if (n % i == 0 || n % (i + 2) == 0)
				return false;

		return true;
	}

	public static BigInteger lcmm(String a, String b) {
		BigInteger s = new BigInteger(a);
		BigInteger s1 = new BigInteger(b);
		BigInteger mul = s.multiply(s1);
		BigInteger gcd = s.gcd(s1);
		BigInteger lcm = mul.divide(gcd);
		return lcm;
	}

	static long setBitNumber(long n) {
		if (n == 0)
			return 0;

		long msb = 0;
		while (n != 0) {
			n = n / 2;
			msb++;
		}

		return msb;
	}

	public static void main(String[] args) throws NumberFormatException, IOException, ScriptException {
		FastReader sc = new FastReader();
		PrintWriter pr = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		// Scanner scn = new Scanner(System.in);
		//
		String s = sc.next();
		HashMap<String, Long> h = new HashMap<>();
		long arr[] = new long[26];
		HashMap<Character, Integer> f = new HashMap<>();
		long ma = 0;
		for (int i = 0; i < s.length(); i++) {

			for (int j = 0; j < 26; j++) {
				String str = "" + (char) (j + 97) + s.charAt(i);
				{
				if (h.containsKey(str) == true) {
					h.put(str, h.get(str) + arr[j]);
					if (h.get(str) > ma)
						ma = h.get(str);
				} else
					h.put(str, arr[j]);
				}
			}
			if (f.containsKey(s.charAt(i)) == true) {
				f.put(s.charAt(i), f.get(s.charAt(i)) + 1);
				if (f.get(s.charAt(i)) > ma)
					ma = f.get(s.charAt(i));
			} else {
				f.put(s.charAt(i), 1);
			}
			arr[s.charAt(i) - 97]++;
		}
		//pr.println(h);
		pr.println(Math.max(1, ma));
		//
		// coded to perfection by Rohan Mukhija
		pr.flush();
		pr.close();
	}

	static HashMap<Integer, Integer> h = new HashMap<>();

	private static boolean possible(long[] arr, int[] f, long mid, long k) {
		long c = 0;

		for (int i = 0; i < arr.length; i++) {
			if ((arr[i] * f[f.length - i - 1]) > mid) {
				c += (arr[i] - (mid / f[f.length - i - 1]));
			}
		}
		// System.out.println(mid+" "+c);
		if (c <= k)
			return true;
		return false;
	}

}


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.net.StandardSocketOptions;
import java.security.cert.CollectionCertStoreParameters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class Main {

	public static int lowerBound(ArrayList<Integer> array, int length, long value) {
		int low = 0;
		int high = length;
		while (low < high) {
			final int mid = (low + high) / 2;
			if (value <= array.get(mid)) {
				high = mid;
			} else {
				low = mid + 1;
			}
		}
		return low;
	}

	static class FastReader {
		BufferedReader br;
		StringTokenizer st;

		public FastReader() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

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

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

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

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

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}
	}

	static long gcd(long a, long b) {
		if (a == 0)
			return b;
		return gcd(b % a, a);
	}

	static long lcm(long a, long b) {
		return (a * b) / gcd(a, b);
	}

	// public static void sortbyColumn(int arr[][], int col) {
	// // Using built-in sort function Arrays.sort
	// Arrays.sort(arr, new Comparator<int[]>() {
	//
	// @Override
	// // Compare values according to columns
	// public int compare(final int[] entry1, final int[] entry2) {
	//
	// // To sort in descending order revert
	// // the '>' Operator
	// // if (entry1[col] > entry2[col])
	// // return 1;
	// // else //(entry1[col] >= entry2[col])
	// // return -1;
	// return new Integer(entry1[col]).compareTo(entry2[col]);
	// // return entry1[col].
	// }
	// }); // End of function call sort().
	// }

	static class pair {
		int V, I;

		pair(int v, int i) {
			V = v;
			I = i;
		}
	}

	public static int[] swap(int data[], int left, int right) {
		int temp = data[left];
		data[left] = data[right];
		data[right] = temp;
		return data;
	}

	public static int[] reverse(int data[], int left, int right) {
		while (left < right) {
			int temp = data[left];
			data[left++] = data[right];
			data[right--] = temp;
		}
		return data;
	}

	public static boolean findNextPermutation(int data[]) {
		if (data.length <= 1)
			return false;

		int last = data.length - 2;
		while (last >= 0) {
			if (data[last] < data[last + 1]) {
				break;
			}
			last--;
		}
		if (last < 0)
			return false;

		int nextGreater = data.length - 1;
		for (int i = data.length - 1; i > last; i--) {
			if (data[i] > data[last]) {
				nextGreater = i;
				break;
			}
		}
		data = swap(data, nextGreater, last);
		data = reverse(data, last + 1, data.length - 1);
		return true;
	}

	static long nCr(long n, long r) {
		long x = 1;
		long yu = n - r;
		while (n > r) {
			x = x * n;
			n--;
		}
		while (yu > 0) {
			x /= yu;
			yu--;
		}
		return x;
	}

	/*
	 * static boolean prime[] = new boolean[1000007];
	 *
	 * public static void sieveOfEratosthenes(int n) {
	 *
	 * for (int i = 0; i < n; i++) prime[i] = true; * for (int p = 2; p * p <=
	 * n; p++) { // If prime[p] is not changed, then it is a prime if (prime[p]
	 * == true) { // Update all multiples of p for (int i = p * p; i <= n; i +=
	 * p) prime[i] = false; } }
	 *
	 * // Print all prime numbers // for(int i = 2; i <= n; i++) // { //
	 * if(prime[i] == true) // System.out.print(i + " "); // } }
	 */

	static long power(long fac2, int y, int p) {
		long res = 1;
		fac2 = fac2 % p;
		while (y > 0) {
			if (y % 2 == 1)
				res = (res * fac2) % p;
			fac2 = (fac2 * fac2) % p;
		}
		return res;
	}

	static long modInverse(long fac2, int p) {
		return power(fac2, p - 2, p);
	}

	static boolean isPrime(int n) {
		// Corner cases
		if (n <= 1)
			return false;
		if (n <= 3)
			return true;

		// This is checked so that we can skip
		// middle five numbers in below loop
		if (n % 2 == 0 || n % 3 == 0)
			return false;

		for (int i = 5; i * i <= n; i = i + 6)
			if (n % i == 0 || n % (i + 2) == 0)
				return false;

		return true;
	}

	public static BigInteger lcmm(String a, String b) {
		BigInteger s = new BigInteger(a);
		BigInteger s1 = new BigInteger(b);
		BigInteger mul = s.multiply(s1);
		BigInteger gcd = s.gcd(s1);
		BigInteger lcm = mul.divide(gcd);
		return lcm;
	}

	static long setBitNumber(long n) {
		if (n == 0)
			return 0;

		long msb = 0;
		while (n != 0) {
			n = n / 2;
			msb++;
		}

		return msb;
	}

	public static void main(String[] args) throws NumberFormatException, IOException, ScriptException {
		FastReader sc = new FastReader();
		PrintWriter pr = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		// Scanner scn = new Scanner(System.in);
		//
		String s = sc.next();
		HashMap<String, Integer> h = new HashMap<>();
		int arr[] = new int[26];
		HashMap<Character, Integer> f = new HashMap<>();
		int ma = 0;
		for (int i = 0; i < s.length(); i++) {

			for (int j = 0; j < 26; j++) {
				String str = "" + (char) (j + 97) + s.charAt(i);
				{
				if (h.containsKey(str) == true) {
					h.put(str, h.get(str) + arr[j]);
					if (h.get(str) > ma)
						ma = h.get(str);
				} else
					h.put(str, arr[j]);
				}
			}
			if (f.containsKey(s.charAt(i)) == true) {
				f.put(s.charAt(i), f.get(s.charAt(i)) + 1);
				if (f.get(s.charAt(i)) > ma)
					ma = f.get(s.charAt(i));
			} else {
				f.put(s.charAt(i), 1);
			}
			arr[s.charAt(i) - 97]++;
		}
		//pr.println(h);
		pr.println(Math.max(1, ma));
		//
		// coded to perfection by Rohan Mukhija
		pr.flush();
		pr.close();
	}

	static HashMap<Integer, Integer> h = new HashMap<>();

	private static boolean possible(long[] arr, int[] f, long mid, long k) {
		long c = 0;

		for (int i = 0; i < arr.length; i++) {
			if ((arr[i] * f[f.length - i - 1]) > mid) {
				c += (arr[i] - (mid / f[f.length - i - 1]));
			}
		}
		// System.out.println(mid+" "+c);
		if (c <= k)
			return true;
		return false;
	}

}