#include <bits/stdc++.h>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    string s;
    cin>>s;
    int n=s.length();
    bool a[26]={}; int b[26]={};
    for(int i=0;i<n;i++){
        a[s[i]-'a']=1;
    }
    int i=0,k=0;
    while(i<=25){
        if(a[i]==0){i++;continue;}
        int x=-1,m;
        for(int j=0;j<n;j++){
            if(s[j]==('a'+i)){
                if(x==-1){if(n%2==0)if(j+1>n/2){break;}if(n%2!=0)if(j+1>n-n/2){break;}x=j;m=j+1;}
                else {if(j-x>m)m=j-x;x=j;}
            }
        }
        if(n-x+1>m && s[n-1]!=s[x])m=n-x+1;
        i++;
        b[k++]=m;
    }
    bool g=0;
    sort(b,b+26);
    for(int l=0;l<26;l++){
        if(b[l]==0)continue;
        else{if(n%2==0){if(b[l]>n/2+1)continue;}else if(b[l]>n-n/2)continue;cout<<b[l];g=1;break;}
    }
    if(g==0){if(n%2==0)cout<<n/2+1;else cout<<n-n/2;}
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    string s;
    cin>>s;
    int n=s.length();
    bool a[26]={}; int b[26]={};
    for(int i=0;i<n;i++){
        a[s[i]-'a']=1;
    }
    int i=0,k=0;
    while(i<=25){
        if(a[i]==0){i++;continue;}
        int x=-1,m;
        for(int j=0;j<n;j++){
            if(s[j]==('a'+i)){
                if(x==-1){x=j;m=0;}
                else {if(j-x>m)m=j-x;x=j;}
            }
        }
        i++;
        b[k++]=m;
    }
    bool g=0;
    sort(b,b+26);
    for(int l=0;l<26;l++){
        if(b[l]==0)continue;
        else{ cout<<b[l];g=1;break;}
    }
    if(g==0)cout<<n-n/2;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    string s;
    cin>>s;
    int n=s.length();
    bool a[26]={}; int b[26]={};
    for(int i=0;i<n;i++){
        a[s[i]-'a']=1;
    }
    int i=0,k=0;
    while(i<=25){
        if(a[i]==0){i++;continue;}
        int x=-1,m;
        for(int j=0;j<n;j++){
            if(s[j]==('a'+i)){
                if(x==-1){if(j>n/2){continue;}x=j;m=0;}
                else {if(j-x>m)m=j-x;x=j;}
            }
        }
        if(x!=-1 && n-x+1>m && s[n-1]!=s[x])m=n-x+1;
        i++;
        b[k++]=m;
    }
    bool g=0;
    sort(b,b+26);
    for(int l=0;l<26;l++){
        if(b[l]==0)continue;
        else{cout<<b[l];g=1;break;}
    }
    if(g==0){if(n%2==0)cout<<n/2+1;else cout<<n-n/2;}
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    string s;
    cin>>s;
    int n=s.length();
    bool a[26]={}; int b[26]={};
    for(int i=0;i<n;i++){
        a[s[i]-'a']=1;
    }
    int i=0,k=0;
    while(i<=25){
        if(a[i]==0){i++;continue;}
        int x=-1,m;
        for(int j=0;j<n;j++){
            if(s[j]==('a'+i)){
                if(x==-1){x=j;m=0;}
                else {if(j-x>m)m=j-x;x=j;}
            }
        }
        i++;
        b[k++]=m;
    }
    bool g=0;
    sort(b,b+26);
    for(int l=0;l<26;l++){
        if(b[l]==0)continue;
        else{cout<<b[l];g=1;break;}
    }
    if(g==0){if(n%2==0)cout<<n/2+1;else cout<<n-n/2;}
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include<set>
#include<utility>
using namespace std;
#include<algorithm>
#define ll long long
#define M1 1000000007
#define M2 998244353
#define pll pair<ll int,ll int>
#define fori(i,n) for(ll i=0;i<n;i++)
#define forj(j,m) for(ll j=0;j<m;j++)
#define cont(n) {cout<<n<<endl;continue;}
#define MOD 1000000007
#define fast() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define MAXN   100001
#define vecti vector<ll int>
#define vectp vector<pair<ll int,ll int> >
#define pb push_back
map<ll int, ll int> v;
int main() {
     fast();
     ll int t;
     t=1;
     while(t--){
     string s;
     cin>>s;

     ll int minp=s.length();
     ll int mi=0;
     for(ll int i=0;i<s.length();i++){
       ll int a=s[i]-'a';
       v[a]++;
     }
     ll int count=0;
     for(ll int i=0;i<26;i++){
       if(v[i]>1){
         count++;
       }
     }

     for(ll int i=1;i<=26;i++){
       ll int k=-1;
       ll int maxt=0;
       for(ll int j=0;j<s.length();j++){
       ll int u=s[j]-'a'+1;
       if(u==i){
          maxt=max(maxt,j-k);
          k=j;
       }
       if(j==s.length()-1&&k!=j){
         maxt=maxt=max(maxt,j-k+1);
       }
       }
       minp=min(minp,maxt);
     }

     if(count==0){
       cout<<(s.length())/2 +1<<endl;

     }
     else{
     cout<<minp;
     }
      }
       }


#include <bits/stdc++.h>
#include <iostream>
#include<set>
#include<utility>
using namespace std;
#include<algorithm>
#define ll long long
#define M1 1000000007
#define M2 998244353
#define pll pair<ll int,ll int>
#define fori(i,n) for(ll i=0;i<n;i++)
#define forj(j,m) for(ll j=0;j<m;j++)
#define cont(n) {cout<<n<<endl;continue;}
#define MOD 1000000007
#define fast() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define MAXN   100001
#define vecti vector<ll int>
#define vectp vector<pair<ll int,ll int> >
#define pb push_back
map<ll int, ll int> v;
int main() {
     fast();
     ll int t;
     t=1;
     while(t--){
     string s;
     cin>>s;

     ll int maxt=0;
     ll int minp=s.length();
     ll int mi=0;
     for(ll int i=0;i<s.length();i++){
       ll int a=s[i]-'a';
       v[a]++;
     }
     ll int count=0;
     for(ll int i=0;i<26;i++){
       if(v[i]>1){
         count++;
       }
     }

     for(ll int i=0;i<26;i++){
       ll int k=0;
       for(ll int j=0;j<s.length();j++){
       ll int u=s[j]-'a';
       if(u==i){
          maxt=max(maxt,j-k);
          k=j;
       }
       if(j==s.length()-1&&k!=j){
         maxt=maxt=max(maxt,j-k);
       }
       }
       minp=min(minp,maxt);
     }

     if(count==0){
       cout<<(s.length()-1)/2 +1<<endl;
     }
     else{
     cout<<minp;
     }
      }
       }


#include <bits/stdc++.h>
#include <iostream>
#include<set>
#include<utility>
using namespace std;
#include<algorithm>
#define ll long long
#define M1 1000000007
#define M2 998244353
#define pll pair<ll int,ll int>
#define fori(i,n) for(ll i=0;i<n;i++)
#define forj(j,m) for(ll j=0;j<m;j++)
#define cont(n) {cout<<n<<endl;continue;}
#define MOD 1000000007
#define fast() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define MAXN   100001
#define vecti vector<ll int>
#define vectp vector<pair<ll int,ll int> >
#define pb push_back
map<ll int, ll int> v;
int main() {
     fast();
     ll int t;
     t=1;
     while(t--){
     string s;
     cin>>s;

     ll int minp=s.length();
     ll int mi=0;
     for(ll int i=0;i<s.length();i++){
       ll int a=s[i]-'a';
       v[a]++;
     }
     ll int count=0;
     for(ll int i=0;i<26;i++){
       if(v[i]>1){
         count++;
       }
     }

     for(ll int i=1;i<=26;i++){
       ll int k=0;
       ll int maxt=0;
       for(ll int j=0;j<s.length();j++){
       ll int u=s[j]-'a'+1;
       if(u==i){
          maxt=max(maxt,j-k);
          k=j;
       }
       if(j==s.length()-1&&k!=j){
         maxt=maxt=max(maxt,j-k+1);
       }
       }
       minp=min(minp,maxt);
     }

     if(count==0){
       cout<<(s.length())/2 +1<<endl;

     }
     else{
     cout<<minp;
     }
      }
       }


#include <bits/stdc++.h>
#include <iostream>
#include<set>
#include<utility>
using namespace std;
#include<algorithm>
#define ll long long
#define M1 1000000007
#define M2 998244353
#define pll pair<ll int,ll int>
#define fori(i,n) for(ll i=0;i<n;i++)
#define forj(j,m) for(ll j=0;j<m;j++)
#define cont(n) {cout<<n<<endl;continue;}
#define MOD 1000000007
#define fast() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define MAXN   100001
#define vecti vector<ll int>
#define vectp vector<pair<ll int,ll int> >
#define pb push_back
map<ll int, ll int> v;
int main() {
     fast();
     ll int t;
     t=1;
     while(t--){
     string s;
     cin>>s;

     ll int minp=s.length();
     ll int mi=0;
     for(ll int i=0;i<s.length();i++){
       ll int a=s[i]-'a';
       v[a]++;
     }
     ll int count=0;
     for(ll int i=0;i<26;i++){
       if(v[i]>1){
         count++;
       }
     }

     for(ll int i=1;i<=26;i++){
       ll int k=0;
       ll int maxt=0;
       for(ll int j=0;j<s.length();j++){
       ll int u=s[j]-'a'+1;
       if(u==i){
          maxt=max(maxt,j-k);
          k=j;
       }
       if(j==s.length()-1&&k!=j){
         maxt=maxt=max(maxt,j-k);
       }
       }
       minp=min(minp,maxt);
     }

     if(count==0){
       cout<<(s.length())/2 +1<<endl;

     }
     else{
     cout<<minp;
     }
      }
       }


#include <bits/stdc++.h>
#include <iostream>
#include<set>
#include<utility>
using namespace std;
#include<algorithm>
#define ll long long
#define M1 1000000007
#define M2 998244353
#define pll pair<ll int,ll int>
#define fori(i,n) for(ll i=0;i<n;i++)
#define forj(j,m) for(ll j=0;j<m;j++)
#define cont(n) {cout<<n<<endl;continue;}
#define MOD 1000000007
#define fast() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define MAXN   100001
#define vecti vector<ll int>
#define vectp vector<pair<ll int,ll int> >
#define pb push_back
map<ll int, ll int> v;
int main() {
     fast();
     ll int t;
     t=1;
     while(t--){
     string s;
     cin>>s;

     ll int maxt=0;
     ll int maxp=0;
     ll int mi=0;
     for(ll int i=0;i<s.length();i++){
       ll int a=s[i]-'a';
       v[a]++;
     }
     ll int count=0;
     for(ll int i=0;i<26;i++){
       if(v[i]>1){
         count++;
       }
     }
     for(ll int i=0;i<26;i++){
        maxt=max(maxt,v[i]);
        if(maxt>maxp){
            maxp=maxt;
            mi=i;
        }
     }
     ll int j=0;
     ll int ml=0;
     for(ll int i=0;i<s.length();i++){
        ll int u=s[i]-'a';
        if(i==s.length()-1){
          ml=max(ml,i-j);
        }
        if(u==mi){
            ml=max(ml,i-j);
            j=i;
        }

     }
     if(count==0){
       cout<<(s.length()-1)/2 +1<<endl;
     }
     else{
     cout<<ml;
     }
      }
       }


#include <bits/stdc++.h>
#include <iostream>
#include<set>
#include<utility>
using namespace std;
#include<algorithm>
#define ll long long
#define M1 1000000007
#define M2 998244353
#define pll pair<ll int,ll int>
#define fori(i,n) for(ll i=0;i<n;i++)
#define forj(j,m) for(ll j=0;j<m;j++)
#define cont(n) {cout<<n<<endl;continue;}
#define MOD 1000000007
#define fast() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define MAXN   100001
#define vecti vector<ll int>
#define vectp vector<pair<ll int,ll int> >
#define pb push_back
map<ll int, ll int> v;
int main() {
     fast();
     ll int t;
     t=1;
     while(t--){
     string s;
     cin>>s;

     ll int minp=s.length();
     ll int mi=0;
     for(ll int i=0;i<s.length();i++){
       ll int a=s[i]-'a';
       v[a]++;
     }
     ll int count=0;
     for(ll int i=0;i<26;i++){
       if(v[i]>1){
         count++;
       }
     }

     for(ll int i=1;i<=26;i++){
       ll int k=0;
       ll int maxt=0;
       for(ll int j=0;j<s.length();j++){
       ll int u=s[j]-'a'+1;
       if(u==i){
          maxt=max(maxt,j-k);
          k=j;
       }
       if(j==s.length()-1&&k!=j){
         maxt=maxt=max(maxt,j-k);
       }
       }
       minp=min(minp,maxt);
     }

     if(count==0){
       cout<<(s.length()-1)/2 +1<<endl;

     }
     else{
     cout<<minp;
     }
      }
       }


#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    cin>>s;
    int n = s.size();

    int mina;
    if (n%2==0) mina = (n+2)/2;
    else mina = (n+1)/2;

    int diff[26]{0};
    int count[26]{0};
    map<int,vector<int>>m;
    for (int i=0;i<s.size();i++)
    {
        int ind = s[i]-97;
        count[ind]++;
        if (m[ind].size()==0)
        {
            diff[ind]=i+1;
            m[ind].push_back(i+1);
        }
        else
        {
            diff[ind]=max(diff[ind],i+1-m[ind].back());
            m[ind].push_back(i+1);
        }

    }

    for (int i=0;i<26;i++)
    {
        if (diff[i]!=0)
        {
            int val = diff[i];
            int value;
            if (n%val==0)
            value = n/val;
            else
            {
                value = n/val;
                value++;
            }
            if (count[i]>=value)
            mina = min(mina,val);

        }
    }
    cout<<mina<<'\n';
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
string fun(string str)
{
    int i;
    int n = str.length();

    // starting point of current substring.
    int st = 0;

    // length of current substring.
    int currlen;

    // maximum length substring without repeating
    // characters.
    int maxlen = 0;

    // starting index of maximum length substring.
    int start;

    // Hash Map to store last occurrence of each
    // already visited character.
    unordered_map<char, int> pos;

    // Last occurrence of first character is index 0;
    pos[str[0]] = 0;

    for (i = 1; i < n; i++) {

        // If this character is not present in hash,
        // then this is first occurrence of this
        // character, store this in hash.
        if (pos.find(str[i]) == pos.end())
            pos[str[i]] = i;

        else {
            // If this character is present in hash then
            // this character has previous occurrence,
            // check if that occurrence is before or after
            // starting point of current substring.
            if (pos[str[i]] >= st) {

                // find length of current substring and
                // update maxlen and start accordingly.
                currlen = i - st;
                if (maxlen < currlen) {
                    maxlen = currlen;
                    start = st;
                }

                // Next substring will start after the last
                // occurrence of current character to avoid
                // its repetition.
                st = pos[str[i]] + 1;
            }

            // Update last occurrence of
            // current character.
            pos[str[i]] = i;
        }
    }

    // Compare length of last substring with maxlen and
    // update maxlen and start accordingly.
    if (maxlen < i - st) {
        maxlen = i - st;
        start = st;
    }

    // The required longest substring without
    // repeating characters is from str[start]
    // to str[start+maxlen-1].
    return str.substr(start, maxlen);
}
int main()
{
    string s;
    cin>>s;
    int n = s.size();

    int mina;
    if (n%2==0) mina = (n+2)/2;
    else mina = (n+1)/2;

    string t = fun(s);
    int len = t.size();
    mina=min(mina,len);
    cout<<mina;
    /*
    int diff[26]{0};
    int count[26]{0};
    map<int,vector<int>>m;
    for (int i=0;i<s.size();i++)
    {
        int ind = s[i]-97;
        count[ind]++;
        if (m[ind].size()==0)
        {
            diff[ind]=i+1;
            m[ind].push_back(i+1);
        }
        else
        {
            diff[ind]=max(diff[ind],i+1-m[ind].back());
            m[ind].push_back(i+1);
        }

    }
    for (int i=0;i<26;i++)
    {
        if (m[i].size()>0)
        diff[i]=max(diff[i],n+1-m[i].back());
    }

    for (int i=0;i<26;i++)
    {
        if (diff[i]!=0)
        {
            int val = diff[i];
            int value;
            if (n%val==0)
            value = n/val;
            else
            {
                value = n/val;
                value++;
            }
            if (count[i]>=value)
            mina = min(mina,val);

        }
    }
    */
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    cin>>s;
    int n = s.size();

    int mina;
    if (n%2==0) mina = (n+2)/2;
    else mina = (n+1)/2;

    int diff[26]{0};
    int count[26]{0};
    map<int,vector<int>>m;
    for (int i=0;i<s.size();i++)
    {
        int ind = s[i]-97;
        count[ind]++;
        if (m[ind].size()==0)
        {
            diff[ind]=i+1;
            m[ind].push_back(i+1);
        }
        else
        {
            diff[ind]=max(diff[ind],i+1-m[ind].back());
            m[ind].push_back(i+1);
        }

    }
    for (int i=0;i<26;i++)
    {
        if (m[i].size()>0)
        diff[i]=max(diff[i],n+1-m[i].back());
    }

    for (int i=0;i<26;i++)
    {
        if (diff[i]!=0)
        {
            int val = diff[i];
            int value;
            if (n%val==0)
            value = n/val;
            else
            {
                value = n/val;
                value++;
            }
            if (count[i]>=value)
            mina = min(mina,val);

        }
    }
    cout<<mina<<'\n';
    return 0;
}


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

int main()
{
    string s;
    cin>>s;
    int n = s.size();

    int mina;
    if (n%2==0) mina = (n+2)/2;
    else mina = (n+1)/2;

    int diff[26]{0};
    int count[26]{0};
    map<int,vector<int>>m;
    for (int i=0;i<s.size();i++)
    {
        int ind = s[i]-97;
        count[ind]++;
        if (m[ind].size()==0)
        {
            diff[ind]=i+1;
            m[ind].push_back(i+1);
        }
        else
        {
            diff[ind]=max(diff[ind],i+1-m[ind].back());
            m[ind].push_back(i+1);
        }

    }
    for (int i=0;i<26;i++)
    {
        if (m[i].size()>0)
        diff[i]=max(diff[i],n+1-m[i].back());
    }

    for (int i=0;i<26;i++)
    {
        if (diff[i]!=0)
        {
            int val = diff[i];
            int value;
            value = n/val;
            if (count[i]>=value)
            mina = min(mina,val);

        }
    }

    cout<<mina;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
string fun(string str)
{
    int i;
    int n = str.length();

    // starting point of current substring.
    int st = 0;

    // length of current substring.
    int currlen;

    // maximum length substring without repeating
    // characters.
    int maxlen = 0;

    // starting index of maximum length substring.
    int start;

    // Hash Map to store last occurrence of each
    // already visited character.
    unordered_map<char, int> pos;

    // Last occurrence of first character is index 0;
    pos[str[0]] = 0;

    for (i = 1; i < n; i++) {

        // If this character is not present in hash,
        // then this is first occurrence of this
        // character, store this in hash.
        if (pos.find(str[i]) == pos.end())
            pos[str[i]] = i;

        else {
            // If this character is present in hash then
            // this character has previous occurrence,
            // check if that occurrence is before or after
            // starting point of current substring.
            if (pos[str[i]] >= st) {

                // find length of current substring and
                // update maxlen and start accordingly.
                currlen = i - st;
                if (maxlen < currlen) {
                    maxlen = currlen;
                    start = st;
                }

                // Next substring will start after the last
                // occurrence of current character to avoid
                // its repetition.
                st = pos[str[i]] + 1;
            }

            // Update last occurrence of
            // current character.
            pos[str[i]] = i;
        }
    }

    // Compare length of last substring with maxlen and
    // update maxlen and start accordingly.
    if (maxlen < i - st) {
        maxlen = i - st;
        start = st;
    }

    // The required longest substring without
    // repeating characters is from str[start]
    // to str[start+maxlen-1].
    return str.substr(start, maxlen);
}
int main()
{
    string s;
    cin>>s;
    int n = s.size();

    int mina;
    if (n%2==0) mina = (n+2)/2;
    else mina = (n+1)/2;

    string t = fun(s);
    int len = t.size();

    int diff[26]{0};
    int count[26]{0};
    map<int,vector<int>>m;
    for (int i=0;i<s.size();i++)
    {
        int ind = s[i]-97;
        count[ind]++;
        if (m[ind].size()==0)
        {
            diff[ind]=i+1;
            m[ind].push_back(i+1);
        }
        else
        {
            diff[ind]=max(diff[ind],i+1-m[ind].back());
            m[ind].push_back(i+1);
        }

    }
    for (int i=0;i<26;i++)
    {
        if (m[i].size()>0)
        diff[i]=max(diff[i],n+1-m[i].back());
    }

    for (int i=0;i<26;i++)
    {
        if (diff[i]!=0)
        {
            int val = diff[i];
            int value;
            if (n%val==0)
            value = n/val;
            else
            {
                value = n/val;
                value++;
            }
            if (count[i]>=value)
            mina = min(mina,val);

        }
    }
    mina = min(mina,len);
    cout<<mina;
    return 0;
}


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

int main()
{
    string s;
    cin>>s;
    int n = s.size();

    int mina;
    if (n%2==0) mina = (n+2)/2;
    else mina = (n+1)/2;

    int diff[26]{0};
    int count[26]{0};
    map<int,vector<int>>m;
    for (int i=0;i<s.size();i++)
    {
        int ind = s[i]-97;
        count[ind]++;
        if (m[ind].size()==0)
        {
            diff[ind]=i+1;
            m[ind].push_back(i+1);
        }
        else
        {
            diff[ind]=max(diff[ind],i+1-m[ind].back());
            m[ind].push_back(i+1);
        }

    }
    for (int i=0;i<26;i++)
    {
        if (m[i].size()>0)
        diff[i]=max(diff[i],n+1-m[i].back());
    }

    for (int i=0;i<26;i++)
    {
        if (diff[i]!=0)
        {
            int val = diff[i];
            int value;
            if (n%val==0)
            value = n/val;
            else
            {
                value = n/val;
                value++;
            }
            if (count[i]>=value)
            mina = min(mina,val);

        }
    }

    cout<<mina;
    return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
std::string s;
std::vector<int> f(26,0);
std::vector<int> l(26,0);
std::vector<int> e(26,0);
std::cin>>s;
int sz=s.size();
for (int i=0;i<s.size();i++)
    {
    f[static_cast<int>(s[i]-'a')]=std::max(i-l[static_cast<int>(s[i]-'a')],f[static_cast<int>(s[i]-'a')]);
    e[static_cast<int>(s[i]-'a')]=sz-i;
    l[static_cast<int>(s[i]-'a')]=i;
    }

int ret=1000000;

bool flag=true;
for (int i=0;i<26;i++)
    {
    if (l[i]!=f[i])
        {
        flag=false;
        break;
        }
    }
if (flag==true)
    {
    ret=1+(s.size()>>1);
    }
else
{
    for (int i=0;i<26;i++)
    {
    f[i]=std::max(f[i],e[i]);
    }
    for (auto x:f)
        {
        ret=(x!=0)?std::min(ret,x):ret;
        }

}

std::cout<<ret<<std::endl;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
std::string s;
std::vector<int> f(26,0);
std::vector<int> l(26,0);
std::vector<int> e(26,0);
std::vector<int> b(26,-1);
std::cin>>s;
int sz=s.size();
for (int i=0;i<s.size();i++)
    {
    f[static_cast<int>(s[i]-'a')]=std::max(i-l[static_cast<int>(s[i]-'a')],f[static_cast<int>(s[i]-'a')]);
    e[static_cast<int>(s[i]-'a')]=sz-i;
    if (b[static_cast<int>(s[i]-'a')]==-1)
        {
        b[static_cast<int>(s[i]-'a')]=i+1;
        }
    l[static_cast<int>(s[i]-'a')]=i;
    }

int ret=1000000;

bool flag=true;
for (int i=0;i<26;i++)
    {
    if (l[i]!=f[i])
        {
        flag=false;
        break;
        }
    }
if (flag==true)
    {
    ret=1+(s.size()>>1);
    }
else
{
    for (int i=0;i<26;i++)
    {
    f[i]=std::max(f[i],e[i]);
    f[i]=std::max(f[i],b[i]);
    }
    for (auto x:f)
        {
        ret=(x!=0)?std::min(ret,x):ret;
        }

}

std::cout<<ret<<std::endl;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
std::string s;
std::vector<int> f(26,0);
std::vector<int> l(26,0);
std::cin>>s;
for (int i=0;i<s.size();i++)
    {
    f[static_cast<int>(s[i]-'a')]=std::max(i-l[static_cast<int>(s[i]-'a')],f[static_cast<int>(s[i]-'a')]);
    l[static_cast<int>(s[i]-'a')]=i;
    }
int ret=1000000;

for (auto x:f)
    {
    ret=(x!=0)?std::min(ret,x):ret;
    }
bool flag=true;
for (int i=0;i<s.size();i++)
    {
    if (l[i]!=f[i])
        {
        flag=false;
        break;
        }
    }
if (flag==true)
    {
    ret=1+(s.size()>>1);
    }

std::cout<<ret<<std::endl;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
std::string s;
std::vector<int> f(26,0);
std::vector<int> l(26,0);
std::cin>>s;
for (int i=0;i<s.size();i++)
    {
    f[static_cast<int>(s[i]-'a')]=std::max(i-l[static_cast<int>(s[i]-'a')],f[static_cast<int>(s[i]-'a')]);
    l[static_cast<int>(s[i]-'a')]=i;
    }
int ret=1000000;

for (auto x:f)
    {
    ret=(x!=0)?std::min(ret,x):ret;
    }
bool flag=true;
for (int i=0;i<26;i++)
    {
    if (l[i]!=f[i])
        {
        flag=false;
        break;
        }
    }
if (flag==true)
    {
    ret=1+(s.size()>>1);
    }

std::cout<<ret<<std::endl;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
std::string s;
std::vector<int> f(26,0);
std::vector<int> l(26,0);
std::vector<int> e(26,0);
std::vector<int> b(26,-1);
std::cin>>s;
int sz=s.size();
for (int i=0;i<s.size();i++)
    {
    f[static_cast<int>(s[i]-'a')]=std::max(i-l[static_cast<int>(s[i]-'a')],f[static_cast<int>(s[i]-'a')]);
    e[static_cast<int>(s[i]-'a')]=sz-i;
    if (b[static_cast<int>(s[i]-'a')]==-1)
        {
        b[static_cast<int>(s[i]-'a')]=i+1;
        }
    l[static_cast<int>(s[i]-'a')]=i;
    }

int ret=1000000;

bool flag=true;
for (int i=0;i<26;i++)
    {
    if ((e[i]-1)!=f[i])
        {
        flag=false;
        break;
        }
    }
if (flag==true)
    {
    ret=1+(s.size()>>1);
    }
else
{
    for (int i=0;i<26;i++)
    {
    f[i]=std::max(f[i],e[i]);
    f[i]=std::max(f[i],b[i]);
    }
    for (auto x:f)
        {
        ret=(x!=0)?std::min(ret,x):ret;
        }

}

std::cout<<ret<<std::endl;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
std::string s;
std::vector<int> f(26,0);
std::vector<int> l(26,0);
std::vector<int> e(26,0);
std::cin>>s;
int sz=s.size();
for (int i=0;i<s.size();i++)
    {
    f[static_cast<int>(s[i]-'a')]=std::max(i-l[static_cast<int>(s[i]-'a')],f[static_cast<int>(s[i]-'a')]);
    e[static_cast<int>(s[i]-'a')]=sz-i;
    l[static_cast<int>(s[i]-'a')]=i;
    }
for (int i=0;i<26;i++)
{
f[i]=std::max(f[i],e[i]);
}

int ret=1000000;

for (auto x:f)
    {
    ret=(x!=0)?std::min(ret,x):ret;
    }
bool flag=true;
for (int i=0;i<26;i++)
    {
    if (l[i]!=f[i])
        {
        flag=false;
        break;
        }
    }
if (flag==true)
    {
    ret=1+(s.size()>>1);
    }

std::cout<<ret<<std::endl;
}


#include <bits/stdc++.h>
#include<map>
#include<vector>
#include<set>
#define ll long long
#define se second
using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  ll t,a,b,c,d=0,n,m,k=0,sum=0,i,j;

     ll prv,val;
    string str;
    cin>>str;
     ll dp[26]{};
     n=str.size();
     map<char,vector<ll>>mp;
    for(i=0;i<n;i++)
    {
    	mp[str[i]].push_back(i);
	}
	 ll ans = n;
  for (auto p: mp) {
      val = 0;
      prv = -1;
    for (auto k: p.se)
	{
      val = max(val, k - prv);
      prv = k;
    }
    val = max(val, n - prv);
    ans = min(ans, val);
  }
  cout << ans << "\n";

  return 0;
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ll  long long
#define PI  acos(-1)
#define pb  push_back
#define ins insert
#define INF 5000000000000000007 //1e18+7
#define mk  make_pair
#define lb(v,x) lower_bound(all(v),x)
#define ub(v,x)  upper_bound(all(v),x)
#define ff  first
#define ss  second
#define rev reverse
#define endl "\n"
#define max3(x,y,z)  max(x,max(y,z))
#define min3(x,y,z)  min(x,min(y,z))
#define sz(a) (ll)a.size()
#define double long double
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define mset(x,y)  memset(x,y,sizeof(x))
#define all(x)   (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define bp(n)  __builtin_popcountll(n)
#define mxt(a)  *(max_element(a.begin(),a.end()))
#define mnt(a)  *(min_element(a.begin(),a.end()))
#define unique_sort(c) (sort(all(c)), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define rep(i,a,b) for(ll i=(a);i<=(b);++i)
#define trav(a, x)    for(auto &a : x)
#define re(i,n)       for(ll i=0;i<n;++i)
#define int2Bin(x,y)  bitset <y> z=x; cout<<z.to_string()<<endl;
const double eps=1e-7;
const string alpha = "abcdefghijklmnopqrstuvwxyz";
// int dx[8]={+1, +1, +1, 0, 0, -1, -1, -1};
// int dy[8]={+1, 0, -1, +1, -1, +1, 0, -1};
int dx[4]={1, 0, 0, -1};
int dy[4]={0, -1, 1, 0};
ll power(ll x,ll y){ll ans=1;x=x;while(y>0){if(y&1)ans=(ans*x);y=y>>1;x=(x*x);}return ans;}
ll sqr(ll x) { return x * x;}
template <typename T> T gcd(T a,T b){ if(a==0) return b; return gcd(b%a,a); }
template <class T> inline void chmax(T &x,T y){ x = max((x), (y));}
template <class T> inline void chmin(T &x,T y){ x = min((x), (y));}
template <class T> T abs(T x) { return x>0 ? x : -x;}
template <typename T> T powm(T a,T b, ll m){T cnt=1; while(b>0){ if(b%2==1) cnt=(cnt*a)%m; b/=2; a=(a*a)%m; }return cnt%m;}
typedef pair<int,int>  pii;
typedef pair<ll,ll>  pll;
typedef vector<pll>  vpll;
typedef vector<pii>  vpii;
typedef vector<ll>   vll;
typedef vector<int>  vii;
#define minpq priority_queue<T,vector<T>,greater<T> >;
// #define T int
// #define ordered_set tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>
//*X.find_by_order(k) returns the kth largest element (0-based).
//X.order_of_key(val) returns the no. of values less than val.
ll ncr(ll n,ll r){ll ans=1;if(r>n)return 0;if(r>n-r)r=n-r;for(ll i=0;i<r;i++){ans*=(n-i);ans/=(i+1);}return ans;}
const int MOD=1000000007;
const int N=40005;
struct compare{
    bool operator() (const int &a,const int &b) const{
        return a>b;
    }
};
void prec(){

}
ll par[N],ans;
int root(int v){
    return par[v]<0?v:(par[v] = root(par[v]));
}
void merge(int x,int y){
    if((x = root(x)) == (y = root(y)))  return;
    if(par[y]<par[x]) swap(x, y);
    par[x]+=par[y];
    par[y]=x;
}
void run(){
    mset(par,-1);
    int n;cin>>n;
    rep(i,1,n) {
        int x;cin>>x;
        merge(x,i);
    }
    int mx2=0,mx1=0;
    for(int i=1; i<=n; ++i) {
        if(par[i]>=0) continue;
        int siz=-1*par[i];
        ans+=1ll*siz*siz;
        if(siz>mx1) {
            mx2=mx1;
            mx1=siz;
        }else {
            chmax(mx2,siz);
        }
    }
    ans+=2ll*mx1*mx2;
    cout<<ans;
}
int32_t main(){
    cin.sync_with_stdio(0);cin.tie(0);
    cin.exceptions(cin.failbit);
    int tc=1;
    //cin>>tc;
    prec();
    re(i,tc)
        run();
    return 0;
}
/*
    stuff you should look for
    * int overflow,array bounds.
    * special cases (n=1?).
    * N,MOD value.
*/


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ll  long long
#define PI  acos(-1)
#define pb  push_back
#define ins insert
#define INF 5000000000000000007 //1e18+7
#define mk  make_pair
#define lb(v,x) lower_bound(all(v),x)
#define ub(v,x)  upper_bound(all(v),x)
#define ff  first
#define ss  second
#define rev reverse
#define endl "\n"
#define max3(x,y,z)  max(x,max(y,z))
#define min3(x,y,z)  min(x,min(y,z))
#define sz(a) (ll)a.size()
#define double long double
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define mset(x,y)  memset(x,y,sizeof(x))
#define all(x)   (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define bp(n)  __builtin_popcountll(n)
#define mxt(a)  *(max_element(a.begin(),a.end()))
#define mnt(a)  *(min_element(a.begin(),a.end()))
#define unique_sort(c) (sort(all(c)), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define rep(i,a,b) for(ll i=(a);i<=(b);++i)
#define trav(a, x)    for(auto &a : x)
#define re(i,n)       for(ll i=0;i<n;++i)
#define int2Bin(x,y)  bitset <y> z=x; cout<<z.to_string()<<endl;
const double eps=1e-7;
const string alpha = "abcdefghijklmnopqrstuvwxyz";
// int dx[8]={+1, +1, +1, 0, 0, -1, -1, -1};
// int dy[8]={+1, 0, -1, +1, -1, +1, 0, -1};
int dx[4]={1, 0, 0, -1};
int dy[4]={0, -1, 1, 0};
ll power(ll x,ll y){ll ans=1;x=x;while(y>0){if(y&1)ans=(ans*x);y=y>>1;x=(x*x);}return ans;}
ll sqr(ll x) { return x * x;}
template <typename T> T gcd(T a,T b){ if(a==0) return b; return gcd(b%a,a); }
template <class T> inline void chmax(T &x,T y){ x = max((x), (y));}
template <class T> inline void chmin(T &x,T y){ x = min((x), (y));}
template <class T> T abs(T x) { return x>0 ? x : -x;}
template <typename T> T powm(T a,T b, ll m){T cnt=1; while(b>0){ if(b%2==1) cnt=(cnt*a)%m; b/=2; a=(a*a)%m; }return cnt%m;}
typedef pair<int,int>  pii;
typedef pair<ll,ll>  pll;
typedef vector<pll>  vpll;
typedef vector<pii>  vpii;
typedef vector<ll>   vll;
typedef vector<int>  vii;
#define minpq priority_queue<T,vector<T>,greater<T> >;
// #define T int
// #define ordered_set tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>
//*X.find_by_order(k) returns the kth largest element (0-based).
//X.order_of_key(val) returns the no. of values less than val.
ll ncr(ll n,ll r){ll ans=1;if(r>n)return 0;if(r>n-r)r=n-r;for(ll i=0;i<r;i++){ans*=(n-i);ans/=(i+1);}return ans;}
const int MOD=1000000007;
const int N=100005;
struct compare{
    bool operator() (const int &a,const int &b) const{
        return a>b;
    }
};
void prec(){

}
ll par[N],ans;
int root(int v){
    return par[v]<0?v:(par[v] = root(par[v]));
}
void merge(int x,int y){
    if((x = root(x)) == (y = root(y)))  return;
    if(par[y]<par[x]) swap(x, y);
    par[x]+=par[y];
    par[y]=x;
}
void run(){
    mset(par,-1);
    int n;cin>>n;
    rep(i,1,n) {
        int x;cin>>x;
        merge(x,i);
    }
    int mx2=0,mx1=0;
    for(int i=1; i<=n; ++i) {
        if(par[i]>=0) continue;
        int siz=-1*par[i];
        ans+=1ll*siz*siz;
        if(siz>mx1) {
            mx2=mx1;
            mx1=siz;
        }else {
            chmax(mx2,siz);
        }
    }
    ans+=2ll*mx1*mx2;
    cout<<ans;
}
int32_t main(){
    cin.sync_with_stdio(0);cin.tie(0);
    cin.exceptions(cin.failbit);
    int tc=1;
    //cin>>tc;
    prec();
    re(i,tc)
        run();
    return 0;
}
/*
    stuff you should look for
    * int overflow,array bounds.
    * special cases (n=1?).
    * N,MOD value.
*/


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ll  long long
#define PI  acos(-1)
#define pb  push_back
#define ins insert
#define INF 5000000000000000007 //1e18+7
#define mk  make_pair
#define lb(v,x) lower_bound(all(v),x)
#define ub(v,x)  upper_bound(all(v),x)
#define ff  first
#define ss  second
#define rev reverse
#define endl "\n"
#define max3(x,y,z)  max(x,max(y,z))
#define min3(x,y,z)  min(x,min(y,z))
#define sz(a) (ll)a.size()
#define double long double
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define mset(x,y)  memset(x,y,sizeof(x))
#define all(x)   (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define bp(n)  __builtin_popcountll(n)
#define mxt(a)  *(max_element(a.begin(),a.end()))
#define mnt(a)  *(min_element(a.begin(),a.end()))
#define unique_sort(c) (sort(all(c)), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define rep(i,a,b) for(ll i=(a);i<=(b);++i)
#define trav(a, x)    for(auto &a : x)
#define re(i,n)       for(ll i=0;i<n;++i)
#define int2Bin(x,y)  bitset <y> z=x; cout<<z.to_string()<<endl;
const double eps=1e-7;
const string alpha = "abcdefghijklmnopqrstuvwxyz";
// int dx[8]={+1, +1, +1, 0, 0, -1, -1, -1};
// int dy[8]={+1, 0, -1, +1, -1, +1, 0, -1};
int dx[4]={1, 0, 0, -1};
int dy[4]={0, -1, 1, 0};
ll power(ll x,ll y){ll ans=1;x=x;while(y>0){if(y&1)ans=(ans*x);y=y>>1;x=(x*x);}return ans;}
ll sqr(ll x) { return x * x;}
template <typename T> T gcd(T a,T b){ if(a==0) return b; return gcd(b%a,a); }
template <class T> inline void chmax(T &x,T y){ x = max((x), (y));}
template <class T> inline void chmin(T &x,T y){ x = min((x), (y));}
template <class T> T abs(T x) { return x>0 ? x : -x;}
template <typename T> T powm(T a,T b, ll m){T cnt=1; while(b>0){ if(b%2==1) cnt=(cnt*a)%m; b/=2; a=(a*a)%m; }return cnt%m;}
typedef pair<int,int>  pii;
typedef pair<ll,ll>  pll;
typedef vector<pll>  vpll;
typedef vector<pii>  vpii;
typedef vector<ll>   vll;
typedef vector<int>  vii;
#define minpq priority_queue<T,vector<T>,greater<T> >;
// #define T int
// #define ordered_set tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>
//*X.find_by_order(k) returns the kth largest element (0-based).
//X.order_of_key(val) returns the no. of values less than val.
ll ncr(ll n,ll r){ll ans=1;if(r>n)return 0;if(r>n-r)r=n-r;for(ll i=0;i<r;i++){ans*=(n-i);ans/=(i+1);}return ans;}
const int MOD=1000000007;
const int N=40005;
struct compare{
    bool operator() (const int &a,const int &b) const{
        return a>b;
    }
};
void prec(){

}
ll par[N],ans;
int root(int v){
    return par[v]<0?v:(par[v] = root(par[v]));
}
void merge(int x,int y){
    if((x = root(x)) == (y = root(y)))  return;
    if(par[y]<par[x]) swap(x, y);
    par[x]+=par[y];
    par[y]=x;
}
void run(){
    mset(par,-1);
    int n;cin>>n;
    rep(i,1,n) {
        int x;cin>>x;
        merge(x,i);
    }
    int mx2=-100,mx1=-100;
    for(int i=1; i<=n; ++i) {
        if(par[i]>=0) continue;
        int siz=-1*par[i];
        ans+=1ll*siz*siz;
        if(siz>mx1) {
            mx2=mx1;
            mx1=siz;
        }else {
            chmax(mx2,siz);
        }
    }
    ans+=1ll*mx1*mx2;
    cout<<ans;
}
int32_t main(){
    cin.sync_with_stdio(0);cin.tie(0);
    cin.exceptions(cin.failbit);
    int tc=1;
    //cin>>tc;
    prec();
    re(i,tc)
        run();
    return 0;
}
/*
    stuff you should look for
    * int overflow,array bounds.
    * special cases (n=1?).
    * N,MOD value.
*/


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define ll  long long
#define PI  acos(-1)
#define pb  push_back
#define ins insert
#define INF 5000000000000000007 //1e18+7
#define mk  make_pair
#define lb(v,x) lower_bound(all(v),x)
#define ub(v,x)  upper_bound(all(v),x)
#define ff  first
#define ss  second
#define rev reverse
#define endl "\n"
#define max3(x,y,z)  max(x,max(y,z))
#define min3(x,y,z)  min(x,min(y,z))
#define sz(a) (ll)a.size()
#define double long double
#define coud(a,b) cout<<fixed << setprecision((b)) << (a)
#define mset(x,y)  memset(x,y,sizeof(x))
#define all(x)   (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define bp(n)  __builtin_popcountll(n)
#define mxt(a)  *(max_element(a.begin(),a.end()))
#define mnt(a)  *(min_element(a.begin(),a.end()))
#define unique_sort(c) (sort(all(c)), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define rep(i,a,b) for(ll i=(a);i<=(b);++i)
#define trav(a, x)    for(auto &a : x)
#define re(i,n)       for(ll i=0;i<n;++i)
#define int2Bin(x,y)  bitset <y> z=x; cout<<z.to_string()<<endl;
const double eps=1e-7;
const string alpha = "abcdefghijklmnopqrstuvwxyz";
// int dx[8]={+1, +1, +1, 0, 0, -1, -1, -1};
// int dy[8]={+1, 0, -1, +1, -1, +1, 0, -1};
int dx[4]={1, 0, 0, -1};
int dy[4]={0, -1, 1, 0};
ll power(ll x,ll y){ll ans=1;x=x;while(y>0){if(y&1)ans=(ans*x);y=y>>1;x=(x*x);}return ans;}
ll sqr(ll x) { return x * x;}
template <typename T> T gcd(T a,T b){ if(a==0) return b; return gcd(b%a,a); }
template <class T> inline void chmax(T &x,T y){ x = max((x), (y));}
template <class T> inline void chmin(T &x,T y){ x = min((x), (y));}
template <class T> T abs(T x) { return x>0 ? x : -x;}
template <typename T> T powm(T a,T b, ll m){T cnt=1; while(b>0){ if(b%2==1) cnt=(cnt*a)%m; b/=2; a=(a*a)%m; }return cnt%m;}
typedef pair<int,int>  pii;
typedef pair<ll,ll>  pll;
typedef vector<pll>  vpll;
typedef vector<pii>  vpii;
typedef vector<ll>   vll;
typedef vector<int>  vii;
#define minpq priority_queue<T,vector<T>,greater<T> >;
// #define T int
// #define ordered_set tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>
//*X.find_by_order(k) returns the kth largest element (0-based).
//X.order_of_key(val) returns the no. of values less than val.
ll ncr(ll n,ll r){ll ans=1;if(r>n)return 0;if(r>n-r)r=n-r;for(ll i=0;i<r;i++){ans*=(n-i);ans/=(i+1);}return ans;}
const int MOD=1000000007;
const int N=40005;
struct compare{
    bool operator() (const int &a,const int &b) const{
        return a>b;
    }
};
void prec(){

}
ll par[N],ans;
int root(int v){
    return par[v]<0?v:(par[v] = root(par[v]));
}
void merge(int x,int y){
    if((x = root(x)) == (y = root(y)))  return;
    if(par[y]<par[x]) swap(x, y);
    par[x]+=par[y];
    par[y]=x;
}
void run(){
    mset(par,-1);
    int n;cin>>n;
    rep(i,1,n) {
        int x;cin>>x;
        merge(x,i);
    }
    int mx2=-100,mx1=-100;
    for(int i=1; i<=n; ++i) {
        if(par[i]>=0) continue;
        int siz=-1*par[i];
        ans+=1ll*siz*siz;
        if(siz>mx1) {
            mx2=mx1;
            mx1=siz;
        }else {
            chmax(mx2,siz);
        }
    }
    ans+=2ll*mx1*mx2;
    cout<<ans;
}
int32_t main(){
    cin.sync_with_stdio(0);cin.tie(0);
    cin.exceptions(cin.failbit);
    int tc=1;
    //cin>>tc;
    prec();
    re(i,tc)
        run();
    return 0;
}
/*
    stuff you should look for
    * int overflow,array bounds.
    * special cases (n=1?).
    * N,MOD value.
*/


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxc = 1e5+5;
ll a[maxc],b[maxc];
ll c=0;
ll vis[maxc];
vector<ll> s;

ll dfs(ll n)
{
  vis[n] = 1;
  c++;
  if(!vis[a[n]])
    dfs(a[n]);
  if(!vis[b[n]] && b[n]!=-1)
    dfs(b[n]);
}

int main(){
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ll n;
  cin>>n;
  for(ll i=1;i<=n;i++)
    {
      cin>>a[i];
      b[a[i]]=i;
    }

  memset(vis,0,sizeof vis);

  for(ll i=1;i<=n;i++)
    {
      if(!vis[i])
	{

	  s.push_back(c);
	  c=0;
	  dfs(i);
	}
    }

    s.push_back(c);
  sort(s.begin() , s.end() , greater<ll>());

  ll ans=0;
  s[1] += s[0];
  for(ll i = 1;i<s.size();i++)
    {
      ans += (ll) s[i] * s[i];
    }

  cout<<ans<<endl;
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxc = 1e5+5;
ll a[maxc],b[maxc];
ll c=0;
ll vis[maxc];
vector<ll> s;

ll dfs(ll n)
{
  vis[n] = 1;
  c++;
  if(!vis[a[n]])
    dfs(a[n]);
  if(!vis[b[n]] && b[n]!=-1)
    dfs(b[n]);
}

int main(){
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ll n;
  cin>>n;
  for(ll i=1;i<=n;i++)
    {
      cin>>a[i];
      b[a[i]]=i;
    }

  memset(vis,0,sizeof vis);

  for(ll i=1;i<=n;i++)
    {
      if(!vis[i])
	{
	  dfs(i);
	  s.push_back(c);
	  c=0;
	}
    }

  sort(s.begin() , s.end() , greater<ll>());

  ll ans=0;
  s[1] += s[0];
  for(ll i = 1;i<s.size();i++)
    {
      ans += (ll) s[i] * s[i];
    }

  cout<<ans<<endl;
  return 0;
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#define _USE_MATH_DEFINES
#include<cmath>
#include<math.h>
#include<bits/stdc++.h>
#include<unordered_map>
#include<queue>
using namespace std;
//typedefs
typedef long long  ll;
typedef pair<int,int> pr;
typedef vector<int> vi;
typedef unsigned long long  ull;
//macros
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define  SR 100000
#define llp(i,a,b) for(i=a;i<b;i++)
#define llpr(i,a,b) for(i=a;i>b;i--)
#define lp(n) for(int i=0;i<n;i++)
#define setp(x,y) fixed<<setprecision(x)<<y
#define oo 1000000000
// #define endll '\n'
void solve();

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE

    // For getting input from input.txt file
    freopen("input.txt", "r", stdin);

    // Printing the Output to output.txt file
    freopen("output.txt", "w", stdout);
#endif
    solve();
    return 0;
}

vi parent(SR+1);
vi ans(SR+1,1);
int findAncestor(int a)
{
    if(parent[a]!=a) parent[a]=findAncestor(parent[a]);
    return parent[a];
}
void solve()
{
    int n;
    cin>>n;
    int i;
    llp(i,1,n+1) parent[i]=i;
    llp(i,1,n+1)
    {
        int v;
        cin>>v;
        if(findAncestor(i)!=findAncestor(v))
        {
            parent[findAncestor(v)]=findAncestor(i);
            ans[findAncestor(i)]+=ans[findAncestor(v)];
        }
    }
    vi vals;
    llp(i,1,n+1)
    {
        if(parent[i]==i) vals.PB(ans[i]);
    }
    sort(vals.begin(),vals.end());
    int f=0,s=0;
    if(vals.size()>=2)
    {
            f=vals[vals.size()-1];
            s=vals[vals.size()-2];
    }

    int count=0;
    count+=(f+s)*(f+s);
    llp(i,0,vals.size()-2) count+=vals[i]*vals[i];
    cout<<count;
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#define _USE_MATH_DEFINES
#include<cmath>
#include<math.h>
#include<bits/stdc++.h>
#include<unordered_map>
#include<queue>
using namespace std;
//typedefs
typedef long long  ll;
typedef pair<int,int> pr;
typedef vector<int> vi;
typedef unsigned long long  ull;
//macros
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define  SR 100000
#define llp(i,a,b) for(i=a;i<b;i++)
#define llpr(i,a,b) for(i=a;i>b;i--)
#define lp(n) for(int i=0;i<n;i++)
#define setp(x,y) fixed<<setprecision(x)<<y
#define oo 1000000000
// #define endll '\n'
void solve();

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE

    // For getting input from input.txt file
    freopen("input.txt", "r", stdin);

    // Printing the Output to output.txt file
    freopen("output.txt", "w", stdout);
#endif
    solve();
    return 0;
}

vi parent(SR+1);
vi ans(SR+1,1);
int findAncestor(int a)
{
    if(parent[a]!=a) parent[a]=findAncestor(parent[a]);
    return parent[a];
}
void solve()
{
    int n;
    cin>>n;
    int i;
    llp(i,1,n+1) parent[i]=i;
    llp(i,1,n+1)
    {
        int v;
        cin>>v;
        if(findAncestor(i)!=findAncestor(v))
        {
            ans[findAncestor(i)]+=ans[findAncestor(v)];
            parent[findAncestor(v)]=findAncestor(i);
        }
    }
    vector<ll> vals;
    llp(i,1,n+1)
    {
        if(parent[i]==i) vals.PB(ans[i]);
    }
    sort(vals.begin(),vals.end());
    ll count=0;
    ll f=0,s=0;
    if(vals.size()>=2)
    {
    f=vals[vals.size()-1];
    s=vals[vals.size()-2];
    count+=(f+s)*(f+s);
    llp(i,0,vals.size()-2) count+=vals[i]*vals[i];
    cout<<count;
    }
    else
    {
            llp(i,0,vals.size()) count+=vals[i]*vals[i];
            cout<<count;
    }

}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#define _USE_MATH_DEFINES
#include<cmath>
#include<math.h>
#include<bits/stdc++.h>
#include<unordered_map>
#include<queue>
using namespace std;
//typedefs
typedef long long  ll;
typedef pair<int,int> pr;
typedef vector<int> vi;
typedef unsigned long long  ull;
//macros
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define  SR 100000
#define llp(i,a,b) for(i=a;i<b;i++)
#define llpr(i,a,b) for(i=a;i>b;i--)
#define lp(n) for(int i=0;i<n;i++)
#define setp(x,y) fixed<<setprecision(x)<<y
#define oo 1000000000
// #define endll '\n'
void solve();

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE

    // For getting input from input.txt file
    freopen("input.txt", "r", stdin);

    // Printing the Output to output.txt file
    freopen("output.txt", "w", stdout);
#endif
    solve();
    return 0;
}

vi parent(SR+1);
vi ans(SR+1,1);
int findAncestor(int a)
{
    if(parent[a]!=a) parent[a]=findAncestor(parent[a]);
    return parent[a];
}
void solve()
{
    int n;
    cin>>n;
    int i;
    llp(i,1,n+1) parent[i]=i;
    llp(i,1,n+1)
    {
        int v;
        cin>>v;
        if(findAncestor(i)!=findAncestor(v))
        {
            parent[findAncestor(v)]=findAncestor(i);
            ans[findAncestor(i)]+=ans[findAncestor(v)];
        }
    }
    vector<ll> vals;
    llp(i,1,n+1)
    {
        if(parent[i]==i) vals.PB(ans[i]);
    }
    sort(vals.begin(),vals.end());
    ll f=0,s=0;
    if(vals.size()>=2)
    {
            f=vals[vals.size()-1];
            s=vals[vals.size()-2];
    }

    ll count=0;
    count+=(f+s)*(f+s);
    llp(i,0,vals.size()-2) count+=vals[i]*vals[i];
    cout<<count;
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#define _USE_MATH_DEFINES
#include<cmath>
#include<math.h>
#include<bits/stdc++.h>
#include<unordered_map>
#include<queue>
using namespace std;
//typedefs
typedef long long  ll;
typedef pair<int,int> pr;
typedef vector<int> vi;
typedef unsigned long long  ull;
//macros
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define  SR 100000
#define llp(i,a,b) for(i=a;i<b;i++)
#define llpr(i,a,b) for(i=a;i>b;i--)
#define lp(n) for(int i=0;i<n;i++)
#define setp(x,y) fixed<<setprecision(x)<<y
#define oo 1000000000
// #define endll '\n'
void solve();

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE

    // For getting input from input.txt file
    freopen("input.txt", "r", stdin);

    // Printing the Output to output.txt file
    freopen("output.txt", "w", stdout);
#endif
    solve();
    return 0;
}

vi parent(SR+1);
vi ans(SR+1,1);
int findAncestor(int a)
{
    if(parent[a]!=a) parent[a]=findAncestor(parent[a]);
    return parent[a];
}
void solve()
{
    int n;
    cin>>n;
    int i;
    llp(i,1,n+1) parent[i]=i;
    llp(i,1,n+1)
    {
        int v;
        cin>>v;
        if(findAncestor(i)!=findAncestor(v))
        {
            parent[findAncestor(v)]=findAncestor(i);
            ans[findAncestor(i)]+=ans[findAncestor(v)];
        }
    }
    vector<ll> vals;
    llp(i,1,n+1)
    {
        if(parent[i]==i) vals.PB(ans[i]);
    }
    sort(vals.begin(),vals.end());
    ll count=0;
    ll f=0,s=0;
    if(vals.size()>=2)
    {
    f=vals[vals.size()-1];
    s=vals[vals.size()-2];
    count+=(f+s)*(f+s);
    llp(i,0,vals.size()-2) count+=vals[i]*vals[i];
    cout<<count;
    }
    else
    {
            llp(i,0,vals.size()) count+=vals[i]*vals[i];
            cout<<count;
    }

}


#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
#define PB push_back
#define MP make_pair
using namespace std;
bool sortinrev(const pair<int,int> &a,
               const pair<int,int> &b)
{
       return (a.first > b.first);
}
int main()
{
  ll int n;
  cin>>n;

  ll int a[n+1];ll int i;
  for(i=1;i<=n;i++)
  {
      cin>>a[i];
  }
  if(n==1)
  {
      cout<<"1\n";
      exit(0);
  }
  ll int k=1;
  ll int count=0;
  ll int f[n+1]={0};
  ll int size[n+1]={0};
  i=1;ll int fl=0;
  while(1)
  {//cout<<count<<" "<<i<<" "<<k<<endl;
      if(count==n)
      break;
      if(a[i]==i)
      {//cout<<i<<endl;
          f[a[i]]=k;
          count++;
           size[k]++;
          if(count<n)
          k++;

          i++;
      }
      else if(f[a[i]]==0)
      {//cout<<i<<endl;
          f[a[i]]=k;
          count++;
          i=a[i];
          size[k]++;
          fl=1;
      }
      else if(f[a[i]]!=0 && fl==1)
      {///cout<<i<<endl;
          i++;
          k++;fl=0;
          //k++;
      }
      else if(f[a[i]]!=0&& fl==0)
      i++;
  }//cout<<"jsjs";
  vector<pair<ll int,ll int> > v;
  for(i=1;i<=k;i++)
  {
      v.PB(MP(size[i],i));
  }///cout<<endl;
  sort(v.begin(),v.end(),sortinrev);
 /* for(i=0;i<v.size();i++)
 {
     cout<<v[i].F<<" "<<v[i].S<<endl;
 }*/
  if(v.size()>=2 && v[0].F>1)
  {
      v[1].F=v[0].F+v[1].F;

  }
  else if(v.size()<2)
  {
      cout<<v[0].F*v[0].F<<endl;
      exit(0);
  }
  ll int ans=0;
  for(i=1;i<v.size();i++)
  {
      ans=ans+v[i].F*v[i].F;
  }
  if(v[0].F==1)
  ans++;
  cout<<ans<<endl;
}


#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
#define PB push_back
#define MP make_pair
using namespace std;
bool sortinrev(const pair<int,int> &a,
               const pair<int,int> &b)
{
       return (a.first > b.first);
}
int main()
{
  ll int n;
  cin>>n;
  ll int a[n+1];ll int i;
  for(i=1;i<=n;i++)
  {
      cin>>a[i];
  }
  ll int k=1;
  ll int count=0;
  ll int f[n+1]={0};
  ll int size[n+1]={0};
  i=1;ll int fl=0;
  while(1)
  {//cout<<count<<" "<<i<<" "<<k<<endl;
      if(count==n)
      break;
      if(a[i]==i)
      {//cout<<i<<endl;
          f[a[i]]=k;
          count++;
           size[k]++;
          k++;

          i++;
      }
      else if(f[a[i]]==0)
      {//cout<<i<<endl;
          f[a[i]]=k;
          count++;
          i=a[i];
          size[k]++;
          fl=1;
      }
      else if(f[a[i]]!=0 && fl==1)
      {///cout<<i<<endl;
          i++;
          k++;fl=0;
          //k++;
      }
      else if(f[a[i]]!=0&& fl==0)
      i++;
  }//cout<<"jsjs";
  vector<pair<ll int,ll int> > v;
  for(i=1;i<=k;i++)
  {
      v.PB(MP(size[i],i));
  }///cout<<endl;
  sort(v.begin(),v.end(),sortinrev);
 /* for(i=0;i<v.size();i++)
 {
     cout<<v[i].F<<" "<<v[i].S<<endl;
 }*/
  if(v.size()>=2)
  {
      v[1].F=v[0].F+v[1].F;

  }
  else
  {
      cout<<v[0].F*v[0].F<<endl;
      exit(0);
  }
  ll int ans=0;
  for(i=1;i<v.size();i++)
  {
      ans=ans+v[i].F*v[i].F;
  }
  cout<<ans<<endl;
}


#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
#define PB push_back
#define MP make_pair
using namespace std;
bool sortinrev(const pair<int,int> &a,
               const pair<int,int> &b)
{
       return (a.first > b.first);
}
int main()
{
  ll int n;
  cin>>n;

  ll int a[n+1];ll int i;
  for(i=1;i<=n;i++)
  {
      cin>>a[i];
  }
  if(n==1)
  {
      cout<<"1\n";
      exit(0);
  }
  ll int k=1;
  ll int count=0;
  ll int f[n+1]={0};
  ll int size[n+1]={0};
  i=1;ll int fl=0;
  while(1)
  {//cout<<count<<" "<<i<<" "<<k<<endl;
      if(count==n)
      break;
      if(a[i]==i)
      {//cout<<i<<endl;
          f[a[i]]=k;
          count++;
           size[k]++;
          if(count<n)
          k++;

          i++;
      }
      else if(f[a[i]]==0)
      {//cout<<i<<endl;
          f[a[i]]=k;
          count++;
          i=a[i];
          size[k]++;
          fl=1;
      }
      else if(f[a[i]]!=0 && fl==1)
      {///cout<<i<<endl;
          i++;
          k++;fl=0;
          //k++;
      }
      else if(f[a[i]]!=0&& fl==0)
      i++;
  }//cout<<"jsjs";
  vector<pair<ll int,ll int> > v;
  for(i=1;i<=k;i++)
  {
      v.PB(MP(size[i],i));
  }///cout<<endl;
  sort(v.begin(),v.end(),sortinrev);
 /* for(i=0;i<v.size();i++)
 {
     cout<<v[i].F<<" "<<v[i].S<<endl;
 }*/
  if(v.size()>=2 )
  {
      v[1].F=v[0].F+v[1].F;

  }
  else if(v.size()<2)
  {
      cout<<v[0].F*v[0].F<<endl;
      exit(0);
  }
  ll int ans=0;
  for(i=1;i<v.size();i++)
  {
      ans=ans+v[i].F*v[i].F;
  }

  cout<<ans<<endl;
}


#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
#define PB push_back
#define MP make_pair
using namespace std;
bool sortinrev(const pair<int,int> &a,
               const pair<int,int> &b)
{
       return (a.first > b.first);
}
int main()
{
  ll int n;
  cin>>n;

  ll int a[n+1];ll int i;
  for(i=1;i<=n;i++)
  {
      cin>>a[i];
  }
  if(n==1)
  {
      cout<<"1\n";
      exit(0);
  }
  ll int k=1;
  ll int count=0;
  ll int f[n+1]={0};
  ll int size[n+1]={0};
  i=1;ll int fl=0;
  while(1)
  {//cout<<count<<" "<<i<<" "<<k<<endl;
      if(count==n)
      break;
      if(a[i]==i)
      {//cout<<i<<endl;
          f[a[i]]=k;
          count++;
           size[k]++;
          k++;

          i++;
      }
      else if(f[a[i]]==0)
      {//cout<<i<<endl;
          f[a[i]]=k;
          count++;
          i=a[i];
          size[k]++;
          fl=1;
      }
      else if(f[a[i]]!=0 && fl==1)
      {///cout<<i<<endl;
          i++;
          k++;fl=0;
          //k++;
      }
      else if(f[a[i]]!=0&& fl==0)
      i++;
  }//cout<<"jsjs";
  vector<pair<ll int,ll int> > v;
  for(i=1;i<=k;i++)
  {
      v.PB(MP(size[i],i));
  }///cout<<endl;
  sort(v.begin(),v.end(),sortinrev);
 /* for(i=0;i<v.size();i++)
 {
     cout<<v[i].F<<" "<<v[i].S<<endl;
 }*/
  if(v.size()>=2)
  {
      v[1].F=v[0].F+v[1].F;

  }
  else
  {
      cout<<v[0].F*v[0].F<<endl;
      exit(0);
  }
  ll int ans=0;
  for(i=1;i<v.size();i++)
  {
      ans=ans+v[i].F*v[i].F;
  }
  cout<<ans<<endl;
}


#include<bits/stdc++.h>
#define ll long long
#define F first
#define S second
#define PB push_back
#define MP make_pair
using namespace std;
bool sortinrev(const pair<int,int> &a,
               const pair<int,int> &b)
{
       return (a.first > b.first);
}
int main()
{
  ll int n;
  cin>>n;
  ll int a[n+1];ll int i;
  for(i=1;i<=n;i++)
  {
      cin>>a[i];
  }
  ll int k=1;
  ll int count=0;
  ll int f[n+1]={0};
  ll int size[n+1]={0};
  i=1;ll int fl=0;
  while(1)
  {//cout<<count<<" "<<i<<" "<<k<<endl;
      if(count==n)
      break;
      if(a[i]==i)
      {//cout<<i<<endl;
          f[a[i]]=k;
          count++;
           size[k]++;
          k++;

          i++;
      }
      else if(f[a[i]]==0)
      {//cout<<i<<endl;
          f[a[i]]=k;
          count++;
          i=a[i];
          size[k]++;
          fl=1;
      }
      else if(f[a[i]]!=0 && fl==1)
      {///cout<<i<<endl;
          i++;
          k++;fl=0;
          //k++;
      }
      else if(f[a[i]]!=0&& fl==0)
      i++;
  }//cout<<"jsjs";
  vector<pair<ll int,ll int> > v;
  for(i=1;i<=k;i++)
  {
      v.PB(MP(size[i],i));
  }///cout<<endl;
  sort(v.begin(),v.end(),sortinrev);
 /* for(i=0;i<v.size();i++)
 {
     cout<<v[i].F<<" "<<v[i].S<<endl;
 }*/
  if(v.size()>=2)
  {
      v[1].F=v[0].F+v[1].F;

  }
  else
  {
      cout<<v[0].F*v[0].F<<endl;
      exit(0);
  }
  ll int ans=0;
  for(i=1;i<v.size();i++)
  {
      ans=ans+v[i].F*v[i].F;
  }
  cout<<ans;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long int lo;
typedef pair< int,int > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 500005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,vis[li],val;
int cev;
string s;
vector<int> v[li];
vector<int> vv;

void dfs(int node){
	if(vis[node]==1)return ;
	vis[node]=1;
	val++;
	for(int i=0;i<(int)v[node].size();i++){
		dfs(v[node][i]);
	}
	return;
}

int main(void){
	scanf("%d",&n);
	FOR{
		scanf("%d",&a[i]);
		v[a[i]].pb(i);
		//~ v[i].pb(a[i]);
	}
	FOR{
		val=0;
		//~ cev+=;
		//~ if(vis[i]==1)continue;
		dfs(i);
		//~ val++;
		cev+=val*val;
		//~ cout<<val<<endl;
		vv.pb(val);
	}
	//~ cout<<cev<<endl;
	//~ vv.pb(1);
	//~ vv.pb(1);
	//~ vv.pb(1);
	sort(vv.begin(),vv.end());
	reverse(vv.begin(),vv.end());
	cev+=vv[0]*vv[1]*2;
	//~ cout<<vv[0]<<" "<<vv[1]<<endl;
	printf("%d\n",cev);
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long int lo;
typedef pair< int,int > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 500005;
const lo mod = 1000000007;

int n,m,b[li],a[li],k,flag,t,vis[li],val;
int cev;
string s;
vector<int> v[li];
vector<int> vv;

void dfs(int node){
	if(vis[node]==1)return ;
	vis[node]=1;
	val++;
	for(int i=0;i<(int)v[node].size();i++){
		dfs(v[node][i]);
	}
	return;
}

int main(void){
	scanf("%d",&n);
	FOR{
		scanf("%d",&a[i]);
		v[a[i]].pb(i);
		//~ v[i].pb(a[i]);
	}
	FOR{
		val=0;
		//~ cev+=;
		//~ if(vis[i]==1)continue;
		dfs(i);
		//~ val++;
		cev+=val*val;
		//~ cout<<val<<endl;
		vv.pb(val);
	}
	//~ cout<<cev<<endl;
	vv.pb(0);
	vv.pb(0);
	vv.pb(0);
	sort(vv.begin(),vv.end());
	reverse(vv.begin(),vv.end());
	cev+=vv[0]*vv[1]*2;
	//~ cout<<vv[0]<<" "<<vv[1]<<endl;
	printf("%d\n",cev);
	return 0;
}


//Sani buyuk Osman Pasa Plevneden cikmam diyor.
//FatihSultanMehmedHan
//Abdulhamid Han
//Bismillahirrahmanirrahim
//█▀█─█──█──█▀█─█─█
//█▄█─█──█──█▄█─█▄█
//█─█─█▄─█▄─█─█─█─█

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>

using namespace std;

typedef long long int lo;
typedef pair< int,int > PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fio() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define FOR for(int i=1;i<=n;i++)
#define mid ((start+end)/2)
#define ort ((bas+son)/2)

const lo MAX = -1000000000000000000;
const lo MIN = 1000000000000000000;
const lo inf = 1000000000;
const lo KOK = 100000;
const lo LOG = 30;
const lo li = 500005;
const lo mod = 1000000007;

lo n,m,b[li],a[li],k,flag,t,vis[li],val;
lo cev;
string s;
vector<lo> v[li];
vector<lo> vv;

void dfs(lo node){
	if(vis[node]==1)return ;
	vis[node]=1;
	val++;
	for(lo i=0;i<(lo)v[node].size();i++){
		dfs(v[node][i]);
	}
	return;
}

int main(void){
	scanf("%lld",&n);
	FOR{
		scanf("%lld",&a[i]);
		v[a[i]].pb(i);
		//~ v[i].pb(a[i]);
	}
	FOR{
		val=0;
		//~ cev+=;
		//~ if(vis[i]==1)continue;
		dfs(i);
		//~ val++;
		cev+=val*val;
		//~ cout<<val<<endl;
		vv.pb(val);
	}
	//~ cout<<cev<<endl;
	vv.pb(0);
	vv.pb(0);
	vv.pb(0);
	sort(vv.begin(),vv.end());
	reverse(vv.begin(),vv.end());
	cev+=vv[0]*vv[1]*2;
	//~ cout<<vv[0]<<" "<<vv[1]<<endl;
	printf("%lld\n",cev);
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define mk make_pair
#define pb push_back
using namespace std;
ll mod = 998244353;
vector<vector<int> > g ;
int vis[100001];
ll ct = 0 ;
void dfs(int x){
    vis[x] = 1 ;
    ct++;
    for(int i=0 ; i<g[x].size() ; i++){
        if(!vis[g[x][i]])
            dfs(g[x][i]);
    }
}
int main(){
    int n ;
    cin >> n ;
    g.resize(n+1);
    for(int i=0 ; i<n ;  i++){
        int x ;
        scanf("%d" , &x);
        g[i+1].pb(x);
    }
    ll ans = 0 ;
    vector<int> v ;
    for(int i=1 ; i<=n ; i++){
        if(!vis[i]){
            ct = 0;
            dfs(i);
            v.pb(ct);
        }
    }
    sort(v.rbegin() , v.rend());
    if(v.size() == 1) ans += v[0] * v[0] ;
    else ans += (v[0]+v[1])*(v[0]+v[1]);
    for(int i=2; i<v.size() ; i++){
        ans += v[i]*v[i];
    }
    cout << ans;
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define mk make_pair
#define pb push_back
using namespace std;
ll mod = 998244353;
vector<vector<int> > g ;
int vis[100001];
ll ct = 0 ;
void dfs(int x){
    vis[x] = 1 ;
    ct++;
    for(int i=0 ; i<g[x].size() ; i++){
        if(!vis[g[x][i]])
            dfs(g[x][i]);
    }
}
int main(){
    int n ;
    cin >> n ;
    g.resize(n+1);
    for(int i=0 ; i<n ;  i++){
        int x ;
        scanf("%d" , &x);
        g[i+1].pb(x);
    }
    ll ans = 0 ;
    vector<ll> v ;
    for(int i=1 ; i<=n ; i++){
        if(!vis[i]){
            ct = 0;
            dfs(i);
            v.pb(ct);
        }
    }
    sort(v.rbegin() , v.rend());
    if(v.size() == 1) ans += v[0] * v[0] ;
    else ans += (v[0]+v[1])*(v[0]+v[1]);
    for(int i=2; i<v.size() ; i++){
        ans += v[i]*v[i];
    }
    cout << ans;
    return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
typedef long double ldo;
#define lli 			long long int
#define mod				(ll) 1000000007
#define pb 				push_back
#define f(i,s,n) 		for (int i=s;i<n;i++)
#define vii				vector<int>
#define seti      set<int>
#define vll				vector<ll>
#define vpp				vector<pp>
#define vss				vector<string>
#define lcm(a,b)		(a*b)/__gcd(a,b)
#define all(a)			a.begin(),a.end()
#define abs(a) 			a>0?a:-1*a
#define all(a)			a.begin(),a.end()
#define bs(v,x)			binary_search(all(v),x)
#define vii2d       vector<vector<int>>
int n;
void addEdge(vector<int> adj[], int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}

// A utility function to do DFS of graph
// recursively from a given vertex u.
int DFSUtil(int u, vector<int> adj[],vector<bool> &visited)
{
    visited[u] = true;
    int k=0;
    for (int i=0; i<adj[u].size(); i++)
        if (visited[adj[u][i]] == false)
            k+=DFSUtil(adj[u][i], adj, visited);
    return k+1;
}

// This function does DFSUtil() for all
// unvisited vertices.
void DFS(vector<int> adj[], int V)
{

    vii ans;
    vector<bool> visited(V, false);
    for (int u=0; u<V; u++)
        if (visited[u] == false)
        {
           int v=DFSUtil(u, adj, visited);
           //cout<<v<<endl;
           ans.pb(v);
        }
    if (ans.size()==1)
    {    cout<<lli(ans[0])*lli(ans[0])<<endl;
        return;
      }
    sort(ans.begin(),ans.end());
    ans[ans.size()-1]+=ans[ans.size()-2];
    ans[ans.size()-2]=0;
    long long int tot=0;
    f(i,0,ans.size())
    {
      //cout<<ans[i]<<endl;
      tot+=(lli)(ans[i])*(lli)(ans[i]);
    }
    cout<<tot<<endl;

}
void solve(int count)
{
  int n;
  cin>>n;
  vii adj[n];
  int a[n];
  f(i,0,n)
  {
    cin>>a[i];
    addEdge(adj,i,a[i]-1);
  }
  DFS(adj,n);

}
int main()
{
    int t=1;
    //cin>>t;
    int count=1;
    while(t--)
    {
      solve(count);
      count+=1;
    }
	return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
typedef long double ldo;
#define lli 			long long int
#define mod				(ll) 1000000007
#define pb 				push_back
#define f(i,s,n) 		for (int i=s;i<n;i++)
#define vii				vector<int>
#define seti      set<int>
#define vll				vector<ll>
#define vpp				vector<pp>
#define vss				vector<string>
#define lcm(a,b)		(a*b)/__gcd(a,b)
#define all(a)			a.begin(),a.end()
#define abs(a) 			a>0?a:-1*a
#define all(a)			a.begin(),a.end()
#define bs(v,x)			binary_search(all(v),x)
#define vii2d       vector<vector<int>>
int n;
void addEdge(vector<int> adj[], int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}

// A utility function to do DFS of graph
// recursively from a given vertex u.
int DFSUtil(int u, vector<int> adj[],vector<bool> &visited)
{
    visited[u] = true;
    int k=0;
    for (int i=0; i<adj[u].size(); i++)
        if (visited[adj[u][i]] == false)
            k+=DFSUtil(adj[u][i], adj, visited);
    return k+1;
}

// This function does DFSUtil() for all
// unvisited vertices.
void DFS(vector<int> adj[], int V)
{

    vii ans;
    vector<bool> visited(V, false);
    for (int u=0; u<V; u++)
        if (visited[u] == false)
        {
           int v=DFSUtil(u, adj, visited);
           //cout<<v<<endl;
           ans.pb(v);
        }
    if (ans.size()==1)
    {    cout<<ans[0]*ans[0]<<endl;
        return;
      }
    sort(ans.begin(),ans.end());
    ans[ans.size()-1]+=ans[ans.size()-2];
    ans[ans.size()-2]=0;
    long long int tot=0;
    //tot=1000000*1000000;
  //  cout<<tot<<endl;
    f(i,0,ans.size())
    {
      //cout<<ans[i]<<endl;
      tot+=ans[i]*ans[i];
    }
    cout<<tot<<endl;

}
void solve(int count)
{
  int n;
  cin>>n;
  vii adj[n];
  int a[n];
  f(i,0,n)
  {
    cin>>a[i];
    addEdge(adj,i,a[i]-1);
  }
  DFS(adj,n);

}
int main()
{
    int t=1;
    //cin>>t;
    int count=1;
    while(t--)
    {
      solve(count);
      count+=1;
    }
	return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
typedef long double ldo;
#define lli 			long long int
#define mod				(ll) 1000000007
#define pb 				push_back
#define f(i,s,n) 		for (int i=s;i<n;i++)
#define vii				vector<int>
#define seti      set<int>
#define vll				vector<ll>
#define vpp				vector<pp>
#define vss				vector<string>
#define lcm(a,b)		(a*b)/__gcd(a,b)
#define all(a)			a.begin(),a.end()
#define abs(a) 			a>0?a:-1*a
#define all(a)			a.begin(),a.end()
#define bs(v,x)			binary_search(all(v),x)
#define vii2d       vector<vector<int>>
int n;
void addEdge(vector<int> adj[], int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}

// A utility function to do DFS of graph
// recursively from a given vertex u.
int DFSUtil(int u, vector<int> adj[],vector<bool> &visited)
{
    visited[u] = true;
    int k=0;
    for (int i=0; i<adj[u].size(); i++)
        if (visited[adj[u][i]] == false)
            k+=DFSUtil(adj[u][i], adj, visited);
    return k+1;
}

// This function does DFSUtil() for all
// unvisited vertices.
void DFS(vector<int> adj[], int V)
{

    vii ans;
    vector<bool> visited(V, false);
    for (int u=0; u<V; u++)
        if (visited[u] == false)
        {
           int v=DFSUtil(u, adj, visited);
           ans.pb(v);
        }
    sort(ans.begin(),ans.end());
    ans[ans.size()-1]+=ans[ans.size()-2];
    ans[ans.size()-2]=0;
    long tot=0;
    f(i,0,ans.size())
    {
      //cout<<ans[i]<<endl;
      tot+=ans[i]*ans[i];
    }
    cout<<tot<<endl;

}
void solve(int count)
{
  int n;
  cin>>n;
  vii adj[n];
  int a[n];
  f(i,0,n)
  {
    cin>>a[i];
    addEdge(adj,i,a[i]-1);
  }
  DFS(adj,n);

}
int main()
{
    int t=1;
    //cin>>t;
    int count=1;
    while(t--)
    {
      solve(count);
      count+=1;
    }
	return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
typedef long double ldo;
#define lli 			long long int
#define mod				(ll) 1000000007
#define pb 				push_back
#define f(i,s,n) 		for (int i=s;i<n;i++)
#define vii				vector<int>
#define seti      set<int>
#define vll				vector<ll>
#define vpp				vector<pp>
#define vss				vector<string>
#define lcm(a,b)		(a*b)/__gcd(a,b)
#define all(a)			a.begin(),a.end()
#define abs(a) 			a>0?a:-1*a
#define all(a)			a.begin(),a.end()
#define bs(v,x)			binary_search(all(v),x)
#define vii2d       vector<vector<int>>
int n;
void addEdge(vector<int> adj[], int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}

// A utility function to do DFS of graph
// recursively from a given vertex u.
int DFSUtil(int u, vector<int> adj[],vector<bool> &visited)
{
    visited[u] = true;
    int k=0;
    for (int i=0; i<adj[u].size(); i++)
        if (visited[adj[u][i]] == false)
            k+=DFSUtil(adj[u][i], adj, visited);
    return k+1;
}

// This function does DFSUtil() for all
// unvisited vertices.
void DFS(vector<int> adj[], int V)
{

    vii ans;
    vector<bool> visited(V, false);
    for (int u=0; u<V; u++)
        if (visited[u] == false)
        {
           int v=DFSUtil(u, adj, visited);
           //cout<<v<<endl;
           ans.pb(v);
        }
    if (ans.size()==1)
    {    cout<<(lli)(ans[0])*(lli)(ans[0])<<endl;
        return;
      }
    sort(ans.begin(),ans.end());
    ans[ans.size()-1]+=ans[ans.size()-2];
    ans[ans.size()-2]=0;
    long long int tot=0;
    f(i,0,ans.size())
    {
      //cout<<ans[i]<<endl;
      tot+=(lli)(ans[i])*(lli)(ans[i]);
    }
    cout<<tot<<endl;

}
void solve(int count)
{
  int n;
  cin>>n;
  vii adj[n];
  int a[n];
  f(i,0,n)
  {
    cin>>a[i];
    addEdge(adj,i,a[i]-1);
  }
  DFS(adj,n);

}
int main()
{
    int t=1;
    //cin>>t;
    int count=1;
    while(t--)
    {
      solve(count);
      count+=1;
    }
	return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
typedef long double ldo;
#define lli 			long long int
#define mod				(ll) 1000000007
#define pb 				push_back
#define f(i,s,n) 		for (int i=s;i<n;i++)
#define vii				vector<int>
#define seti      set<int>
#define vll				vector<ll>
#define vpp				vector<pp>
#define vss				vector<string>
#define lcm(a,b)		(a*b)/__gcd(a,b)
#define all(a)			a.begin(),a.end()
#define abs(a) 			a>0?a:-1*a
#define all(a)			a.begin(),a.end()
#define bs(v,x)			binary_search(all(v),x)
#define vii2d       vector<vector<int>>
int n;
void addEdge(vector<int> adj[], int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}

// A utility function to do DFS of graph
// recursively from a given vertex u.
int DFSUtil(int u, vector<int> adj[],vector<bool> &visited)
{
    visited[u] = true;
    int k=0;
    for (int i=0; i<adj[u].size(); i++)
        if (visited[adj[u][i]] == false)
            k+=DFSUtil(adj[u][i], adj, visited);
    return k+1;
}

// This function does DFSUtil() for all
// unvisited vertices.
void DFS(vector<int> adj[], int V)
{

    vii ans;
    vector<bool> visited(V, false);
    for (int u=0; u<V; u++)
        if (visited[u] == false)
        {
           int v=DFSUtil(u, adj, visited);
           //cout<<v<<endl;
           ans.pb(v);
        }
    if (ans.size()==1)
    {    cout<<ans[0]*ans[0]<<endl;
        return;
      }
    sort(ans.begin(),ans.end());
    ans[ans.size()-1]+=ans[ans.size()-2];
    ans[ans.size()-2]=0;
    long long int tot=0;
    f(i,0,ans.size())
    {
      //cout<<ans[i]<<endl;
      tot+=(lli)(ans[i])*(lli)(ans[i]);
    }
    cout<<tot<<endl;

}
void solve(int count)
{
  int n;
  cin>>n;
  vii adj[n];
  int a[n];
  f(i,0,n)
  {
    cin>>a[i];
    addEdge(adj,i,a[i]-1);
  }
  DFS(adj,n);

}
int main()
{
    int t=1;
    //cin>>t;
    int count=1;
    while(t--)
    {
      solve(count);
      count+=1;
    }
	return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
typedef long double ldo;
#define lli 			long long int
#define mod				(ll) 1000000007
#define pb 				push_back
#define f(i,s,n) 		for (int i=s;i<n;i++)
#define vii				vector<int>
#define seti      set<int>
#define vll				vector<ll>
#define vpp				vector<pp>
#define vss				vector<string>
#define lcm(a,b)		(a*b)/__gcd(a,b)
#define all(a)			a.begin(),a.end()
#define abs(a) 			a>0?a:-1*a
#define all(a)			a.begin(),a.end()
#define bs(v,x)			binary_search(all(v),x)
#define vii2d       vector<vector<int>>
int n;
void addEdge(vector<int> adj[], int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}

// A utility function to do DFS of graph
// recursively from a given vertex u.
int DFSUtil(int u, vector<int> adj[],vector<bool> &visited)
{
    visited[u] = true;
    int k=0;
    for (int i=0; i<adj[u].size(); i++)
        if (visited[adj[u][i]] == false)
            k+=DFSUtil(adj[u][i], adj, visited);
    return k+1;
}

// This function does DFSUtil() for all
// unvisited vertices.
void DFS(vector<int> adj[], int V)
{

    vii ans;
    vector<bool> visited(V, false);
    for (int u=0; u<V; u++)
        if (visited[u] == false)
        {
           int v=DFSUtil(u, adj, visited);
           //cout<<v<<endl;
           ans.pb(v);
        }
    if (ans.size()==1)
    {    cout<<ans[0]*ans[0]<<endl;
        return;
      }
    sort(ans.begin(),ans.end());
    ans[ans.size()-1]+=ans[ans.size()-2];
    ans[ans.size()-2]=0;
    long long tot=0;
    f(i,0,ans.size())
    {
      //cout<<ans[i]<<endl;
      tot+=ans[i]*ans[i];
    }
    cout<<tot<<endl;

}
void solve(int count)
{
  int n;
  cin>>n;
  vii adj[n];
  int a[n];
  f(i,0,n)
  {
    cin>>a[i];
    addEdge(adj,i,a[i]-1);
  }
  DFS(adj,n);

}
int main()
{
    int t=1;
    //cin>>t;
    int count=1;
    while(t--)
    {
      solve(count);
      count+=1;
    }
	return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
typedef long double ldo;
#define lli 			long long int
#define mod				(ll) 1000000007
#define pb 				push_back
#define f(i,s,n) 		for (int i=s;i<n;i++)
#define vii				vector<int>
#define seti      set<int>
#define vll				vector<ll>
#define vpp				vector<pp>
#define vss				vector<string>
#define lcm(a,b)		(a*b)/__gcd(a,b)
#define all(a)			a.begin(),a.end()
#define abs(a) 			a>0?a:-1*a
#define all(a)			a.begin(),a.end()
#define bs(v,x)			binary_search(all(v),x)
#define vii2d       vector<vector<int>>
int n;
void addEdge(vector<int> adj[], int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}

// A utility function to do DFS of graph
// recursively from a given vertex u.
int DFSUtil(int u, vector<int> adj[],vector<bool> &visited)
{
    visited[u] = true;
    int k=0;
    for (int i=0; i<adj[u].size(); i++)
        if (visited[adj[u][i]] == false)
            k+=DFSUtil(adj[u][i], adj, visited);
    return k+1;
}

// This function does DFSUtil() for all
// unvisited vertices.
void DFS(vector<int> adj[], int V)
{

    vii ans;
    vector<bool> visited(V, false);
    for (int u=0; u<V; u++)
        if (visited[u] == false)
        {
           int v=DFSUtil(u, adj, visited);
           ans.pb(v);
        }
    sort(ans.begin(),ans.end());
    if (ans.size()==0)
      {  cout<<ans[0]*ans[0]<<endl;
        return;
      }
    int e=-1;
    for (int i=0;i<ans.size()-1;i++)
    {
      if (ans[i]>=2)
      {
          ans[i]-=2;
          e=2;
          break;
        }

    }
    if (e==-1)
    {  e=1;
      ans[0]-=e;
    }
    ans[ans.size()-1]+=e;
    long tot=0;
    f(i,0,ans.size())
    {
      //cout<<ans[i]<<endl;
      tot+=ans[i]*ans[i];
    }
    cout<<tot<<endl;

}
void solve(int count)
{
  int n;
  cin>>n;
  vii adj[n];
  int a[n];
  f(i,0,n)
  {
    cin>>a[i];
    addEdge(adj,i,a[i]-1);
  }
  DFS(adj,n);

}
int main()
{
    int t=1;
    //cin>>t;
    int count=1;
    while(t--)
    {
      solve(count);
      count+=1;
    }
	return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
typedef long double ldo;
#define lli 			long long int
#define mod				(ll) 1000000007
#define pb 				push_back
#define f(i,s,n) 		for (int i=s;i<n;i++)
#define vii				vector<int>
#define seti      set<int>
#define vll				vector<ll>
#define vpp				vector<pp>
#define vss				vector<string>
#define lcm(a,b)		(a*b)/__gcd(a,b)
#define all(a)			a.begin(),a.end()
#define abs(a) 			a>0?a:-1*a
#define all(a)			a.begin(),a.end()
#define bs(v,x)			binary_search(all(v),x)
#define vii2d       vector<vector<int>>
int n;
void addEdge(vector<int> adj[], int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}

// A utility function to do DFS of graph
// recursively from a given vertex u.
int DFSUtil(int u, vector<int> adj[],vector<bool> &visited)
{
    visited[u] = true;
    int k=0;
    for (int i=0; i<adj[u].size(); i++)
        if (visited[adj[u][i]] == false)
            k+=DFSUtil(adj[u][i], adj, visited);
    return k+1;
}

// This function does DFSUtil() for all
// unvisited vertices.
void DFS(vector<int> adj[], int V)
{

    vii ans;
    vector<bool> visited(V, false);
    for (int u=0; u<V; u++)
        if (visited[u] == false)
        {
           int v=DFSUtil(u, adj, visited);
           //cout<<v<<endl;
           ans.pb(v);
        }
    if (ans.size()==1)
    {    cout<<ans[0]*ans[0]<<endl;
        return;
      }
    sort(ans.begin(),ans.end());
    ans[ans.size()-1]+=ans[ans.size()-2];
    ans[ans.size()-2]=0;
    long tot=0;
    f(i,0,ans.size())
    {
      //cout<<ans[i]<<endl;
      tot+=ans[i]*ans[i];
    }
    cout<<tot<<endl;

}
void solve(int count)
{
  int n;
  cin>>n;
  vii adj[n];
  int a[n];
  f(i,0,n)
  {
    cin>>a[i];
    addEdge(adj,i,a[i]-1);
  }
  DFS(adj,n);

}
int main()
{
    int t=1;
    //cin>>t;
    int count=1;
    while(t--)
    {
      solve(count);
      count+=1;
    }
	return 0;
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
typedef long double ldo;
#define lli 			long long int
#define mod				(ll) 1000000007
#define pb 				push_back
#define f(i,s,n) 		for (int i=s;i<n;i++)
#define vii				vector<int>
#define seti      set<int>
#define vll				vector<ll>
#define vpp				vector<pp>
#define vss				vector<string>
#define lcm(a,b)		(a*b)/__gcd(a,b)
#define all(a)			a.begin(),a.end()
#define abs(a) 			a>0?a:-1*a
#define all(a)			a.begin(),a.end()
#define bs(v,x)			binary_search(all(v),x)
#define vii2d       vector<vector<int>>
int n;
void addEdge(vector<int> adj[], int u, int v)
{
    adj[u].push_back(v);
    adj[v].push_back(u);
}

// A utility function to do DFS of graph
// recursively from a given vertex u.
int DFSUtil(int u, vector<int> adj[],vector<bool> &visited)
{
    visited[u] = true;
    int k=0;
    for (int i=0; i<adj[u].size(); i++)
        if (visited[adj[u][i]] == false)
            k+=DFSUtil(adj[u][i], adj, visited);
    return k+1;
}

// This function does DFSUtil() for all
// unvisited vertices.
void DFS(vector<int> adj[], int V)
{

    vii ans;
    vector<bool> visited(V, false);
    for (int u=0; u<V; u++)
        if (visited[u] == false)
        {
           int v=DFSUtil(u, adj, visited);
           //cout<<v<<endl;
           ans.pb(v);
        }
    if (ans.size()==1)
    {    cout<<ans[0]*ans[0]<<endl;
        return;
      }
    sort(ans.begin(),ans.end());
    ans[ans.size()-1]+=ans[ans.size()-2];
    ans[ans.size()-2]=0;
    long long int tot=0;
    //tot=1000000*1000000;
    cout<<tot<<endl;
    f(i,0,ans.size())
    {
      //cout<<ans[i]<<endl;
      tot+=ans[i]*ans[i];
    }
    cout<<tot<<endl;

}
void solve(int count)
{
  int n;
  cin>>n;
  vii adj[n];
  int a[n];
  f(i,0,n)
  {
    cin>>a[i];
    addEdge(adj,i,a[i]-1);
  }
  DFS(adj,n);

}
int main()
{
    int t=1;
    //cin>>t;
    int count=1;
    while(t--)
    {
      solve(count);
      count+=1;
    }
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
//#include"stdafx.h"
#include <iostream>
#include <iomanip>
#include<stack>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string>
#include <assert.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include<cmath>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <bitset>
#include <deque>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <fstream>
#include <ostream>
#include<functional>
using namespace std;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef long long ll;
typedef vector<pair<int, int>> vp;
typedef vector<vector<pair<int, int>>> vvp;
typedef unsigned long long ull;
typedef long  double ld;
const ll Mod = 1000000007;
const int N = 100005;
int p[N], sz[N],save[N];

int get(int i) {
	return save[i]== i ? i : save[i]=get(save[i]);
}
int main() {
	//freopen("test.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n;
	scanf("%d", &n);

	for (int i = 1; i <= n; i++)
		save[i] = i;
	for (int i = 1; i <= n; i++) {

		scanf("%d", &p[i]);

		save[get(i)] = save[get(p[i])];
	}
	for (int i = 1; i <= n; i++)
		sz[get(i)]++;

	vi all;
	for (int i = 1; i <= n; i++)
		if (get(i) == i)
			all.push_back(sz[i]);

	sort(all.begin(), all.end());
	if (all.size() >= 2) {

		int last = all.back();
		all.pop_back();
		all.back() += last;

	}
	ll ans = 0;
	for (int i = 0; i < all.size(); i++)
		ans += (1ll * all[i])*all[i];

	cout << ans << endl;

	//cout << flush;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
//#include"stdafx.h"
#include <iostream>
#include <iomanip>
#include<stack>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string>
#include <assert.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include<cmath>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <bitset>
#include <deque>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <fstream>
#include <ostream>
#include<functional>
using namespace std;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef long long ll;
typedef vector<pair<int, int>> vp;
typedef vector<vector<pair<int, int>>> vvp;
typedef unsigned long long ull;
typedef long  double ld;
const ll Mod = 1000000007;
const int N = 100005;
int p[N];
vi sz;

int get(int i) {
	return p[i] == i ? i : get(p[i]);
}
int main() {
	//freopen("test.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n;
	scanf("%d", &n);
	sz.resize(n + 1,0);
	for (int i = 1; i <= n; i++)
		p[i] = i;
	for (int i = 1; i <= n; i++) {
		int v;
		scanf("%d", &v);
		p[v] = get(i);

		sz[get(i)]++;

	}
	sort(sz.begin(), sz.end());
	int last = sz.back();
	sz.pop_back();
	last = last + sz.back();
	sz.pop_back();
	ll ans = (last * 1ll)*last;

	for (int i = sz.size()-1; i > 0; i--)
		ans += (sz[i] * 1ll)*sz[i];

	cout << ans << endl;

	//cout << flush;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
//#include"stdafx.h"
#include <iostream>
#include <iomanip>
#include<stack>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string>
#include <assert.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include<cmath>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <bitset>
#include <deque>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <fstream>
#include <ostream>
#include<functional>
using namespace std;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef long long ll;
typedef vector<pair<int, int>> vp;
typedef vector<vector<pair<int, int>>> vvp;
typedef unsigned long long ull;
typedef long  double ld;
const ll Mod = 1000000007;
const int N = 100005;
int p[N], sz[N],save[N];

int get(int i) {
	return save[i]== i ? i : save[i]=get(p[i]);
}
int main() {
	//freopen("test.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n;
	scanf("%d", &n);

	for (int i = 1; i <= n; i++)
		save[i] = i;
	for (int i = 1; i <= n; i++) {

		scanf("%d", &p[i]);

		save[get(i)] = save[get(p[i])];
	}
	for (int i = 1; i <= n; i++)
		sz[get(i)]++;

	vi all;
	for (int i = 1; i <= n; i++)
		if (get(i) == i)
			all.push_back(sz[i]);

	sort(all.begin(), all.end());
	if (all.size() >= 2) {

		int last = all.back();
		all.pop_back();
		all.back() += last;

	}
	ll ans = 0;
	for (int i = 0; i < all.size(); i++)
		ans += (1ll * all[i])*all[i];

	cout << ans << endl;

	//cout << flush;
	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace std;
using namespace __gnu_pbds;
template<typename T>
using indexed_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define all(v)			((v).begin()), ((v).end())
#define SZ(v)			((int)((v).size()))
#define clr(v, d)		memset(v, d, sizeof(v))
#define has(c,i) 		((c).find(i) != end(c))
#define UNIQUE(v)       sort(all(v));v.erase(unique(all(v)),v.end());
#define has_str(s, c)	((s).find(c) != string::npos)
typedef long long ll;
constexpr int N = 100000+9;
constexpr int mod = 1e9+7;
bool vis[N];
int n, a[N];
int dfs (int now) {
    if(vis[now])
        return 0;
    vis[now] = true;
    return 1 + dfs(a[now]);
}
void solve () {
    clr(vis, false);
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    vector<int> ans;
    for(int i = 1; i <= n; ++i) {
        if(!vis[i]) {
            ans.push_back(dfs(i));
        }
    }
    sort(all(ans));
    if(SZ(ans) > 1) {
        int x = ans.back();
        ans.pop_back();
        int y = ans.back();
        ans.pop_back();
        ans.push_back(x + y);
    }
    ll answer = 0;
    for(ll to : ans)
        answer += to * to;
    cout << answer << endl;
}
int main() {
#ifdef online_judge
    freopen("input.txt", "wt", stdin);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    solve();
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace std;
using namespace __gnu_pbds;
template<typename T>
using indexed_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define all(v)			((v).begin()), ((v).end())
#define SZ(v)			((int)((v).size()))
#define clr(v, d)		memset(v, d, sizeof(v))
#define has(c,i) 		((c).find(i) != end(c))
#define UNIQUE(v)       sort(all(v));v.erase(unique(all(v)),v.end());
#define has_str(s, c)	((s).find(c) != string::npos)
typedef long long ll;
constexpr int N = 2e5+9;
constexpr int mod = 1e9+7;
bool vis[N];
int n, a[N];
int dfs (int now) {
    if(vis[now])
        return 0;
    vis[now] = true;
    return 1 + dfs(a[now]);
}
void solve () {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    vector<int> ans;
    for(int i = 1; i <= n; ++i) {
        if(!vis[i]) {
            ans.push_back(dfs(i));
        }
    }
    sort(all(ans));
    if(SZ(ans) > 1) {
        int x = ans.back();
        ans.pop_back();
        int y = ans.back();
        ans.pop_back();
        ans.push_back(x + y);
    }
    ll answer = 0;
    for(auto to : ans)
        answer += to * to;
    cout << answer << endl;
}
int main() {
#ifdef online_judge
    freopen("input.txt", "wt", stdin);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    solve();
    return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
#define for0(i, n) for (ll i = 0; i < (ll)(n); ++i) // 0 based indexing
#define for1(i, n) for (ll i = 1; i <= (ll)(n); ++i) // 1 based indexing
#define forc(i, l, r) for (ll i = (ll)(l); i <= (ll)(r); ++i) // closed llerver from l to r r inclusive
#define forr0(i, n) for (ll i = (ll)(n) - 1; i >= 0; --i) // reverse 0 based.
#define forr1(i, n) for (ll i = (ll)(n); i >= 1; --i) // reverse 1 based

//short hand for usual tokens
#define pb push_back
#define fi first
#define se second

// to be used with algorithms that processes a container Eg: find(all(c),42)
#define all(x) (x).begin(), (x).end() //Forward traversal
#define rall(x) (x).rbegin(), (x).rend() //reverse traversal

using namespace std;
vector<ll> pr;
ll findParent(ll x) {
    if(x != pr[x]) {
        pr[x] = findParent(pr[x]);
    }
    return pr[x];
}
void unions(ll x,ll y) {
    pr[findParent(x)] = findParent(y);
}

int main () {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    ll n;
    cin>>n;
    pr = vector<ll>(n);
    for(ll i = 0;i<n;i++) pr[i] = i;
    for(ll i = 0;i<n;i++) {
        ll p;
        cin>>p;
        p--;
        unions(i,p);
    }
    vector<ll> ranks(n+1,0);
    for(ll i = 0;i<n;i++) {
        ranks[findParent(i)]++;
    }
    sort(rall(ranks));
    ll ans = 0;
    ll idx = -1;
    for(ll i = 0;i<n;i++) {
        ans += ranks[i] * ranks[i];
        if(!ranks[i]) {
            idx = i-1;
            break;
        }
    }
    cout<<(idx == 0 ? ans : ans + 2*ranks[0]*ranks[1])<<endl;
    return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
#define for0(i, n) for (int i = 0; i < (int)(n); ++i) // 0 based indexing
#define for1(i, n) for (int i = 1; i <= (int)(n); ++i) // 1 based indexing
#define forc(i, l, r) for (int i = (int)(l); i <= (int)(r); ++i) // closed interver from l to r r inclusive
#define forr0(i, n) for (int i = (int)(n) - 1; i >= 0; --i) // reverse 0 based.
#define forr1(i, n) for (int i = (int)(n); i >= 1; --i) // reverse 1 based

//short hand for usual tokens
#define pb push_back
#define fi first
#define se second

// to be used with algorithms that processes a container Eg: find(all(c),42)
#define all(x) (x).begin(), (x).end() //Forward traversal
#define rall(x) (x).rbegin(), (x).rend() //reverse traversal

using namespace std;
vector<int> pr;
int findParent(int x) {
    if(x != pr[x]) {
        pr[x] = findParent(pr[x]);
    }
    return pr[x];
}
int unions(int x,int y) {
    pr[findParent(x)] = findParent(y);
}

int main () {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n;
    cin>>n;
    pr = vector<int>(n);
    for(int i = 0;i<n;i++) pr[i] = i;
    for(int i = 0;i<n;i++) {
        int p;
        cin>>p;
        p--;
        unions(i,p);
    }
    vector<int> ranks(n,0);
    for(int i = 0;i<n;i++) {
        ranks[findParent(i)]++;
    }
    sort(rall(ranks));
    ll ans = 0;
    int idx = -1;
    for(int i = 0;i<n;i++) {
        ans += ranks[i] * ranks[i];
        if(!ranks[i]) {
            idx = i-1;
            break;
        }
    }
    cout<<(idx == 0 ? ans : ans + 2*ranks[0]*ranks[1])<<endl;
    return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
#define for0(i, n) for (int i = 0; i < (int)(n); ++i) // 0 based indexing
#define for1(i, n) for (int i = 1; i <= (int)(n); ++i) // 1 based indexing
#define forc(i, l, r) for (int i = (int)(l); i <= (int)(r); ++i) // closed interver from l to r r inclusive
#define forr0(i, n) for (int i = (int)(n) - 1; i >= 0; --i) // reverse 0 based.
#define forr1(i, n) for (int i = (int)(n); i >= 1; --i) // reverse 1 based

//short hand for usual tokens
#define pb push_back
#define fi first
#define se second

// to be used with algorithms that processes a container Eg: find(all(c),42)
#define all(x) (x).begin(), (x).end() //Forward traversal
#define rall(x) (x).rbegin(), (x).rend() //reverse traversal

using namespace std;
vector<int> pr;
int findParent(int x) {
    if(x != pr[x]) {
        pr[x] = findParent(pr[x]);
    }
    return pr[x];
}
void unions(int x,int y) {
    pr[findParent(x)] = findParent(y);
}

int main () {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n;
    cin>>n;
    pr = vector<int>(n);
    for(int i = 0;i<n;i++) pr[i] = i;
    for(int i = 0;i<n;i++) {
        int p;
        cin>>p;
        p--;
        unions(i,p);
    }
    vector<int> ranks(n+1,0);
    for(int i = 0;i<n;i++) {
        ranks[findParent(i)]++;
    }
    sort(rall(ranks));
    ll ans = 0;
    int idx = -1;
    for(int i = 0;i<n;i++) {
        ans += ranks[i] * ranks[i];
        if(!ranks[i]) {
            idx = i-1;
            break;
        }
    }
    cout<<(idx == 0 ? ans : ans + 2*ranks[0]*ranks[1])<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define mxn 100005
#define ll long long
using namespace std;
int p[mxn], vis[mxn];
vector<int>vec;
int dfs(int x)
{
    vis[x]= 1;
    int ret= 1;
    if(!vis[ p[x] ])ret+= dfs(p[x]);
    return ret;
}
int main()
{
    int n;
    scanf("%d", &n);
    for(int i=1; i<=n; i++)scanf("%d", &p[i]);
    for(int i=1; i<=n; i++)if(!vis[i])vec.push_back(dfs(i));
    vec.push_back(0);
    sort(vec.begin(), vec.end(), greater<int>());
    ll sum= (vec[0]+vec[1])*(vec[0]+vec[1]);
    for(int i=2; i<vec.size(); i++)sum+= vec[i]*1ll*vec[i];
    printf("%lld\n", sum);
    return 0;
}


#include<bits/stdc++.h>
#define mxn 100005
#define ll long long
using namespace std;
int p[mxn], vis[mxn];
vector<int>vec;
int dfs(int x)
{
    vis[x]= 1;
    int ret= 1;
    if(!vis[ p[x] ])ret+= dfs(p[x]);
    return ret;
}
int main()
{
    int n;
    scanf("%d", &n);
    for(int i=1; i<=n; i++)scanf("%d", &p[i]);
    for(int i=1; i<=n; i++)if(!vis[i])vec.push_back(dfs(i));
    vec.push_back(0);
    sort(vec.begin(), vec.end(), greater<int>());
    ll sum= (vec[0]+vec[1])*1ll*(vec[0]+vec[1]);
    for(int i=2; i<vec.size(); i++)sum+= vec[i]*1ll*vec[i];
    printf("%lld\n", sum);
    return 0;
}


/*Our biggest fear is not that we are inadequate,
It is that we are powerful beyond measure*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<int> adj[100001];
bool visited[100001];
int dfs(int u) {
	visited[u] = true;
	int cnt = 1;
	for(int i = 0 ; i < adj[u].size() ; i ++) {
		if(!visited[adj[u][i]]) {
			cnt ++;
			dfs(adj[u][i]);
		}
	}
	return cnt;
}
int main()
{
	ios_base::sync_with_stdio(false);cin.tie(NULL);
	int n;
	cin >> n;
	for(int i = 1 ; i <= n ; i ++) {
		int a;	cin >> a;
		adj[i].push_back(a);
	}
	vector<int> graph_lengths;
	for(int i = 1 ; i <= n ; i ++) {
		if(!visited[i]) {
			graph_lengths.push_back(dfs(i));
		}
	}
	sort( graph_lengths.begin(), graph_lengths.end() );
	int len = graph_lengths.size();
	ll a = 0;
	if(len > 1) {
		a = graph_lengths[len-1] + graph_lengths[len-2];
	}
	else
		a = graph_lengths[len-1];
	ll temp = 0;
	for (int i = 0; i < len-2; i++)
	{
		int m = graph_lengths[i];
		temp += m * m;
	}

	cout << a*a + temp;;
}


/*Our biggest fear is not that we are inadequate,
It is that we are powerful beyond measure*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<ll> adj[100001];
bool visited[100001];
int dfs(int u) {
	visited[u] = true;
	int cnt = 1;
	for(int i = 0 ; i < adj[u].size() ; i ++) {
		if(!visited[adj[u][i]]) {
			cnt +=dfs(adj[u][i]);

		}
	}
	return cnt;
}
int main()
{
	ios_base::sync_with_stdio(false);cin.tie(NULL);
	ll n;
	cin >> n;
	for(ll i = 1 ; i <= n ; i ++) {
		ll c;	cin >> c;
		adj[i].push_back(c);
	}
	vector<ll> graph_lengths;
	for(ll i = 1 ; i <= n ; i ++) {
		if(!visited[i]) {
			graph_lengths.push_back(dfs(i));
		}
	}

	sort( graph_lengths.begin(), graph_lengths.end() );

	ll len = graph_lengths.size();
	ll a = 0;
	if(len > 1) {
		a = (graph_lengths[len-1] + graph_lengths[len-2]) * (graph_lengths[len-1] + graph_lengths[len-2]);
	}
	else
		a = graph_lengths[len-1] * graph_lengths[len-1];

	for (int i = 0; i < len-2; i++)
	{
		int temp = graph_lengths[i];
		a += (temp * temp);
	}

	cout << a;
}


/*Our biggest fear is not that we are inadequate,
It is that we are powerful beyond measure*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<ll> adj[100001];
bool visited[100001];
int dfs(int u) {
	visited[u] = true;
	int cnt = 1;
	for(int i = 0 ; i < adj[u].size() ; i ++) {
		if(!visited[adj[u][i]]) {
			cnt ++;
			dfs(adj[u][i]);
		}
	}
	return cnt;
}
int main()
{
	ios_base::sync_with_stdio(false);cin.tie(NULL);
	ll n;
	cin >> n;
	for(ll i = 1 ; i <= n ; i ++) {
		int a;	cin >> a;
		adj[i].push_back(a);
	}
	vector<ll> graph_lengths;
	for(ll i = 1 ; i <= n ; i ++) {
		if(!visited[i]) {
			graph_lengths.push_back(dfs(i));
		}
	}
	sort( graph_lengths.begin(), graph_lengths.end() );

	ll len = graph_lengths.size();
	ll a = 0;
	if(len > 1) {
		a = (graph_lengths[len-1] + graph_lengths[len-2]) * (graph_lengths[len-1] + graph_lengths[len-2]);
	}
	else
		a = graph_lengths[len-1] * graph_lengths[len-1];

	for (int i = 0; i < len-2; i++)
	{
		int temp = graph_lengths[i];
		a += (temp * temp);
	}

	cout << a;
}


/*Our biggest fear is not that we are inadequate,
It is that we are powerful beyond measure*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<ll> adj[100001];
bool visited[100001];
int dfs(int u) {
	visited[u] = true;
	int cnt = 1;
	for(int i = 0 ; i < adj[u].size() ; i ++) {
		if(!visited[adj[u][i]]) {
			cnt ++;
			dfs(adj[u][i]);
		}
	}
	return cnt;
}
int main()
{
	ios_base::sync_with_stdio(false);cin.tie(NULL);
	ll n;
	cin >> n;
	for(ll i = 1 ; i <= n ; i ++) {
		ll c;	cin >> c;
		adj[i].push_back(c);
	}
	vector<ll> graph_lengths;
	for(ll i = 1 ; i <= n ; i ++) {
		if(!visited[i]) {
			graph_lengths.push_back(dfs(i));
		}
	}
	sort( graph_lengths.begin(), graph_lengths.end() );

	ll len = graph_lengths.size();
	ll a = 0;
	if(len > 1) {
		a = (graph_lengths[len-1] + graph_lengths[len-2]) * (graph_lengths[len-1] + graph_lengths[len-2]);
	}
	else
		a = graph_lengths[len-1] * graph_lengths[len-1];

	for (int i = 0; i < len-2; i++)
	{
		int temp = graph_lengths[i];
		a += (temp * temp);
	}

	cout << a;
}