//package baobab;

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

public class E {

    public static final boolean DEBUG_PRINTS = false;

    public static void main(String[] args) {
        Solver solver = new Solver();
    }

    static class Solver {
        IO io;

        public Solver() {
            this.io = new IO();
            try {
                solve();
            } catch (RuntimeException e) {
                if (!e.getMessage().equals("Clean exit")) {
                    throw e;
                }
            } finally {
                io.close();
            }
        }

        /****************************** START READING HERE ********************************/

        void solve() {
            String s = io.next();
            List<Integer>[] starts = new ArrayList[28];
            for (int c='a'; c<='z'; c++) {
                starts[c-'a'] = new ArrayList<>();
            }
            for (int i=0; i<s.length(); i++) {
                int c = s.charAt(i);
                starts[c-'a'].add(i);
            }
            double ans = 0;
            for (int c='a'; c<='z'; c++) {
                double bestChoice = 0;
                if (starts[c-'a'].size() == 0) {
                    continue;
                }
                for (int dist=1; dist<s.length(); dist++) {
                    int[] counts = new int[28];
                    for (int start : starts[c-'a']) {
                        int nextPos = (start + dist) % s.length();
                        int nextChar = s.charAt(nextPos);
                        counts[nextChar-'a']++;
                    }
                    int countGood = 0;
                    int countBad = 0;
                    for (int nextChar='a'; nextChar<='z'; nextChar++) {
                        int count = counts[nextChar-'a'];
                        if (count == 1) {
                            countGood += count;
                        } else {
                            countBad += count;
                        }
                    }
                    double currChoice = countGood * 1.0 / (countBad+countGood);
                    bestChoice = Math.max(bestChoice, currChoice);
                }
                double probGettingCFirst = (starts[c-'a'].size() * 1.0 / s.length());
                ans += (probGettingCFirst * bestChoice);
            }
            io.println(ans);
        }

        /************************** UTILITY CODE BELOW THIS LINE **************************/

        long MOD = (long)1e9 + 7;

        List<Integer>[] toGraph(IO io, int n) {
            List<Integer>[] g = new ArrayList[n+1];
            for (int i=1; i<=n; i++) g[i] = new ArrayList<>();
            for (int i=1; i<=n-1; i++) {
                int a = io.nextInt();
                int b = io.nextInt();
                g[a].add(b);
                g[b].add(a);
            }
            return g;
        }

        class Point {
            int y;
            int x;

            public Point(int y, int x) {
                this.y = y;
                this.x = x;
            }
        }

        class IDval implements Comparable<IDval> {
            int id;
            long val;

            public IDval(int id, long val) {
                this.val = val;
                this.id = id;
            }

            @Override
            public int compareTo(IDval o) {
                if (this.val < o.val) return -1;
                if (this.val > o.val) return 1;
                return this.id - o.id;
            }
        }

        long pow(long base, int exp) {
            if (exp == 0) return 1L;
            long x = pow(base, exp/2);
            long ans = x * x;
            if (exp % 2 != 0) ans *= base;
            return ans;
        }

        long gcd(long... v) {
            /** Chained calls to Euclidean algorithm. */
            if (v.length == 1) return v[0];
            long ans = gcd(v[1], v[0]);
            for (int i=2; i<v.length; i++) {
                ans = gcd(ans, v[i]);
            }
            return ans;
        }

        long gcd(long a, long b) {
            /** Euclidean algorithm. */
            if (b == 0) return a;
            return gcd(b, a%b);
        }

        int[] generatePrimesUpTo(int last) {
            /* Sieve of Eratosthenes. Practically O(n). Values of 0 indicate primes. */
            int[] div = new int[last+1];
            for (int x=2; x<=last; x++) {
                if (div[x] > 0) continue;
                for (int u=2*x; u<=last; u+=x) {
                    div[u] = x;
                }
            }
            return div;
        }

        long lcm(long a, long b) {
            /** Least common multiple */
            return a * b / gcd(a,b);
        }

        private class ElementCounter {
            private HashMap<Long, Integer> elements;

            public ElementCounter() {
                elements = new HashMap<>();
            }

            public void add(long element) {
                int count = 1;
                if (elements.containsKey(element)) count += elements.get(element);
                elements.put(element, count);
            }

            public void remove(long element) {
                int count = elements.get(element);
                count--;
                if (count == 0) elements.remove(element);
                else elements.put(element, count);
            }

            public int get(long element) {
                if (!elements.containsKey(element)) return 0;
                return elements.get(element);
            }

            public int size() {
                return elements.size();
            }
        }

        class StringCounter {
            HashMap<String, Long> elements;

            public StringCounter() {
                elements = new HashMap<>();
            }

            public void add(String identifier) {
                long count = 1;
                if (elements.containsKey(identifier)) count += elements.get(identifier);
                elements.put(identifier, count);
            }

            public void remove(String identifier) {
                long count = elements.get(identifier);
                count--;
                if (count == 0) elements.remove(identifier);
                else elements.put(identifier, count);
            }

            public long get(String identifier) {
                if (!elements.containsKey(identifier)) return 0;
                return elements.get(identifier);
            }

            public int size() {
                return elements.size();
            }
        }

        class DisjointSet {
            /** Union Find / Disjoint Set data structure. */
            int[] size;
            int[] parent;
            int componentCount;

            public DisjointSet(int n) {
                componentCount = n;
                size = new int[n];
                parent = new int[n];
                for (int i=0; i<n; i++) parent[i] = i;
                for (int i=0; i<n; i++) size[i] = 1;
            }

            public void join(int a, int b) {
                /* Find roots */
                int rootA = parent[a];
                int rootB = parent[b];
                while (rootA != parent[rootA]) rootA = parent[rootA];
                while (rootB != parent[rootB]) rootB = parent[rootB];

                if (rootA == rootB) {
                    /* Already in the same set */
                    return;
                }

                /* Merge smaller set into larger set. */
                if (size[rootA] > size[rootB]) {
                    size[rootA] += size[rootB];
                    parent[rootB] = rootA;
                } else {
                    size[rootB] += size[rootA];
                    parent[rootA] = rootB;
                }
                componentCount--;
            }

        }

        class LCAFinder {

            /* O(n log n) Initialize: new LCAFinder(graph)
             * O(log n) Queries: find(a,b) returns lowest common ancestor for nodes a and b */

            int[] nodes;
            int[] depths;
            int[] entries;
            int pointer;
            FenwickMin fenwick;

            public LCAFinder(List<Integer>[] graph) {
                this.nodes = new int[(int)10e6];
                this.depths = new int[(int)10e6];
                this.entries = new int[graph.length];
                this.pointer = 1;
                boolean[] visited = new boolean[graph.length+1];
                dfs(1, 0, graph, visited);
                fenwick = new FenwickMin(pointer-1);
                for (int i=1; i<pointer; i++) {
                    fenwick.set(i, depths[i] * 1000000L + i);
                }
            }

            private void dfs(int node, int depth, List<Integer>[] graph, boolean[] visited) {
                visited[node] = true;
                entries[node] = pointer;
                nodes[pointer] = node;
                depths[pointer] = depth;
                pointer++;
                for (int neighbor : graph[node]) {
                    if (visited[neighbor]) continue;
                    dfs(neighbor, depth+1, graph, visited);
                    nodes[pointer] = node;
                    depths[pointer] = depth;
                    pointer++;
                }
            }

            public int find(int a, int b) {
                int left = entries[a];
                int right = entries[b];
                if (left > right) {
                    int temp = left;
                    left = right;
                    right = temp;
                }
                long mixedBag = fenwick.getMin(left, right);
                int index = (int) (mixedBag % 1000000L);
                return nodes[index];
            }
        }

        class FenwickMin {
            long n;
            long[] original;
            long[] bottomUp;
            long[] topDown;

            public FenwickMin(int n) {
                this.n = n;
                original = new long[n+2];
                bottomUp = new long[n+2];
                topDown = new long[n+2];
            }

            public void set(int modifiedNode, long value) {
                long replaced = original[modifiedNode];
                original[modifiedNode] = value;
                // Update left tree
                int i = modifiedNode;
                long v = value;
                while (i <= n) {
                    if (v > bottomUp[i]) {
                        if (replaced == bottomUp[i]) {
                            v = Math.min(v, original[i]);
                            for (int r=1 ;; r++) {
                                int x = (i&-i)>>>r;
                                if (x == 0) break;
                                int child = i-x;
                                v = Math.min(v, bottomUp[child]);
                            }
                        } else break;
                    }
                    if (v == bottomUp[i]) break;
                    bottomUp[i] = v;
                    i += (i&-i);
                }
                // Update right tree
                i = modifiedNode;
                v = value;
                while (i > 0) {
                    if (v > topDown[i]) {
                        if (replaced == topDown[i]) {
                            v = Math.min(v, original[i]);
                            for (int r=1 ;; r++) {
                                int x = (i&-i)>>>r;
                                if (x == 0) break;
                                int child = i+x;
                                if (child > n+1) break;
                                v = Math.min(v, topDown[child]);
                            }
                        } else break;
                    }
                    if (v == topDown[i]) break;
                    topDown[i] = v;
                    i -= (i&-i);
                }
            }

            public long getMin(int a, int b) {
                long min = original[a];
                int prev = a;
                int curr = prev + (prev&-prev); // parent right hand side
                while (curr <= b) {
                    min = Math.min(min, topDown[prev]); // value from the other tree
                    prev = curr;
                    curr = prev + (prev&-prev);;
                }
                min = Math.min(min, original[prev]);
                prev = b;
                curr = prev - (prev&-prev); // parent left hand side
                while (curr >= a) {
                    min = Math.min(min,bottomUp[prev]); // value from the other tree
                    prev = curr;
                    curr = prev - (prev&-prev);
                }
                return min;
            }

        }

        class FenwickSum {
            public long[] d;

            public FenwickSum(int n) {
                d=new long[n+1];
            }

            /** a[0] must be unused. */
            public FenwickSum(long[] a) {
                d=new long[a.length];
                for (int i=1; i<a.length; i++) {
                    modify(i, a[i]);
                }
            }

            /** Do not modify i=0. */
            void modify(int i, long v) {
                while (i<d.length) {
                    d[i] += v;
                    // Move to next uplink on the RIGHT side of i
                    i += (i&-i);
                }
            }

            /** Returns sum from a to b, *BOTH* inclusive. */
            long getSum(int a, int b) {
                return getSum(b) - getSum(a-1);
            }

            private long getSum(int i) {
                long sum = 0;
                while (i>0) {
                    sum += d[i];
                    // Move to next uplink on the LEFT side of i
                    i -= (i&-i);
                }
                return sum;
            }
        }

        class SegmentTree {
            /** Query sums with log(n) modifyRange */
            int N;
            long[] p;

            public SegmentTree(int n) {
                /* TODO: Test that this works. */
                for (N=2; N<n; N++) N *= 2;
                p = new long[2*N];
            }

            public void modifyRange(int a, int b, long change) {
                muuta(a, change);
                muuta(b+1, -change);
            }

            void muuta(int k, long muutos) {
                k += N;
                p[k] += muutos;
                for (k /= 2; k >= 1; k /= 2) {
                    p[k] = p[2*k] + p[2*k+1];
                }
            }

            public long get(int k) {
                int a = N;
                int b = k+N;
                long s = 0;
                while (a <= b) {
                    if (a%2 == 1) s += p[a++];
                    if (b%2 == 0) s += p[b--];
                    a /= 2;
                    b /= 2;
                }
                return s;
            }

        }

        class Zalgo {

            public int pisinEsiintyma(String haku, String kohde) {
                char[] s = new char[haku.length() + 1 + kohde.length()];
                for (int i=0; i<haku.length(); i++) {
                    s[i] = haku.charAt(i);
                }
                int j = haku.length();
                s[j++] = '#';
                for (int i=0; i<kohde.length(); i++) {
                    s[j++] = kohde.charAt(i);
                }
                int[] z = toZarray(s);
                int max = 0;
                for (int i=haku.length(); i<z.length; i++) {
                    max = Math.max(max, z[i]);
                }
                return max;
            }

            public int[] toZarray(char[] s) {
                int n = s.length;
                int[] z = new int[n];
                int a = 0, b = 0;
                for (int i = 1; i < n; i++) {
                    if (i > b) {
                        for (int j = i; j < n && s[j - i] == s[j]; j++)  z[i]++;
                    }
                    else {
                        z[i] = z[i - a];
                        if (i + z[i - a] > b) {
                            for (int j = b + 1; j < n && s[j - i] == s[j]; j++) z[i]++;
                            a = i;
                            b = i + z[i] - 1;
                        }
                    }
                }
                return z;
            }

            public List<Integer> getStartIndexesWhereWordIsFound(String haku, String kohde) {
                // this is alternative use case
                char[] s = new char[haku.length() + 1 + kohde.length()];
                for (int i=0; i<haku.length(); i++) {
                    s[i] = haku.charAt(i);
                }
                int j = haku.length();
                s[j++] = '#';
                for (int i=0; i<kohde.length(); i++) {
                    s[j++] = kohde.charAt(i);
                }
                int[] z = toZarray(s);
                List<Integer> indexes = new ArrayList<>();
                for (int i=haku.length(); i<z.length; i++) {
                    if (z[i] < haku.length()) continue;
                    indexes.add(i);
                }
                return indexes;
            }

        }

        class StringHasher {

            class HashedString {
                long[] hashes;
                long[] modifiers;

                public HashedString(long[] hashes, long[] modifiers) {
                    this.hashes = hashes;
                    this.modifiers = modifiers;
                }
            }

            long P;
            long M;

            public StringHasher() {
                initializePandM();
            }

            HashedString hashString(String s) {
                int n = s.length();
                long[] hashes = new long[n];
                long[] modifiers = new long[n];
                hashes[0] = s.charAt(0);
                modifiers[0] = 1;
                for (int i=1; i<n; i++) {
                    hashes[i] = (hashes[i-1] * P + s.charAt(i)) % M;
                    modifiers[i] = (modifiers[i-1] * P) % M;
                }
                return new HashedString(hashes, modifiers);
            }

            /**
             * Indices are inclusive.
             */
            long getHash(HashedString hashedString, int startIndex, int endIndex) {
                long[] hashes = hashedString.hashes;
                long[] modifiers = hashedString.modifiers;
                long result = hashes[endIndex];
                if (startIndex > 0) result -= (hashes[startIndex-1] * modifiers[endIndex-startIndex+1]) % M;
                if (result < 0) result += M;
                return result;
            }

            // Less interesting methods below

            /**
             * Efficient for 2 input parameter strings in particular.
             */
            HashedString[] hashString(String first, String second) {
                HashedString[] array = new HashedString[2];
                int n = first.length();
                long[] modifiers = new long[n];
                modifiers[0] = 1;

                long[] firstHashes = new long[n];
                firstHashes[0] = first.charAt(0);
                array[0] = new HashedString(firstHashes, modifiers);

                long[] secondHashes = new long[n];
                secondHashes[0] = second.charAt(0);
                array[1] = new HashedString(secondHashes, modifiers);

                for (int i=1; i<n; i++) {
                    modifiers[i] = (modifiers[i-1] * P) % M;
                    firstHashes[i] = (firstHashes[i-1] * P + first.charAt(i)) % M;
                    secondHashes[i] = (secondHashes[i-1] * P + second.charAt(i)) % M;
                }
                return array;
            }

            /**
             * Efficient for 3+ strings
             * More efficient than multiple hashString calls IF strings are same length.
             */
            HashedString[] hashString(String... strings) {
                HashedString[] array = new HashedString[strings.length];
                int n = strings[0].length();
                long[] modifiers = new long[n];
                modifiers[0] = 1;
                for (int j=0; j<strings.length; j++) {
                    // if all strings are not same length, defer work to another method
                    if (strings[j].length() != n) {
                        for (int i=0; i<n; i++) {
                            array[i] = hashString(strings[i]);
                        }
                        return array;
                    }

                    // otherwise initialize stuff
                    long[] hashes = new long[n];
                    hashes[0] = strings[j].charAt(0);
                    array[j] = new HashedString(hashes, modifiers);
                }
                for (int i=1; i<n; i++) {
                    modifiers[i] = (modifiers[i-1] * P) % M;
                    for (int j=0; j<strings.length; j++) {
                        String s = strings[j];
                        long[] hashes = array[j].hashes;
                        hashes[i] = (hashes[i-1] * P + s.charAt(i)) % M;
                    }
                }
                return array;
            }

            void initializePandM() {
                ArrayList<Long> modOptions = new ArrayList<>(20);
                modOptions.add(353873237L);
                modOptions.add(353875897L);
                modOptions.add(353878703L);
                modOptions.add(353882671L);
                modOptions.add(353885303L);
                modOptions.add(353888377L);
                modOptions.add(353893457L);
                P = modOptions.get(new Random().nextInt(modOptions.size()));

                modOptions.clear();
                modOptions.add(452940277L);
                modOptions.add(452947687L);
                modOptions.add(464478431L);
                modOptions.add(468098221L);
                modOptions.add(470374601L);
                modOptions.add(472879717L);
                modOptions.add(472881973L);
                M = modOptions.get(new Random().nextInt(modOptions.size()));

            }
        }

        private static class Prob {

            /** For heavy calculations on probabilities, this class
             *  provides more accuracy & efficiency than doubles.
             *  Math explained: https://en.wikipedia.org/wiki/Log_probability
             *  Quick start:
             *      - Instantiate probabilities, eg. Prob a = new Prob(0.75)
             *      - add(), multiply() return new objects, can perform on nulls & NaNs.
             *      - get() returns probability as a readable double */

            /** Logarithmized probability. Note: 0% represented by logP NaN. */
            private double logP;

            /** Construct instance with real probability. */
            public Prob(double real) {
                if (real > 0) this.logP = Math.log(real);
                else this.logP = Double.NaN;
            }

            /** Construct instance with already logarithmized value. */
            static boolean dontLogAgain = true;
            public Prob(double logP, boolean anyBooleanHereToChooseThisConstructor) {
                this.logP = logP;
            }

            /** Returns real probability as a double. */
            public double get() {
                return Math.exp(logP);
            }

            @Override
            public String toString() {
                return ""+get();
            }

            /***************** STATIC METHODS BELOW ********************/

            /** Note: returns NaN only when a && b are both NaN/null. */
            public static Prob add(Prob a, Prob b) {
                if (nullOrNaN(a) && nullOrNaN(b)) return new Prob(Double.NaN, dontLogAgain);
                if (nullOrNaN(a)) return copy(b);
                if (nullOrNaN(b)) return copy(a);

                double x = Math.max(a.logP, b.logP);
                double y = Math.min(a.logP, b.logP);
                double sum = x + Math.log(1 + Math.exp(y - x));
                return new Prob(sum, dontLogAgain);
            }

            /** Note: multiplying by null or NaN produces NaN (repping 0% real prob). */
            public static Prob multiply(Prob a, Prob b) {
                if (nullOrNaN(a) || nullOrNaN(b)) return new Prob(Double.NaN, dontLogAgain);
                return new Prob(a.logP + b.logP, dontLogAgain);
            }

            /** Returns true if p is null or NaN. */
            private static boolean nullOrNaN(Prob p) {
                return (p == null || Double.isNaN(p.logP));
            }

            /** Returns a new instance with the same value as original. */
            private static Prob copy(Prob original) {
                return new Prob(original.logP, dontLogAgain);
            }
        }

        public class StronglyConnectedComponents {

            /** Kosaraju's algorithm */

            ArrayList<Integer>[] forw;
            ArrayList<Integer>[] bacw;

            /** Use: getCount(2, new int[] {1,2}, new int[] {2,1}) */
            public int getCount(int n, int[] mista, int[] minne) {
                forw = new ArrayList[n+1];
                bacw = new ArrayList[n+1];
                for (int i=1; i<=n; i++) {
                    forw[i] = new ArrayList<Integer>();
                    bacw[i] = new ArrayList<Integer>();
                }
                for (int i=0; i<mista.length; i++) {
                    int a = mista[i];
                    int b = minne[i];
                    forw[a].add(b);
                    bacw[b].add(a);
                }
                int count = 0;
                List<Integer> list = new ArrayList<Integer>();
                boolean[] visited = new boolean[n+1];
                for (int i=1; i<=n; i++) {
                    dfsForward(i, visited, list);
                }
                visited = new boolean[n+1];
                for (int i=n-1; i>=0; i--) {
                    int node = list.get(i);
                    if (visited[node]) continue;
                    count++;
                    dfsBackward(node, visited);
                }
                return count;
            }

            public void dfsForward(int i, boolean[] visited, List<Integer> list) {
                if (visited[i]) return;
                visited[i] = true;
                for (int neighbor : forw[i]) {
                    dfsForward(neighbor, visited, list);
                }
                list.add(i);
            }

            public void dfsBackward(int i, boolean[] visited) {
                if (visited[i]) return;
                visited[i] = true;
                for (int neighbor : bacw[i]) {
                    dfsBackward(neighbor, visited);
                }
            }
        }

        class DrawGrid {

            void draw(boolean[][] d) {
                System.out.print("  ");
                for (int x=0; x<d[0].length; x++) {
                    System.out.print(" " + x + " ");
                }
                System.out.println("");
                for (int y=0; y<d.length; y++) {
                    System.out.print(y + " ");
                    for (int x=0; x<d[0].length; x++) {
                        System.out.print((d[y][x] ? "[x]" : "[ ]"));
                    }
                    System.out.println("");
                }
            }

            void draw(int[][] d) {
                int max = 1;
                for (int y=0; y<d.length; y++) {
                    for (int x=0; x<d[0].length; x++) {
                        max = Math.max(max, ("" + d[y][x]).length());
                    }
                }
                System.out.print("  ");
                String format = "%" + (max+2) + "s";
                for (int x=0; x<d[0].length; x++) {
                    System.out.print(String.format(format, x) + " ");
                }
                format = "%" + (max) + "s";
                System.out.println("");
                for (int y=0; y<d.length; y++) {
                    System.out.print(y + " ");
                    for (int x=0; x<d[0].length; x++) {
                        System.out.print(" [" + String.format(format, (d[y][x])) + "]");
                    }
                    System.out.println("");
                }
            }

        }

        class BaseConverter {

            /* Palauttaa luvun esityksen kannassa base */
            public String convert(Long number, int base) {
                return Long.toString(number, base);
            }

            /* Palauttaa luvun esityksen kannassa baseTo, kun annetaan luku Stringinä kannassa baseFrom */
            public String convert(String number, int baseFrom, int baseTo) {
                return Long.toString(Long.parseLong(number, baseFrom), baseTo);
            }

            /* Tulkitsee kannassa base esitetyn luvun longiksi (kannassa 10) */
            public long longify(String number, int baseFrom) {
                return Long.parseLong(number, baseFrom);
            }
        }

        class Binary implements Comparable<Binary> {

            /**
             * Use example: Binary b = new Binary(Long.toBinaryString(53249834L));
             *
             * When manipulating small binary strings, instantiate new Binary(string)
             * When just reading large binary strings, instantiate new Binary(string,true)
             * get(int i) returns a character '1' or '0', not an int.
             */

            private boolean[] d;
            private int first; // Starting from left, the first (most remarkable) '1'
            public int length;

            public Binary(String binaryString) {
                this(binaryString, false);
            }
            public Binary(String binaryString, boolean initWithMinArraySize) {
                length = binaryString.length();
                int size = Math.max(2*length, 1);
                first = length/4;
                if (initWithMinArraySize) {
                    first = 0;
                    size = Math.max(length, 1);
                }
                d = new boolean[size];
                for (int i=0; i<length; i++) {
                    if (binaryString.charAt(i) == '1') d[i+first] = true;
                }
            }

            public void addFirst(char c) {
                if (first-1 < 0) doubleArraySize();
                first--;
                d[first] = (c == '1' ? true : false);
                length++;
            }

            public void addLast(char c) {
                if (first+length >= d.length) doubleArraySize();
                d[first+length] = (c == '1' ? true : false);
                length++;
            }

            private void doubleArraySize() {
                boolean[] bigArray = new boolean[(d.length+1) * 2];
                int newFirst = bigArray.length / 4;
                for (int i=0; i<length; i++) {
                    bigArray[i + newFirst] = d[i + first];
                }
                first = newFirst;
                d = bigArray;
            }

            public boolean flip(int i) {
                boolean value = (this.d[first+i] ? false : true);
                this.d[first+i] = value;
                return value;
            }

            public void set(int i, char c) {
                boolean value = (c == '1' ? true : false);
                this.d[first+i] = value;
            }

            public char get(int i) {
                return (this.d[first+i] ? '1' : '0');
            }

            @Override
            public int compareTo(Binary o) {
                if (this.length != o.length) return this.length - o.length;
                int len = this.length;
                for (int i=0; i<len; i++) {
                    int diff = this.get(i) - o.get(i);
                    if (diff != 0) return diff;
                }
                return 0;
            }

            @Override
            public String toString() {
                StringBuilder sb = new StringBuilder();
                for (int i=0; i<length; i++) {
                    sb.append(d[i+first] ? '1' : '0');
                }
                return sb.toString();
            }

        }

        class BinomialCoefficients {
            /** Total number of K sized unique combinations from pool of size N (unordered)
             N! / ( K! (N - K)! )   */

            /** For simple queries where output fits in long. */
            public long biCo(long n, long k) {
                long r = 1;
                if (k > n) return 0;
                for (long d = 1; d <= k; d++) {
                    r *= n--;
                    r /= d;
                }
                return r;
            }

            /** For multiple queries with same n, different k. */
            public long[] precalcBinomialCoefficientsK(int n, int maxK) {
                long v[] = new long[maxK+1];
                v[0] = 1; // nC0 == 1
                for (int i=1; i<=n; i++) {
                    for (int j=Math.min(i,maxK); j>0; j--) {
                        v[j] = v[j] + v[j-1]; // Pascal's triangle
                    }
                }
                return v;
            }

            /** When output needs % MOD. */
            public long[] precalcBinomialCoefficientsK(int n, int k, long M) {
                long v[] = new long[k+1];
                v[0] = 1; // nC0 == 1
                for (int i=1; i<=n; i++) {
                    for (int j=Math.min(i,k); j>0; j--) {
                        v[j] = v[j] + v[j-1]; // Pascal's triangle
                        v[j] %= M;
                    }
                }
                return v;
            }
        }

        class Trie {
            int N;
            int Z;
            int nextFreeId;
            int[][] pointers;
            boolean[] end;

            /** maxLenSum = maximum possible sum of length of words */
            public Trie(int maxLenSum, int alphabetSize) {
                this.N = maxLenSum;
                this.Z = alphabetSize;
                this.nextFreeId = 1;
                pointers = new int[N+1][alphabetSize];
                end = new boolean[N+1];
            }

            public void addWord(String word) {
                int curr = 0;
                for (int j=0; j<word.length(); j++) {
                    int c = word.charAt(j) - 'a';
                    int next = pointers[curr][c];
                    if (next == 0) {
                        next = nextFreeId++;
                        pointers[curr][c] = next;
                    }
                    curr = next;
                }
                int last = word.charAt(word.length()-1) - 'a';
                end[last] = true;
            }

            public boolean hasWord(String word) {
                int curr = 0;
                for (int j=0; j<word.length(); j++) {
                    int c = word.charAt(j) - 'a';
                    int next = pointers[curr][c];
                    if (next == 0) return false;
                    curr = next;
                }
                int last = word.charAt(word.length()-1) - 'a';
                return end[last];
            }

        }

        private class IO extends PrintWriter {
            private InputStreamReader r;
            private static final int BUFSIZE = 1 << 15;
            private char[] buf;
            private int bufc;
            private int bufi;
            private StringBuilder sb;

            public IO() {
                super(new BufferedOutputStream(System.out));
                r = new InputStreamReader(System.in);

                buf = new char[BUFSIZE];
                bufc = 0;
                bufi = 0;
                sb = new StringBuilder();
            }

            /** Print, flush, return nextInt. */
            private int queryInt(String s) {
                io.println(s);
                io.flush();
                return nextInt();
            }

            /** Print, flush, return nextLong. */
            private long queryLong(String s) {
                io.println(s);
                io.flush();
                return nextLong();
            }

            /** Print, flush, return next word. */
            private String queryNext(String s) {
                io.println(s);
                io.flush();
                return next();
            }

            private void fillBuf() throws IOException {
                bufi = 0;
                bufc = 0;
                while(bufc == 0) {
                    bufc = r.read(buf, 0, BUFSIZE);
                    if(bufc == -1) {
                        bufc = 0;
                        return;
                    }
                }
            }

            private boolean pumpBuf() throws IOException {
                if(bufi == bufc) {
                    fillBuf();
                }
                return bufc != 0;
            }

            private boolean isDelimiter(char c) {
                return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f';
            }

            private void eatDelimiters() throws IOException {
                while(true) {
                    if(bufi == bufc) {
                        fillBuf();
                        if(bufc == 0) throw new RuntimeException("IO: Out of input.");
                    }

                    if(!isDelimiter(buf[bufi])) break;
                    ++bufi;
                }
            }

            public String next() {
                try {
                    sb.setLength(0);

                    eatDelimiters();
                    int start = bufi;

                    while(true) {
                        if(bufi == bufc) {
                            sb.append(buf, start, bufi - start);
                            fillBuf();
                            start = 0;
                            if(bufc == 0) break;
                        }

                        if(isDelimiter(buf[bufi])) break;
                        ++bufi;
                    }

                    sb.append(buf, start, bufi - start);

                    return sb.toString();
                } catch(IOException e) {
                    throw new RuntimeException("IO.next: Caught IOException.");
                }
            }

            public int nextInt() {
                try {
                    int ret = 0;

                    eatDelimiters();

                    boolean positive = true;
                    if(buf[bufi] == '-') {
                        ++bufi;
                        if(!pumpBuf()) throw new RuntimeException("IO.nextInt: Invalid int.");
                        positive = false;
                    }

                    boolean first = true;
                    while(true) {
                        if(!pumpBuf()) break;
                        if(isDelimiter(buf[bufi])) {
                            if(first) throw new RuntimeException("IO.nextInt: Invalid int.");
                            break;
                        }
                        first = false;

                        if(buf[bufi] >= '0' && buf[bufi] <= '9') {
                            if(ret < -214748364) throw new RuntimeException("IO.nextInt: Invalid int.");
                            ret *= 10;
                            ret -= (int)(buf[bufi] - '0');
                            if(ret > 0) throw new RuntimeException("IO.nextInt: Invalid int.");
                        } else {
                            throw new RuntimeException("IO.nextInt: Invalid int.");
                        }

                        ++bufi;
                    }

                    if(positive) {
                        if(ret == -2147483648) throw new RuntimeException("IO.nextInt: Invalid int.");
                        ret = -ret;
                    }

                    return ret;
                } catch(IOException e) {
                    throw new RuntimeException("IO.nextInt: Caught IOException.");
                }
            }

            public long nextLong() {
                try {
                    long ret = 0;

                    eatDelimiters();

                    boolean positive = true;
                    if(buf[bufi] == '-') {
                        ++bufi;
                        if(!pumpBuf()) throw new RuntimeException("IO.nextLong: Invalid long.");
                        positive = false;
                    }

                    boolean first = true;
                    while(true) {
                        if(!pumpBuf()) break;
                        if(isDelimiter(buf[bufi])) {
                            if(first) throw new RuntimeException("IO.nextLong: Invalid long.");
                            break;
                        }
                        first = false;

                        if(buf[bufi] >= '0' && buf[bufi] <= '9') {
                            if(ret < -922337203685477580L) throw new RuntimeException("IO.nextLong: Invalid long.");
                            ret *= 10;
                            ret -= (long)(buf[bufi] - '0');
                            if(ret > 0) throw new RuntimeException("IO.nextLong: Invalid long.");
                        } else {
                            throw new RuntimeException("IO.nextLong: Invalid long.");
                        }

                        ++bufi;
                    }

                    if(positive) {
                        if(ret == -9223372036854775808L) throw new RuntimeException("IO.nextLong: Invalid long.");
                        ret = -ret;
                    }

                    return ret;
                } catch(IOException e) {
                    throw new RuntimeException("IO.nextLong: Caught IOException.");
                }
            }

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

        }

        void print(Object output) {
            io.println(output);
        }

        void done(Object output) {
            print(output);
            done();
        }

        void done() {
            io.close();
            throw new RuntimeException("Clean exit");
        }

        long min(long... v) {
            long ans = v[0];
            for (int i=1; i<v.length; i++) {
                ans = Math.min(ans, v[i]);
            }
            return ans;
        }

        double min(double... v) {
            double ans = v[0];
            for (int i=1; i<v.length; i++) {
                ans = Math.min(ans, v[i]);
            }
            return ans;
        }

        int min(int... v) {
            int ans = v[0];
            for (int i=1; i<v.length; i++) {
                ans = Math.min(ans, v[i]);
            }
            return ans;
        }

        long max(long... v) {
            long ans = v[0];
            for (int i=1; i<v.length; i++) {
                ans = Math.max(ans, v[i]);
            }
            return ans;
        }

        double max(double... v) {
            double ans = v[0];
            for (int i=1; i<v.length; i++) {
                ans = Math.max(ans, v[i]);
            }
            return ans;
        }

        int max(int... v) {
            int ans = v[0];
            for (int i=1; i<v.length; i++) {
                ans = Math.max(ans, v[i]);
            }
            return ans;
        }

        void debug(Object output) {
            if (DEBUG_PRINTS) {
                System.out.println(output);
            }
        }
    }

}


//package com.company;

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

public class Main {
    public static void main(String[] args) throws IOException {
        MyScanner sc = new MyScanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
//        long st = System.currentTimeMillis();
        Tanks.solve(sc, pw);
//        pw.println(System.currentTimeMillis() - st);
        pw.close();
    }
    public static class Tanks {
        static List<Integer>[] idxs;
        static int[] solus;
        static char[] str;
        static int n;
        public static void solve(MyScanner sc, PrintWriter pw) throws IOException {
            str = sc.next().toCharArray();
//            str = new char[4];
//            Random rnd = new Random();
//            for (int i = 0; i < 4; i++) {
////                str[i] = 'a';
//                int c = (int)(rnd.nextDouble() * 26);
//                str[i] = (char)(c + 'a');
//            }
            n = str.length;
            idxs = new List[26];
            for (int i = 0; i < idxs.length; i++) {
                idxs[i] = new ArrayList<>();
            }
            solus = new int[n];
            for (int i = 0; i < n; i++) {
                str[i] -= 'a';
                idxs[str[i]].add(i);
            }
            int su = 0;
            for (int i = 0; i < 26; i++) {
                if (idxs[i].size() == 0) continue;
                if (idxs[i].size() == 1) {
//                    solus[idxs[i].get(0)] = 1;
                    su += 1;
                    continue;
                }
                int start = idxs[i].get(0);
                int bs = 0;
                for (int j = 1; j < n; j++) {
                    boolean br = false;
                    int cc = 0;
                    int[] cnt = new int[26];
                    for (int k = 0; k < idxs[i].size(); k++) {
                        int pt = (idxs[i].get(k) + j) % n;
                        if (cnt[str[pt]] == 0) {
                            cnt[str[pt]] = idxs[i].get(k) + 1;
                        } else {
                            cnt[str[pt]] = -1;
                        }
                    }
                    for (int k = 0; k < 26; k++) {
                        if (cnt[k] > 0) {
                            cc++;
//                            solus[cnt[k] - 1] = 1;
                        }
                    }
                    bs = Math.max(bs, cc);
                }
                su += bs;
            }
//            for (int i = 0; i < n; i++) {
//                su += solus[i] == 1 ? 1 : 0;
//            }
            pw.println((su + 0.0) / n);
        }

    }

    static class MyScanner {
        StringTokenizer st;
        BufferedReader br;

        public MyScanner(InputStream s){  br = new BufferedReader(new InputStreamReader(s));}

        public MyScanner(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 R468_E {
	static BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer st = new StringTokenizer("");

	public static void main(String[] args) throws Exception {
      String s = readString();
      ArrayList<ArrayList<Integer>> a = new ArrayList();
      for(int i = 'a'; i <= 'z'; ++i)
         a.add(new ArrayList());

      for(int i = 0; i < s.length(); ++i) {
         a.get(s.charAt(i)-'a').add(i);
      }

      int d = 0;
      for(ArrayList<Integer> b : a) {
         if(!b.isEmpty()) {
            int max = 0;
            for(int i = 1; i < s.length(); ++i) {
               int[] t = new int['z'-'a'+1];
               for(int c : b)
                  t[s.charAt((c+i)%s.length())-'a']++;
               int c = 0;
               for(int j = 0; j <= 'z'-'a'; ++j)
                  if(t[j] == 1)
                     ++c;
               max = Math.max(max, c);
            }
            d += max;
         }
      }

      System.out.println((double)d/s.length());
	}

	static String readString() throws Exception {
		while(!st.hasMoreTokens())
			st = new StringTokenizer(stdin.readLine());
		return st.nextToken();
	}
	static int readInt() throws Exception {
		return Integer.parseInt(readString());
	}
	static long readLong() throws Exception {
		return Long.parseLong(readString());
	}
	static double readDouble() throws Exception {
		return Double.parseDouble(readString());
	}
}


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

public class R468_E {
	static BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer st = new StringTokenizer("");

	public static void main(String[] args) throws Exception {
      String s = readString();
      ArrayList<ArrayList<Integer>> a = new ArrayList();
      for(int i = 'a'; i <= 'z'; ++i)
         a.add(new ArrayList());

      for(int i = 0; i < s.length(); ++i) {
         a.get(s.charAt(i)-'a').add(i);
      }

      int d = 0;
      for(ArrayList<Integer> b : a) {
         if(!b.isEmpty()) {
            int max = 0;
            for(int i = 1; i < s.length(); ++i) {
               int[] t = new int['z'-'a'];
               for(int c : b)
                  t[s.charAt((c+i)%s.length())-'a']++;
               int c = 0;
               for(int j = 0; j < 'z'-'a'; ++j)
                  if(t[j] == 1)
                     ++c;
               max = Math.max(max, c);
            }
            d += max;
         }
      }

      System.out.println((double)d/s.length());
	}

	static String readString() throws Exception {
		while(!st.hasMoreTokens())
			st = new StringTokenizer(stdin.readLine());
		return st.nextToken();
	}
	static int readInt() throws Exception {
		return Integer.parseInt(readString());
	}
	static long readLong() throws Exception {
		return Long.parseLong(readString());
	}
	static double readDouble() throws Exception {
		return Double.parseDouble(readString());
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class codeforces {
	public static void main(String[] args) {
		FS scan = new FS(System.in);
		PrintWriter out = new PrintWriter(System.out);

		char[] s = scan.next().toCharArray();

		int[][][] count = new int[26][26][s.length];
		int[] let = new int[26];
		for(int i=0;i<s.length;i++){
			let[s[i]-'a']++;
			for(int j=1;j<s.length;j++){
				int idx2 = (i+j)%s.length;
				count[s[i]-'a'][s[idx2]-'a'][j]++;
			}
		}

		double prob = 0;
		for(int i=0;i<26;i++){
			if(let[i]==0)continue;
			int max = 0;
			for(int j=1;j<s.length;j++){
				int tmp = 0;
				for(int k=0;k<26;k++)
					if(count[i][k][j]==1)
						tmp++;
				max = Math.max(tmp, max);
			}
			prob += (double)max /(double)s.length;
		}

		System.out.println(prob);

		out.close();
	}
	private static class FS {
		BufferedReader br;
		StringTokenizer st;
		public FS(InputStream in) {
			br = new BufferedReader(new InputStreamReader(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());}
	}
}


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/*
 public class _931E {

 }

 */
public class _931E {
  public void solve() throws FileNotFoundException {
    InputStream inputStream = System.in;

    InputHelper in = new InputHelper(inputStream);

    // actual solution
    String s = in.read();

    int n = s.length();

    int[][][] pre = new int[26][n + 1][26];

    int[] cc = new int[26];

    for (int i = 0; i < n; i++) {
      cc[s.charAt(i) - 'a']++;
      for (int j = i + 1; j < n; j++) {
        pre[s.charAt(i) - 'a'][j - i][s.charAt(j) - 'a']++;
      }
      for (int j = 0; j < i; j++) {
        pre[s.charAt(i) - 'a'][n - i + j][s.charAt(j) - 'a']++;
      }
    }

    double[][] prob = new double[26][n + 1];
    double[] max = new double[26];

    for (int i = 0; i < 26; i++) {
      for (int j = 1; j < n; j++) {
        for (int k = 0; k < 26; k++) {
          if (pre[i][j][k] == 1) {
            prob[i][j] += 1.0 / cc[i];
          }
        }
        if (prob[i][j] > max[i]) {
          max[i] = prob[i][j];
        }
      }
    }

    double ans = 0;
    for (int i = 0; i < 26; i++) {
      ans += cc[i] * max[i];
    }

    System.out.println(ans / n);
    // double ans = 0;
    //
    // int[] min = new int[26];
    // int[] minc = new int[26];
    // int[] cc = new int[26];
    //
    // for (int i = 0; i < 26; i++) {
    // min[i] = n + 1;
    // }
    //
    // for (int i = 0; i < n; i++) {
    // int ic = s.charAt(i) - 'a';
    // cc[ic]++;
    // int cmin = n + 1;
    // for (int j = i + 1; j < n; j++) {
    // int jc = s.charAt(j) - 'a';
    // cmin = Math.min(pre[ic][jc][j - i], cmin);
    // }
    // for (int j = 0; j < i; j++) {
    // int jc = s.charAt(j) - 'a';
    // cmin = Math.min(pre[ic][jc][n - i + j], cmin);
    // }
    //
    // if (cmin < min[ic]) {
    // min[ic] = cmin;
    // minc[ic] = 1;
    // } else if (cmin == min[ic]) {
    // minc[ic]++;
    // }
    // }
    //
    // for (int i = 0; i < 26; i++) {
    // ans += (double) minc[i] / (26.0 * min[i]);
    // }
    // System.out.println(ans);
    // end here
  }

  public static void main(String[] args) throws FileNotFoundException {
    (new _931E()).solve();
  }

  class InputHelper {
    StringTokenizer tokenizer = null;
    private BufferedReader bufferedReader;

    public InputHelper(InputStream inputStream) {
      InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
      bufferedReader = new BufferedReader(inputStreamReader, 16384);
    }

    public String read() {
      while (tokenizer == null || !tokenizer.hasMoreTokens()) {
        try {
          String line = bufferedReader.readLine();
          if (line == null) {
            return null;
          }
          tokenizer = new StringTokenizer(line);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }

      return tokenizer.nextToken();
    }

    public Integer readInteger() {
      return Integer.parseInt(read());
    }

    public Long readLong() {
      return Long.parseLong(read());
    }
  }
}


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

public class E {
    public static void main(String[] args) {
        Scanner input = new Scanner();
        StringBuilder output = new StringBuilder();

        String s = input.next();
        int n = s.length();
        int[][][] seen = new int[26][n][26];
        int[][] ones = new int[26][n];

        for (int i = 0; i < n; i++) {
            int first = s.charAt(i) - 'a';
            for (int j = 1; j < n; j++) {
                int second = s.charAt((i + j) % n) - 'a';
                seen[first][j][second]++;
                if (seen[first][j][second] == 1) {
                    ones[first][j]++;
                } else if (seen[first][j][second] == 2) {
                    ones[first][j]--;
                }
            }
        }
        double prob = 0;
        for (int i = 0; i < 26; i++) {
            int total = 0;
            for (int j = 0; j < n; j++) {
                total = max(total, ones[i][j]);
            }
            prob += (double)(total) / (double)n;
        }
        System.out.println(prob);
    }

    private static class Scanner {
        BufferedReader br; StringTokenizer st;
        public Scanner(Reader in) { br = new BufferedReader(in); }
        public Scanner() { this(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 readNextLine() {
            String str = "";
            try { str = br.readLine();
            } catch (IOException e) { e.printStackTrace(); }
            return str; }
        int[] readIntArray(int n) {
            int[] a = new int[n];
            for (int idx = 0; idx < n; idx++) { a[idx] = nextInt(); }
            return a; }
        long[] readLongArray(int n) {
            long[] a = new long[n];
            for (int idx = 0; idx < n; idx++) { a[idx] = nextLong(); }
            return a; }
    } // end Scanner
}


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.StringTokenizer;

public class d {
	public static void main(String[] Args) throws Exception {
		FS sc = new FS(System.in);
		PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		String s = sc.next();
		int x = 0;
		int n = s.length();
		HashSet<Integer>[] hs = new HashSet[n];
		HashSet<Integer>[] hs2 = new HashSet[n];
		for (int j = 0; j < n; j++) {
			hs[j] = new HashSet<Integer>();
			hs2[j] = new HashSet<Integer>();
		}
		for (int i = 0; i < 26; i++) {
			for (int j = 0; j < n; j++) {
				hs[j].clear();
				hs2[j].clear();
			}
			for (int j = 0; j < n; j++)
				if (s.charAt(j) == 'a' + i)
					for (int k = 0; k < n; k++)
						if (!hs[k].add(0 + s.charAt((k + j) % n)))
							hs2[k].add(0 + s.charAt((k + j) % n));
			int tx = 0;
			for (int j = 0; j < n; j++) {
				int y = hs[j].size() - hs2[j].size();
				if (y > tx)
					tx = y;
			}
			x += tx;
		}

		out.println(x * 1.0 / n);
		out.close();
	}

	public static class FS {
		BufferedReader br;
		StringTokenizer st;

		FS(InputStream in) throws Exception {
			br = new BufferedReader(new InputStreamReader(in));
			st = new StringTokenizer(br.readLine());
		}

		FS(File f) throws Exception {
			br = new BufferedReader(new FileReader(f));
			st = new StringTokenizer(br.readLine());
		}

		String next() throws Exception {
			if (st.hasMoreTokens())
				return st.nextToken();
			st = new StringTokenizer(br.readLine());
			return next();
		}

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

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

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


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.StringTokenizer;

public class d {
	public static void main(String[] Args) throws Exception {
		FS sc = new FS(System.in);
		PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		String s = sc.next();
		int x = 0;
		int n = s.length();
		for (int i = 0; i < 26; i++) {
			HashSet<Integer>[] hs = new HashSet[n];
			HashSet<Integer>[] hs2 = new HashSet[n];
			for (int j = 0; j < n; j++) {
				hs[j] = new HashSet<Integer>();
				hs2[j] = new HashSet<Integer>();
			}
			for (int j = 0; j < n; j++)
				if (s.charAt(j) == 'a' + i)
					for (int k = 0; k < n; k++)
						if (!hs[k].add(0 + s.charAt((k + j) % n)))
							hs2[k].add(0 + s.charAt((k + j) % n));
			int tx = 0;
			for (int j = 0; j < n; j++) {
				int y = hs[j].size() - hs2[j].size();
				if (y > tx)
					tx = y;
			}
			x += tx;
		}

		out.println(x * 1.0 / n);
		out.close();
	}

	public static class FS {
		BufferedReader br;
		StringTokenizer st;

		FS(InputStream in) throws Exception {
			br = new BufferedReader(new InputStreamReader(in));
			st = new StringTokenizer(br.readLine());
		}

		FS(File f) throws Exception {
			br = new BufferedReader(new FileReader(f));
			st = new StringTokenizer(br.readLine());
		}

		String next() throws Exception {
			if (st.hasMoreTokens())
				return st.nextToken();
			st = new StringTokenizer(br.readLine());
			return next();
		}

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

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

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


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class d {
	public static void main(String[] Args) throws Exception {
		FS sc = new FS(System.in);
		PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		String s = sc.next();
		int x = 0;
		int n = s.length();
		int[][] cs = new int[26][n];

		for (int i = 0; i < 26; i++) {
			for (int j = 0; j < 26; j++) {
				Arrays.fill(cs[j], 0);
			}
			for (int j = 0; j < n; j++)
				if (s.charAt(j) == 'a' + i) {
					int k = j;
					int c = 0;
					int end = k - 1;
					if (j == 0)
						end = n - 1;
					while (k != end) {
						cs[s.charAt(k) - 'a'][c]++;
						k++;
						c++;
						if (k == n)
							k = 0;
					}
					cs[s.charAt(end) - 'a'][c]++;
				}
			int tx = 0;
			for (int j = 0; j < n; j++) {
				int y = 0;
				for (int k = 0; k < 26; k++)
					if (cs[k][j] == 1)
						y++;
				if (y > tx)
					tx = y;
			}
			x += tx;
		}

		out.println(x * 1.0 / n);
		out.close();
	}

	public static class FS {
		BufferedReader br;
		StringTokenizer st;

		FS(InputStream in) throws Exception {
			br = new BufferedReader(new InputStreamReader(in));
			st = new StringTokenizer(br.readLine());
		}

		FS(File f) throws Exception {
			br = new BufferedReader(new FileReader(f));
			st = new StringTokenizer(br.readLine());
		}

		String next() throws Exception {
			if (st.hasMoreTokens())
				return st.nextToken();
			st = new StringTokenizer(br.readLine());
			return next();
		}

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

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

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


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.StringTokenizer;

public class d {
	public static void main(String[] Args) throws Exception {
		FS sc = new FS(System.in);
		PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		String s = sc.next();
		int x = 0;
		int n = s.length();
		HashSet<Integer>[] hs = new HashSet[n];
		HashSet<Integer>[] hs2 = new HashSet[n];
		for (int j = 0; j < n; j++) {
			hs[j] = new HashSet<Integer>();
			hs2[j] = new HashSet<Integer>();
		}
		for (int i = 0; i < 26; i++) {
			for (int j = 0; j < n; j++) {
				hs[j].clear();
				hs2[j].clear();
			}
			for (int j = 0; j < n; j++)
				if (s.charAt(j) == 'a' + i) {
					int k = j;
					int c = 0;
					int end = k - 1;
					if (j == 0)
						end = n - 1;
					while (k != end) {
						if (!hs[c].add(0 + s.charAt(k)))
							hs2[c].add(0 + s.charAt(k));
						k++;
						c++;
						if (k == n)
							k = 0;
					}
					if (!hs[c].add(0 + s.charAt(end)))
						hs2[c].add(0 + s.charAt(end));
				}
			int tx = 0;
			for (int j = 0; j < n; j++) {
				int y = hs[j].size() - hs2[j].size();
				if (y > tx)
					tx = y;
			}
			x += tx;
		}

		out.println(x * 1.0 / n);
		out.close();
	}

	public static class FS {
		BufferedReader br;
		StringTokenizer st;

		FS(InputStream in) throws Exception {
			br = new BufferedReader(new InputStreamReader(in));
			st = new StringTokenizer(br.readLine());
		}

		FS(File f) throws Exception {
			br = new BufferedReader(new FileReader(f));
			st = new StringTokenizer(br.readLine());
		}

		String next() throws Exception {
			if (st.hasMoreTokens())
				return st.nextToken();
			st = new StringTokenizer(br.readLine());
			return next();
		}

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

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

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


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

import static java.lang.Math.*;

public class Main implements Runnable
{
    static class InputReader
    {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;
        private BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

        public InputReader(InputStream stream)
        {
            this.stream = stream;
        }

        public int read()
        {
            if (numChars==-1)
                throw new InputMismatchException();

            if (curChar >= numChars)
            {
                curChar = 0;
                try
                {
                    numChars = stream.read(buf);
                }
                catch (IOException e)
                {
                    throw new InputMismatchException();
                }

                if(numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public String nextLine()
        {
            String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return str;
        }
        public int nextInt()
        {
            int c = read();

            while(isSpaceChar(c))
                c = read();

            int sgn = 1;

            if (c == '-')
            {
                sgn = -1;
                c = read();
            }

            int res = 0;
            do
            {
                if(c<'0'||c>'9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));

            return res * sgn;
        }

        public long nextLong()
        {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = read();
            }
            long res = 0;

            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));
                return res * sgn;
        }

        public double nextDouble()
        {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.')
            {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, nextInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.')
            {
                c = read();
                double m = 1;
                while (!isSpaceChar(c))
                {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, nextInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }

        public String readString()
        {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do
            {
                res.appendCodePoint(c);
                c = read();
            }
            while (!isSpaceChar(c));

            return res.toString();
        }

        public boolean isSpaceChar(int c)
        {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next()
        {
            return readString();
        }

        public interface SpaceCharFilter
        {
            public boolean isSpaceChar(int ch);
        }
    }

    public static void main(String args[]) throws Exception
    {
        new Thread(null, new Main(),"Main",1<<26).start();
    }
    public void run()
    {
        InputReader sc= new InputReader(System.in);
        PrintWriter w= new PrintWriter(System.out);

        char[] s = sc.next().toCharArray();

        int n = s.length;

        double prob[][][] = new double[26][n][26];
        double[] freq = new double[26];

        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < n; ++j) {
                int ind = (i + j) % n;
                prob[s[i] - 'a'][j][s[ind] - 'a']++;
            }
            freq[s[i] - 'a']++;
        }
        double ans = 0;
        for(int i = 0; i < 26; ++i) {
            double maxp = 0;
            for(int j = 0; j < n; ++j) {
                double cnt = 0;
                for(int k = 0; k < 26; ++k) {
                    if(prob[i][j][k] == 1)
                        cnt++;
                }
                maxp = max(maxp, cnt);
            }
            ans += maxp;
        }

        ans = ans / (double)n;

        w.print(ans);

        w.close();
    }
}


// package cf931;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.IntStream;

import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toMap;

public class CFD { //E
    private static final String INPUT = "bbaabaabbb\n";

    FastScanner sc;

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

    public void run() {
        sc = new FastScanner(oj ? System.in : new ByteArrayInputStream(INPUT.getBytes()));

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

    public void solve() {
        char[] chars = sc.nextLine().toCharArray();
        int n = chars.length;

        Map<Character, List<Integer>> places = new TreeMap<>();
        for (int i = 0; i < n; i++) {
            places.computeIfAbsent(chars[i], ch -> new ArrayList<>()).add(i);
        }

        int res = 0;
        int[] chart = new int[26];
        for (Map.Entry<Character, List<Integer>> entry : places.entrySet()) {
            int chance = 0;
            for (int i = 1; i < n; i++) { //shift
                Arrays.fill(chart, 0);
                int curChance = 0;
                for (int pos : entry.getValue()) {
                    int count = ++chart[chars[(pos + i) % n] - 'a'];
                    if (count == 1) curChance++;
                    if (count == 2) curChance--;
                }
                if (curChance == entry.getValue().size()) {
                    chance = curChance;
                    break;
                } else {
                    chance = Math.max(curChance, chance);
                }
            }
            res += chance;
        }
        System.out.println((double)res / n);
    }

    //********************************************************************************************
    //********************************************************************************************
    //********************************************************************************************

    private static int ceil(double d) {
        int ret = (int) d;
        return ret == d ? ret : ret + 1;
    }

    private static int round(double d) {
        return (int) (d + 0.5);
    }

    private static <T> T elvis(T obj, Supplier<T> defValue) {
        return obj == null ? defValue.get() : obj;
    }

    @SuppressWarnings("SameParameterValue")
    private static <T> T elvis(T obj, T defValue) {
        return obj == null ? defValue : obj;
    }

    private static int gcd(int a, int b) {
        BigInteger b1 = BigInteger.valueOf(a);
        BigInteger b2 = BigInteger.valueOf(b);
        BigInteger gcd = b1.gcd(b2);
        return gcd.intValue();
    }

    private static long gcd(long a, long b) {
        BigInteger b1 = BigInteger.valueOf(a);
        BigInteger b2 = BigInteger.valueOf(b);
        BigInteger gcd = b1.gcd(b2);
        return gcd.longValue();
    }

    private int[] readIntArray(int n) {
        int[] res = new int[n];
        for (int i = 0; i < n; i++) {
            res[i] = sc.nextInt();
        }
        return res;
    }

    private long[] readLongArray(int n) {
        long[] res = new long[n];
        for (int i = 0; i < n; i++) {
            res[i] = sc.nextLong();
        }
        return res;
    }

    @SuppressWarnings("unused")
    static class FastScanner {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        FastScanner(InputStream stream) {
            this.stream = stream;
        }

        int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) return -1;
            }
            return buf[curChar++];
        }

        boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        boolean isEndline(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

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

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

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

        public String next() {
            int c = read();
            while (isSpaceChar(c)) c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public String nextLine() {
            int c = read();
            while (isEndline(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndline(c));
            return res.toString();
        }
    }

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

    private void tr(Object... o) {
        if (!oj) System.out.println(Arrays.deepToString(o));
    }
}


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

/*
 *
 * Comments Here
 *
 */
public class E000
{
	static BufferedReader br;
	static BufferedWriter bw;
	static StringTokenizer st;

	public static void main(String[] args) throws java.lang.Exception
	{
		br = new BufferedReader(new InputStreamReader(System.in));
		bw = new BufferedWriter(new OutputStreamWriter(System.out));
    		/*/
    		File file = new File("src/in.txt");
		try {
			br = new BufferedReader(FileReader(file));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		/**/

		char[] input = br.readLine().toCharArray();
		int l = input.length;

		int[][][] count = new int[26][l][26];

		for(int start = 0; start < l; ++start) {

			char cs = input[start];

			for(int disp = 0; disp < l; ++disp) {

				int end = (start+disp)%l;
				char ce = input[end];

				++count[cs-'a'][disp][ce-'a'];
			}
		}

		int num = 0;
		for(int i = 0; i < 26; ++i) {
			int best = 0;
			for(int j = 0; j < l ; ++j) {
				int curr = 0;
				for(int k = 0; k < 26; ++k){
					if(count[i][j][k] == 1)
						++curr;
				}
				best = Math.max(best, curr);
			}
			num += best;
		}

		double ans = (num*1.0)/input.length;
		bw.write(ans + "\n");

		br.close();
		bw.close();
	}

}


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

public class R468_E {
	FastScanner in;
	PrintWriter out;

	public void solve() {
		String s = in.next();
		int n = s.length();

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

		for (int i = 0; i < n; i++) {
			a[s.charAt(i) - 'a'].add(i);
		}

		double sum = 0;
		for (int i = 0; i < 26; i++) {
			if (a[i].isEmpty())
				continue;

			boolean hit = false;
			double best = 0;
			for (int d = 1; d < n; d++) {
				HashMap<Character, Integer> found = new HashMap<Character, Integer>();
				for (int x : a[i]) {
					if (!found.containsKey(s.charAt((x + d) % n))) {
						found.put(s.charAt((x + d) % n), 1);
					} else {
						found.put(s.charAt((x + d) % n), found.get(s.charAt((x + d) % n)) + 1);
					}
				}
				double lbest = 0;
				for (Character x : found.keySet()) {
					if (found.get(x) == 1) {
						lbest++;
					}
				}
				best = Math.max(best, lbest);
			}

			sum += best;

			// if (!hit) {
			// sum += 1D * a[i].size() / (n-1);
			// }
		}

		out.println(sum / n);
	}

	public void run() {
		in = new FastScanner();
		out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		solve();
		out.close();
	}

	class FastScanner {
		StringTokenizer st;
		BufferedReader br;

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

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				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());
		}
	}

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


import java.io.*;
import java.util.*;
import java.util.function.IntUnaryOperator;

/**
 * gl hf
 */
public class Main {
    static class MyRunnable implements Runnable {
        @Override
        public void run() {

        }

        public void start() {

        }
    }
    static class Task {
        PrintWriter out;
        String s;
        int n;
        public void solve(MyScanner in, PrintWriter out) {
            this.out = out;

            s = in.nextLine();
              n = s.length();

            double res = 0;

             for (char x = 'a'; x <= 'z'; x++) {
                 List<Integer> startIndex = new ArrayList<>();
                 for (int i = 0; i < n; i++) {
                     if (s.charAt(i) == x) {
                         startIndex.add(i);
                     }
                 }

                 double probChar = ((double) startIndex.size()) / n;

                 if (startIndex.size() > 0) {

                     double maxProb = 0;
                     for (int i = 1; i < n; i++) { // ????
                         maxProb = Math.max(maxProb, getProb(x, i, startIndex));
                     }

                    // out.println("Cahr " + x + " max prob " + maxProb);
                     res += maxProb * probChar;
                 }
             }

             out.println(res);
        }

        private double getProb(char c, int offset, List<Integer> startIndex ) {
            if (startIndex.size() == 0) return  0;

            Map<Character, Integer> map = new HashMap<>();

            for (Integer x: startIndex) {
                int ind = (x + offset) % n;
                char charAt = s.charAt(ind);
                int ct = map.getOrDefault(charAt, 0);
                map.put(charAt, ct + 1);
            }

            int uniq = 0;
            int sum = 0;
            for (Integer v: map.values()) {
                if (v == 1) {
                    uniq+=v;
                }
                sum += v;
            }
            //if (uniq > 0)  out.println("uniq " + uniq + " when " + c + " " +offset + " " + (uniq / sum));

            return ((double) uniq )/ sum;
        }

        private boolean can(List<Integer> startIndex) {
            if (startIndex.size() == 0) return false;

            HashSet<Character> currentChars = new HashSet<>();

            for (int offset = 1; offset < n; offset++) {
                currentChars.clear();
                boolean wasSame = false;
                for (Integer i : startIndex) {
                    char willAdd = s.charAt((i + offset) % n);
                    if (currentChars.contains(willAdd)) {
                        wasSame = true;
                        break;
                    } else {
                        currentChars.add(willAdd);
                    }
                }

                if (!wasSame) {
                    out.println("Start ind " + startIndex + " w offset " + offset + " good");
                    return true;
                }

            }

            return false;
        }

        private void printArray(int[] arr) {
            //out.println("Printing arrray of size " + arr.length);
            for (int i = 0; i < arr.length; i++) {
                out.println("Arr[" + i + "] = " + arr[i]);
            }

        }

    }

    public static void main(String[] args) {
        MyScanner in = new MyScanner();
        PrintWriter out = new PrintWriter(System.out);
        Task solver = new Task();
        solver.solve(in, out);
        out.close();
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            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;
        }
    }
}


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

public class E {
	public static void main(String[] args) {
        FastReader fr = new FastReader();
        String str = fr.next();
        int n = str.length();
        ArrayList<ArrayList<Integer>> letterIndexes = new ArrayList<>(26);
        for(int i = 0; i < 26; i++){
            letterIndexes.add(new ArrayList<>());
        }
        for(int i = 0; i < n; i++){
            letterIndexes.get(str.charAt(i)-'a').add(i);
        }
        double[] cond = new double[26];
        for(int i = 0; i < 26; i++){
            if(letterIndexes.get(i).size() == 0) continue;
            double max = 0;
            for(int k = 0; k < n; k++){
                HashMap<Character, Integer> hm = new HashMap<>();
                for(int j = 0; j < letterIndexes.get(i).size(); j++){
                    char c = str.charAt((letterIndexes.get(i).get(j)+k)%n);
                    hm.put(c, hm.getOrDefault(c, 0)+1);
                }
                int count = 0;
                for(char c : hm.keySet()) if(hm.get(c)==1) count++;
                if(count > max) max = count;
            }
            cond[i] = max;
        }
        double prob = 0;
        for(int i = 0; i < 26; i++) prob+=cond[i];
        System.out.println(prob/n);
	}
}

class FastReader{
	BufferedReader br;
	StringTokenizer st;

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

	String next(){
		while(st==null || !st.hasMoreTokens()){
			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;
	}
}

//source: http://www.geeksforgeeks.org/fast-io-in-java-in-competitive-programming/


import java.util.Scanner;
import java.util.ArrayList;
import java.lang.StringBuilder;
public class test3  {
    public static void main(String args[])  {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        int l = s.length();
        int[] ct = new int[26];
        int[][] pos = new int[26][l];
        for (int i = 0; i < l; i++)   {
            int k = s.charAt(i) - 97;
            pos[k][ct[k]] = i;
            ct[k]++;
        }
        int max = -10000;
        int res = 0;
        int[] temp = new int[26];
        for (int i = 0; i < 26; i++)   {
            max = -10000;
            for (int delt = 1; delt < l; delt++)   {
                int cur = 0;
                int m = 0;
                for (int j = 0; j < 26; j++)   {
                    temp[j] = 2;
                }
                for (int j = 0; j < ct[i]; j++)   {
                    m = s.charAt((pos[i][j] + delt)%l) - 97;
                    if (temp[m] == 2)  {
                        cur++;
                        temp[m] = 1;
                    }
                    else if (temp[m] == 1)  {
                        cur--;
                        temp[m] = 0;
                    }
                }
                if (max < cur) max = cur;
            }
            res+= max;
        }
        System.out.println((float)res / (float)l);
    }
}


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

public class utkarsh {

    InputStream is;
    PrintWriter out;

    void solve(){
        //Enter code here utkarsh
        char[] c = ns().toCharArray();
        int n = c.length;
        ArrayList <Integer> a[] = new ArrayList[26];
        for(int i = 0; i < 26; i++) {
            a[i] = new ArrayList<>();
        }
        for(int i = 0; i < n; i++) {
            a[c[i] - 'a'].add(i);
        }
        int b[] = new int[26];
        int x = 0;
        int y, z;
        for(int i = 0; i < 26; i++) {
            if(a[i].isEmpty())  continue;
            if(a[i].size() == 1) {
                x++;
                continue;
            }
            z = 0;
            for(int j = 1; j < n; j++) {
                Arrays.fill(b, 0);
                for(int u : a[i]) {
                    int k = (u + j) % n;
                    k = c[k] - 'a';
                    b[k]++;
                }
                y = 0;
                for(int k = 0; k < 26; k++) {
                    if(b[k] == 1) {
                        y++;
                    }
                }
                if(y > z)   z = y;
            }
            x += z;
        }
        out.println((x + 0.0) / (n + 0.0));
    }

    public static void main(String[] args) { new utkarsh().run();
    }
    void run(){ is = System.in; out = new PrintWriter(System.out); solve(); out.flush();
    }

    byte input[] = new byte[1024];
    int len = 0, ptr = 0;

    int readByte(){ if(ptr >= len){ ptr = 0; try{ len = is.read(input); }catch(IOException e){ throw new InputMismatchException(); } if(len <= 0){ return -1; } } return input[ptr++];
    }
    boolean isSpaceChar(int c){ return !( c >= 33 && c <= 126 );
    }
    int skip(){ int b = readByte(); while(b != -1 && isSpaceChar(b)){ b = readByte(); } return b;
    }

    char nc(){ return (char)skip();
    }
    String ns(){ int b = skip(); StringBuilder sb = new StringBuilder(); while(!isSpaceChar(b)){ sb.appendCodePoint(b); b=readByte(); } return sb.toString();
    }
    int ni(){ int n = 0,b = readByte(); boolean minus = false; while(b != -1 && !( (b >= '0' && b <= '9') || b == '-')){ b = readByte(); } if(b == '-'){ minus = true; b = readByte(); } if(b == -1){ return -1; } while(b >= '0' && b <= '9'){ n = n * 10 + (b - '0'); b = readByte(); } return minus ? -n : n;
    }
    long nl(){ long n = 0L; int b = readByte(); boolean minus = false; while(b != -1 && !( (b >= '0' && b <= '9') || b == '-')){ b = readByte(); } if(b == '-'){ minus = true; b = readByte(); } while(b >= '0' && b <= '9'){ n = n * 10 + (b - '0'); b = readByte(); } return minus ? -n : n;
    }
    double nd(){ return Double.parseDouble(ns());
    }
    float nf(){ return Float.parseFloat(ns());
    }
    int[] na(int n){ int a[] = new int[n]; for(int i = 0; i < n; i++){ a[i] = ni(); } return a;
    }
    char[] ns(int n){ char c[] = new char[n]; int i,b = skip(); for(i = 0; i < n; i++){ if(isSpaceChar(b)){ break; } c[i] = (char)b; b = readByte(); } return i == n ? c : Arrays.copyOf(c,i);
    }
}


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

public class Main {

    void solve(){
        s=ns().toCharArray();
        int n=s.length;

        char ss[]=(new String(s)+new String(s)).toCharArray();
        int cnt[][][]=new int[26][26][n+1];
        int cnt2[]=new int[26];
        for(int i=0;i<n;i++) cnt2[s[i]-'a']++;
        for(int i=0;i<n;i++){
            for(int l=1;l<=n;l++){
                int j=i+l-1;
                cnt[ss[i]-'a'][ss[j]-'a'][j-i]++;
            }

        }
//        shift();
//        shift();
//        shift();
//        pw.println(s);
//        for(int i=0;i<n;i++) {
//            pw.println(cnt[s[0]-'a'][s[i]-'a'][i]);
//        }

        double ans=0;
        for(int i=0;i<26;i++){
            int mx=0;
            for(int d=0;d<n;d++){
                int k=0;
                for(int j=0;j<26;j++){
                    if(cnt[i][j][d]==1)k++;
                }
                mx=Math.max(mx,k);
            }
            ans+=mx;
        }
        ans/=n;
        pw.println(ans);

    }
    char s[];
    void shift(){
        int n=s.length;
        char ch=s[n-1];
        for(int i=n-2;i>=0;i--){
            s[i+1]=s[i];
        }
        s[0]=ch;
    }

    long M=(long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";
    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        pw.flush();
        if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception { new Main().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 void tr(Object... o) { if(INPUT.length() > 0)System.out.println(Arrays.deepToString(o)); }
}


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

import static java.lang.Math.*;

public class cfs468E {

    public static void main(String[] args) {
        FastScanner sc = new FastScanner();
        StringBuilder sb = new StringBuilder();
        char[] letters = sc.next().toCharArray();
        int n = letters.length;
        int[] allLetterFreq = new int[26];
        for (int i : letters) {
            allLetterFreq[i - 'a']++;
        }
        int[][][] freq = new int[26][26][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) { // j is the offset
                freq[letters[i] - 'a'][letters[((j+i)%n+n)%n] - 'a'][j]++;
            }
        }
        double sum = 0;
        for (int i = 0; i < 26; i++) { // given first letter is i
            // determine which offset j will give best information
            if (allLetterFreq[i] == 0) continue;

            int mostDistinct = 0;
            for (int j = 0; j < n; j++) {
                int distinct = 0;
                for (int k = 0; k < 26; k++) {
                    if (freq[i][k][j] == 1) distinct++;
                }
                mostDistinct = Math.max(mostDistinct, distinct);
            }
            double toAdd = (allLetterFreq[i] / (n * 1.0)) * ((1.0 * mostDistinct) / allLetterFreq[i]);
            sum += toAdd;
        }
        sb.append(sum);

        System.out.print(sb);
    }

    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(Reader in) {
            br = new BufferedReader(in);
        }

        public FastScanner() {
            this(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 readNextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        int[] readIntArray(int n) {
            int[] a = new int[n];
            for (int idx = 0; idx < n; idx++) {
                a[idx] = nextInt();
            }
            return a;
        }

        long[] readLongArray(int n) {
            long[] a = new long[n];
            for (int idx = 0; idx < n; idx++) {
                a[idx] = nextLong();
            }
            return a;
        }
    }
}


#include<string>
#include<iostream>
using namespace std;
int main()
{

	int a[4], s = 0;
	string  b;
	for (int c = 0; c < 4; c++)
		cin >> a[c];
	cin >> b;
	for (int c = 0; b[c] != '\0'; c++)
		s += a[b[c] - 49];
	cout << s;
}


#include<IoStReaM>
#include<CmAtH>
#include<IoManIp>
#include<AlGoRiThM>
#include<StRiNG>
#include<CoNiO.H>
#include<CtImE>
#include<CsTdLiB>
#include<FsTrEaM>
#include<VecToR>
#include<QuEuE>
#include<DeQuE>
#include<StAcK>
#include<MaP>
#include<SeT>
#define pi 3.1415926535897932384
#define ee 2.718281828
#define mod (int)1e9+7
#define f(c_name, from, to) for(int c_name = from; c_name < to; c_name++)
#define w(true) while(true)
#define pub push_back
#define pob pop_back
#define re return
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
using namespace std;
//const ll OO = 1e6 + 555;
int main()
{
	int x[4], res = 0;
	f(i, 0, 4)
		cin >> x[i];
	string s;
	cin >> s;
	f(i, 0, s.size())
	{
		if (s[i] == '1')
			res += x[0];
		if (s[i] == '2')
			res += x[1];
		if (s[i] == '3')
			res += x[2];
		if (s[i] == '4')
			res += x[3];
	}
	cout << res << endl;
}


#include<IoStReaM>
#include<CmAtH>
#include<IoManIp>
#include<AlGoRiThM>
#include<StRiNG>
#include<CoNiO.H>
#include<CtImE>
#include<CsTdLiB>
#include<FsTrEaM>
#include<VecToR>
#include<QuEuE>
#include<DeQuE>
#include<StAcK>
#include<MaP>
#include<SeT>
#define pi 3.1415926535897932384
#define ee 2.718281828
#define mod (int)1e9+7
#define f(c_name, from, to) for(int c_name = from; c_name < to; c_name++)
#define w(true) while(true)
#define pub push_back
#define pob pop_back
#define re return
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
using namespace std;
//const ll OO = 1e6 + 555;
int main()
{
	int x[4], res = 0;
	f(i, 0, 4)
		cin >> x[i];
	string s;
	cin >> s;
	f(i, 0, s.size())
		res += x[s[i] - 49];
	cout << res << endl;
}