//Created by Aminul on 9/3/2019.

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

import static java.lang.Math.max;

public class CF802I_fast {
    public static void main(String[] args) throws Exception {
        FastReader in = new FastReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        SuffixArray SA = new SuffixArray();
        int test = in.nextInt();
        for(int t = 1; t <= test; t++) {
            char[] s = in.next().toCharArray();
            int n = s.length;
            int sa[] = SA.getSuffixArray(s);
            final int lcp[] = lcp(sa, s);
            long ans = 0;

            SegTree segTree = new SegTree(n + 1);
            for (int i = n - 1; i >= 0; i--) {
                int len = n - sa[i];
                ans += segTree.query(1, len) + len;
                segTree.clearRange(lcp[i] + 1, n);
                segTree.update(1, lcp[i], 1);
            }

            segTree = new SegTree(n + 1);
            for (int i = 0; i < n; i++) {
                int len = n - sa[i];
                ans += segTree.query(1, len);
                if(i + 1 < n) segTree.clearRange(lcp[i + 1] + 1, n);
                if(i + 1 < n) segTree.update(1, lcp[i + 1], 1);
            }

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

    static class SuffixArray {
        char str[];
        int N, m;
        int [] SA;
        int [] x, y, w;
        int max_n;

        SuffixArray() {

        }

        int[] getSuffixArray(char[] s) {
            str = changeString(s);
            m = 256;
            N = str.length;
            max_n = max(m, N + 1);
            SA = new int[N];

            x = new int[max_n];
            y = new int[max_n];
            w = new int[max_n];

            DA();
            SA = Arrays.copyOf(SA, N - 1);
            return SA;
        }

        boolean cmp(int a, int b, int l) {
            return (y[a] == y[b] && y[a + l] == y[b + l]);
        }

        void Sort() {
            for (int i = 0; i < m; ++i) w[i] = 0;
            for (int i = 0; i < N; ++i) ++w[x[y[i]]];
            for (int i = 0; i < m - 1; ++i) w[i + 1] += w[i];
            for (int i = N - 1; i >= 0; --i) SA[--w[x[y[i]]]] = y[i];
        }

        void DA() {
            for (int i = 0; i < N; ++i) {
                x[i] = str[i];
                y[i] = i;
            }
            Sort();
            for (int i, j = 1, p = 1; p < N; j <<= 1, m = p) {
                for (p = 0, i = N - j; i < N; i++) y[p++] = i;
                for (int k = 0; k < N; ++k) if (SA[k] >= j) y[p++] = SA[k] - j;
                Sort();
                for (swap(), p = 1, x[SA[0]] = 0, i = 1; i < N; ++i) x[SA[i]] = cmp(SA[i - 1], SA[i], j) ? p - 1 : p++;
            }
        }

        void swap() {
            int t[] = x;  x = y;  y = t;
        }

        static char[] changeString(char[] s){
            char [] t = new char[s.length+1];
            System.arraycopy(s, 0, t, 0, s.length);
            t[s.length] = '~';
            return t;
        }
    }

    static int[] suffixArray(char[] S) {
        int n = S.length;
        Integer ord[] = new Integer[n];
        for (int i = 0; i < n; i++) ord[i] = n - 1 - i;
        Arrays.sort(ord, (a, b) -> Character.compare(S[a], S[b]));
        int order[] = new int[n];
        for (int i = 0; i < n; i++) order[i] = ord[i];
        //Arrays.sort(order, new Comparator<Integer>() {public int compare(Integer o1, Integer o2) { return S[o1] - S[o2]; }});
        int[] sa = new int[n];
        int[] classes = new int[n];
        for (int i = 0; i < n; i++) {
            sa[i] = order[i];
            classes[i] = S[i];
        }
        for (int len = 1; len < n; len <<= 1) {
            int[] c = classes.clone();
            for (int i = 0; i < n; i++) {
                classes[sa[i]] = i > 0 && c[sa[i - 1]] == c[sa[i]] && sa[i - 1] + len < n
                        && c[sa[i - 1] + (len >> 1)] == c[sa[i] + (len >> 1)] ? classes[sa[i - 1]] : i;
            }
            int[] cnt = new int[n];
            for (int i = 0; i < n; i++) {
                cnt[i] = i;
            }
            int[] s = sa.clone();
            for (int i = 0; i < n; i++) {
                int s1 = s[i] - len;
                if (s1 >= 0) {
                    sa[cnt[classes[s1]]++] = s1;
                }
            }
        }
        return sa;
    }

    static int[] lcp(int[] sa, char[] s) {
        int n = sa.length;
        int[] rank = new int[n];
        for (int i = 0; i < n; i++)
            rank[sa[i]] = i;
        int[] lcp = new int[n];

        for (int i = 0, h = 0; i < n; i++) {
            if (rank[i] < n - 1) {
                for (int j = sa[rank[i] + 1]; max(i, j) + h < s.length
                        && s[i + h] == s[j + h]; ++h)
                    ;
                lcp[rank[i] + 1] = h;
                if (h > 0)
                    --h;
            }
        }
        return lcp;
    }

    static void debug(Object... obj) {
        System.err.println(Arrays.deepToString(obj));
    }

    static class SegTree {
        Node root;
        int n;

        SegTree(int N) {
            n = N;
            root = new Node();
        }

        void pushDown(Node node, int s, int m, int e) {
            if (node.lazy == 0) return;
            if (node.left != null) {
                node.left.value += (m - s + 1) * node.lazy;
                node.left.lazy += node.lazy;
            }
            if (node.right != null) {
                node.right.value += (e - m) * node.lazy;
                node.right.lazy += node.lazy;
            }
            node.lazy = 0;
        }

        void update(int l, int r, int v) {
            update(root, 1, n, l, r, v);
        }

        void update(Node node, int s, int e, int a, int b, int value) {
            if (s > e || s > b || e < a) return;
            if (s >= a && e <= b) {
                node.lazy += value;
                node.value += (e - s + 1) * value;
                return;
            }
            int m = (s + e) / 2;
            if (node.left == null) node.left = new Node();
            if (node.right == null) node.right = new Node();
            pushDown(node, s, m, e);
            update(node.left, s, m, a, b, value);
            update(node.right, m + 1, e, a, b, value);
            node.value = node.left.value + node.right.value;
        }

        void clearRange(int l, int r) {
            root = clearRange(root, 1, n, l, r);
        }

        Node clearRange(Node node, int s, int e, int a, int b) {
            if (s > e || s > b || e < a) return node;
            if (s >= a && e <= b) {
                return new Node();
            }
            int m = (s + e) / 2;
            if (node.left == null) node.left = new Node();
            if (node.right == null) node.right = new Node();
            pushDown(node, s, m, e);
            node.left = clearRange(node.left, s, m, a, b);
            node.right = clearRange(node.right, m + 1, e, a, b);
            node.value = node.left.value + node.right.value;
            return node;
        }

        long query(int l, int r) {
            return query(root, 1, n, l, r);
        }

        long query(Node node, int s, int e, int a, int b) {
            if (s > e || s > b || e < a) return 0;
            if (s >= a && e <= b) {
                return node.value;
            }
            int m = (s + e) / 2;
            if (node.left == null) node.left = new Node();
            if (node.right == null) node.right = new Node();
            pushDown(node, s, m, e);
            return query(node.left, s, m, a, b) + query(node.right, m + 1, e, a, b);
        }

        static class Node {
            Node left, right;
            long value, lazy;

            Node() {
            }

            Node(int v) {
                value = v;
            }

            @Override
            public String toString() {
                return "[" + value + ", " + lazy + "]";
            }
        }
    }

    static class FastReader {
        InputStream is;
        private byte[] inbuf = new byte[1024];
        private int lenbuf = 0, ptrbuf = 0;

        public FastReader(InputStream is) {
            this.is = is;
        }

        public 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++];
        }

        public boolean isSpaceChar(int c) {
            return !(c >= 33 && c <= 126);
        }
        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

        public int skip() {
            int b;
            while ((b = readByte()) != -1 && isSpaceChar(b)) ;
            return b;
        }

        public String next() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while (!(isSpaceChar(b))) {
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }

        public String nextLine() {
            int c = skip();
            StringBuilder sb = new StringBuilder();
            while (!isEndOfLine(c)){
                sb.appendCodePoint(c);
                c = readByte();
            }
            return sb.toString();
        }

        public int nextInt() {
            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 << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public long nextLong() {
            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 << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

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

        public char[] next(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);
        }

        public char readChar() {
            return (char) skip();
        }
    }
}


//Created by Aminul on 9/3/2019.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;

import static java.lang.Math.max;

public class CF802I {
    public static void main(String[] args) throws Exception {
        //Scanner in = new Scanner(System.in);
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(System.out);
        int test = Integer.parseInt(br.readLine());
        for(int t = 1; t <= test; t++) {
            char[] s = br.readLine().toCharArray();
            int n = s.length;
            int sa[] = suffixArray(s);
            final int lcp[] = lcp(sa, s);
            long ans = 0;

            SegTree segTree = new SegTree(n + 1);
            for (int i = n - 1; i >= 0; i--) {
                int len = n - sa[i];
                ans += segTree.query(1, len) + len;
                segTree.clearRange(lcp[i] + 1, n);
                segTree.update(1, lcp[i], 1);
            }

            segTree = new SegTree(n + 1);
            for (int i = 0; i < n; i++) {
                int len = n - sa[i];
                ans += segTree.query(1, len);
                if(i + 1 < n) segTree.clearRange(lcp[i + 1] + 1, n);
                if(i + 1 < n) segTree.update(1, lcp[i + 1], 1);
            }

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

    static int[] suffixArray(char[] S) {
        int n = S.length;
        Integer ord[] = new Integer[n];
        for (int i = 0; i < n; i++) ord[i] = n - 1 - i;
        Arrays.sort(ord, (a, b) -> Character.compare(S[a], S[b]));
        int order[] = new int[n];
        for (int i = 0; i < n; i++) order[i] = ord[i];
        //Arrays.sort(order, new Comparator<Integer>() {public int compare(Integer o1, Integer o2) { return S[o1] - S[o2]; }});
        int[] sa = new int[n];
        int[] classes = new int[n];
        for (int i = 0; i < n; i++) {
            sa[i] = order[i];
            classes[i] = S[i];
        }
        for (int len = 1; len < n; len <<= 1) {
            int[] c = classes.clone();
            for (int i = 0; i < n; i++) {
                classes[sa[i]] = i > 0 && c[sa[i - 1]] == c[sa[i]] && sa[i - 1] + len < n
                        && c[sa[i - 1] + (len >> 1)] == c[sa[i] + (len >> 1)] ? classes[sa[i - 1]] : i;
            }
            int[] cnt = new int[n];
            for (int i = 0; i < n; i++) {
                cnt[i] = i;
            }
            int[] s = sa.clone();
            for (int i = 0; i < n; i++) {
                int s1 = s[i] - len;
                if (s1 >= 0) {
                    sa[cnt[classes[s1]]++] = s1;
                }
            }
        }
        return sa;
    }

    static int[] lcp(int[] sa, char[] s) {
        int n = sa.length;
        int[] rank = new int[n];
        for (int i = 0; i < n; i++)
            rank[sa[i]] = i;
        int[] lcp = new int[n];

        for (int i = 0, h = 0; i < n; i++) {
            if (rank[i] < n - 1) {
                for (int j = sa[rank[i] + 1]; max(i, j) + h < s.length
                        && s[i + h] == s[j + h]; ++h)
                    ;
                lcp[rank[i] + 1] = h;
                if (h > 0)
                    --h;
            }
        }
        return lcp;
    }

    static void debug(Object... obj) {
        System.err.println(Arrays.deepToString(obj));
    }

    static class SegTree {
        Node root;
        int n;

        SegTree(int N) {
            n = N;
            root = new Node();
        }

        void pushDown(Node node, int s, int m, int e) {
            if (node.lazy == 0) return;
            if (node.left != null) {
                node.left.value += (m - s + 1) * node.lazy;
                node.left.lazy += node.lazy;
            }
            if (node.right != null) {
                node.right.value += (e - m) * node.lazy;
                node.right.lazy += node.lazy;
            }
            node.lazy = 0;
        }

        void update(int l, int r, int v) {
            update(root, 1, n, l, r, v);
        }

        void update(Node node, int s, int e, int a, int b, int value) {
            if (s > e || s > b || e < a) return;
            if (s >= a && e <= b) {
                node.lazy += value;
                node.value += (e - s + 1) * value;
                return;
            }
            int m = (s + e) / 2;
            if (node.left == null) node.left = new Node();
            if (node.right == null) node.right = new Node();
            pushDown(node, s, m, e);
            update(node.left, s, m, a, b, value);
            update(node.right, m + 1, e, a, b, value);
            node.value = node.left.value + node.right.value;
        }

        void clearRange(int l, int r) {
            root = clearRange(root, 1, n, l, r);
        }

        Node clearRange(Node node, int s, int e, int a, int b) {
            if (s > e || s > b || e < a) return node;
            if (s >= a && e <= b) {
                return new Node();
            }
            int m = (s + e) / 2;
            if (node.left == null) node.left = new Node();
            if (node.right == null) node.right = new Node();
            pushDown(node, s, m, e);
            node.left = clearRange(node.left, s, m, a, b);
            node.right = clearRange(node.right, m + 1, e, a, b);
            node.value = node.left.value + node.right.value;
            return node;
        }

        long query(int l, int r) {
            return query(root, 1, n, l, r);
        }

        long query(Node node, int s, int e, int a, int b) {
            if (s > e || s > b || e < a) return 0;
            if (s >= a && e <= b) {
                return node.value;
            }
            int m = (s + e) / 2;
            if (node.left == null) node.left = new Node();
            if (node.right == null) node.right = new Node();
            pushDown(node, s, m, e);
            return query(node.left, s, m, a, b) + query(node.right, m + 1, e, a, b);
        }

        static class Node {
            Node left, right;
            long value, lazy;

            Node() {
            }

            Node(int v) {
                value = v;
            }

            @Override
            public String toString() {
                return "[" + value + ", " + lazy + "]";
            }
        }
    }
}


//Created by Aminul on 9/3/2019.

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

import static java.lang.Math.max;

public class CF802I_fast {
    public static void main(String[] args) throws Exception {
        FastReader in = new FastReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        int test = in.nextInt();
        for(int t = 1; t <= test; t++) {
            char[] s = in.next().toCharArray();
            int n = s.length;
            int sa[] = suffixArray(s);
            final int lcp[] = lcp(sa, s);
            long ans = 0;

            SegTree segTree = new SegTree(n + 1);
            for (int i = n - 1; i >= 0; i--) {
                int len = n - sa[i];
                ans += segTree.query(1, len) + len;
                segTree.clearRange(lcp[i] + 1, n);
                segTree.update(1, lcp[i], 1);
            }

            segTree = new SegTree(n + 1);
            for (int i = 0; i < n; i++) {
                int len = n - sa[i];
                ans += segTree.query(1, len);
                if(i + 1 < n) segTree.clearRange(lcp[i + 1] + 1, n);
                if(i + 1 < n) segTree.update(1, lcp[i + 1], 1);
            }

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

    static int[] suffixArray(char[] S) {
        int n = S.length;
        Integer ord[] = new Integer[n];
        for (int i = 0; i < n; i++) ord[i] = n - 1 - i;
        Arrays.sort(ord, (a, b) -> Character.compare(S[a], S[b]));
        int order[] = new int[n];
        for (int i = 0; i < n; i++) order[i] = ord[i];
        //Arrays.sort(order, new Comparator<Integer>() {public int compare(Integer o1, Integer o2) { return S[o1] - S[o2]; }});
        int[] sa = new int[n];
        int[] classes = new int[n];
        for (int i = 0; i < n; i++) {
            sa[i] = order[i];
            classes[i] = S[i];
        }
        for (int len = 1; len < n; len <<= 1) {
            int[] c = classes.clone();
            for (int i = 0; i < n; i++) {
                classes[sa[i]] = i > 0 && c[sa[i - 1]] == c[sa[i]] && sa[i - 1] + len < n
                        && c[sa[i - 1] + (len >> 1)] == c[sa[i] + (len >> 1)] ? classes[sa[i - 1]] : i;
            }
            int[] cnt = new int[n];
            for (int i = 0; i < n; i++) {
                cnt[i] = i;
            }
            int[] s = sa.clone();
            for (int i = 0; i < n; i++) {
                int s1 = s[i] - len;
                if (s1 >= 0) {
                    sa[cnt[classes[s1]]++] = s1;
                }
            }
        }
        return sa;
    }

    static int[] lcp(int[] sa, char[] s) {
        int n = sa.length;
        int[] rank = new int[n];
        for (int i = 0; i < n; i++)
            rank[sa[i]] = i;
        int[] lcp = new int[n];

        for (int i = 0, h = 0; i < n; i++) {
            if (rank[i] < n - 1) {
                for (int j = sa[rank[i] + 1]; max(i, j) + h < s.length
                        && s[i + h] == s[j + h]; ++h)
                    ;
                lcp[rank[i] + 1] = h;
                if (h > 0)
                    --h;
            }
        }
        return lcp;
    }

    static void debug(Object... obj) {
        System.err.println(Arrays.deepToString(obj));
    }

    static class SegTree {
        Node root;
        int n;

        SegTree(int N) {
            n = N;
            root = new Node();
        }

        void pushDown(Node node, int s, int m, int e) {
            if (node.lazy == 0) return;
            if (node.left != null) {
                node.left.value += (m - s + 1) * node.lazy;
                node.left.lazy += node.lazy;
            }
            if (node.right != null) {
                node.right.value += (e - m) * node.lazy;
                node.right.lazy += node.lazy;
            }
            node.lazy = 0;
        }

        void update(int l, int r, int v) {
            update(root, 1, n, l, r, v);
        }

        void update(Node node, int s, int e, int a, int b, int value) {
            if (s > e || s > b || e < a) return;
            if (s >= a && e <= b) {
                node.lazy += value;
                node.value += (e - s + 1) * value;
                return;
            }
            int m = (s + e) / 2;
            if (node.left == null) node.left = new Node();
            if (node.right == null) node.right = new Node();
            pushDown(node, s, m, e);
            update(node.left, s, m, a, b, value);
            update(node.right, m + 1, e, a, b, value);
            node.value = node.left.value + node.right.value;
        }

        void clearRange(int l, int r) {
            root = clearRange(root, 1, n, l, r);
        }

        Node clearRange(Node node, int s, int e, int a, int b) {
            if (s > e || s > b || e < a) return node;
            if (s >= a && e <= b) {
                return new Node();
            }
            int m = (s + e) / 2;
            if (node.left == null) node.left = new Node();
            if (node.right == null) node.right = new Node();
            pushDown(node, s, m, e);
            node.left = clearRange(node.left, s, m, a, b);
            node.right = clearRange(node.right, m + 1, e, a, b);
            node.value = node.left.value + node.right.value;
            return node;
        }

        long query(int l, int r) {
            return query(root, 1, n, l, r);
        }

        long query(Node node, int s, int e, int a, int b) {
            if (s > e || s > b || e < a) return 0;
            if (s >= a && e <= b) {
                return node.value;
            }
            int m = (s + e) / 2;
            if (node.left == null) node.left = new Node();
            if (node.right == null) node.right = new Node();
            pushDown(node, s, m, e);
            return query(node.left, s, m, a, b) + query(node.right, m + 1, e, a, b);
        }

        static class Node {
            Node left, right;
            long value, lazy;

            Node() {
            }

            Node(int v) {
                value = v;
            }

            @Override
            public String toString() {
                return "[" + value + ", " + lazy + "]";
            }
        }
    }

    static class FastReader {
        InputStream is;
        private byte[] inbuf = new byte[1024];
        private int lenbuf = 0, ptrbuf = 0;

        public FastReader(InputStream is) {
            this.is = is;
        }

        public 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++];
        }

        public boolean isSpaceChar(int c) {
            return !(c >= 33 && c <= 126);
        }
        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

        public int skip() {
            int b;
            while ((b = readByte()) != -1 && isSpaceChar(b)) ;
            return b;
        }

        public String next() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while (!(isSpaceChar(b))) {
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }

        public String nextLine() {
            int c = skip();
            StringBuilder sb = new StringBuilder();
            while (!isEndOfLine(c)){
                sb.appendCodePoint(c);
                c = readByte();
            }
            return sb.toString();
        }

        public int nextInt() {
            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 << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public long nextLong() {
            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 << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

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

        public char[] next(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);
        }

        public char readChar() {
            return (char) skip();
        }
    }
}


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

public class Main {

    public static InputReader in = new InputReader(System.in);
    public static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args)
    {
        int a;
        String s;
        SAM part=new SAM();
        a=in.nextInt();
        while (a--!=0)
        {
            s=in.next();
            part.init(2*s.length()+10,26);
            for(int i=0;i<s.length();++i)
                part.insert(s.charAt(i)-'a');
            long ans=0;
            part.topo();
            SAM_node part2=part.root;
            for(int i=0;i<s.length();++i)
            {
                part2=part2.next[s.charAt(i)-'a'];
                part2.cnt=1;
            }
            for(int i=part.cur-1;i>0;--i)
                part.pool[i].pre.cnt+=part.pool[i].cnt;
            for(int i=part.cur-1;i>0;--i)
                ans+=(long)part.pool[i].cnt*(long)part.pool[i].cnt*((long)part.pool[i].step-(long)part.pool[i].pre.step);
            out.println(ans);
        }
        out.flush();
        out.close();
    }
}
class SAM_node
{
    SAM_node pre,next[];
    int step,cnt;
    SAM_node(int sigma)
    {
        next=new SAM_node[sigma];
        Arrays.fill(next,null);
        step=0;
        cnt=0;
        pre=null;
    }
}
class SAM
{
    SAM_node SAM_pool[],root,last;
    int d[];
    SAM_node pool[];
    int cur;
    int sigma;
    void topo() {
        int cnt = cur;
        int maxVal = 0;
        Arrays.fill(d, 0);
        for (int i = 1; i < cnt; i++) {
            maxVal = Math.max(maxVal, SAM_pool[i].step);

        d[SAM_pool[i].step]++;
    }
        for (int i = 1; i <= maxVal; i++)
            d[i] += d[i - 1];
        for (int i = 1; i < cnt; i++)
            pool[d[SAM_pool[i].step]--] = SAM_pool[i];
        pool[0] = root;
    }
    void init(int a,int b)
    {
        d=new int[a];
        pool=new SAM_node[a];
        SAM_pool=new SAM_node[a];
        SAM_pool[0]=new SAM_node(b);
        sigma=b;
        root=last=SAM_pool[0];
        cur=1;
    }
    void insert(int w)
    {
        SAM_node p=last;
        SAM_pool[cur]=new SAM_node(sigma);
        SAM_node np=SAM_pool[cur];
        last=np;
        cur++;
        np.step=p.step+1;
        while (p!=null && p.next[w]==null)
        {
            p.next[w]=np;
            p = p.pre;
        }
        if(p==null)
        {
            np.pre=root;
        }
        else
        {
            SAM_node q=p.next[w];
            if(p.step+1==q.step)
                np.pre=q;
            else {
                SAM_node nq = SAM_pool[cur++] = new SAM_node(sigma);
                nq.next = Arrays.copyOf(q.next, sigma);
                nq.cnt = q.cnt;
                nq.step = p.step + 1;
                nq.pre = q.pre;
                q.pre = nq;
                np.pre = nq;
                while (p != null && p.next[w]==(q)) {
                    p.next[w] = nq;
                    p = p.pre;
                }
            }
        }
    }
}
class InputReader{
    private final static int BUF_SZ = 65536;
    BufferedReader in;
    StringTokenizer tokenizer;
    public InputReader(InputStream in) {
        super();
        this.in = new BufferedReader(new InputStreamReader(in),BUF_SZ);
        tokenizer = new StringTokenizer("");
    }
    public String next() {
        while (!tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(in.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }
    public int nextInt() {
        return Integer.parseInt(next());
    }
    public long nextLong()
    {
        return Long.parseLong(next());
    }
}


#include <cstring>
#include <algorithm>
#include <cstdio>

typedef long long ll;
const int N = 200010;
int _w;

int T;
char s[N];

namespace SAM {
	int ch[N][26], nid;
	int len[N], par[N], cnt[N];

	int append( int p, int c ) {
		int np = nid++;
		len[np] = len[p] + 1;
		while( p != -1 && !ch[p][c] )
			ch[p][c] = np, p = par[p];
		if( p == -1 ) {
			par[np] = 0;
		} else {
			int q = ch[p][c];
			if( len[q] == len[p] + 1 ) {
				par[np] = q;
			} else {
				int nq = nid++;
				for( int i = 0; i < 26; ++i )
					ch[nq][i] = ch[q][i];
				par[nq] = par[q];
				len[nq] = len[p] + 1;
				par[q] = par[np] = nq;
				while( p != -1 && ch[p][c] == q )
					ch[p][c] = nq, p = par[p];
			}
		}
		return np;
	}
	void build( char *s ) {
		memset(ch, 0, sizeof ch);
		nid = 1;
		len[0] = 0, par[0] = -1;
		int u = 0;
		for( ; *s; ++s ) u = append(u, *s - 'a');
	}
	void solve( char *s ) {
		memset(cnt, 0, sizeof cnt);
		int u = 0;
		for( ; *s; ++s ) {
			u = ch[u][*s - 'a'];
			++cnt[u];
		}
		for( int i = nid-1; i; --i )
			cnt[par[i]] += cnt[i];
		ll ans = 0;
		for( int i = 1; i < nid; ++i )
			ans += 1LL * cnt[i] * cnt[i] * (len[i] - len[par[i]]);
		printf( "%lld\n", ans );
	}
}

int main() {
	_w = scanf( "%d", &T );
	while( T-- ) {
		_w = scanf( "%s", s );
		SAM::build(s);
		SAM::solve(s);
	}
	return 0;
}


#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>

using std::vector;
typedef long long ll;
const int N = 200010;
int _w;

int T, n;
char s[N];

namespace SAM {
	int ch[N][26], nid;
	int len[N], par[N], cnt[N];
	vector<int> buc[N];

	int append( int p, int c ) {
		int np = nid++;
		len[np] = len[p] + 1;
		while( p != -1 && !ch[p][c] )
			ch[p][c] = np, p = par[p];
		if( p == -1 ) {
			par[np] = 0;
		} else {
			int q = ch[p][c];
			if( len[q] == len[p] + 1 ) {
				par[np] = q;
			} else {
				int nq = nid++;
				for( int i = 0; i < 26; ++i )
					ch[nq][i] = ch[q][i];
				par[nq] = par[q];
				len[nq] = len[p] + 1;
				par[q] = par[np] = nq;
				while( p != -1 && ch[p][c] == q )
					ch[p][c] = nq, p = par[p];
			}
		}
		return np;
	}
	void build( char *s ) {
		memset(ch, 0, sizeof ch);
		nid = 1;
		len[0] = 0, par[0] = -1;
		int u = 0;
		for( ; *s; ++s ) u = append(u, *s - 'a');
	}
	void solve( char *s ) {
		memset(cnt, 0, sizeof cnt);
		int u = 0;
		for( ; *s; ++s ) {
			u = ch[u][*s - 'a'];
			++cnt[u];
		}
		for( int i = 0; i <= n; ++i )
			buc[i].clear();
		for( int i = 1; i < nid; ++i )
			buc[len[i]].push_back(i);
		for( int i = n; i; --i )
			for( int j = 0; j < (int)buc[i].size(); ++j ) {
				int u = buc[i][j];
				cnt[par[u]] += cnt[u];
			}
		ll ans = 0;
		for( int i = 1; i < nid; ++i )
			ans += 1LL * cnt[i] * cnt[i] * (len[i] - len[par[i]]);
		printf( "%lld\n", ans );
	}
}

int main() {
	_w = scanf( "%d", &T );
	while( T-- ) {
		_w = scanf( "%s", s );
		n = (int)strlen(s);
		SAM::build(s);
		SAM::solve(s);
	}
	return 0;
}


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

typedef long long LL;
typedef pair<int, int> II;

const int N = (int) 1e5 + 10;
int n;
char S[N];
LL ans, sum;
LL p[N], f[N];
vector<int> Z[N];

struct SuffixArray {
    char S[N];
    int n, SA[N], LCP[N];
    void Init(string T) {
        n = (int) T.size();
        for (int i = 1; i <= n; ++i) S[i] = T[i - 1];
        BuildSA();
        BuildLCP();
    }

    int C[N], L[N], R[N], num[N], pos[N]; bool mark[N];
    void Init() {
        memset(C, 0, sizeof C);
        for (int i = 1; i <= n; ++i) C[(int) S[i]]++;
        for (int i = 1; i <= 255; ++i) C[i] += C[i - 1];
        for (int i = 1; i <= n; ++i) R[C[(int) S[i]]--] = i;
        for (int i = 1; i <= n; ++i) mark[i] = i == 1 || S[R[i - 1]] != S[R[i]];
    }
    void Sort(int k) {
        for (int i = 1; i <= n; ++i) C[i] = 0;
        for (int i = 1; i <= n; ++i) C[num[L[i]]]++;
        for (int i = 1; i <= n; ++i) C[i] += C[i - 1];
        for (int i = n; i >= 1; --i) R[C[num[L[i]]]--] = L[i];
        for (int i = 1, p = -1; i <= n; ++i) {
            int x = num[(R[i] + k + n - 1) % n + 1];
            mark[i] = p != x || num[R[i - 1]] != num[R[i]]; p = x;
        }
    }
    void BuildSA() {
        n = n + 1; S[n] = 0; Init();
        for (int k = 1; k <= n; k <<= 1) {
            for (int i = 1, d = 0; i <= n; ++i) {
                if (mark[i]) d++; num[R[i]] = d;
                L[i] = (R[i] - k + n - 1) % n + 1;
            }
            Sort(k);
        }
        n = n - 1;
        for (int i = 0; i <= n; ++i) SA[i] = R[i + 1];
    }
    void BuildLCP() {
        for (int i = 1; i <= n; ++i) pos[SA[i]] = i;
        for (int i = 1, q = 0; i <= n; ++i, q = max(0, q - 1)) {
            int j = SA[pos[i] - 1];
            while (S[i + q] == S[j + q]) q++;
            LCP[pos[i]] = q;
        }
    }
} SA;

int Root(int u) {
	if (p[u] < 0) return u;
	return p[u] = Root(p[u]);
}

void Merge(int u, int v) {
	u = Root(u);
	v = Root(v);
	if (u == v) return;
	sum -= f[u] * f[u];
	sum -= f[v] * f[v];
	if (p[u] > p[v]) swap(u, v);
	p[u] += p[v]; p[v] = u;
	f[u] += f[v];
	sum += f[u] * f[u];
}

int main() {
	int TC; scanf("%d", &TC);
	while (TC--) {
		scanf("%s", S + 1);
		n = strlen(S + 1);

		SA.Init(string(S + 1, S + 1 + n));
		for (int i = 1; i <= n; ++i) Z[i].clear();
		for (int i = 1; i <= n; ++i) Z[SA.LCP[i]].push_back(i);

		ans = 0;
		sum = 0;
		for (int i = 1; i <= n; ++i) p[i] = -1, f[i] = 0;
		for (int len = n; len >= 1; --len) {
			int x = Root(SA.pos[n - len + 1]);
			sum -= f[x] * f[x]; f[x]++;
			sum += f[x] * f[x];
			for (int i = 0; i < (int) Z[len].size(); ++i) {
				int p = Z[len][i];
				Merge(p - 1, p);
			}
			ans += sum;
			//cout << "# "<< sum << endl;
		}
		cout << ans << "\n";
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>

#define rep(i,x,y) for (int i=x;i<=y;i++)
#define dep(i,y,x) for (int i=y;i>=x;i--)
#define sz(x) (int)(x.size())

using namespace std;

typedef long long LL;
typedef unsigned long long uLL;

const int maxn=100000+7;

struct Node{
    LL v,cnt;
} Q[maxn];

int T,n,maxi,k,j,h,size;
int sa[maxn],temp[maxn],rank[maxn],next[maxn],c[maxn],lcp[maxn];
char s[maxn];

LL tot,ans,p;

void Suffix_Array()
{
    maxi=n;
    rep(i,1,n) sa[i]=i,rank[i]=(int)(s[i]-'a'+1),maxi=max(maxi,rank[i]);

    for (int len=1;len<=n;len<<=1)
    {
        memset(c,0,sizeof(c));
        rep(i,1,n)
        {
            k=sa[i];
            if ((k+len)>n) next[k]=0; else next[k]=rank[k+len];
            ++c[next[k]];
        }

        rep(i,1,maxi) c[i]+=c[i-1];
        dep(i,n,1) temp[c[next[sa[i]]]--]=sa[i];

        memset(c,0,sizeof(c));
        rep(i,1,n) ++c[rank[temp[i]]];
        rep(i,1,maxi) c[i]+=c[i-1];
        dep(i,n,1) sa[c[rank[temp[i]]]--]=temp[i];

        temp[0]=0;
        rep(i,1,n)
        {
            temp[sa[i]]=temp[sa[i-1]];
            if ((rank[sa[i]]!=rank[sa[i-1]])||(next[sa[i]]!=next[sa[i-1]])) ++temp[sa[i]];
        }

        rep(i,1,n) rank[i]=temp[i];
        maxi=rank[sa[n]];

        if (maxi>=n) break;
    }
}

void LCP_Array()
{
    h=0;
    rep(i,1,n) rank[sa[i]]=i;

    rep(i,1,n)
    {
        j=sa[rank[i]-1];
        if (h>0) --h;

        for (;((i+h)<=n)&&((j+h)<=n);++h)
            if (s[i+h]!=s[j+h]) break;
        lcp[rank[j]]=h;
    }
}

void ins(LL k)
{
    p=1;
    while ((size>0)&&(Q[size].v>=k)) ans-=Q[size].v*Q[size].cnt,p+=Q[size].cnt,--size;
    ans+=p*k;
    Q[++size]=(Node){k,p};
}

int main()
{
    scanf("%d",&T);
    while (T--)
    {
        scanf("%s",s+1);
        n=strlen(s+1);

        Suffix_Array();
        LCP_Array();

        tot=0;

        size=0,ans=0;
        rep(i,1,n) tot+=i;
        rep(i,2,n)
        {
            ins((LL)lcp[i-1]);
            tot+=ans;
        }

        size=0,ans=0;
        dep(i,n-1,1)
        {
            ins((LL)lcp[i]);
            tot+=ans;
        }

        printf("%I64d\n",tot);
    }

    // system("pause");
    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
#include <string>
#define Rep(i, x, y) for (int i = x; i <= y; i ++)
#define Dwn(i, x, y) for (int i = x; i >= y; i --)
#define u sam[x]
#define w sam[z]
#define v u.t[c]
#define vn sam[v]
#define r sam[y]
using namespace std;
typedef long long ll;
typedef double db;
const int N = 300005;
int n, sz = 1, lt = 1, hd, tl, cn[N], in[N], que[N], T;
ll ans;
char s[N];
struct arr { int par, t[27], l; } sam[N];
void extend(int c) {
    int x = lt, z = ++ sz; lt = sz, w.l = u.l + 1;
	memset(w.t, 0, sizeof(w.t));
    cn[z] = 1;
    for (; !v && x; x = u.par) v = z;
    if (!x) w.par = 1;
    else if (vn.l == u.l + 1) w.par = v, in[v] ++; // cout << v<<endl;
    else {
        int y = ++ sz, tv = v;
        r = vn, r.l = u.l + 1, vn.par = w.par = y;
        in[y] = 2;
        for (; v == tv; x = u.par) v = y;
    }
}
int main()
{
	cin >> T;
	while (T --) {
		ans = 0;
		memset(cn, 0, sizeof(cn));
		memset(in, 0, sizeof(in));
		memset(sam[1].t, 0, sizeof(sam[1].t));
		sz = 1, lt = 1, hd = tl = 0;
		scanf ("%s", s + 1);
		n = strlen(s + 1);
		Rep(i, 1, n) extend(s[i] - 'a');
		Rep(i, 1, sz) if (!in[i]) que[++ tl] = i;
		while (hd < tl) {
			int x = que[++ hd];
			// cout << x <<" "<<cn[x]<<endl;
			ans += (ll)cn[x] * cn[x] * (u.l - sam[u.par].l);
			cn[u.par] += cn[x];
			in[u.par] --;
			if (!in[u.par]) que[++ tl] = u.par;
		}
		cout << ans << endl;
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100005;
int T,n,m,SA[N],rank[N],height[N],tmp[N],tax[N];
char s[N];
int st[N],top,pos[N];
void Sort(int n,int m){
	for (int i=0;i<=m;i++)
		tax[i]=0;
	for (int i=1;i<=n;i++)
		tax[rank[i]]++;
	for (int i=1;i<=m;i++)
		tax[i]+=tax[i-1];
	for (int i=n;i>=1;i--)
		SA[tax[rank[tmp[i]]]--]=tmp[i];
}
bool cmp(int rk[],int x,int y,int w){
	return rk[x]==rk[y]&&rk[x+w]==rk[y+w];
}
void Suffix_Array(char s[],int n){
	memset(SA,0,sizeof SA);
	memset(tmp,0,sizeof tmp);
	memset(rank,0,sizeof rank);
	memset(height,0,sizeof height);
	for (int i=1;i<=n;i++)
		rank[i]=s[i],tmp[i]=i;
	m=127;
	Sort(n,m);
	for (int w=1,p=0;p<n;w<<=1,m=p){
		p=0;
		for (int i=n-w+1;i<=n;i++)
			tmp[++p]=i;
		for (int i=1;i<=n;i++)
			if (SA[i]>w)
				tmp[++p]=SA[i]-w;
		Sort(n,m);
		swap(rank,tmp);
		rank[SA[1]]=p=1;
		for (int i=2;i<=n;i++)
			rank[SA[i]]=cmp(tmp,SA[i],SA[i-1],w)?p:++p;
	}
	for (int i=1,j,k=0;i<=n;height[rank[i++]]=k)
		for (k=max(k-1,0),j=SA[rank[i]-1];s[i+k]==s[j+k];k++);
}
int main(){
	scanf("%d",&T);
	while (T--){
		scanf("%s",s+1);
		n=strlen(s+1);
		Suffix_Array(s,n);
		LL ans=0;
		top=0;
		memset(st,0,sizeof st);
		memset(pos,0,sizeof pos);
		SA[n+1]=height[0]=0;
		for (int i=2;i<=n+1;i++){
			int nowpos=i,len=height[i];
			while (top>0&&st[top]>len){
				LL v1=st[top]-max(st[top-1],len);
				LL v2=i-pos[top]+1;
				ans+=v1*v2*v2;
				nowpos=pos[top--];
			}
			while (top>0&&st[top]==len)
				nowpos=pos[top--];
			st[++top]=len;
			pos[top]=nowpos;
		}
		for (int i=1;i<=n;i++)
			ans+=n-i+1-max(height[rank[i]],height[rank[i]+1]);
		printf("%I64d\n",ans);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

typedef long long ll;

const int N = 2 * 100010;
const int NS = 1; //Numero de palavras da

int cn, cd, ns, en = 1, lst;
string S[NS]; int si = -1;
/* sufn[si][i] no do sufixo S[si][i...] */
vector<int> sufn[N];

struct node {
  int l, r, si;
  int p, suf, ct;
  map<char, int> adj;
  node() : l(0), r(-1), suf(0), p(0) {}
  node(int L, int R, int S, int P) : l(L), r(R), si(S), p(P), ct(0) {}
  inline int len() { return r - l + 1; }
  inline int operator[](int i) { return S[si][l + i]; }
  inline int& operator()(char c) { return adj[c]; }
} t[N];

inline int new_node(int L, int R, int S, int P) {
  t[en] = node(L, R, S, P);
  return en++;
}

void add_string(string s) {
  s += '$';
  S[++si] = s;
  sufn[si].resize(s.size() + 1);
  cn = cd = 0;
  int i = 0; const int n = s.size();
  for(int j = 0; j < n; j++) {
    for(; i <= j; i++) {
      if(cd == t[cn].len() && t[cn](s[j]))
        cn = t[cn](s[j]), cd = 0;
      if(cd < t[cn].len() && t[cn][cd] == s[j]) {
        cd++;
        if(j < s.size() - 1) break;
        else {
          if(i) t[lst].suf = cn;
          for(; i <= j; i++) {
            sufn[si][i] = cn;
            cn = t[cn].suf;
          }
        }
      } else if(cd == t[cn].len()) {
        sufn[si][i] = en;
        if(i) t[lst].suf = en; lst = en;
        t[cn](s[j]) = new_node(j, n - 1, si, cn);
        cn = t[cn].suf;
        cd = t[cn].len();
      } else {
        int mid = new_node(t[cn].l, t[cn].l + cd - 1, t[cn].si, t[cn].p);
        t[t[cn].p](t[cn][0]) = mid;
        if(ns) t[ns].suf = mid;
        if(i) t[lst].suf = en; lst = en;
        sufn[si][i] = en;
        t[mid](s[j]) = new_node(j, n - 1, si, mid);
        t[mid](t[cn][cd]) = cn;
        t[cn].p = mid; t[cn].l += cd;
        cn = t[mid].p;
        int g = cn? j - cd : i + 1;
        cn = t[cn].suf;
        while(g < j && g + t[t[cn](S[si][g])].len() <= j) cn = t[cn](S[si][g]), g += t[cn].len();
        if(g == j) ns = 0, t[mid].suf = cn, cd = t[cn].len();
        else ns = mid, cn = t[cn](S[si][g]), cd = j - g;
      }
    }
  }
}

char str[N];
ll ans = 0;

inline ll sq(ll x) {
  return x * x;
}

ll dfs(int x, int len) {
  ll qtd = 0;
  for(map<char, int>::iterator it = t[x].adj.begin(); it != t[x].adj.end(); it++) {
    qtd += dfs(it->S, t[it->S].len());
  }
  if(t[x].adj.empty()) qtd = 1, len--;
  if(len >= 0) ans += sq(qtd) * len;
  return qtd;
}

inline void main2() {
  sufn[0].clear();
  cn = 0, cd = 0, ns = 0, en = 1, lst = 0;
  si = -1;
  for(int i = 0; i < N; ++i) t[i] = node();
  scanf(" %s", str);
  add_string((string)str);
  ans = 0;
  dfs(0, 0);
  printf("%lld\n", ans);
}

int main() {
  int t; scanf("%d", &t);
  while(t--) main2();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

typedef long long ll;

const int N = 2 * 100010;
const int NS = 1; //Numero de palavras da

int cn, cd, ns, en = 1, lst;
string S[NS]; int si = -1;
/* sufn[si][i] no do sufixo S[si][i...] */
vector<int> sufn[N];

struct node {
  int l, r, si;
  int p, suf, ct;
  map<char, int> adj;
  node() : l(0), r(-1), suf(0), p(0) {}
  node(int L, int R, int S, int P) : l(L), r(R), si(S), p(P), ct(0) {}
  inline int len() { return r - l + 1; }
  inline int operator[](int i) { return S[si][l + i]; }
  inline int& operator()(char c) { return adj[c]; }
} t[N];

inline int new_node(int L, int R, int S, int P) {
  t[en] = node(L, R, S, P);
  return en++;
}

void add_string(string s) {
  s += '$';
  S[++si] = s;
  sufn[si].resize(s.size() + 1);
  cn = cd = 0;
  int i = 0; const int n = s.size();
  for(int j = 0; j < n; j++) {
    for(; i <= j; i++) {
      if(cd == t[cn].len() && t[cn](s[j]))
        cn = t[cn](s[j]), cd = 0;
      if(cd < t[cn].len() && t[cn][cd] == s[j]) {
        cd++;
        if(j < s.size() - 1) break;
        else {
          if(i) t[lst].suf = cn;
          for(; i <= j; i++) {
            sufn[si][i] = cn;
            cn = t[cn].suf;
          }
        }
      } else if(cd == t[cn].len()) {
        sufn[si][i] = en;
        if(i) t[lst].suf = en; lst = en;
        t[cn](s[j]) = new_node(j, n - 1, si, cn);
        cn = t[cn].suf;
        cd = t[cn].len();
      } else {
        int mid = new_node(t[cn].l, t[cn].l + cd - 1, t[cn].si, t[cn].p);
        t[t[cn].p](t[cn][0]) = mid;
        if(ns) t[ns].suf = mid;
        if(i) t[lst].suf = en; lst = en;
        sufn[si][i] = en;
        t[mid](s[j]) = new_node(j, n - 1, si, mid);
        t[mid](t[cn][cd]) = cn;
        t[cn].p = mid; t[cn].l += cd;
        cn = t[mid].p;
        int g = cn? j - cd : i + 1;
        cn = t[cn].suf;
        while(g < j && g + t[t[cn](S[si][g])].len() <= j) cn = t[cn](S[si][g]), g += t[cn].len();
        if(g == j) ns = 0, t[mid].suf = cn, cd = t[cn].len();
        else ns = mid, cn = t[cn](S[si][g]), cd = j - g;
      }
    }
  }
}

char str[N];
ll ans = 0;

inline ll sq(ll x) {
  return x * x;
}

ll dfs(int x, int len) {
  ll qtd = 0;
  for(map<char, int>::iterator it = t[x].adj.begin(); it != t[x].adj.end(); it++) {
    qtd += dfs(it->S, t[it->S].len());
  }
  if(t[x].adj.empty()) qtd = 1, len--;
  if(len >= 0) ans += sq(qtd) * len;
  return qtd;
}

inline void main2() {
  sufn[0].clear();
  for(int i = 0; i < en; ++i) t[i] = node();
  cn = 0, cd = 0, ns = 0, en = 1, lst = 0;
  si = -1;
  scanf(" %s", str);
  add_string((string)str);
  ans = 0;
  dfs(0, 0);
  printf("%lld\n", ans);
}

int main() {
  int t; scanf("%d", &t);
  while(t--) main2();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

/******* SUFFIX-ARRAY ****************************************/
const int MaxC = 256;
const int MAX = 100020;
int offset,n;
int suma[MAX], tmp[MAX];
int rank1[MAX], rank2[MAX];
int c[MAX], p[MAX], lcp[MAX];
bool different( int a, int b ) {
    if ( b + offset >= n ) return true;
	if ( rank1[ a ] != rank1[ b ] ) return true;
	if ( rank2[ a ] != rank2[ b ] ) return true;
	return false;
}
/*
recordar que cuando se concatenan varias palabras
con un caracter intermedio hay que poner la condidcion
text[i+offset] != '{'
*/
void suffix_array(string &text){
    n = text.size();
    for(int i=0;i<MaxC;i++) suma[i] = 0;
    for(int i=0;i<n;i++) suma[text[i]]++;
    for(int i=0;i<MaxC;i++) suma[i+1]+=suma[i];
    for(int i=0;i<n;i++) c[i]=suma[text[i]]-1;
    for(offset=1;offset<=n;offset<<=1){
        for(int i=0;i<n;i++){
            rank1[i]=c[i];
            rank2[i]=(i + offset < n) ? c[i+offset] : 0;
        }
        fill(suma,suma+n,0);
        for(int i=0;i<n;i++) suma[rank2[i]]++;
        for(int i=0;i<n;i++) suma[i+1]+=suma[i];
        for(int i=0;i<n;i++) tmp[--suma[rank2[i]]]=i;
        fill( suma, suma + n, 0 );
        for(int i=0;i<n;i++) suma[rank1[i]]++;
        for(int i=0;i<n;i++) suma[i+1]+=suma[i];
        for(int i=n-1;i>=0;i--) p[--suma[rank1[tmp[i]]]]=tmp[i];
        c[p[0]] = 0;
        for(int i=1;i<n;i++){
            c[p[i]]=c[p[i-1]];
            if(different(p[i],p[i-1]))
                c[p[i]]++;
        }
    }
    offset=0;
    for(int i=0;i<n;i++){
        if(c[i]==n-1){
            lcp[n-1]=0;
            continue;
        }
        /*
        recordar que cuando se concatenan varias palabras
        con un caracter intermedio hay que poner
        la condidcion text[i+offset] != '{'
        */
        while(text[i+offset]==text[p[c[i]+1]+offset] && text[i+offset] != '{')
            offset++;
        lcp[c[i]]=offset;
        if(offset>0) offset--;
    }
}

void clear(){
    offset = n = 0;
    for( int i = 0; i < MAX; i++ ){
        suma[i] = tmp[i] = rank1[i] = rank2[i] = c[i] = p[i] = lcp[i] = 0;
    }
}

typedef long long ll;

ll x[MAX], x2[MAX];

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

    //freopen("dat.txt","r",stdin);

    int T; cin >> T;

    while( T-- ){
        clear();

        string s; cin >> s;

        suffix_array( s );

        stack<int> st;

        x[n-1] = 0;
        x2[n-1] = 0;
        st.push(n-1);

        for( int i = n-2; i >= 0; i-- ){
            while( !st.empty() && lcp[i] <= lcp[ st.top() ] ){
                st.pop();
            }

            int j = 0;

            if( st.empty() ){
                j = n-1;
            }
            else{
                j = st.top();
            }

            //cerr << "i = " << i << " j = " << j << '\n';

            x[i] = x[j] + (ll)lcp[i] * (ll)(j-i) + lcp[i] - lcp[j];
            x2[i] = x2[j] + 2ll * (j-i) * x[j] + (ll)(j-i)*(j-i) * lcp[j] +
                    (ll)(j-i+1)*(j-i+1) * (lcp[i] - lcp[j]);

            st.push(i);
        }

        /*for( int i = 0; i < n; i++ ){
            cerr << "i = " << i << "  p[i] = " << p[i] << "  lcp[i] = " << lcp[i] << "  x[i] = " << x[i] << "  x2[i] = " << x2[i] << "  ";
            cerr << s.substr(p[i] , n - p[i]) << '\n';
        }*/

        ll sol = n - p[0] - lcp[0] + x2[0];

        for( int i = 1; i < n; i++ ){
            sol += n - p[i] - max( lcp[i-1] , lcp[i] );

            if( lcp[i-1] >= lcp[i] ){
                continue;
            }

            sol += x2[i];
            sol -= x2[i-1] - 2LL * x[i-1] + lcp[i-1];
        }

        cout << sol << '\n';

        /*for( int i = 0; i < n; i++ ){
            cerr << "i = " << i << " p[i] = " << p[i] << " lcp[i] = " << lcp[i] << " l[i] = " << l[i] << " r[i] = " << r[i];
            cerr << " --> " << s.substr( p[i] , n - p[i] ) << '\n';
        }*/
    }
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <cstdlib>
#include <string>
#include <complex>
#include <bitset>
#include <cmath>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
typedef pair<pii, int> piii;
typedef pair<pll, ll> plll;
typedef pair<pdd, double> pddd;
typedef complex<double> cpx;
#define mst(x,v) memset(x,v,sizeof(x))
#define rgs register
#define rp(k,x,v) for(rgs int k = x;k<v;++k)
#define rps(s) for(rgs int i = 0;s[i];++i)
#define RP(k,x,v) for(rgs int k = x;k<=v;++k)
#define lp(k,x,v) for(rgs int k = x;k>v;--k)
#define LP(k,x,v) for(rgs int k = x;k>=v;--k)
#define lowbit(x) (x&-x)
#define adde(u,v) edg[++ecnt]=Edge(u,v,g[u]),g[u]=ecnt
#define addew(u,v,w) edg[++ecnt]=Edge(u,v,g[u],w),g[u]=ecnt
#define addedg(u,v,w,cap) edg[++ecnt]=Edge(u,v,g[u],w,cap),g[u]=ecnt,edg[++ecnt]=Edge(v,u,g[v],-w,0),g[v]=ecnt
#define fson(x) for(rgs int i = g[x];~i;i=edg[i].next)
#define LB lower_bound
#define UB upper_bound
#define inp(n,a) RP(i,1,n) ru(a[i]);
#define mpt int mid = l+r>>1;
#define all(a) a.begin(),a.end()
#define inr (ql<=l && r<=qr)
#define upmax(a,b) a=max(a,b)
#define upmin(a,b) a=min(a,b)
const int INF = 1 << 29;
const ll LINF = 1LL << 60;
ll mod = 1e9 + 7;
char READ_DATA;
int SIGNAL_INPUT;
template <typename Type>
inline Type ru(Type &v)
{
	SIGNAL_INPUT = 1;
	while ((READ_DATA = getchar()) < '0' || READ_DATA > '9')
		if (READ_DATA == '-')
			SIGNAL_INPUT = -1;
		else if (READ_DATA == EOF)
			return EOF;
	v = READ_DATA - '0';
	while ((READ_DATA = getchar()) >= '0' && READ_DATA <= '9')
		v = v * 10 + READ_DATA - '0';
	v *= SIGNAL_INPUT;
	return v;
}
inline ll modru(ll &v)
{
	ll p = 0;
	SIGNAL_INPUT = 1;
	while ((READ_DATA = getchar()) < '0' || READ_DATA > '9')
		if (READ_DATA == '-')
			SIGNAL_INPUT = -1;
		else if (READ_DATA == EOF)
			return EOF;
	p = v = READ_DATA - '0';
	while ((READ_DATA = getchar()) >= '0' && READ_DATA <= '9')
	{
		v = (v * 10 + READ_DATA - '0') % mod;
		p = (p * 10 + READ_DATA - '0') % (mod - 1);
	}
	v *= SIGNAL_INPUT;
	return p;
}
template<typename A, typename B > inline char ru(A&x, B&y) { if (ru(x) == EOF) return EOF; ru(y); return 2; }
template<typename A, typename B, typename C>inline char ru(A&x, B&y, C&z) { if (ru(x) == EOF) return EOF; ru(y); ru(z); return 3; }
template<typename A, typename B, typename C, typename D>inline char ru(A&x, B&y, C&z, D&w) { if (ru(x) == EOF) return EOF; ru(y); ru(z); ru(w); return 4; }
struct Edge
{
	int  u, v, next;
	ll w, cap, flow;
	Edge(int _u = 0, int _v = 0, int nxt = -1, ll _w = 1, ll _cap = 0)
	{
		u = _u;
		v = _v;
		w = _w;
		cap = _cap;
		flow = 0;
		next = nxt;
	}

	int operator<(const Edge &b) const
	{
		return w < b.w;
	}
};

const int maxn = 1e6 + 5;
double eps = 1e-12;

int T;
char s[maxn];
int n,saki,rk[maxn], tmp[maxn], sa[maxn], lcp[maxn];
int cmp(const int &i, const int &j)
{
	if (rk[i] != rk[j])
		return rk[i] < rk[j];
	int ri = i + saki <= n ? rk[i + saki] : -1;
	int rj = j + saki <= n ? rk[j + saki] : -1;
	return ri < rj;
}

void SA()
{
	RP(i, 0, n) rk[i] = s[sa[i] = i];

	for (saki = 1; saki <= n; saki <<= 1)
	{
		sort(sa, sa + n + 1, cmp);
		tmp[sa[0]] = 1;
		RP(i, 1, n) tmp[sa[i]] = tmp[sa[i - 1]] + cmp(sa[i - 1], sa[i]);
		RP(i, 0, n) rk[i] = tmp[i];
	}

	RP(i, 0, n) rk[sa[i]] = i;
	int j, h = 0;
	RP(i, 0, n)
	{
		j = sa[rk[i] - 1];

		if (h)--h;
		while (i + h < n&&j + h < n && s[i + h] == s[j + h])
			++h;
		lcp[rk[i]] = h;
	}
}

int q[maxn], l, r;

int main()
{
	ru(T);
	while (T--)
	{
		scanf("%s", s); n = strlen(s);
		SA();
		ll ans = 0, cnt = 0;
		int cur;
		int  j = 2;
		q[l = r = 1] = 0;
		RP(i, 1, n)
		{
			if (lcp[i] == 0)
			{
				ans += (n - sa[i]);
			}
			else
			{
				upmax(j, i + 1);
				while (j <= n && lcp[j] >= q[r])
				{
					q[++r] = lcp[j];
					++j;
				}
				ans += (r - l + 2)*(r - l + 2);
			}
			++l;
			if (l > r)
				q[++r] = 0;
		}
		cout << ans << endl;
	}
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <cstdlib>
#include <string>
#include <complex>
#include <bitset>
#include <cmath>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
typedef pair<pii, int> piii;
typedef pair<pll, ll> plll;
typedef pair<pdd, double> pddd;
typedef complex<double> cpx;
#define mst(x,v) memset(x,v,sizeof(x))
#define rgs register
#define rp(k,x,v) for(rgs int k = x;k<v;++k)
#define rps(s) for(rgs int i = 0;s[i];++i)
#define RP(k,x,v) for(rgs int k = x;k<=v;++k)
#define lp(k,x,v) for(rgs int k = x;k>v;--k)
#define LP(k,x,v) for(rgs int k = x;k>=v;--k)
#define lowbit(x) (x&-x)
#define adde(u,v) edg[++ecnt]=Edge(u,v,g[u]),g[u]=ecnt
#define addew(u,v,w) edg[++ecnt]=Edge(u,v,g[u],w),g[u]=ecnt
#define addedg(u,v,w,cap) edg[++ecnt]=Edge(u,v,g[u],w,cap),g[u]=ecnt,edg[++ecnt]=Edge(v,u,g[v],-w,0),g[v]=ecnt
#define fson(x) for(rgs int i = g[x];~i;i=edg[i].next)
#define LB lower_bound
#define UB upper_bound
#define inp(n,a) RP(i,1,n) ru(a[i]);
#define mpt int mid = l+r>>1;
#define all(a) a.begin(),a.end()
#define inr (ql<=l && r<=qr)
#define upmax(a,b) a=max(a,b)
#define upmin(a,b) a=min(a,b)
const int INF = 1 << 29;
const ll LINF = 1LL << 60;
ll mod = 1e9 + 7;
char READ_DATA;
int SIGNAL_INPUT;
template <typename Type>
inline Type ru(Type &v)
{
	SIGNAL_INPUT = 1;
	while ((READ_DATA = getchar()) < '0' || READ_DATA > '9')
		if (READ_DATA == '-')
			SIGNAL_INPUT = -1;
		else if (READ_DATA == EOF)
			return EOF;
	v = READ_DATA - '0';
	while ((READ_DATA = getchar()) >= '0' && READ_DATA <= '9')
		v = v * 10 + READ_DATA - '0';
	v *= SIGNAL_INPUT;
	return v;
}
inline ll modru(ll &v)
{
	ll p = 0;
	SIGNAL_INPUT = 1;
	while ((READ_DATA = getchar()) < '0' || READ_DATA > '9')
		if (READ_DATA == '-')
			SIGNAL_INPUT = -1;
		else if (READ_DATA == EOF)
			return EOF;
	p = v = READ_DATA - '0';
	while ((READ_DATA = getchar()) >= '0' && READ_DATA <= '9')
	{
		v = (v * 10 + READ_DATA - '0') % mod;
		p = (p * 10 + READ_DATA - '0') % (mod - 1);
	}
	v *= SIGNAL_INPUT;
	return p;
}
template<typename A, typename B > inline char ru(A&x, B&y) { if (ru(x) == EOF) return EOF; ru(y); return 2; }
template<typename A, typename B, typename C>inline char ru(A&x, B&y, C&z) { if (ru(x) == EOF) return EOF; ru(y); ru(z); return 3; }
template<typename A, typename B, typename C, typename D>inline char ru(A&x, B&y, C&z, D&w) { if (ru(x) == EOF) return EOF; ru(y); ru(z); ru(w); return 4; }
struct Edge
{
	int  u, v, next;
	ll w, cap, flow;
	Edge(int _u = 0, int _v = 0, int nxt = -1, ll _w = 1, ll _cap = 0)
	{
		u = _u;
		v = _v;
		w = _w;
		cap = _cap;
		flow = 0;
		next = nxt;
	}

	int operator<(const Edge &b) const
	{
		return w < b.w;
	}
};

const int maxn = 1e5 + 5;
double eps = 1e-12;

int T;
char s[maxn];
int n;

struct SAM
{
	struct Node
	{
		int len, fa, sz;
		map<int, int> go;
		Node(int val = 0)
		{
			len = val;
			fa = sz = 0;
		}
	}node[maxn * 2];
	int n, cur, last;

	void init()
	{
		while (n--)
		{
			node[n].len = node[n].fa = node[n].sz = 0;
			node[n].go.clear();
		}
		n = cur = last = 0;
	}

	inline int find(int cur, int c)
	{
		return node[cur].go.find(c) != node[cur].go.end();
	}

	void add(int c)
	{
		cur = ++n;
		node[cur] = Node(node[last].len + 1);
		while (last && !find(last, c))
		{
			node[last].go[c] = cur;
			last = node[last].fa;
		}

		int q = node[last].go[c];
		if (q)
		{
			if (node[q].len == node[last].len + 1)
				node[cur].fa = q;
			else
			{
				int nq = ++n;
				node[nq] = node[q];
				node[nq].len = node[last].len + 1;
				node[nq].sz = 0;
				while (find(last, c) && node[last].go[c] == q)
				{
					node[last].go[c] = nq;
					last = node[last].fa;
				}
				node[q].fa = node[cur].fa = nq;
			}
		}
		else
		{
			node[last].go[c] = cur;
		}
		node[cur].sz = 1;
		last = cur;
	}

	Edge edg[maxn * 2];
	int ecnt, g[maxn * 2];
	ll ans;

	void dfs(int u)
	{
		fson(u)
		{
			dfs(edg[i].v);
			node[u].sz += node[edg[i].v].sz;
		}
		ans += (ll)(node[u].len-node[node[u].fa].len)*node[u].sz*node[u].sz;
	}
	ll solve()
	{
		ans = 0;
		mst(g, ecnt = -1);
		RP(i, 1, n)
			adde(node[i].fa, i);
		dfs(0);
		return ans;
	}
}sam;

int main()
{
	ru(T);
	while (T--)
	{
		scanf("%s", s);
		sam.init();
		rps(s)
			sam.add(s[i] - 'a');
		cout << sam.solve() << endl;
	}
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
char str[200000+5];
long long f[200000+5];
struct node{
	int nxt[26];
	int fa;
	long long len;
}t[200000+10];
long long ans=0;
int last,tot;
vector<int>g[200000+5];
void insrt(int x)
{
	int nd=++tot;f[nd]=1;
	int p=last;
	last=nd;
	t[nd].len=t[p].len+1;
	//cout<<p<<" woc "<<endl;
	//cout<<t[1].nxt[x]<<endl;
	for(;p&&t[p].nxt[x]==0;p=t[p].fa) t[p].nxt[x]=nd;
	//cout<<t[1].nxt[x]<<endl;
	//cout<<p<<" "<<nd<<" "<<last<<" qwq "<<endl;
	if(!p) t[nd].fa=1;
    else
    {
    	int q=t[p].nxt[x];
    	if(t[p].len+1==t[q].len) t[nd].fa=q;
    	else
    	{
    		int nt=++tot;
    		t[nt]=t[q];
    		t[nd].fa=t[q].fa=nt;
    		t[nt].len=t[p].len+1;
    		for(;t[p].nxt[x]==q&&p;p=t[p].fa) t[p].nxt[x]=nt;
    	}
    }
}
void init()
{
	last=1,tot=1;
	memset(t,0,sizeof(t));
	for(int i=0;i<=200000+3;i++) g[i].clear(),f[i]=0;
}
void dfs(int u)
{
	for(int i=0;i<g[u].size();i++)
	{
		dfs(g[u][i]);
		f[u]+=f[g[u][i]];
	}
	//cout<<"!"<<u<<" "<<f[u]<<endl;
    ans+=(t[u].len-t[t[u].fa].len)*f[u]*f[u];
    return ;
}
int main()
{
	int T_T;
	cin>>T_T;
	while(T_T--)
	{
		scanf("%s",str);
        int len=strlen(str);
        init();
        ans=0;
        for(int i=0;i<len;i++)
        	insrt(str[i]-'a');
        //for(int i=1;i<=tot;i++)
        	//cout<<" fuck "<<i<<" "<<t[i].fa<<" "<<endl;
        for(int i=1;i<=tot;i++)
        	g[t[i].fa].push_back(i);
        dfs(0);
        printf("%lld\n",ans);
	}
	return 0;
}


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

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<int, LL> PIL;
typedef pair<LL, int> PLI;
typedef vector<int> VI;
typedef vector<PII> VPII;
typedef double DB;

#define pb push_back
#define mset(a, b) memset(a, b, sizeof a)
#define all(x) (x).begin(), (x).end()
#define bit(x) (1 << (x))
#define bitl(x) (1LL << (x))
#define sqr(x) ((x) * (x))
#define sz(x) ((int)(x.size()))
#define cnti(x) (__builtin_popcount(x))
#define cntl(x) (__builtin_popcountll(x))
#define clzi(x) (__builtin_clz(x))
#define clzl(x) (__builtin_clzll(x))
#define ctzi(x) (__builtin_ctz(x))
#define ctzl(x) (__builtin_ctzll(x))

#define X first
#define Y second

#define Error(x) cout << #x << " = " << x << endl

template <typename T, typename U>
inline void chkmax(T& x, U y) {
	if (x < y) x = y;
}

template <typename T, typename U>
inline void chkmin(T& x, U y) {
	if (y < x) x = y;
}

const int MAXN = 222222;

char s[MAXN];
int L[MAXN], C[MAXN], E[MAXN][26], P[MAXN], ID[MAXN], cnt[MAXN];
int n, m, cur;

void extend(int c) {
	int x = cur, y = cur = ++m;
	L[cur] = L[x] + 1, C[cur] = 1;
	for (; x && !E[x][c]; x = P[x]) E[x][c] = y;
	if (!x) P[y] = 1;
	else {
		int z = E[x][c];
		if (L[z] == L[x] + 1) P[y] = z;
		else {
			int u = ++m; L[u] = L[x] + 1, memcpy(E[u], E[z], sizeof(E[u])), P[u] = P[z], P[z] = P[y] = u;
			for (; x && E[x][c] == z; x = P[x]) E[x][c] = u;
		}
	}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	int ncase;
	for (scanf("%d", &ncase); ncase--; ) {
		memset(E, 0, sizeof E);
		memset(L, 0, sizeof L);
		memset(P, 0, sizeof P);
		memset(C, 0, sizeof C);
		m = cur = 1;
		scanf("%s", s);
		n = strlen(s);
		for (int i = 0; s[i]; i++) extend(s[i] - 'a');
		memset(cnt, 0, sizeof cnt);
		for (int i = 1; i <= m; i++) cnt[L[i]]++;
		for (int i = 1; i <= n; i++) cnt[i] += cnt[i-1];
		for (int i = m; i > 0; i--) ID[cnt[L[i]]--] = i;
		for (int i = m, u; i > 0; i--) u = ID[i], C[P[u]] += C[u];
		unsigned long long ans = 0;
		for (int i = 1; i <= m; i++) ans += 1ULL*C[i]*C[i]*(L[i]-L[P[i]]);
		cout << ans << endl;
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 100000;
typedef long long LL;
struct tnode{
    int ch[26], len, fail;
    LL dp;
}pool[MAXN*2+10];
int pcnt, last;
void Insert(char ch){
    int id=ch-'a';
    int p=last, np=++pcnt;
    pool[np].len = pool[last].len+1;
    last=np;
    while(p&&!pool[p].ch[id]){
        pool[p].ch[id] = np;
        p = pool[p].fail;
    }
    if(!p){
        pool[np].fail = 1;
        return ;
    }
    int q = pool[p].ch[id];
    if(pool[q].len == pool[p].len+1){
        pool[np].fail = q;
        return ;
    }
    int nq = ++pcnt;
    pool[nq] = pool[q];
    pool[nq].len = pool[p].len+1;
    pool[np].fail = pool[q].fail = nq;
    while(p&&pool[p].ch[id] == q){
        pool[p].ch[id] = nq;
        p = pool[p].fail;
    }
}
int ord[MAXN*2+10];
bool cmp(int a, int b){
    return pool[a].len > pool[b].len;
}
LL DP(){
    for(int i=1;i<=pcnt;i++)
        ord[i] = i;
    sort(ord+1, ord+1+pcnt, cmp);
    LL ans=0;
    for(int i=1;i<=pcnt;i++){
        ans += 1ll*(pool[ord[i]].len-pool[pool[ord[i]].fail].len)*pool[ord[i]].dp*pool[ord[i]].dp;
        pool[pool[ord[i]].fail].dp += pool[ord[i]].dp;
    }
    return ans;
}
char s[MAXN+10];
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        memset(pool, 0, sizeof pool);
        pcnt = last = 1;
        scanf("%s", s);
        int len = strlen(s), now = 1;
        for(int i=0;i<len;i++)
            Insert(s[i]);
        for(int i=0;i<len;i++){
            now = pool[now].ch[s[i]-'a'];
            pool[now].dp ++;
        }
        printf("%I64d\n", DP());
    }

    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 100000;
typedef long long LL;
struct tnode{
    int ch[26], len, fail;
    LL dp;
}pool[MAXN*2+10];
int pcnt, last;
void Insert(char ch){
    int id=ch-'a';
    int p=last, np=++pcnt;
    pool[np].len = pool[last].len+1;
    last=np;
    while(p&&!pool[p].ch[id]){
        pool[p].ch[id] = np;
        p = pool[p].fail;
    }
    if(!p){
        pool[np].fail = 1;
        return ;
    }
    int q = pool[p].ch[id];
    if(pool[q].len == pool[p].len+1){
        pool[np].fail = q;
        return ;
    }
    int nq = ++pcnt;
    pool[nq] = pool[q];
    pool[nq].len = pool[p].len+1;
    pool[np].fail = pool[q].fail = nq;
    while(p&&pool[p].ch[id] == q){
        pool[p].ch[id] = nq;
        p = pool[p].fail;
    }
}
int ord[MAXN+10];
bool cmp(int a, int b){
    return pool[a].len > pool[b].len;
}
LL DP(){
    for(int i=1;i<=pcnt;i++)
        ord[i] = i;
    sort(ord+1, ord+1+pcnt, cmp);
    LL ans=0;
    for(int i=1;i<=pcnt;i++){
        ans += 1ll*(pool[ord[i]].len-pool[pool[ord[i]].fail].len)*pool[ord[i]].dp*pool[ord[i]].dp;
        pool[pool[ord[i]].fail].dp += pool[ord[i]].dp;
    }
    return ans;
}
char s[MAXN+10];
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        memset(pool, 0, sizeof pool);
        pcnt = last = 1;
        scanf("%s", s);
        int len = strlen(s), now = 1;
        for(int i=0;i<len;i++)
            Insert(s[i]);
        for(int i=0;i<len;i++){
            now = pool[now].ch[s[i]-'a'];
            pool[now].dp ++;
        }
        printf("%I64d\n", DP());
    }

    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 100000;
typedef long long LL;
LL pow(LL a, LL b){
    LL ret=1;
    while(b){
        if(b&1)
            ret=ret*a;
        a=a*a;
        b>>=1;
    }
    return ret;
}
struct tnode{
    int ch[26], len, fail;
    LL dp;
}pool[MAXN+10];
int pcnt, last;
void Insert(char ch){
    int id=ch-'a';
    int p=last, np=++pcnt;
    pool[np].len = pool[last].len+1;
    last=np;
    while(p&&!pool[p].ch[id]){
        pool[p].ch[id] = np;
        p = pool[p].fail;
    }
    if(!p){
        pool[np].fail = 1;
        return ;
    }
    int q = pool[p].ch[id];
    if(pool[q].len == pool[p].len+1){
        pool[np].fail = q;
        return ;
    }
    int nq = ++pcnt;
    pool[nq] = pool[q];
    pool[nq].len = pool[p].len+1;
    pool[np].fail = pool[q].fail = nq;
    while(p&&pool[p].ch[id] == q){
        pool[p].ch[id] = nq;
        p = pool[p].fail;
    }
}
int ord[MAXN+10];
bool cmp(int a, int b){return pool[a].len > pool[b].len;}
LL DP(){
    for(int i=1;i<=pcnt;i++)
        ord[i] = i;
    sort(ord+1, ord+1+pcnt, cmp);
    LL ans=0;
    for(int i=1;i<=pcnt;i++){
        ans += 1ll*(pool[ord[i]].len-pool[pool[ord[i]].fail].len)*pool[ord[i]].dp*pool[ord[i]].dp;
        pool[pool[ord[i]].fail].dp += pool[ord[i]].dp;
    }
    return ans;
}
char s[MAXN+10];
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        memset(pool, 0, sizeof pool);
        pcnt = last = 1;
        scanf("%s", s);
        int len = strlen(s), now = 1;
        for(int i=0;i<len;i++)
            Insert(s[i]);
        for(int i=0;i<len;i++){
            now = pool[now].ch[s[i]-'a'];
            pool[now].dp ++;
        }
        printf("%I64d\n", DP());
    }

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;

const int MAXN = 100005;

struct Edge
{
	int to, next;
	Edge() {}
}e[MAXN << 1];
int head[MAXN << 1], te = 0;

inline void insertE(int u, int v)
{
	e[++te].to = v;
	e[te].next = head[u];
	head[u] = te;
}

struct Node
{
	int l, p, trans[26];
	Node() {}
	Node(int a, int b) : l(a), p(b) { memset(trans, 0, sizeof(trans)); }
}node[MAXN << 1];
int r[MAXN << 1], root = 1, last = 1, cnt = 1;

long long res = 0;

inline void insert(int x, int len)
{
	int p = last, np = ++cnt;
	node[np] = Node(len, 0), r[np] = 1;
	for ( ; p && node[p].trans[x] == 0; p = node[p].p)
		node[p].trans[x] = np;
	if (!p)
		node[np].p = root;
	else
	{
		int q = node[p].trans[x];
		if (node[q].l == node[p].l + 1)
			node[np].p = q;
		else
		{
			int nq = ++cnt;
			node[nq] = Node(node[p].l + 1, node[q].p);
			for (int i = 0; i < 26; i++)
				node[nq].trans[i] = node[q].trans[i];
			node[q].p = nq;
			node[np].p = nq;
			for ( ; p && node[p].trans[x] == q; p = node[p].p)
				node[p].trans[x] = nq;
		}
	}
	last = np;
}

void dfs(int u)
{
	for (int j = head[u]; j != 0; j = e[j].next)
	{
		int v = e[j].to;
		dfs(v);
		r[u] += r[v];
	}
}

void init(string &now)
{
	memset(r, 0, sizeof(r));
	root = 1, last = 1, cnt = 1;
	node[root] = Node(0, 0);
	for (int i = 0; i < now.size(); i++)
		insert(now[i] - 'a', i + 1);
	memset(head, 0, sizeof(head));
	te = 0;
	for (int i = 2; i <= cnt; i++)
		insertE(node[i].p, i);
	dfs(1);
}

int n;

string s;

int main()
{
	ios::sync_with_stdio(false);
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> s;
		init(s);
		res = 0;
		for (int i = 2; i <= cnt; i++)
		{
			int len = node[i].l - node[node[i].p].l;
			res += (long long)(r[i]) * r[i] * len;
		}
		cout << res << endl;
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int MAXN = 100000 + 10;
const int MAXPOOL = MAXN * 2;

struct SuffixAutomaton {
    int len[MAXPOOL];
    int fa[MAXPOOL];
    int size[MAXPOOL];
    int ch[MAXPOOL][26];
    int last, alloc;
    void extend(int c)
    {
        int p = last, np = ++alloc;
        size[np] = 1;
        len[np] = len[p] + 1;
        last = np;
        while (p && !ch[p][c])
            ch[p][c] = np, p = fa[p];
        if (!p)
            fa[np] = 1;
        else {
            int q = ch[p][c];
            if (len[q] == len[p] + 1)
                fa[np] = q;
            else {
                int nq = ++alloc;
                memcpy(ch[nq], ch[q], sizeof(ch[q]));
                fa[nq] = fa[q];
                len[nq] = len[p] + 1;
                fa[np] = fa[q] = nq;
                while (p && ch[p][c] == q)
                    ch[p][c] = nq, p = fa[p];
            }
        }
    }
    void init()
    {
        memset(fa, 0, sizeof(fa));
        memset(ch, 0, sizeof(ch));
        memset(len, 0, sizeof(len));
        memset(size, 0, sizeof(size));
        alloc = 1;
    }
    ll build(char str[])
    {
        init();
        last = 1;
        for (int i = 0; str[i]; ++i)
            extend(str[i] - 'a');
        static int rank[MAXPOOL];
        static int tax[MAXPOOL];
        memset(rank, 0, sizeof(rank));
        memset(tax, 0, sizeof(tax));
        for (int i = 1; i <= alloc; ++i)
            tax[len[i]]++;
        for (int i = 1; i <= alloc; ++i)
            tax[i] += tax[i - 1];
        for (int i = 1; i <= alloc; ++i)
            rank[tax[len[i]]--] = i;
        for (int i = alloc; i >= 1; --i) {
            int p = rank[i];
            size[fa[p]] += size[p];
        }
        ll ans = 0;
        for (int i = 1; i <= alloc; ++i)
            ans += 1ll * size[i] * size[i] * (len[i] - len[fa[i]]);
        return ans;
    }
} sam;

int main()
{
    int T;
    static char str[MAXN];
    cin >> T;
    while (T--) {
        cin >> str;
        cout << sam.build(str) << endl;
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100005;
int T,n,m,SA[N],rank[N],height[N],tmp[N],tax[N];
char s[N];
int st[N],top,pos[N];
void Sort(int n,int m){
    for (int i=0;i<=m;i++)
        tax[i]=0;
    for (int i=1;i<=n;i++)
        tax[rank[i]]++;
    for (int i=1;i<=m;i++)
        tax[i]+=tax[i-1];
    for (int i=n;i>=1;i--)
        SA[tax[rank[tmp[i]]]--]=tmp[i];
}
bool cmp(int rk[],int x,int y,int w){
    return rk[x]==rk[y]&&rk[x+w]==rk[y+w];
}
void Suffix_Array(char s[],int n){
    memset(SA,0,sizeof SA);
    memset(tmp,0,sizeof tmp);
    memset(rank,0,sizeof rank);
    memset(height,0,sizeof height);
    for (int i=1;i<=n;i++)
        rank[i]=s[i],tmp[i]=i;
    m=127;
    Sort(n,m);
    for (int w=1,p=0;p<n;w<<=1,m=p){
        p=0;
        for (int i=n-w+1;i<=n;i++)
            tmp[++p]=i;
        for (int i=1;i<=n;i++)
            if (SA[i]>w)
                tmp[++p]=SA[i]-w;
        Sort(n,m);
        swap(rank,tmp);
        rank[SA[1]]=p=1;
        for (int i=2;i<=n;i++)
            rank[SA[i]]=cmp(tmp,SA[i],SA[i-1],w)?p:++p;
    }
    for (int i=1,j,k=0;i<=n;height[rank[i++]]=k)
        for (k=max(k-1,0),j=SA[rank[i]-1];s[i+k]==s[j+k];k++);
}
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%s",s+1);
        n=strlen(s+1);
        Suffix_Array(s,n);
        LL ans=0;
        top=0;
        memset(st,0,sizeof st);
        memset(pos,0,sizeof pos);
        SA[n+1]=height[0]=0;
        for (int i=2;i<=n+1;i++){
            int nowpos=i,len=height[i];
            while (top>0&&st[top]>len){
                LL v1=st[top]-max(st[top-1],len);
                LL v2=i-pos[top]+1;
                ans+=v1*v2*v2;
                nowpos=pos[top--];
            }
            while (top>0&&st[top]==len)
                nowpos=pos[top--];
            st[++top]=len;
            pos[top]=nowpos;
        }
        for (int i=1;i<=n;i++)
            ans+=n-i+1-max(height[rank[i]],height[rank[i]+1]);
        printf("%I64d\n",ans);
    }
    return 0;
}


#include<iostream>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<cctype>
#include<cassert>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<list>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<iomanip>
#include<utility>
#include<functional>
using namespace std;
#define mp make_pair
#define pb push_back
#define pf push_front
#define X first
#define Y second
#define rg register
#define il inline
#define lch(x) ((x)<<1)
#define rch(x) ((x)<<1^1)
#define rep0(i,n) for(int i=0;i<(n);++i)
#define rep(i,st,ed) for(int i=(st);i<=(ed);++i)
#define per(i,ed,st) for(int i=(ed);i>=(st);--i)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef double dbl;
typedef long double ldb;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
template<typename T> il T qmin(const T &a,const T &b) {return a<b?a:b;}
template<typename T> il T qmax(const T &a,const T &b) {return a>b?a:b;}
template<typename T> il void getmin(T &a,const T b) {if(a>b) a=b;}
template<typename T> il void getmax(T &a,const T b) {if(a<b) a=b;}
il void fileio(string s){
	freopen((s+".in").c_str(),"r",stdin);
	freopen((s+".out").c_str(),"w",stdout);
}

const int inf=(int)1e9+7;
const ll linf=(ll)1e17+7;
const int N=2e5+7;

int ch[N][26],par[N],val[N],tot[N],node,root,last;
ll sum[N];

il int newnode(int v){
	val[++node]=v;
	tot[node]=0;
	memset(ch[node],0,sizeof(int)*26);
	return node;
}

il void ins(int c){
	int p=last,np=newnode(val[p]+1);
	tot[np]=1;
	while(p&&!ch[p][c]) ch[p][c]=np,p=par[p];
	if(!p){
		par[np]=root;
	}else{
		int q=ch[p][c];
		if(val[q]==val[p]+1){
			par[np]=q;
		}else{
			int nq=newnode(val[p]+1);
			memcpy(ch[nq],ch[q],sizeof(int)*26);
			par[nq]=par[q];
			par[q]=par[np]=nq;
			while(p&&ch[p][c]==q) ch[p][c]=nq,p=par[p];
		}
	}
	last=np;
}

char s[N];
int n;
int c[N],id[N];

int main(){
	int kase;
	scanf("%d",&kase);
	while(kase--){
		scanf("%s",s),n=strlen(s);
		node=0;
		root=last=newnode(0);
		rep0(i,n) ins(s[i]-'a');
		memset(c,0,sizeof(int)*(n+1));
		rep(i,1,node) ++c[val[i]];
		rep(i,1,n) c[i]+=c[i-1];
		per(i,node,1) id[c[val[i]]--]=i;
		per(i,node,1) tot[par[id[i]]]+=tot[id[i]];
		memset(sum,0,sizeof(ll)*(n+1));
		rep(i,2,node) sum[tot[i]]+=(ll)val[i]-val[par[i]];
		ll ans=0;
		rep(i,1,n) ans+=sum[i]*i*i;
	//	rep(i,1,n) cerr<<sum[i]<<",";cerr<<endl;
		printf("%lld\n",ans);
	}
	return 0;
}


#include<iostream>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<cctype>
#include<cassert>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<list>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<iomanip>
#include<utility>
#include<functional>
using namespace std;
#define mp make_pair
#define pb push_back
#define pf push_front
#define X first
#define Y second
#define rg register
#define il inline
#define lch(x) ((x)<<1)
#define rch(x) ((x)<<1^1)
#define rep0(i,n) for(int i=0;i<(n);++i)
#define rep(i,st,ed) for(int i=(st);i<=(ed);++i)
#define per(i,ed,st) for(int i=(ed);i>=(st);--i)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef double dbl;
typedef long double ldb;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
template<typename T> il T qmin(const T &a,const T &b) {return a<b?a:b;}
template<typename T> il T qmax(const T &a,const T &b) {return a>b?a:b;}
template<typename T> il void getmin(T &a,const T b) {if(a>b) a=b;}
template<typename T> il void getmax(T &a,const T b) {if(a<b) a=b;}
il void fileio(string s){
	freopen((s+".in").c_str(),"r",stdin);
	freopen((s+".out").c_str(),"w",stdout);
}

const int inf=(int)1e9+7;
const ll linf=(ll)1e17+7;
const int N=2e5+7;

int ch[N][26],par[N],val[N],tot[N],node=1,root=1,last=1;
int sum[N];

il int newnode(int v){
	val[++node]=v;
	tot[node]=0;
	memset(ch[v],0,sizeof(int)*26);
	return node;
}

il void ins(int c){
	int p=last,np=newnode(val[p]+1);
	tot[np]=1;
	while(p&&!ch[p][c]) ch[p][c]=np,p=par[p];
	if(!p){
		par[np]=root;
	}else{
		int q=ch[p][c];
		if(val[q]==val[p]+1){
			par[np]=q;
		}else{
			int nq=newnode(val[p]+1);
			memcpy(ch[nq],ch[q],sizeof(int)*26);
			par[nq]=par[q];
			par[q]=par[np]=nq;
			while(p&&ch[p][c]==q) ch[p][c]=nq,p=par[p];
		}
	}
	last=np;
}

char s[N];
int n;
int c[N],id[N];

int main(){
	int kase;
	scanf("%d",&kase);
	while(kase--){
		scanf("%s",s),n=strlen(s);
		node=0;
		root=last=newnode(0);
		rep0(i,n) ins(s[i]-'a');
		memset(c,0,sizeof(int)*(n+1));
		rep(i,1,node) ++c[val[i]];
		rep(i,1,n) c[i]+=c[i-1];
		per(i,node,1) id[c[val[i]]--]=i;
		per(i,node,1) tot[par[id[i]]]+=tot[id[i]];
		memset(sum,0,sizeof(int)*(n+1));
		rep(i,2,node) sum[tot[i]]+=val[i]-val[par[i]];
		ll ans=0;
		rep(i,1,n) ans+=(ll)sum[i]*i*i;
	//	rep(i,1,n) cerr<<sum[i]<<",";cerr<<endl;
		printf("%lld\n",ans);
	}
	return 0;
}


#include<iostream>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<cctype>
#include<cassert>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<list>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<iomanip>
#include<utility>
#include<functional>
using namespace std;
#define mp make_pair
#define pb push_back
#define pf push_front
#define X first
#define Y second
#define rg register
#define il inline
#define lch(x) ((x)<<1)
#define rch(x) ((x)<<1^1)
#define rep0(i,n) for(int i=0;i<(n);++i)
#define rep(i,st,ed) for(int i=(st);i<=(ed);++i)
#define per(i,ed,st) for(int i=(ed);i>=(st);--i)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef double dbl;
typedef long double ldb;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
template<typename T> il T qmin(const T &a,const T &b) {return a<b?a:b;}
template<typename T> il T qmax(const T &a,const T &b) {return a>b?a:b;}
template<typename T> il void getmin(T &a,const T b) {if(a>b) a=b;}
template<typename T> il void getmax(T &a,const T b) {if(a<b) a=b;}
il void fileio(string s){
	freopen((s+".in").c_str(),"r",stdin);
	freopen((s+".out").c_str(),"w",stdout);
}

const int inf=(int)1e9+7;
const ll linf=(ll)1e17+7;
const int N=2e5+7;

int ch[N][26],par[N],val[N],tot[N],node,root,last;
ll sum[N];

il int newnode(int v){
	val[++node]=v;
	tot[node]=0;
	memset(ch[node],0,sizeof(int)*26);
	return node;
}

il void ins(int c){
	int p=last,np=newnode(val[p]+1);
	tot[np]=1;
	while(p&&!ch[p][c]) ch[p][c]=np,p=par[p];
	if(!p){
		par[np]=root;
	}else{
		int q=ch[p][c];
		if(val[q]==val[p]+1){
			par[np]=q;
		}else{
			int nq=newnode(val[p]+1);
			memcpy(ch[nq],ch[q],sizeof(int)*26);
			par[nq]=par[q];
			par[q]=par[np]=nq;
			while(p&&ch[p][c]==q) ch[p][c]=nq,p=par[p];
		}
	}
	last=np;
}

char s[N];
int n;
int c[N],id[N];

int main(){
	int kase;
	scanf("%d",&kase);
	while(kase--){
		scanf("%s",s),n=strlen(s);
		node=0;
		root=last=newnode(0);
		rep0(i,n) ins(s[i]-'a');
		memset(c,0,sizeof(int)*(n+1));
		rep(i,1,node) ++c[val[i]];
		rep(i,1,n) c[i]+=c[i-1];
		per(i,node,1) id[c[val[i]]--]=i;
		per(i,node,1) tot[par[id[i]]]+=tot[id[i]];
		memset(sum,0,sizeof(int)*(n+1));
		rep(i,2,node) sum[tot[i]]+=(ll)val[i]-val[par[i]];
		ll ans=0;
		rep(i,1,n) ans+=sum[i]*i*i;
	//	rep(i,1,n) cerr<<sum[i]<<",";cerr<<endl;
		printf("%lld\n",ans);
	}
	return 0;
}


#include<iostream>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<cctype>
#include<cassert>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<list>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<iomanip>
#include<utility>
#include<functional>
using namespace std;
#define mp make_pair
#define pb push_back
#define pf push_front
#define X first
#define Y second
#define rg register
#define il inline
#define lch(x) ((x)<<1)
#define rch(x) ((x)<<1^1)
#define rep0(i,n) for(int i=0;i<(n);++i)
#define rep(i,st,ed) for(int i=(st);i<=(ed);++i)
#define per(i,ed,st) for(int i=(ed);i>=(st);--i)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef double dbl;
typedef long double ldb;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
template<typename T> il T qmin(const T &a,const T &b) {return a<b?a:b;}
template<typename T> il T qmax(const T &a,const T &b) {return a>b?a:b;}
template<typename T> il void getmin(T &a,const T b) {if(a>b) a=b;}
template<typename T> il void getmax(T &a,const T b) {if(a<b) a=b;}
il void fileio(string s){
	freopen((s+".in").c_str(),"r",stdin);
	freopen((s+".out").c_str(),"w",stdout);
}

const int inf=(int)1e9+7;
const ll linf=(ll)1e17+7;
const int N=2e5+7;

int ch[N][26],par[N],val[N],tot[N],node=1,root=1,last=1;
int sum[N];

il int newnode(int v){
	val[++node]=v;
	tot[node]=0;
	memset(ch[node],0,sizeof(int)*26);
	return node;
}

il void ins(int c){
	int p=last,np=newnode(val[p]+1);
	tot[np]=1;
	while(p&&!ch[p][c]) ch[p][c]=np,p=par[p];
	if(!p){
		par[np]=root;
	}else{
		int q=ch[p][c];
		if(val[q]==val[p]+1){
			par[np]=q;
		}else{
			int nq=newnode(val[p]+1);
			memcpy(ch[nq],ch[q],sizeof(int)*26);
			par[nq]=par[q];
			par[q]=par[np]=nq;
			while(p&&ch[p][c]==q) ch[p][c]=nq,p=par[p];
		}
	}
	last=np;
}

char s[N];
int n;
int c[N],id[N];

int main(){
	int kase;
	scanf("%d",&kase);
	while(kase--){
		scanf("%s",s),n=strlen(s);
		node=0;
		root=last=newnode(0);
		rep0(i,n) ins(s[i]-'a');
		memset(c,0,sizeof(int)*(n+1));
		rep(i,1,node) ++c[val[i]];
		rep(i,1,n) c[i]+=c[i-1];
		per(i,node,1) id[c[val[i]]--]=i;
		per(i,node,1) tot[par[id[i]]]+=tot[id[i]];
		memset(sum,0,sizeof(int)*(n+1));
		rep(i,2,node) sum[tot[i]]+=val[i]-val[par[i]];
		ll ans=0;
		rep(i,1,n) ans+=(ll)sum[i]*i*i;
	//	rep(i,1,n) cerr<<sum[i]<<",";cerr<<endl;
		printf("%lld\n",ans);
	}
	return 0;
}


/*
 * test.cpp
 *
 *
 *      Author: Fireworks
 */

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<string>
#include<map>
#include<cmath>
#include<bitset>
#include<set>
#include<iomanip>
#include<fstream>
#include<bitset>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<list>
#include<sstream>

using namespace std;

typedef pair<int,int> ii;
typedef pair<int,long long> il;
typedef pair<long long,long long> ll;
typedef pair<ll,int> lli;
typedef pair<long long,int> li;
typedef pair<double,double> dd;
typedef pair<ii,int> iii;
typedef pair<double,int> di;
long long mod = 1000000007LL;
long long base = 37;
long long large = 1000000000000000000LL;

string t;
int n;
vector<int> ra,tempra,sa,tempsa,c;

void countingSort(int k){
	int i,sum,maxi=max(400,n);
	c.assign(max(400,n+10),0);
	for(i=0;i<n;i++){
		c[i+k<n?ra[i+k]:0]++;
	}
	for(i=sum=0;i<maxi;i++){
		int temp=c[i];
		c[i]=sum;
		sum+=temp;
	}
	for(i=0;i<n;i++){
		tempsa[c[sa[i]+k < n ? ra[sa[i]+k] : 0]++]=sa[i];
	}
	for(i=0;i<n;i++){
		sa[i]=tempsa[i];
	}
}

void constructSA(){
	int i,k,r;
	for(i=0;i<n;i++) ra[i]=(int)t[i];
	for(i=0;i<n;i++) sa[i]=i;
	for(k=1;k<n;k=k<<1){
		countingSort(k);
		countingSort(0);
		tempra[sa[0]]=r=0;
		for(i=1;i<n;i++){
			tempra[sa[i]]=(ra[sa[i]]==ra[sa[i-1]]&&ra[sa[i]+k]==ra[sa[i-1]+k]) ? r : ++r;
		}
		for(i=0;i<n;i++){
			ra[i]=tempra[i];
		}
		if(ra[sa[n-1]]==n-1) break;
	}
}

vector<int> phi,plcp,lcp;
void computeLCP(){
	int i,L;
	phi.assign(n+10,0);
	lcp=plcp=phi;
	phi[sa[0]]=-1;
	for(i=1;i<n;i++){
		phi[sa[i]]=sa[i-1];
	}
	for(i=L=0;i<n;i++){
		if(phi[i]==-1){
			plcp[i]=0;
			continue;
		}
		while(t[i+L]==t[phi[i]+L]) L++;
		plcp[i]=L;
		L=max(L-1,0);
	}
	for(i=0;i<n;i++){
		lcp[i]=plcp[sa[i]];
	}
}

vector<long long> addv,setv,sum;

int ul,ur;
long long uv;
bool isset;

void maintain(int o,int l,int r){
	if(setv[o]!=-1){
		sum[o]=1LL*(r-l+1)*(setv[o]+addv[o]);
	}else{
		sum[o]=sum[o*2]+sum[o*2+1]+addv[o]*(r-l+1);
	}
}
void pushdown(int o,int l,int r){
	if(setv[o]!=-1){
		setv[o*2]=setv[o*2+1]=setv[o];
		addv[o*2]=addv[o*2+1]=0LL;
		setv[o]=-1;
	}
	if(addv[o]>0){
		addv[o*2]+=addv[o];
		addv[o*2+1]+=addv[o];
		addv[o]=0;
	}
}

void update(int o,int l,int r){
	if(ur<ul) return;
	if(ul<=l&&ur>=r){
		if(isset){
			setv[o]=uv;
			addv[o]=0;
		}else{
			addv[o]+=uv;
		}
	}else{
		pushdown(o,l,r);
		int m = (l+r)/2;
		if(ul<=m){
			update(o*2,l,m);
		}else{
			maintain(o*2,l,m);
		}
		if(ur>m){
			update(o*2+1,m+1,r);
		}else{
			maintain(o*2+1,m+1,r);
		}
	}
	maintain(o,l,r);
}

int ql,qr;
long long re;
void query(int o,int l,int r,long long add){
	if(ql<=l&&qr>=r){
		re+=sum[o]+add*(r-l+1);
	}else{
		int m = (l+r)/2;
		if(ql<=m) query(o*2,l,m,add+addv[o]);
		if(qr>m) query(o*2+1,m+1,r,add+addv[o]);
	}
}
int main(){

	int tt;
	cin>>tt;
	while(tt--){
		cin>>t;//get the string which need suffix array
		t=t+"$";//add termination indicator
		n=(int)t.length();
		ra.assign(max(400,n+10),0);
		tempra=sa=tempsa=c=ra;//vector initialize
		constructSA();
		computeLCP();
		/*for(int i=0;i<n;i++){
			cout<<t.substr(sa[i],t.length())<<endl;
			cout<<lcp[i]<<endl;
		}*/
		sum.assign(4*n+10,0LL);
		addv.assign(4*n+10,0LL);
		setv.assign(4*n+10,-1LL);
		long long ans = 0LL;
		for(int i=0;i<n;i++){
			isset = true;
			uv = 0;
			ul = lcp[i];
			ur = n-1;
			update(1,0,n-1);
			isset=false;
			uv=1;
			ul=0;
			ur=lcp[i]-1;
			update(1,0,n-1);
			ans+=sum[1];
		}
		cout<<2LL*ans+1LL*n*(n-1)/2<<endl;
	}

	/*int t;
	sum.assign(500,0);
	setv.assign(500,-1);
	addv.assign(500,0);
	while(cin>>t){
		if(t==1){
			cin>>ul>>ur>>uv>>isset;
			update(1,0,100-1);
		}else{
			cin>>ql>>qr;
			re=0LL;
			query(1,0,100-1,0LL);
			cout<<re<<endl;
		}
	}*/

	/*int totalcase;
	int testcase=0;
	cin>>totalcase;
	ofstream out;
	out.open("result.txt");

	while(totalcase--){
		testcase++;
		out<<"Case #"<<testcase<<": ";
		cout<<testcase<<": "<<endl;

		//GOGOGO

		//END
	}
	out.close();*/

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>

using namespace std;

const int MAXN = 1000000;

struct Node
{
	int go[26], pa;
	int len, cnt, deg;
	Node() : pa(0), len(0), cnt(0), deg(0)
	{
		memset(go, 0, sizeof(go));
	}
	void copy(const Node &now)
	{
		memcpy(go, now.go, sizeof(go));
		pa = now.pa;
	}
}
node[2 * MAXN];
int null, root, last, tot = 0;

int newNode()
{
	node[tot] = Node();
	return tot++;
}

void insert(int c)
{
	int p = last, np = newNode();
	node[np].cnt = 1;
	node[np].len = node[p].len + 1;
	while(p && !node[p].go[c])
		node[p].go[c] = np, p = node[p].pa;
	// cout << c << ' ' << p << ' ' << np << endl;
	if(!p)
		node[np].pa = root;
	else
	{
		int q = node[p].go[c];
		if(node[q].len == node[p].len + 1)
			node[np].pa = q;
		else
		{
			int nq = newNode();
			node[nq].copy(node[q]);
			node[nq].len = node[p].len + 1;
			node[np].pa = node[q].pa = nq;
			while(p && node[p].go[c] == q)
				node[p].go[c] = nq, p = node[p].pa;
		}
	}
	last = np;
}

void calc()
{
	static queue<int> q;
	while(!q.empty()) q.pop();

	for(int i = 2; i < tot; i++)
		node[node[i].pa].deg++;
	for(int i = 1; i < tot; i++)
		if(node[i].deg == 0)
			q.push(i);
	while(!q.empty())
	{
		int x = q.front();
		q.pop();
		if(node[x].pa == 0) continue;
		node[node[x].pa].cnt += node[x].cnt;
		node[node[x].pa].deg--;
		if(!node[node[x].pa].deg)
			q.push(node[x].pa);
	}
}
void solve()
{
	tot = 0;
	null = newNode(), last = root = newNode();

	string s;
	cin >> s;
	for(int i = 0; i < s.size(); i++)
		insert(s[i] - 'a');
	calc();

	long long ans = 0;
	for(int i = 2; i < tot; i++)
		ans = (ans + (long long)node[i].cnt * node[i].cnt * (node[i].len - node[node[i].pa].len));
	cout << ans << endl;
}

int main()
{
	ios::sync_with_stdio(false);
	// freopen("1.in", "r", stdin);
	// freopen("1.out", "w", stdout);

	int T;
	cin >> T;
	while(T--)
		solve();

	return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#define N 500010<<1

using namespace std;

typedef long long ll;

struct SAM_{
    int next[N][26],fail[N],stp[N],p,cnt,t[N],r[N];
    ll f[N],w[N];
    SAM_(){p=cnt=1;}
    void clear(){
    	p=cnt=1;
    	memset(next,0,sizeof(next));
    	memset(fail,0,sizeof(fail));
    	memset(stp,0,sizeof(stp));
    	memset(t,0,sizeof(t));
    	memset(r,0,sizeof(r));
    	memset(f,0,sizeof(f));
    	memset(w,0,sizeof(w));
		}
    void Extend(int x){
        x-='a';
        int np=++cnt;stp[np]=stp[p]+1;w[np]=f[np]=1;
        while(p&&!next[p][x]) next[p][x]=np,p=fail[p];
        if(!p) fail[np]=1;
        else{
            int q=next[p][x];
            if(stp[q]==stp[p]+1) fail[np]=q;
            else{
                int nq=++cnt;stp[nq]=stp[p]+1;
                memcpy(next[nq],next[q],sizeof(next[q]));
                fail[nq]=fail[q];
                fail[q]=fail[np]=nq;
                while(p&&next[p][x]==q) next[p][x]=nq,p=fail[p];
            }
        }
        p=np;
    }
    void Samort(){
        int i;
        for(i=0;i<=cnt;i++) t[i]=0;
        for(i=1;i<=cnt;i++) t[stp[i]]++;
        for(i=1;i<=cnt;i++) t[i]+=t[i-1];
        for(i=1;i<=cnt;i++) r[t[stp[i]]--]=i;
    }
    void Solve(int n){
        for(int i=cnt;i;i--)f[fail[r[i]]]+=f[r[i]];
        ll Ans=0;
        for(int i=2;i<=cnt;i++)
					Ans+=1LL*(stp[i]-stp[fail[i]])*f[i]*f[i];
        printf("%I64d\n",Ans);
    }
}SAM;

char A[N];
int n;

int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		SAM.clear();
		scanf("%s",A+1);n=strlen(A+1);
    for(int i=n;i;i--)
      SAM.Extend(A[i]);
    SAM.Samort();
    SAM.Solve(n);
	}
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200005
using namespace std;
typedef long long ll;
inline int read(){
	int sum = 0, t = 1; char ch = getchar();
	while(ch < '0' || ch > '9'){ if(ch == '-') t = -1; ch = getchar(); }
	while(ch >= '0' && ch <= '9'){ sum = sum * 10  + ch - '0'; ch = getchar(); }
	return sum * t;
}

char s[N];

struct node{ int nxt[26], par, len, rt; }c[N];

int tot, rt, las;

void insert(int x){
	int p = las, np = ++tot, q, nq;
	c[np].len = c[p].len + 1; c[np].rt = 1;
	for(; p && !c[p].nxt[x] ; p = c[p].par) c[p].nxt[x] = np;
	if(!p) c[np].par = rt;
	else {
		q = c[p].nxt[x];
		if(c[q].len == c[p].len + 1) c[np].par = q;
		else {
			c[nq = ++tot] = c[q];
			c[nq].rt = 0;
			c[nq].len = c[p].len + 1;
			c[np].par = c[q].par = nq;
			for(; p && c[p].nxt[x] == q ; p = c[p].par) c[p].nxt[x] = nq;
		}
	}
	las = np;
}

int nxt[N], fir[N], to[N], cnt;
int sz[N], n;
ll ans;

void init(){
	memset(c, 0, sizeof(node) * (tot + 1));
	memset(fir, 0, sizeof(int) * (tot + 1));
	cnt = 0;
	tot = rt = las = 1;
}

void add(int x, int y){
	nxt[++cnt] = fir[x]; to[cnt] = y; fir[x] = cnt;
}

void dfs(int x){
	sz[x] = c[x].rt;
	for(int i = fir[x]; i ; i = nxt[i]){
		int y = to[i];
		dfs(y);
		sz[x] += sz[y];
	}
	ans += 1LL * (c[x].len - c[c[x].par].len) * sz[x] * sz[x];
}

int main(){
	for(int T = read(); T ; T--){
		init();
		scanf("%s", s + 1); n = strlen(s + 1);
		for(int i = 1; i <= n; i++)
			insert(s[i] - 'a');
		for(int i = 2; i <= tot; i++) add(c[i].par, i);
		ans = 0;
		dfs(rt);
		printf("%lld\n", ans);
	}
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define maxn 100005
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;

char s[maxn];

int x[maxn],y[maxn],wss[maxn],wv[maxn],sa[maxn],rank[maxn],height[maxn];

int T,n;

ll ans;

struct note{
	int lcp,wz;
}a[maxn];

int l[maxn],r[maxn];

bool cmp(int *rank,int i,int j,int l){
	return rank[i]==rank[j] && rank[i+l]==rank[j+l];
}

void SA(){
	int i,j,p,m='z'+1;
	fo(i,1,n) wss[x[i]=s[i]]++;
	fo(i,1,m) wss[i]+=wss[i-1];
	fd(i,n,1) sa[wss[x[i]]--]=i;
	for(p=0,j=1;p<n;m=p,j*=2) {
		for(p=0,i=n-j+1;i<=n;i++) y[++p]=i;
		for(i=1;i<=n;i++) if (sa[i]>j) y[++p]=sa[i]-j;
		for(i=1;i<=n;i++) wv[i]=x[y[i]];
		for(i=1;i<=m;i++) wss[i]=0;
		for(i=1;i<=n;i++) wss[wv[i]]++;
		for(i=1;i<=m;i++) wss[i]+=wss[i-1];
		for(i=n;i>=1;i--) sa[wss[wv[i]]--]=y[i];
		swap(x,y);
		for(p=1,x[sa[1]]=1,i=2;i<=n;i++)
			x[sa[i]]=cmp(y,sa[i-1],sa[i],j) ? p : ++p;
	}
}

void getheight(){
	int i,j,k=0;
	for(i=1;i<=n;i++) rank[sa[i]]=i;
	for(i=1;i<=n;height[rank[i++]]=k)
		for(k ? --k : k,j=sa[rank[i]-1];s[i+k]==s[j+k];k++);
}

bool cmp1(note i,note j){
	return i.lcp>j.lcp;
}

int main(){
	scanf("%d",&T);
	while (T--){
		mem(wss,0);
		n=0;
		char c=getchar();
		while (c<'a' || c>'z') c=getchar();
		while (c>='a' && c<='z') {
			s[++n]=c;
			l[n]=r[n]=n;
			c=getchar();
		}
		s[n+1]=0;
		SA();
		getheight();
		ll ans=1ll *n*(n+1) / 2;
		fo(i,2,n) {
			a[i-1].wz=i;
			a[i-1].lcp=height[i];
		}
		sort(a+1,a+n,cmp1);
		fo(i,1,n-1) {
			int wz=a[i].wz;
			ans=ans+2ll * a[i].lcp * (r[wz]-wz+1) * (wz-l[wz-1]);
			r[l[wz-1]]=r[wz];
			l[r[wz]]=l[wz-1];
		}
		printf("%I64d\n",ans);
	}
	return 0;
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<queue>
#define LL long long
using namespace std;
inline int read( )
{
  int sum=0;char c=getchar( );bool f=0;
  while(c<'0'||c>'9') {if(c=='-') f=1;c=getchar( );}
  while(c>='0'&&c<='9') {sum=sum*10+c-'0';c=getchar( );}
  if(f) return -sum;
  return sum;
}
const int N=200005;
int n,T;char s[N];
int rt,cnt,lst,son[N][26],f[N],Rs[N],Max[N];
inline void add(int x)
{
  int P=++cnt,U=lst;
  Max[P]=Max[U]+1;lst=P;Rs[P]=1;
  for(;U&&!son[U][x];U=f[U]) son[U][x]=P;
  if(!U) {f[P]=rt;return;}
  int Q=son[U][x];
  if(Max[Q]==Max[U]+1) {f[P]=Q;return;}
  int NP=++cnt;Max[NP]=Max[U]+1;
  for(;son[U][x]==Q;U=f[U]) son[U][x]=NP;
  f[NP]=f[Q];f[Q]=f[P]=NP;memcpy(son[NP],son[Q],sizeof(son[Q]));
}
int c[N],id[N],u[N];
int main( )
{
  int i,j,x;LL ans;
  T=read( );
  while(T--)
    {
      scanf("%s",s+1);
      rt=1;cnt=1;lst=1;ans=0;n=strlen(s+1);
      for(i=1;i<=n;i++) add(s[i]-'a');
      for(i=0;i<=cnt;i++) c[i]=id[i]=0;
      for(i=1;i<=cnt;i++) c[Max[i]]++;
      for(i=1;i<=n;i++) c[i]+=c[i-1];
      for(i=1;i<=cnt;i++) id[c[Max[i]]--]=i;
      for(i=cnt;i>=2;i--) x=id[i],Rs[f[x]]+=Rs[x];
      for(i=1;i<=cnt;i++) u[i]=0;u[rt]=1;
      for(i=1;i<=cnt;i++)
	{
	  x=id[i];
	  if(i!=1) ans+=(LL)Rs[x]*Rs[x]*u[x];
	  for(j=0;j<26;j++)
	    if(son[x][j]) u[son[x][j]]+=u[x];
	}
      cout<<ans<<endl;
      for(i=1;i<=cnt;i++)
	{
	  f[i]=0;Rs[i]=0;Max[i]=0;
	  for(j=0;j<26;j++) son[i][j]=0;
	}
    }
  return 0;
}


//By Akanesasu
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<ctime>
#include<cstdlib>
#include<string>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#include<bitset>
#include<vector>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];~x;x=nx[x])
#define ll long long
#define pii pair<int,int>
#define pdd pair<double,double>
#define mk(a,b) make_pair(a,b)
#define fs first
#define sc second
#define pb push_back
#define VI vector<int>
#define VS vector<string>
using namespace std;
inline ll rd(){
	ll x=0;int ch=getchar(),f=1;
	while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
	if (ch=='-'){f=-1;ch=getchar();}
	while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}
inline void rt(ll x){
	if (x<0) putchar('-'),x=-x;
	if (x>=10) rt(x/10),putchar(x%10+'0');
		else putchar(x+'0');
}
const int maxn=200005;
struct node{
	node *to[26],*par;
	int mx,right,vis;
}a[maxn],*last,*root,*qu[maxn];
int n,ndc;
node *newnode(int x){
	node *p=++ndc+a;
	p->mx=x;
	return p;
}
char s[maxn];
void insert(int x){
	node *p=last,*np=newnode(p->mx+1);np->right++;
	while (p&&!p->to[x]) p->to[x]=np,p=p->par;
	if (!p) np->par=root;
	else{
		node *q=p->to[x];
		if (q->mx==p->mx+1) np->par=q;
		else{
			node *nq=newnode(p->mx+1);
			memcpy(nq->to,q->to,sizeof q->to);
			nq->par=q->par;
			q->par=np->par=nq;
			while (p&&p->to[x]==q) p->to[x]=nq,p=p->par;
		}
	}
	last=np;
}
ll ans;
int he,ta;
void getans(){
	he=1,ta=0;qu[++ta]=root;root->vis=1;
	while (he<=ta){
		node *u=qu[he++];
		rep(i,0,25){
			node *v=u->to[i];
			if (v&&!v->vis) qu[++ta]=v,v->vis=1;
		}
	}
	drp(i,ta,2){
		node *p=qu[i];
		p->par->right+=p->right;
		ans=ans+(ll)p->right*p->right*(p->mx-p->par->mx);
	}
}
void initalize(){
	memset(a,0,sizeof a);ndc=ans=0;
	root=last=newnode(0);
}
int main(){
	for (int T=rd();T--;){
		initalize();
		scanf("%s",s);
		n=strlen(s);
		rep(i,0,n-1) insert(s[i]-'a');
		getans();
		rt(ans),putchar('\n');
	}
}