#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

using namespace std;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef vector<vector<int> > vvi;
typedef vector<vector<ii> > vvii;

#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define fill(a,x) memset(a,x,sizeof(a))
#define ff first
#define ss second
#define trav(a, x) for(auto& a : x)
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
const ll INF = 1e18;
const int mod = 1e9+7;
ll gcd(ll a,ll b){if (a==0) return b;return gcd(b%a,a);}
ll lcm(ll a,ll b){return a*(b/gcd(a,b));}
ll Abs(ll a){if(a>0)return a;return -a;}
ll Ceil(ll a,ll b){if(a%b==0)return a/b;else return a/b+1;}
double Abs(double a){if(a>0)return a;return -a;}

//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

#define ordered_set tree<int, null_type,less_equal<int>, rb_tree_tag,tree_order_statistics_node_update>

inline int pow_(ll x, ll y,ll p){
  int r = 1; while(y){if(y & 1) r = r * x % p; y >>= 1; x = x * x % p;} return r;
}
inline int inv_(int x){return pow_(x, mod - 2, mod);}
inline int add(int a, int b){a += b; if(a >= mod) a -= mod; return a;}
inline int mul(int a, int b){return a * 1LL * b % mod;}
inline int sub(int a, int b){a -= b; if(a < 0) a += mod; return a;}

mt19937_64 mrand(chrono::steady_clock::now().time_since_epoch().count());
ll m = 1e9 + 7, p = 256;

int main()
{
    #ifdef LOCAL_TEST
    freopen("in.txt","r",stdin);
    //freopen("out.txt", "w", stdout);
    #else
    ios_base::sync_with_stdio(false);cin.tie(NULL);
    #endif
    string s,t;
    cin>>s>>t;
    ll k;
    cin>>k;
    set<ll> w;
    for(int i=0;i<s.size();i++){
      int cnt = 0;
      ll hash_value = 0;
      ll p_pow = 1;
      string q;
      for(int j=i;j<s.size();j++){
        hash_value = (hash_value + (s[j]-'a'+1)*p_pow) % m;
        p_pow = (p_pow*p)%m;
        if(!(t[s[j]-'a']-'0')){
          cnt++;
        }
        if(cnt<=k){
          w.insert(hash_value);
        } else{
          break;
        }
      }
    }

    cout << w.size() << "\n";
}


#include <bits/stdc++.h>

#if DEBUG
    #include "debug.h"
#else
    #define debug(args...)
#endif

using namespace std;

#define int long long

typedef vector<int> vi;
typedef pair<int,int> ii;

#define M 1000000
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define fill(a,x) memset(a,x,sizeof(a))
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int INF = 1e18;
const int mod = 1e9+7;
const int N = 2e5 + 10;
inline int add(int x,int y){
  x += y;
  if(x >= mod) x -= mod;
  return x;
}
inline int mul(int x,int y){
  x = (1LL * x * y) % mod;
  return x;
}
inline int pow_(int x, int y, int p = mod){
  int r = 1; while(y){if(y & 1) r = r * x % p; y >>= 1; x = x * x % p;} return r;
}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int hash_[N];
int b = (rng() % (int)1e8) + 1e8;

int32_t main(){
  fast;

  string s;
  cin >> s;
  int n = s.length();
  string good;
  cin >> good;
  int k;
  cin >> k;
  hash_[0] = s[0] - '0';
  for(int i = 1; i < n; i++) {
    hash_[i] = (mul(hash_[i - 1] , b) + s[i] - '0') % mod;
  }
  int ans = 0;
  set<int>st;
  for(int i = 1; i <= n; i++) {
    int cc = 0;
    for(int j = 0; j < n; j++) {
      if(good[s[j] - 'a'] == '0')
        cc++;
      if(j - i >= 0) {
        if(good[s[j-i] - 'a'] == '0')
          cc--;
      }
      if(j >= i - 1) {
        int val = ((hash_[j] - (j - i < 0 ? 0 : mul(hash_[j - i],pow_(b,i)))) % mod + mod) % mod;
        if(cc <= k and st.find(val) == st.end()) {
          ans++;
          st.insert(val);
        }
      }
    }
  }

  cout << ans;

  return 0;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>

#if DEBUG
    #include "debug.h"
#else
    #define debug(args...)
#endif

using namespace std;

typedef vector<int> vi;
typedef pair<int,int> ii;
typedef long long ll;

#define M 1000000
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define fill(a,x) memset(a,x,sizeof(a))
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int INF = 1e18;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// const int mod = 1e9+7;
int mod1 = 1e9 + rng() % (int)1e8;
int mod2 = 1e9 + rng() % (int)1e8;
const int N = 2e5 + 10;
inline int add(int x,int y, int mod){
  x += y;
  if(x >= mod) x -= mod;
  return x;
}
inline int mul(int x,int y, int mod){
  x = (1LL * x * y) % mod;
  return x;
}
inline int pow_(ll x, ll y, int p){
  ll r = 1; while(y){if(y & 1) r = r * x % p; y >>= 1; x = x * x % p;} return r;
}

int hash1_[N];
int hash2_[N];
int b = (rng() % (int)1e8) + 1e8;

int32_t main(){
  fast;

  string s;
  cin >> s;
  int n = s.length();
  string good;
  cin >> good;
  int k;
  cin >> k;
  hash1_[0] = s[0] - '0';
  hash2_[0] = s[0] - '0';
  for(int i = 1; i < n; i++) {
    hash1_[i] = (mul(hash1_[i - 1] , b, mod1) + s[i] - '0') % mod1;
    hash2_[i] = (mul(hash2_[i - 1] , b, mod2) + s[i] - '0') % mod2;
  }
  int ans = 0;
  set<int>st1;
  set<int>st2;
  for(int i = 1; i <= n; i++) {
    int cc = 0;
    for(int j = 0; j < n; j++) {
      if(good[s[j] - 'a'] == '0')
        cc++;
      if(j - i >= 0) {
        if(good[s[j-i] - 'a'] == '0')
          cc--;
      }
      if(j >= i - 1) {
        int val1 = ((hash1_[j] - (j - i < 0 ? 0 : mul(hash1_[j - i],pow_(b,i,mod1), mod1))) % mod1 + mod1) % mod1;
        int val2 = ((hash2_[j] - (j - i < 0 ? 0 : mul(hash2_[j - i],pow_(b,i,mod2), mod2))) % mod2 + mod2) % mod2;
        if(cc <= k and (st1.find(val1) == st1.end() or st2.find(val2) == st2.end())) {
          ans++;
          st1.insert(val1);
          st2.insert(val2);
        }
      }
    }
  }
  cout << ans;

  return 0;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#if DEBUG
    #include "debug.h"
#else
    #define debug(args...)
#endif

#define int long long

using namespace std;

typedef vector<int> vi;
typedef pair<int,int> ii;
// typedef long long ll;

#define M 1000000
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define fill(a,x) memset(a,x,sizeof(a))
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int INF = 1e18;
// int mod = rng() % (int)1e8 + 1e9;
int mod = rng()&(1ll<<48)-1 | 1ll<<48; int base =  256;
const int N = 2e5 + 10;
inline int add(int x,int y){
  x += y;
  if(x >= mod) x -= mod;
  return x;
}
inline int mul(int x,int y){
  x = (1LL * x * y) % mod;
  return x;
}
clock_t time_p=clock();

// int base = rng() % (int)1e8 + 1e8;

int32_t main(){
  fast;

  // freopen("in.txt","r",stdin);
  // freopen("out.txt","w",stdout);

  string s,good;
  cin >> s >> good;
  int k;
  cin >> k;
  set<int>st;
  for(int i = 0; i < s.length(); i++) {
    int hashv = 0;
    int powp = 1;
    int cc = 0;
    for(int j = i; j < s.length(); j++) {
      hashv = (hashv + (s[j] - '0') * powp) % mod;
      powp = (powp * base) % mod;
      if(good[s[j]-'a'] == '0')
        cc++;
      if(cc <= k)
        st.insert(hashv);
    }
  }

  cout << sz(st);

  time_p=clock()-time_p;
  cerr<<"\nTime Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";

  return 0;
}


#include <bits/stdc++.h>

#if DEBUG
    #include "debug.h"
#else
    #define debug(args...)
#endif

using namespace std;

#define int long long

typedef vector<int> vi;
typedef pair<int,int> ii;

#define M 1000000
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define fill(a,x) memset(a,x,sizeof(a))
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int INF = 1e18;
const int mod = 1e9+7;
const int N = 2e5 + 10;
inline int add(int x,int y){
  x += y;
  if(x >= mod) x -= mod;
  return x;
}
inline int mul(int x,int y){
  x = (1LL * x * y) % mod;
  return x;
}
inline int pow_(int x, int y, int p = mod){
  int r = 1; while(y){if(y & 1) r = r * x % p; y >>= 1; x = x * x % p;} return r;
}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int hash_[N];
int b = (rng() % (int)1e8) + 1e8;

int32_t main(){
  fast;

  string s;
  cin >> s;
  int n = s.length();
  string good;
  cin >> good;
  int k;
  cin >> k;
  hash_[0] = s[0] - '0';
  for(int i = 1; i < n; i++) {
    hash_[i] = (mul(hash_[i - 1] , b) + s[i] - '0') % mod;
  }
  int ans = 0;
  set<int>st;
  for(int i = 1; i <= n; i++) {
    int cc = 0;
    for(int j = 0; j < n; j++) {
      if(good[s[j] - 'a'] == '0')
        cc++;
      if(j - i >= 0) {
        if(good[s[j-i] - 'a'] == '0')
          cc--;
      }
      if(j >= i - 1) {
        if(cc <= k and st.find(((hash_[j] - (j - i < 0 ? 0 : mul(hash_[j - i],pow_(b,i)))) % mod + mod) % mod) == st.end()) {
          ans++;
          // cout << j << " " << i << "\n";
          st.insert(((hash_[j] - (j - i < 0 ? 0 : mul(hash_[j - i],pow_(b,i)))) % mod + mod) % mod);
        }
      }
    }
  }
  // debug(st);

  cout << ans;

  return 0;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

#if DEBUG
    #include "debug.h"
#else
    #define debug(args...)
#endif

using namespace std;

typedef vector<int> vi;
typedef pair<int,int> ii;
typedef long long ll;

#define M 1000000
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define fill(a,x) memset(a,x,sizeof(a))
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int INF = 1e18;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// const int mod = 1e9+7;
int mod1 = 1e9 + rng() % (int)1e8;
int mod2 = 1e9 + rng() % (int)1e8;
const int N = 2e5 + 10;
inline int add(int x,int y, int mod){
  x += y;
  if(x >= mod) x -= mod;
  return x;
}
inline int mul(int x,int y, int mod){
  x = (1LL * x * y) % mod;
  return x;
}
inline int pow_(ll x, ll y, int p){
  ll r = 1; while(y){if(y & 1) r = r * x % p; y >>= 1; x = x * x % p;} return r;
}

int hash1_[N];
int hash2_[N];
int b = (rng() % (int)1e8) + 1e8;

int32_t main(){
  fast;

  string s;
  cin >> s;
  int n = s.length();
  string good;
  cin >> good;
  int k;
  cin >> k;
  hash1_[0] = s[0] - '0';
  hash2_[0] = s[0] - '0';
  for(int i = 1; i < n; i++) {
    hash1_[i] = (mul(hash1_[i - 1] , b, mod1) + s[i] - '0') % mod1;
    hash2_[i] = (mul(hash2_[i - 1] , b, mod2) + s[i] - '0') % mod2;
  }
  int ans = 0;
  set<int>st1;
  set<int>st2;
  for(int i = 1; i <= n; i++) {
    int cc = 0;
    for(int j = 0; j < n; j++) {
      if(good[s[j] - 'a'] == '0')
        cc++;
      if(j - i >= 0) {
        if(good[s[j-i] - 'a'] == '0')
          cc--;
      }
      if(j >= i - 1) {
        int val1 = ((hash1_[j] - (j - i < 0 ? 0 : mul(hash1_[j - i],pow_(b,i,mod1), mod1))) % mod1 + mod1) % mod1;
        int val2 = ((hash2_[j] - (j - i < 0 ? 0 : mul(hash2_[j - i],pow_(b,i,mod2), mod2))) % mod2 + mod2) % mod2;
        if(cc <= k and (st1.find(val1) == st1.end() or st2.find(val2) == st2.end())) {
          ans++;
          st1.insert(val1);
          st2.insert(val2);
        }
      }
    }
  }
  cout << ans;

  return 0;
}


#include <bits/stdc++.h>

#if DEBUG
    #include "debug.h"
#else
    #define debug(args...)
#endif

using namespace std;

// #define int long long

typedef vector<int> vi;
typedef pair<int,int> ii;
typedef long long ll;

#define M 1000000
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define fill(a,x) memset(a,x,sizeof(a))
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int INF = 1e18;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// const int mod = 1e9+7;
int mod1 = 1e9 + rng() % (int)1e8;
int mod2 = 1e9 + rng() % (int)1e8;
const int N = 2e5 + 10;
inline int add(int x,int y, int mod){
  x += y;
  if(x >= mod) x -= mod;
  return x;
}
inline int mul(int x,int y, int mod){
  x = (1LL * x * y) % mod;
  return x;
}
inline int pow_(ll x, ll y, int p){
  ll r = 1; while(y){if(y & 1) r = r * x % p; y >>= 1; x = x * x % p;} return r;
}

int hash1_[N];
int hash2_[N];
int b = (rng() % (int)1e8) + 1e8;

int32_t main(){
  fast;

  string s;
  cin >> s;
  int n = s.length();
  string good;
  cin >> good;
  int k;
  cin >> k;
  hash1_[0] = s[0] - '0';
  hash2_[0] = s[0] - '0';
  for(int i = 1; i < n; i++) {
    hash1_[i] = (mul(hash1_[i - 1] , b, mod1) + s[i] - '0') % mod1;
    hash2_[i] = (mul(hash2_[i - 1] , b, mod2) + s[i] - '0') % mod2;
  }
  int ans = 0;
  set<int>st1;
  set<int>st2;
  for(int i = 1; i <= n; i++) {
    int cc = 0;
    for(int j = 0; j < n; j++) {
      if(good[s[j] - 'a'] == '0')
        cc++;
      if(j - i >= 0) {
        if(good[s[j-i] - 'a'] == '0')
          cc--;
      }
      if(j >= i - 1) {
        int val1 = ((hash1_[j] - (j - i < 0 ? 0 : mul(hash1_[j - i],pow_(b,i,mod1), mod1))) % mod1 + mod1) % mod1;
        int val2 = ((hash2_[j] - (j - i < 0 ? 0 : mul(hash2_[j - i],pow_(b,i,mod2), mod2))) % mod2 + mod2) % mod2;
        if(cc <= k and (st1.find(val1) == st1.end() or st2.find(val2) == st2.end())) {
          ans++;
          st1.insert(val1);
          st2.insert(val2);
        }
      }
    }
  }
  cout << ans;

  return 0;
}


#include <bits/stdc++.h>

#if DEBUG
    #include "debug.h"
#else
    #define debug(args...)
#endif

using namespace std;

#define int long long

typedef vector<int> vi;
typedef pair<int,int> ii;

#define M 1000000
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define fill(a,x) memset(a,x,sizeof(a))
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int INF = 1e18;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// const int mod = 1e9+7;
int mod = 1e9 + rng() % (int)1e8;
const int N = 2e5 + 10;
inline int add(int x,int y){
  x += y;
  if(x >= mod) x -= mod;
  return x;
}
inline int mul(int x,int y){
  x = (1LL * x * y) % mod;
  return x;
}
inline int pow_(int x, int y, int p = mod){
  int r = 1; while(y){if(y & 1) r = r * x % p; y >>= 1; x = x * x % p;} return r;
}

int hash_[N];
int b = (rng() % (int)1e8) + 1e8;

int32_t main(){
  fast;

  string s;
  cin >> s;
  int n = s.length();
  string good;
  cin >> good;
  int k;
  cin >> k;
  hash_[0] = s[0] - '0';
  for(int i = 1; i < n; i++) {
    hash_[i] = (mul(hash_[i - 1] , b) + s[i] - '0') % mod;
  }
  int ans = 0;
  set<int>st;
  for(int i = 1; i <= n; i++) {
    int cc = 0;
    for(int j = 0; j < n; j++) {
      if(good[s[j] - 'a'] == '0')
        cc++;
      if(j - i >= 0) {
        if(good[s[j-i] - 'a'] == '0')
          cc--;
      }
      if(j >= i - 1) {
        int val = ((hash_[j] - (j - i < 0 ? 0 : mul(hash_[j - i],pow_(b,i)))) % mod + mod) % mod;
        if(cc <= k and st.find(val) == st.end()) {
          ans++;
          st.insert(val);
        }
      }
    }
  }

  cout << ans;

  return 0;
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;

using namespace std;

#if DEBUG && !ONLINE_JUDGE
    #include "debug.h"
#else
    #define debug(...)
#endif

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef vector<vector<int> > vvi;
typedef vector<vector<ii> > vvii;

#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define fill(a,x) memset(a,x,sizeof(a))
#define ff first
#define ss second
#define trav(a, x) for(auto& a : x)
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
const ll INF = 1e18;
const int mod = 1e9+7;
ll gcd(ll a,ll b){if (a==0) return b;return gcd(b%a,a);}
ll lcm(ll a,ll b){return a*(b/gcd(a,b));}
ll Abs(ll a){if(a>0)return a;return -a;}
ll Ceil(ll a,ll b){if(a%b==0)return a/b;else return a/b+1;}
double Abs(double a){if(a>0)return a;return -a;}

//*X.find_by_order(2) element at index=2
//X.order_of_key(1) how many elements strictly less than 1

#define ordered_set tree<int, null_type,less_equal<int>, rb_tree_tag,tree_order_statistics_node_update>

inline int pow_(ll x, ll y,ll p){
  int r = 1; while(y){if(y & 1) r = r * x % p; y >>= 1; x = x * x % p;} return r;
}
inline int inv_(int x){return pow_(x, mod - 2, mod);}
inline int add(int a, int b){a += b; if(a >= mod) a -= mod; return a;}
inline int mul(int a, int b){return a * 1LL * b % mod;}
inline int sub(int a, int b){a -= b; if(a < 0) a += mod; return a;}

mt19937_64 mrand(chrono::steady_clock::now().time_since_epoch().count());
ll m = (1ll << 32)-1, p = 256;

int main()
{
    #ifdef LOCAL_TEST
    freopen("in.txt","r",stdin);
    //freopen("out.txt", "w", stdout);
    #else
    ios_base::sync_with_stdio(false);cin.tie(NULL);
    #endif
    string s,t;
    cin>>s>>t;
    ll k;
    cin>>k;
    set<ll> w;
    for(int i=0;i<s.size();i++){
      int cnt = 0;
      ll hash_value = 0;
      ll p_pow = 1;
      string q;
      for(int j=i;j<s.size();j++){
        hash_value = (hash_value + (s[j]-'a'+1)*p_pow) % m;
        p_pow = (p_pow*p)%m;
        if(!(t[s[j]-'a']-'0')){
          cnt++;
        }
        if(cnt<=k){
          w.insert(hash_value);
        } else{
          break;
        }
      }
    }

    cout << w.size() << "\n";
}


#include <bits/stdc++.h>

#if DEBUG
    #include "debug.h"
#else
    #define debug(args...)
#endif

using namespace std;

// #define int long long

typedef vector<int> vi;
typedef pair<int,int> ii;
typedef long long ll;

#define M 1000000
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define sz(x) (int)x.size()
#define fill(a,x) memset(a,x,sizeof(a))
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int INF = 1e18;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// const int mod = 1e9+7;
int mod = 1e9 + rng() % (int)1e8;
const int N = 2e5 + 10;
inline int add(int x,int y){
  x += y;
  if(x >= mod) x -= mod;
  return x;
}
inline int mul(int x,int y){
  x = (1LL * x * y) % mod;
  return x;
}
inline int pow_(ll x, ll y, int p = mod){
  ll r = 1; while(y){if(y & 1) r = r * x % p; y >>= 1; x = x * x % p;} return r;
}

int hash_[N];
int b = (rng() % (int)1e8) + 1e8;

int32_t main(){
  fast;

  string s;
  cin >> s;
  int n = s.length();
  string good;
  cin >> good;
  int k;
  cin >> k;
  hash_[0] = s[0] - '0';
  for(int i = 1; i < n; i++) {
    hash_[i] = (mul(hash_[i - 1] , b) + s[i] - '0') % mod;
  }
  int ans = 0;
  set<int>st;
  for(int i = 1; i <= n; i++) {
    int cc = 0;
    for(int j = 0; j < n; j++) {
      if(good[s[j] - 'a'] == '0')
        cc++;
      if(j - i >= 0) {
        if(good[s[j-i] - 'a'] == '0')
          cc--;
      }
      if(j >= i - 1) {
        int val = ((hash_[j] - (j - i < 0 ? 0 : mul(hash_[j - i],pow_(b,i)))) % mod + mod) % mod;
        if(cc <= k and st.find(val) == st.end()) {
          ans++;
          st.insert(val);
        }
      }
    }
  }
  cout << ans;

  return 0;
}


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

#define all(x)            (x).begin(), (x).end()
#define sz(x)             (int)x.size()
#define len(x)            (int)x.length()
#define ac(x, i)          get<i>(x)
#define pb                push_back
#define mp                make_pair
#define ff                first
#define ss                second
#define trace(x)          cerr << #x << ": " << x << "\n"
#define trav0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trav1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trap0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define trap1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define travMap(a)        cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << "(" << i.ff << ", " << i.ss << "), "; cerr << "]\n"
#define traverse(a)       cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << i << ", "; cerr << "]\n"
#define random_permute(x) shuffle(all(x), mt)

typedef unsigned int uint;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef map<int, int> mapii;
typedef map<ll, ll> mapll;
typedef map<ll, int> mapli;
typedef unordered_map<int, int> umapii;
typedef unordered_map<ll, int> umapli;
const int infi = 1e9;
const ll infl = 1e18;
const int MOD = 1e9 + 7;
template <typename Map> bool map_compare (Map const &lhs, Map const &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());}
auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt(seed);
int randint(int p = MOD) { return mt() % p;}
ll randlong(ll p = infl) { return mt() % p;}
ll log_2 (ll n) { return (n > 1ll)? 1ll + log_2(n/2): 0ll;}
inline void add(ll&a, ll b) {a += b; if (a >= MOD) a -= MOD;}
inline void sub(ll&a, ll b) {a -= b; if (a < 0) a += MOD;}
template <class T>
struct cmp { // for priority_queue
  bool operator() (const T& x, const T& y) const {
    return x > y; // edit here
  }
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

#define int long long int

const int rdx = 117;

signed main() {
#ifdef HP
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false); cin.tie(NULL);
  string s;
  cin >> s;
  int n = len(s);
  unordered_map<int, int> m;
  vb c(200);
  string _t; cin >> _t;
  int k; cin >> k;
  for (int i = 0; i < 26; i++) {
    c[i + 'a'] = (_t[i] == '1');
  }
  int ans = 0;
  set<int> h[1501];
  for (int i = 0; i < n; i++) {
    int hash = 0;
    int w = 0;
    for (int j = i; j < n; j++) {
      w += (c[s[j]])? 0: 1;
      if (w > k) break;
      hash = hash * rdx + s[j];
      h[j - i + 1].insert(hash);
    }
  }
  for (int i = 0; i <= 1500; i++) {
    ans += sz(h[i]);
  }
  cout << ans << "\n";
  return 0;
}


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

#define all(x)            (x).begin(), (x).end()
#define sz(x)             (int)x.size()
#define len(x)            (int)x.length()
#define ac(x, i)          get<i>(x)
#define pb                push_back
#define mp                make_pair
#define ff                first
#define ss                second
#define trace(x)          cerr << #x << ": " << x << "\n"
#define trav0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trav1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trap0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define trap1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define travMap(a)        cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << "(" << i.ff << ", " << i.ss << "), "; cerr << "]\n"
#define traverse(a)       cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << i << ", "; cerr << "]\n"
#define random_permute(x) shuffle(all(x), mt)

typedef unsigned int uint;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef map<int, int> mapii;
typedef map<ll, ll> mapll;
typedef map<ll, int> mapli;
typedef unordered_map<int, int> umapii;
typedef unordered_map<ll, int> umapli;
const int infi = 1e9;
const ll infl = 1e18;
const int MOD = 1e9 + 7;
template <typename Map> bool map_compare (Map const &lhs, Map const &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());}
auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt(seed);
int randint(int p = MOD) { return mt() % p;}
ll randlong(ll p = infl) { return mt() % p;}
ll log_2 (ll n) { return (n > 1ll)? 1ll + log_2(n/2): 0ll;}
inline void add(ll&a, ll b) {a += b; if (a >= MOD) a -= MOD;}
inline void sub(ll&a, ll b) {a -= b; if (a < 0) a += MOD;}
template <class T>
struct cmp { // for priority_queue
  bool operator() (const T& x, const T& y) const {
    return x > y; // edit here
  }
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

#define int long long int

const int rdx = 31;

signed main() {
#ifdef HP
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false); cin.tie(NULL);
  string s;
  cin >> s;
  int n = len(s);
  unordered_map<int, int> m;
  vb c(200);
  string _t; cin >> _t;
  int k; cin >> k;
  for (int i = 0; i < 26; i++) {
    c[i + 'a'] = (_t[i] == '1');
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int hash = 7;
    int w = 0;
    for (int j = i; j < n; j++) {
      w += (c[s[j]])? 0: 1;
      if (w > k) break;
      hash = ((rdx * hash) % MOD + (int)(s[j] - 'a' + 1) % MOD) % MOD;
      if (m[hash]) continue;
      m[hash] = 1;
      ans++;
    }
  }
  cout << ans << "\n";
  return 0;
}


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

#define all(x)            (x).begin(), (x).end()
#define sz(x)             (int)x.size()
#define len(x)            (int)x.length()
#define ac(x, i)          get<i>(x)
#define pb                push_back
#define mp                make_pair
#define ff                first
#define ss                second
#define trace(x)          cerr << #x << ": " << x << "\n"
#define trav0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trav1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trap0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define trap1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define travMap(a)        cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << "(" << i.ff << ", " << i.ss << "), "; cerr << "]\n"
#define traverse(a)       cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << i << ", "; cerr << "]\n"
#define random_permute(x) shuffle(all(x), mt)

typedef unsigned int uint;
typedef long long int ll;
typedef unsigned long long int ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef map<int, int> mapii;
typedef map<ll, ll> mapll;
typedef map<ll, int> mapli;
typedef unordered_map<int, int> umapii;
typedef unordered_map<ll, int> umapli;
const int infi = 1e9;
const ll infl = 1e18;
const int MOD = 1e9 + 7;
template <typename Map> bool map_compare (Map const &lhs, Map const &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());}
auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt(seed);
int randint(int p = MOD) { return mt() % p;}
ll randlong(ll p = infl) { return mt() % p;}
ll log_2 (ll n) { return (n > 1ll)? 1ll + log_2(n/2): 0ll;}
inline void add(ll&a, ll b) {a += b; if (a >= MOD) a -= MOD;}
inline void sub(ll&a, ll b) {a -= b; if (a < 0) a += MOD;}
template <class T>
struct cmp { // for priority_queue
  bool operator() (const T& x, const T& y) const {
    return x > y; // edit here
  }
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

signed main() {
#ifdef HP
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false); cin.tie(NULL);
  string s;
  cin >> s;
  int n = len(s);
  vb c(200, false);
  string ome;
  cin >> ome;
  for (int i = 0; i < 26; i++) {
    c['a'+i] = ome[i] == '1';
  }
  int k;
  cin >> k;
  ll ans = 0;
  auto Hash = [&] (const string& s) {
    const int p = 31;
    const int m = 1e9 + 9;
    long long hash_value = 0;
    long long p_pow = 1;
    for (char c : s) {
      hash_value = (hash_value + (c - 'a' + 1) * p_pow) % m;
      p_pow = (p_pow * p) % m;
    }
    return hash_value;
  };
  unordered_map<long long, int> m;
  for (int i = 0; i < n; i++) {
    int w = 0;
    string t = "";
    for (int j = i; j < n; j++) {
      t += s[j];
      w += (!c[s[j]])?1: 0;
      if (w > k) break;
      long long h = Hash(t);
      if (m[h]) continue;
      m[h] = 1;
      ++ans;
    }
  }
  cout << ans << "\n";
  return 0;
}


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

#define all(x)            (x).begin(), (x).end()
#define sz(x)             (int)x.size()
#define len(x)            (int)x.length()
#define ac(x, i)          get<i>(x)
#define pb                push_back
#define mp                make_pair
#define ff                first
#define ss                second
#define trace(x)          cerr << #x << ": " << x << "\n"
#define trav0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trav1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trap0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define trap1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define travMap(a)        cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << "(" << i.ff << ", " << i.ss << "), "; cerr << "]\n"
#define traverse(a)       cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << i << ", "; cerr << "]\n"
#define random_permute(x) shuffle(all(x), mt)

typedef unsigned int uint;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef map<int, int> mapii;
typedef map<ll, ll> mapll;
typedef map<ll, int> mapli;
typedef unordered_map<int, int> umapii;
typedef unordered_map<ll, int> umapli;
const int infi = 1e9;
const ll infl = 1e18;
const int MOD = 1e9 + 7;
template <typename Map> bool map_compare (Map const &lhs, Map const &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());}
auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt(seed);
int randint(int p = MOD) { return mt() % p;}
ll randlong(ll p = infl) { return mt() % p;}
ll log_2 (ll n) { return (n > 1ll)? 1ll + log_2(n/2): 0ll;}
inline void add(ll&a, ll b) {a += b; if (a >= MOD) a -= MOD;}
inline void sub(ll&a, ll b) {a -= b; if (a < 0) a += MOD;}
template <class T>
struct cmp { // for priority_queue
  bool operator() (const T& x, const T& y) const {
    return x > y; // edit here
  }
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

#define int long long int

const int rdx = 117;

signed main() {
#ifdef HP
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false); cin.tie(NULL);
  string s;
  cin >> s;
  int n = len(s);
  unordered_map<int, int> m;
  vb c(200);
  string _t; cin >> _t;
  int k; cin >> k;
  for (int i = 0; i < 26; i++) {
    c[i + 'a'] = (_t[i] == '1');
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int hash = 0;
    int w = 0;
    for (int j = i; j < n; j++) {
      w += (c[s[j]])? 0: 1;
      if (w > k) break;
      hash = hash * rdx + s[j];
      if (m[hash]) continue;
      m[hash] = 1;
      ans++;
    }
  }
  cout << ans << "\n";
  return 0;
}


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

#define all(x)            (x).begin(), (x).end()
#define sz(x)             (int)x.size()
#define len(x)            (int)x.length()
#define ac(x, i)          get<i>(x)
#define pb                push_back
#define mp                make_pair
#define ff                first
#define ss                second
#define trace(x)          cerr << #x << ": " << x << "\n"
#define trav0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trav1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trap0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define trap1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define travMap(a)        cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << "(" << i.ff << ", " << i.ss << "), "; cerr << "]\n"
#define traverse(a)       cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << i << ", "; cerr << "]\n"
#define random_permute(x) shuffle(all(x), mt)

typedef unsigned int uint;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef map<int, int> mapii;
typedef map<ll, ll> mapll;
typedef map<ll, int> mapli;
typedef unordered_map<int, int> umapii;
typedef unordered_map<ll, int> umapli;
const int infi = 1e9;
const ll infl = 1e18;
const int MOD = 1e9 + 7;
template <typename Map> bool map_compare (Map const &lhs, Map const &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());}
auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt(seed);
int randint(int p = MOD) { return mt() % p;}
ll randlong(ll p = infl) { return mt() % p;}
ll log_2 (ll n) { return (n > 1ll)? 1ll + log_2(n/2): 0ll;}
inline void add(ll&a, ll b) {a += b; if (a >= MOD) a -= MOD;}
inline void sub(ll&a, ll b) {a -= b; if (a < 0) a += MOD;}
template <class T>
struct cmp { // for priority_queue
  bool operator() (const T& x, const T& y) const {
    return x > y; // edit here
  }
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

#define int long long int

const int rdx = MOD;

signed main() {
#ifdef HP
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false); cin.tie(NULL);
  string s;
  cin >> s;
  int n = len(s);
  unordered_map<int, int> m;
  vb c(200);
  string _t; cin >> _t;
  int k; cin >> k;
  for (int i = 0; i < 26; i++) {
    c[i + 'a'] = (_t[i] == '1');
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int hash = 0;
    int w = 0;
    for (int j = i; j < n; j++) {
      w += (c[s[j]])? 0: 1;
      if (w > k) break;
      hash = ((rdx * hash) % MOD + (s[j] - 'a' + 1) % MOD) % MOD;
      if (m[hash]) continue;
      m[hash] = 1;
      ans++;
    }
  }
  cout << ans << "\n";
  return 0;
}


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

#define all(x)            (x).begin(), (x).end()
#define sz(x)             (int)x.size()
#define len(x)            (int)x.length()
#define ac(x, i)          get<i>(x)
#define pb                push_back
#define mp                make_pair
#define ff                first
#define ss                second
#define trace(x)          cerr << #x << ": " << x << "\n"
#define trav0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trav1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trap0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define trap1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define travMap(a)        cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << "(" << i.ff << ", " << i.ss << "), "; cerr << "]\n"
#define traverse(a)       cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << i << ", "; cerr << "]\n"
#define random_permute(x) shuffle(all(x), mt)

typedef unsigned int uint;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef map<int, int> mapii;
typedef map<ll, ll> mapll;
typedef map<ll, int> mapli;
typedef unordered_map<int, int> umapii;
typedef unordered_map<ll, int> umapli;
const int infi = 1e9;
const ll infl = 1e18;
const int MOD = 1e9 + 9;
template <typename Map> bool map_compare (Map const &lhs, Map const &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());}
auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt(seed);
int randint(int p = MOD) { return mt() % p;}
ll randlong(ll p = infl) { return mt() % p;}
ll log_2 (ll n) { return (n > 1ll)? 1ll + log_2(n/2): 0ll;}
inline void add(ll&a, ll b) {a += b; if (a >= MOD) a -= MOD;}
inline void sub(ll&a, ll b) {a -= b; if (a < 0) a += MOD;}
template <class T>
struct cmp { // for priority_queue
  bool operator() (const T& x, const T& y) const {
    return x > y; // edit here
  }
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

#define int long long int

const int rdx = 1e9 + 7;

signed main() {
#ifdef HP
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false); cin.tie(NULL);
  string s;
  cin >> s;
  int n = len(s);
  unordered_map<int, int> m;
  vb c(200);
  string _t; cin >> _t;
  int k; cin >> k;
  for (int i = 0; i < 26; i++) {
    c[i + 'a'] = (_t[i] == '1');
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int hash = 0;
    int w = 0;
    for (int j = i; j < n; j++) {
      w += (c[s[j]])? 0: 1;
      if (w > k) break;
      hash = ((rdx * hash) % MOD + (s[j] - 'a' + 1) % MOD) % MOD;
      if (m[hash]) continue;
      m[hash] = 1;
      ans++;
    }
  }
  cout << ans << "\n";
  return 0;
}


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

#define all(x)            (x).begin(), (x).end()
#define sz(x)             (int)x.size()
#define len(x)            (int)x.length()
#define ac(x, i)          get<i>(x)
#define pb                push_back
#define mp                make_pair
#define ff                first
#define ss                second
#define trace(x)          cerr << #x << ": " << x << "\n"
#define trav0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trav1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trap0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define trap1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define travMap(a)        cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << "(" << i.ff << ", " << i.ss << "), "; cerr << "]\n"
#define traverse(a)       cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << i << ", "; cerr << "]\n"
#define random_permute(x) shuffle(all(x), mt)

typedef unsigned int uint;
typedef long long int ll;
typedef unsigned long long int ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef map<int, int> mapii;
typedef map<ll, ll> mapll;
typedef map<ll, int> mapli;
typedef unordered_map<int, int> umapii;
typedef unordered_map<ll, int> umapli;
const int infi = 1e9;
const ll infl = 1e18;
const int MOD = 1e9 + 7;
template <typename Map> bool map_compare (Map const &lhs, Map const &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());}
auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt(seed);
int randint(int p = MOD) { return mt() % p;}
ll randlong(ll p = infl) { return mt() % p;}
ll log_2 (ll n) { return (n > 1ll)? 1ll + log_2(n/2): 0ll;}
inline void add(ll&a, ll b) {a += b; if (a >= MOD) a -= MOD;}
inline void sub(ll&a, ll b) {a -= b; if (a < 0) a += MOD;}
template <class T>
struct cmp { // for priority_queue
  bool operator() (const T& x, const T& y) const {
    return x > y; // edit here
  }
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

signed main() {
#ifdef HP
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false); cin.tie(NULL);
  string s;
  cin >> s;
  int n = len(s);
  vb c(200, false);
  string ome;
  cin >> ome;
  for (int i = 0; i < 26; i++) {
    c['a'+i] = ome[i] == '1';
  }
  int k;
  cin >> k;
  ll ans = 0;
  unordered_map<string, int> m;
  for (int i = 0; i < n; i++) {
    int w = 0;
    string t = "";
    for (int j = i; j < n; j++) {
      t += s[j];
      w += (!c[s[j]])?1: 0;
      if (w > k) break;
      if (m[t]) continue;
      m[t] = 1;
      ++ans;
    }
  }
  cout << ans << "\n";
  return 0;
}


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

#define all(x)            (x).begin(), (x).end()
#define sz(x)             (int)x.size()
#define len(x)            (int)x.length()
#define ac(x, i)          get<i>(x)
#define pb                push_back
#define mp                make_pair
#define ff                first
#define ss                second
#define trace(x)          cerr << #x << ": " << x << "\n"
#define trav0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trav1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trap0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define trap1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define travMap(a)        cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << "(" << i.ff << ", " << i.ss << "), "; cerr << "]\n"
#define traverse(a)       cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << i << ", "; cerr << "]\n"
#define random_permute(x) shuffle(all(x), mt)

typedef unsigned int uint;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef map<int, int> mapii;
typedef map<ll, ll> mapll;
typedef map<ll, int> mapli;
typedef unordered_map<int, int> umapii;
typedef unordered_map<ll, int> umapli;
const int infi = 1e9;
const ll infl = 1e18;
const int MOD = 1e9 + 7;
template <typename Map> bool map_compare (Map const &lhs, Map const &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());}
auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt(seed);
int randint(int p = MOD) { return mt() % p;}
ll randlong(ll p = infl) { return mt() % p;}
ll log_2 (ll n) { return (n > 1ll)? 1ll + log_2(n/2): 0ll;}
inline void add(ll&a, ll b) {a += b; if (a >= MOD) a -= MOD;}
inline void sub(ll&a, ll b) {a -= b; if (a < 0) a += MOD;}
template <class T>
struct cmp { // for priority_queue
  bool operator() (const T& x, const T& y) const {
    return x > y; // edit here
  }
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

#define int long long int

const int rdx = randint();

signed main() {
#ifdef HP
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false); cin.tie(NULL);
  string s;
  cin >> s;
  int n = len(s);
  unordered_map<int, int> m;
  vb c(200);
  string _t; cin >> _t;
  int k; cin >> k;
  for (int i = 0; i < 26; i++) {
    c[i + 'a'] = (_t[i] == '1');
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int hash = 0;
    int w = 0;
    for (int j = i; j < n; j++) {
      w += (c[s[j]])? 0: 1;
      if (w > k) break;
      hash = ((rdx * hash) % MOD + (s[j] - 'a' + 1) % MOD) % MOD;
      if (m[hash]) continue;
      m[hash] = 1;
      ans++;
    }
  }
  cout << ans << "\n";
  return 0;
}


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

#define all(x)            (x).begin(), (x).end()
#define sz(x)             (int)x.size()
#define len(x)            (int)x.length()
#define ac(x, i)          get<i>(x)
#define pb                push_back
#define mp                make_pair
#define ff                first
#define ss                second
#define trace(x)          cerr << #x << ": " << x << "\n"
#define trav0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trav1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trap0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define trap1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define travMap(a)        cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << "(" << i.ff << ", " << i.ss << "), "; cerr << "]\n"
#define traverse(a)       cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << i << ", "; cerr << "]\n"
#define random_permute(x) shuffle(all(x), mt)

typedef unsigned int uint;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef map<int, int> mapii;
typedef map<ll, ll> mapll;
typedef map<ll, int> mapli;
typedef unordered_map<int, int> umapii;
typedef unordered_map<ll, int> umapli;
const int infi = 1e9;
const ll infl = 1e18;
const int MOD = 1e9 + 7;
template <typename Map> bool map_compare (Map const &lhs, Map const &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());}
auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt(seed);
int randint(int p = MOD) { return mt() % p;}
ll randlong(ll p = infl) { return mt() % p;}
ll log_2 (ll n) { return (n > 1ll)? 1ll + log_2(n/2): 0ll;}
inline void add(ll&a, ll b) {a += b; if (a >= MOD) a -= MOD;}
inline void sub(ll&a, ll b) {a -= b; if (a < 0) a += MOD;}
template <class T>
struct cmp { // for priority_queue
  bool operator() (const T& x, const T& y) const {
    return x > y; // edit here
  }
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

#define int long long int

const int rdx = 31;

signed main() {
#ifdef HP
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false); cin.tie(NULL);
  string s;
  cin >> s;
  int n = len(s);
  unordered_map<int, int> m;
  vb c(200);
  string _t; cin >> _t;
  int k; cin >> k;
  for (int i = 0; i < 26; i++) {
    c[i + 'a'] = (_t[i] == '1');
  }
  int ans = 0;
  for (int i = 0; i < n; i++) {
    int hash = 0;
    int w = 0;
    for (int j = i; j < n; j++) {
      w += (c[s[j]])? 0: 1;
      if (w > k) break;
      hash = hash * rdx + s[j];
      if (m[hash]) continue;
      m[hash] = 1;
      ans++;
    }
  }
  cout << ans << "\n";
  return 0;
}


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

#define all(x)            (x).begin(), (x).end()
#define sz(x)             (int)x.size()
#define len(x)            (int)x.length()
#define ac(x, i)          get<i>(x)
#define pb                push_back
#define mp                make_pair
#define ff                first
#define ss                second
#define trace(x)          cerr << #x << ": " << x << "\n"
#define trav0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trav1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << a[i] << ", "; cerr << "]\n"
#define trap0(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 0; i < n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define trap1(a, n)       cerr << #a << "[" << n <<  "] = ["; for (int i = 1; i <= n; i++) cerr << "(" << a[i].ff << ", " << a[i].ss << "), "; cerr << "]\n"
#define travMap(a)        cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << "(" << i.ff << ", " << i.ss << "), "; cerr << "]\n"
#define traverse(a)       cerr << #a << "[" << sz(a) <<  "] = ["; for (auto i : a) cerr << i << ", "; cerr << "]\n"
#define random_permute(x) shuffle(all(x), mt)

typedef unsigned int uint;
typedef long long int ll;
typedef unsigned long long int ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef map<int, int> mapii;
typedef map<ll, ll> mapll;
typedef map<ll, int> mapli;
typedef unordered_map<int, int> umapii;
typedef unordered_map<ll, int> umapli;
const int infi = 1e9;
const ll infl = 1e18;
const int MOD = 1e9 + 7;
template <typename Map> bool map_compare (Map const &lhs, Map const &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());}
auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt(seed);
int randint(int p = MOD) { return mt() % p;}
ll randlong(ll p = infl) { return mt() % p;}
ll log_2 (ll n) { return (n > 1ll)? 1ll + log_2(n/2): 0ll;}
inline void add(ll&a, ll b) {a += b; if (a >= MOD) a -= MOD;}
inline void sub(ll&a, ll b) {a -= b; if (a < 0) a += MOD;}
template <class T>
struct cmp { // for priority_queue
  bool operator() (const T& x, const T& y) const {
    return x > y; // edit here
  }
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

struct Trie {
  vector<int> END;
  vector<int> NXT[27];
  vector<bool> CREATED;
  int SIZE;

  void insert (const string& s) {
    int v = 0;
    int l = s.size();
    for (int i = 0; i < l; i++) {
      int c = s[i] - 'a';
      if (!CREATED[NXT[c][v]]) {
        NXT[c][v] = ++SIZE;
        CREATED[SIZE] = 1;
      }
      v = NXT[c][v];
    }
    ++END[v];
  }

  bool search (const string& tmp) {
    int v = 0;
    int l = tmp.size();
    for (int i = 0; i < l; i++) {
      int c = tmp[i] - 'a';
      if (!CREATED[NXT[c][v]]) {
        return false;
      }
      v = NXT[c][v];
    }
    return END[v] > 0;
  }

  Trie (int N) {
    SIZE = 0;
    END.resize(N);
    for (int i = 0; i <= 26; i++) {
      NXT[i].resize(N);
    }
    CREATED.resize(N);
  }
};

const int N = 1e5 + 100;
Trie T = Trie(N);

signed main() {
#ifdef HP
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false); cin.tie(NULL);
  string s;
  cin >> s;
  int n = len(s);
  vb c(200, false);
  string ome;
  cin >> ome;
  for (int i = 0; i < 26; i++) {
    c['a'+i] = ome[i] == '1';
  }
  int k;
  cin >> k;
  ll ans = 0;
  for (int i = 0; i < n; i++) {
    int w = 0;
    string t = "";
    for (int j = i; j < n; j++) {
      t += s[j];
      w += (!c[s[j]])?1: 0;
      if (w > k) break;
      if (T.search(t)) continue;
      T.insert(t);
      ++ans;
    }
  }
  cout << ans << "\n";
  return 0;
}


#include <bits/stdc++.h>
#define ll long long int
#define P pair
#define F first
#define S second
#define p_b push_back
#define ld long double
#define N 5000005
//#include <wadim>
ll mod = 998244353; //4294967296; 1000000000 + 7; 998244353; 2*3*5*7*11*13*17*19*23 + 1
ll inf = (ll)(1e18);
using namespace std;

mt19937 unlucko(chrono::steady_clock::now().time_since_epoch().count());

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//using ordered_set_pair = tree<pair<ll, ll>, null_type, less<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update>;
//using ordered_set=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
//typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
//typedef tree<pair<ll, ll>, null_type, less_equal<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset_pair;

vector<int> graph[1000000];
int bound = 0;
int bfs(int x){
    queue<int> q;
    q.push(x);
    unordered_map<int, int> mp, from;
    int mins = mod;
    while(!q.empty()){
        int y = q.front();
        q.pop();
        for(auto it:graph[y]){
            if(from[y] == it || it * y)
                continue;
            if(!mp[it]){
                from[it] = y;
                mp[it] = mp[y] + 1;
                q.push(it);
            }
            else{
                mins = min(mins, mp[it] + mp[y] + 1);
            }
        }
    }
    return mins;
}

int main() {
    iostream::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> a(n);
    vector<bool> primes(1000000, false);
    for(int i=0;i<n;i++){
        int x, got = 1, v1 = 1, v2 = 1;
        cin >> x;
        bound = max(x, bound);
        for(int j=2;j<=sqrt(x);j++){
            int curr = 0;
            while(x % j == 0){
                x /= j;
                curr ++;
            }
            if(curr % 2){
                got *= j;
                if(v1 == 1)
                    v1 = j;
                else
                    v2 = j;
            }
        }
        if(x != 1){
           if(v1 == 1)
                v1 = x;
            else
                v2 = x;
        }
        if(v1 > v2)
            swap(v1, v2);
        primes[v1] = true;
        primes[v2] = true;
        a[i] = x * got;
        graph[v1].push_back(v2);
        graph[v2].push_back(v1);
    }
    sort(a.begin(), a.end());
    if(a[0] == 1){
        cout << 1;
        return 0;
    }
    for(int i=1;i<n;i++){
        if(a[i] == a[i - 1]){
            cout << 2;
            return 0;
        }
    }
    int mins = mod;
    for(int i=1;i<1000000;i++){
        if(!primes[i])
            continue;
        mins = min(bfs(i), mins);
    }
    if(mins == mod)
        cout << "-1\n";
    else
        cout << mins;
}


#include <bits/stdc++.h>
#define ll long long int
#define P pair
#define F first
#define S second
#define p_b push_back
#define ld long double
#define N 5000005
//#include <wadim>
ll mod = 998244353; //4294967296; 1000000000 + 7; 998244353; 2*3*5*7*11*13*17*19*23 + 1
ll inf = (ll)(1e18);
using namespace std;

mt19937 unlucko(chrono::steady_clock::now().time_since_epoch().count());

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//using ordered_set_pair = tree<pair<ll, ll>, null_type, less<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update>;
//using ordered_set=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
//typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
//typedef tree<pair<ll, ll>, null_type, less_equal<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset_pair;

vector<int> graph[1000000];

int bfs(int x){
    queue<pair<pair<int, int>, int> > q;
    q.push({{x, 1}, x});
    int mins = mod;
    map<int, int> mp;
    while(!q.empty()){
        int y = q.front().F.F, curr = q.front().F.S, prev = q.front().S;
        q.pop();
        mp[y] = curr;
        for(auto it:graph[y]){
            if(it < y)
                continue;
            if(mp[it])
                return mp[it] + mp[y];
            mp[it] = curr;
            q.push({{it, curr + 1}, y});
        }
    }
    return mod;
}

int main() {
    iostream::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> a(n);
    vector<bool> primes(1000000, false);
    for(int i=0;i<n;i++){
        int x, got = 1, v1 = 1, v2 = 1;
        cin >> x;
        for(int j=2;j<=sqrt(x);j++){
            int curr = 0;
            while(x % j == 0){
                x /= j;
                curr ++;
            }
            if(curr % 2){
                got *= j;
                if(v1 == 1)
                    v1 = j;
                else
                    v2 = j;
            }
        }
        if(x != 1){
           if(v1 == 1)
                v1 = x;
            else
                v2 = x;
        }
        primes[v1] = true;
        primes[v2] = true;
        a[i] = x * got;
        graph[v1].push_back(v2);
        graph[v2].push_back(v1);
    }
    for(int i=0;i<n;i++){
        if(a[i] == 1){
            cout << 1;
            return 0;
        }
    }
    int mins = mod;
    for(int i=1;i<1000000;i++){
        if(!primes[i])
            continue;
        mins = min(bfs(i), mins);
    }
    if(mins == mod)
        cout << "-1\n";
    else
        cout << mins;
}


#include <bits/stdc++.h>
#define ll long long int
#define P pair
#define F first
#define S second
#define p_b push_back
#define ld long double
#define N 5000005
//#include <wadim>
ll mod = 998244353; //4294967296; 1000000000 + 7; 998244353; 2*3*5*7*11*13*17*19*23 + 1
ll inf = (ll)(1e18);
using namespace std;

mt19937 unlucko(chrono::steady_clock::now().time_since_epoch().count());

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//using ordered_set_pair = tree<pair<ll, ll>, null_type, less<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update>;
//using ordered_set=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
//typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
//typedef tree<pair<ll, ll>, null_type, less_equal<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset_pair;

vector<int> graph[1000000];

int bfs(int x){
    queue<pair<pair<int, int>, int> > q;
    q.push({{x, 0}, x});
    map<int, int> mp;
    while(!q.empty()){
        int y = q.front().F.F, curr = q.front().F.S, prev = q.front().S;
        q.pop();
        for(auto it:graph[y]){
            if(mp[it])
                return mp[it] + mp[y] + 1;
            if(!mp[it])
                mp[it] = curr + 1;
            else
                continue;
            q.push({{it, curr + 1}, y});
        }
    }
    return mod;
}

int main() {
    iostream::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> a(n);
    vector<bool> primes(1000000, false);
    for(int i=0;i<n;i++){
        int x, got = 1, v1 = 1, v2 = 1;
        cin >> x;
        for(int j=2;j<=sqrt(x);j++){
            int curr = 0;
            while(x % j == 0){
                x /= j;
                curr ++;
            }
            if(curr % 2){
                got *= j;
                if(v1 == 1)
                    v1 = j;
                else
                    v2 = j;
            }
        }
        if(x != 1){
           if(v1 == 1)
                v1 = x;
            else
                v2 = x;
        }
        if(v1 > v2)
            swap(v1, v2);
        primes[v1] = true;
        primes[v2] = true;
        a[i] = x * got;
        graph[v1].push_back(v2);
    }
    for(int i=0;i<n;i++){
        if(a[i] == 1){
            cout << 1;
            return 0;
        }
    }
    int mins = mod;
    for(int i=1;i<1000000;i++){
        if(!primes[i])
            continue;
        mins = min(bfs(i), mins);
    }
    if(mins == mod)
        cout << "-1\n";
    else
        cout << mins;
}


#include <bits/stdc++.h>
#define ll long long int
#define P pair
#define F first
#define S second
#define p_b push_back
#define ld long double
#define N 5000005
//#include <wadim>
ll mod = 998244353; //4294967296; 1000000000 + 7; 998244353; 2*3*5*7*11*13*17*19*23 + 1
ll inf = (ll)(1e18);
using namespace std;

mt19937 unlucko(chrono::steady_clock::now().time_since_epoch().count());

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//using ordered_set_pair = tree<pair<ll, ll>, null_type, less<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update>;
//using ordered_set=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
//typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
//typedef tree<pair<ll, ll>, null_type, less_equal<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset_pair;

vector<int> graph[1000000];
int bound = 0;
int bfs(int x){
    queue<int> q;
    q.push(x);
    unordered_map<int, int> mp, from;
    int mins = mod;
    while(!q.empty()){
        int y = q.front();
        q.pop();
        for(auto it:graph[y]){
            if(from[y] == it || it * y > bound)
                continue;
            if(!mp[it]){
                from[it] = y;
                mp[it] = mp[y] + 1;
                q.push(it);
            }
            else{
                mins = min(mins, mp[it] + mp[y] + 1);
            }
        }
    }
    return mins;
}

int main() {
    iostream::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> a(n);
    vector<bool> primes(1000000, false);
    for(int i=0;i<n;i++){
        int x, got = 1, v1 = 1, v2 = 1;
        cin >> x;
        bound = max(x, bound);
        for(int j=2;j<=sqrt(x);j++){
            int curr = 0;
            while(x % j == 0){
                x /= j;
                curr ++;
            }
            if(curr % 2){
                got *= j;
                if(v1 == 1)
                    v1 = j;
                else
                    v2 = j;
            }
        }
        if(x != 1){
           if(v1 == 1)
                v1 = x;
            else
                v2 = x;
        }
        if(v1 > v2)
            swap(v1, v2);
        primes[v1] = true;
        primes[v2] = true;
        a[i] = x * got;
        graph[v1].push_back(v2);
        graph[v2].push_back(v1);
    }
    sort(a.begin(), a.end());
    if(a[0] == 1){
        cout << 1;
        return 0;
    }
    for(int i=1;i<n;i++){
        if(a[i] == a[i - 1]){
            cout << 2;
            return 0;
        }
    }
    int mins = mod;
    for(int i=1;i<1000000;i++){
        if(!primes[i])
            continue;
        mins = min(bfs(i), mins);
    }
    if(mins == mod)
        cout << "-1\n";
    else
        cout << mins;
}


#include <bits/stdc++.h>
#define ll long long int
#define P pair
#define F first
#define S second
#define p_b push_back
#define ld long double
#define N 5000005
//#include <wadim>
ll mod = 998244353; //4294967296; 1000000000 + 7; 998244353; 2*3*5*7*11*13*17*19*23 + 1
ll inf = (ll)(1e18);
using namespace std;

mt19937 unlucko(chrono::steady_clock::now().time_since_epoch().count());

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//using ordered_set_pair = tree<pair<ll, ll>, null_type, less<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update>;
//using ordered_set=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
//typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
//typedef tree<pair<ll, ll>, null_type, less_equal<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset_pair;

vector<int> graph[1000000];
int bound = 0;
int bfs(int x){
    queue<int> q;
    q.push(x);
    unordered_map<int, int> mp, from;
    int mins = mod;
    while(!q.empty()){
        int y = q.front();
        q.pop();
        for(auto it:graph[y]){
            if(from[y] == it || y > bound / it || x > bound / it)
                continue;
            if(!mp[it]){
                from[it] = y;
                mp[it] = mp[y] + 1;
                q.push(it);
            }
            else{
                mins = min(mins, mp[it] + mp[y] + 1);
            }
        }
    }
    return mins;
}

int main() {
    iostream::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> a(n);
    vector<bool> primes(1000000, false);
    for(int i=0;i<n;i++){
        int x, got = 1, v1 = 1, v2 = 1;
        cin >> x;
        bound = max(x, bound);
        for(int j=2;j<=sqrt(x);j++){
            int curr = 0;
            while(x % j == 0){
                x /= j;
                curr ++;
            }
            if(curr % 2){
                got *= j;
                if(v1 == 1)
                    v1 = j;
                else
                    v2 = j;
            }
        }
        if(x != 1){
           if(v1 == 1)
                v1 = x;
            else
                v2 = x;
        }
        if(v1 > v2)
            swap(v1, v2);
        primes[v1] = true;
        primes[v2] = true;
        a[i] = x * got;
        graph[v1].push_back(v2);
        graph[v2].push_back(v1);
    }
    sort(a.begin(), a.end());
    if(a[0] == 1){
        cout << 1;
        return 0;
    }
    for(int i=1;i<n;i++){
        if(a[i] == a[i - 1]){
            cout << 2;
            return 0;
        }
    }
    int mins = mod;
    for(int i=1;i<1000000;i++){
        if(!primes[i])
            continue;
        mins = min(bfs(i), mins);
    }
    if(mins == mod)
        cout << "-1\n";
    else
        cout << mins;
}


#include <bits/stdc++.h>
#define ll long long int
#define P pair
#define F first
#define S second
#define p_b push_back
#define ld long double
#define N 5000005
//#include <wadim>
ll mod = 998244353; //4294967296; 1000000000 + 7; 998244353; 2*3*5*7*11*13*17*19*23 + 1
ll inf = (ll)(1e18);
using namespace std;

mt19937 unlucko(chrono::steady_clock::now().time_since_epoch().count());

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//using ordered_set_pair = tree<pair<ll, ll>, null_type, less<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update>;
//using ordered_set=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
//typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
//typedef tree<pair<ll, ll>, null_type, less_equal<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset_pair;

vector<int> graph[1000000];

int bfs(int x){
    queue<pair<pair<int, int>, int> > q;
    q.push({{x, 0}, x});
    map<int, int> mp;
    while(!q.empty()){
        int y = q.front().F.F, curr = q.front().F.S, prev = q.front().S;
        q.pop();
        for(auto it:graph[y]){
            if(mp[it])
                return mp[it] + mp[y] + 1;
            if(!mp[it])
                mp[it] = curr + 1;
            q.push({{it, curr + 1}, y});
        }
    }
    return mod;
}

int main() {
    iostream::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> a(n);
    vector<bool> primes(1000000, false);
    for(int i=0;i<n;i++){
        int x, got = 1, v1 = 1, v2 = 1;
        cin >> x;
        for(int j=2;j<=sqrt(x);j++){
            int curr = 0;
            while(x % j == 0){
                x /= j;
                curr ++;
            }
            if(curr % 2){
                got *= j;
                if(v1 == 1)
                    v1 = j;
                else
                    v2 = j;
            }
        }
        if(x != 1){
           if(v1 == 1)
                v1 = x;
            else
                v2 = x;
        }
        if(v1 > v2)
            swap(v1, v2);
        primes[v1] = true;
        primes[v2] = true;
        a[i] = x * got;
        graph[v1].push_back(v2);
    }
    for(int i=0;i<n;i++){
        if(a[i] == 1){
            cout << 1;
            return 0;
        }
    }
    int mins = mod;
    for(int i=1;i<1000000;i++){
        if(!primes[i])
            continue;
        mins = min(bfs(i), mins);
    }
    if(mins == mod)
        cout << "-1\n";
    else
        cout << mins;
}


#include <bits/stdc++.h>
#define ll long long int
#define P pair
#define F first
#define S second
#define p_b push_back
#define ld long double
#define N 5000005
//#include <wadim>
ll mod = 998244353; //4294967296; 1000000000 + 7; 998244353; 2*3*5*7*11*13*17*19*23 + 1
ll inf = (ll)(1e18);
using namespace std;

mt19937 unlucko(chrono::steady_clock::now().time_since_epoch().count());

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//using ordered_set_pair = tree<pair<ll, ll>, null_type, less<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update>;
//using ordered_set=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
//typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
//typedef tree<pair<ll, ll>, null_type, less_equal<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset_pair;

vector<int> graph[1000000];

int bfs(int x){
    queue<pair<pair<int, int>, int> > q;
    q.push({{x, 0}, x});
    map<int, int> mp;
    int mins = mod;
    while(!q.empty()){
        int y = q.front().F.F, curr = q.front().F.S, prev = q.front().S;
        q.pop();
        for(auto it:graph[y]){
            if(mp[it])
                mins = min(mp[it] + mp[y] + 1, mins);
            if(!mp[it])
                mp[it] = curr + 1;
            else
                continue;
            q.push({{it, curr + 1}, y});
        }
    }
    return mins;
}

int main() {
    iostream::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> a(n);
    vector<bool> primes(1000000, false);
    for(int i=0;i<n;i++){
        int x, got = 1, v1 = 1, v2 = 1;
        cin >> x;
        for(int j=2;j<=sqrt(x);j++){
            int curr = 0;
            while(x % j == 0){
                x /= j;
                curr ++;
            }
            if(curr % 2){
                got *= j;
                if(v1 == 1)
                    v1 = j;
                else
                    v2 = j;
            }
        }
        if(x != 1){
           if(v1 == 1)
                v1 = x;
            else
                v2 = x;
        }
        if(v1 > v2)
            swap(v1, v2);
        primes[v1] = true;
        primes[v2] = true;
        a[i] = x * got;
        graph[v1].push_back(v2);
    }
    for(int i=0;i<n;i++){
        if(a[i] == 1){
            cout << 1;
            return 0;
        }
    }
    int mins = mod;
    for(int i=1;i<1000000;i++){
        if(!primes[i])
            continue;
        mins = min(bfs(i), mins);
    }
    if(mins == mod)
        cout << "-1\n";
    else
        cout << mins;
}


#include <bits/stdc++.h>
#define ll long long int
#define P pair
#define F first
#define S second
#define p_b push_back
#define ld long double
#define N 5000005
//#include <wadim>
ll mod = 998244353; //4294967296; 1000000000 + 7; 998244353; 2*3*5*7*11*13*17*19*23 + 1
ll inf = (ll)(1e18);
using namespace std;

mt19937 unlucko(chrono::steady_clock::now().time_since_epoch().count());

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//using ordered_set_pair = tree<pair<ll, ll>, null_type, less<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update>;
//using ordered_set=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
//typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset;
//typedef tree<pair<ll, ll>, null_type, less_equal<pair<ll, ll> >, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset_pair;

vector<int> graph[1000000];
int bound = 0;
int bfs(int x){
    queue<int> q;
    q.push(x);
    map<int, int> mp, from;
    int mins = mod;
    while(!q.empty()){
        int y = q.front();
        q.pop();
        for(auto it:graph[y]){
            if(from[y] == it || it * x > bound)
                continue;
            if(!mp[it]){
                from[it] = y;
                mp[it] = mp[y] + 1;
                q.push(it);
            }
            else{
                mins = min(mins, mp[it] + mp[y] + 1);
            }
        }
    }
    return mins;
}

int main() {
    iostream::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> a(n);
    vector<bool> primes(1000000, false);
    for(int i=0;i<n;i++){
        int x, got = 1, v1 = 1, v2 = 1;
        cin >> x;
        bound = max(x, bound);
        for(int j=2;j<=sqrt(x);j++){
            int curr = 0;
            while(x % j == 0){
                x /= j;
                curr ++;
            }
            if(curr % 2){
                got *= j;
                if(v1 == 1)
                    v1 = j;
                else
                    v2 = j;
            }
        }
        if(x != 1){
           if(v1 == 1)
                v1 = x;
            else
                v2 = x;
        }
        if(v1 > v2)
            swap(v1, v2);
        primes[v1] = true;
        primes[v2] = true;
        a[i] = x * got;
        graph[v1].push_back(v2);
        graph[v2].push_back(v1);
    }
    sort(a.begin(), a.end());
    if(a[0] == 1){
        cout << 1;
        return 0;
    }
    for(int i=1;i<n;i++){
        if(a[i] == a[i - 1]){
            cout << 2;
            return 0;
        }
    }
    int mins = mod;
    for(int i=1;i<1000000;i++){
        if(!primes[i])
            continue;
        mins = min(bfs(i), mins);
    }
    if(mins == mod)
        cout << "-1\n";
    else
        cout << mins;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 10;
int n, a[maxn], ans;
set<pair<int,int>> s;
vector<int> g[maxn], f;
pair<int,int> split(int x)
{
    int p = 1, q = 1, k = sqrt(x) + 1;
    for(int i = 2; i <= k; i++)
    {
        int cnt = 0;
        while(x % i == 0)
        {
            x /= i;
            cnt++;
        }
        if(cnt & 1)
        {
            if(p == 1)
                p = i;
            else
                q = i;
        }
    }
    if(x > 1)
        q = x;
    if(p < q)
        swap(p, q);
    return make_pair(p, q);
}
int d[maxn];
bool vis[maxn];
void BFS(int s)
{
    queue<pair<int,int> > q;
    vis[s] = true;
    d[s] = 0;
    q.push(make_pair(s, -1));
    while(!q.empty())
    {
        int u = q.front().first, fa = q.front().second;
        q.pop();
        for(auto v: g[u])
        {
            if(v == fa)
                continue;
            if(!vis[v])
            {
                vis[v] = true;
                d[v] = d[u] + 1;
                q.push(make_pair(v, u));
            }
            else
                ans = min(ans, d[u] + d[v] + 1);
        }
    }
}
int main()
{
    scanf("%d", &n);
    ans = INF;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        pair<int,int> e = split(a[i]);
        if(e.first == e.second)
            ans = min(ans, 1);
        else if(s.count(e))
            ans = min(ans, 2);
        g[e.first].push_back(e.second);
        g[e.second].push_back(e.first);
        s.insert(e);
    }
    if(ans != INF)
    {
        printf("%d\n", ans);
        return 0;
    }
    for(int i = 1; i <= 1000; i++)
    {
        if(!vis[i])
            BFS(i);
    }
    if(ans == INF)
        printf("-1\n");
    else
        printf("%d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 10;
int n, a[maxn], ans;
set<pair<int,int>> s;
vector<int> g[maxn], f;
pair<int,int> split(int x)
{
    int p = 1, q = 1, k = sqrt(x) + 1;
    for(int i = 2; i <= k; i++)
    {
        int cnt = 0;
        while(x % i == 0)
        {
            x /= i;
            cnt++;
        }
        if(cnt & 1)
        {
            if(p == 1)
                p = i;
            else
                q = i;
        }
    }
    if(x > 1)
        q = x;
    if(p < q)
        swap(p, q);
    return make_pair(p, q);
}
int d[maxn];
bool vis[maxn];
void BFS(int s)
{
    queue<pair<int,int> > q;
    memset(vis, false, sizeof(vis));
    vis[s] = true;
    d[s] = 0;
    q.push(make_pair(s, -1));
    while(!q.empty())
    {
        int u = q.front().first, fa = q.front().second;
        q.pop();
        for(auto v: g[u])
        {
            if(v == fa)
                continue;
            if(!vis[v])
            {
                vis[v] = true;
                d[v] = d[u] + 1;
                q.push(make_pair(v, u));
            }
            else
                ans = min(ans, d[u] + d[v] + 1);
        }
    }
}
int main()
{
    scanf("%d", &n);
    ans = INF;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        pair<int,int> e = split(a[i]);
        if(e.first == e.second)
            ans = min(ans, 1);
        else if(s.count(e))
            ans = min(ans, 2);
        g[e.first].push_back(e.second);
        g[e.second].push_back(e.first);
        s.insert(e);
    }
    if(ans != INF)
    {
        printf("%d\n", ans);
        return 0;
    }
    for(int i = 1; i <= 1000; i++)
        BFS(i);
    if(ans == INF)
        printf("-1\n");
    else
        printf("%d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int maxa = 1e6 + 10;
int n, a[maxn], ans;
bool vis[2*maxn];
struct edge
{
	int u, v;
	int next;
}e[2*maxn];
int head[maxa], deep[maxa], tot;
void add_edge(int u, int v)
{
	e[tot] = edge{u, v, head[u]};
	head[u] = tot++;
	e[tot] = edge{v, u, head[v]};
	head[v] = tot++;
}
void split(int x)
{
    int u = 1, v = 1, k = sqrt(x) + 1;
    for(int i = 2; i <= k; i++)
    {
        int cnt = 0;
        while(x % i == 0)
        {
            x /= i;
            cnt++;
        }
        if(cnt & 1)
        {
            if(u == 1)
                u = i;
            else
                v = i;
        }
    }
    if(x > 1)
        v = x;
    add_edge(u, v);
}
void DFS(int u)
{
    for(int i = head[u]; i != -1; i = e[i].next)
    {
        if(vis[i])
            continue;
        vis[i] = vis[i^1] = true;
        int v = e[i].v;
        if(deep[v])
            ans = min(ans, deep[u] - deep[v] + 1);
        deep[v] = deep[u] + 1;
        DFS(v);
    }
}
int main()
{
    memset(head, -1, sizeof(head));
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        split(a[i]);
    }
    ans  = INF;
    for(int i = 0; i < 2*n; i++)
    {
        if(vis[i])
            continue;
        deep[e[i].u] = 1;
        DFS(e[i].u);
    }
    if(ans == INF)
        printf("-1\n");
    else
        printf("%d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 10;
int n, a[maxn], ans;
set<pair<int,int>> s;
vector<int> g[maxn];
pair<int,int> split(int x)
{
    int p = 1, q = 1, k = sqrt(x) + 1;
    for(int i = 2; i <= k; i++)
    {
        int cnt = 0;
        while(x % i == 0)
        {
            x /= i;
            cnt++;
        }
        if(cnt & 1)
        {
            if(p == 1)
                p = i;
            else
                q = i;
        }
    }
    if(x > 1)
        q = x;
    if(p < q)
        swap(p, q);
    return make_pair(p, q);
}
int d[maxn];
bool vis[maxn];
void BFS(int s)
{
    memset(vis, false, sizeof(vis));
    queue<pair<int,int> > q;
    vis[s] = true;
    d[s] = 0;
    q.push(make_pair(s, -1));
    while(!q.empty())
    {
        int u = q.front().first, fa = q.front().second;
        q.pop();
        for(auto v: g[u])
        {
            if(v == fa)
                continue;
            if(!vis[v])
            {
                vis[v] = true;
                d[v] = d[u] + 1;
                q.push(make_pair(v, u));
            }
            else
            {
                ans = min(ans, d[u] + d[v] + 1);
                return;
            }
        }
    }
}
int main()
{
    scanf("%d", &n);
    ans = INF;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        pair<int,int> e = split(a[i]);
        if(e.first == e.second)
            ans = min(ans, 1);
        else if(s.count(e))
            ans = min(ans, 2);
        g[e.first].push_back(e.second);
        g[e.second].push_back(e.first);
        s.insert(e);
    }
    if(ans != INF)
    {
        printf("%d\n", ans);
        return 0;
    }
    for(int i = 1; i <= 1000; i++)
        BFS(i);
    if(ans == INF)
        printf("-1\n");
    else
        printf("%d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int maxa = 1e6 + 10;
int n, a[maxn], ans;
bool vis[2*maxn];
struct edge
{
	int u, v;
	int next;
}e[2*maxn];
int head[maxa], deep[maxa], tot;
void add_edge(int u, int v)
{
	e[tot] = edge{u, v, head[u]};
	head[u] = tot++;
	e[tot] = edge{v, u, head[v]};
	head[v] = tot++;
}
void split(int x)
{
    int u = 1, v = 1, k = sqrt(x) + 1;
    for(int i = 2; i <= k; i++)
    {
        int cnt = 0;
        while(x % i == 0)
        {
            x /= i;
            cnt++;
        }
        if(cnt & 1)
        {
            if(u == 1)
                u = i;
            else
                v = i;
        }
    }
    if(x > 1)
        v = x;
    add_edge(u, v);
}
void DFS(int u)
{
    for(int i = head[u]; i != -1; i = e[i].next)
    {
        if(vis[i])
            continue;
        vis[i] = vis[i^1] = true;
        int v = e[i].v;
        if(deep[v])
            ans = min(ans, deep[u] - deep[v] + 1);
        else
        {
            deep[v] = deep[u] + 1;
            DFS(v);
        }
    }
}
int main()
{
    memset(head, -1, sizeof(head));
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        split(a[i]);
    }
    ans  = INF;
    for(int i = 0; i < 2*n; i++)
    {
        if(vis[i])
            continue;
        deep[e[i].u] = 1;
        DFS(e[i].u);
    }
    if(ans == INF)
        printf("-1\n");
    else
        printf("%d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 10;
int n, a[maxn], ans;
set<pair<int,int>> s;
vector<int> g[maxn], f;
pair<int,int> split(int x)
{
    int p = 1, q = 1, k = sqrt(x) + 1;
    for(int i = 2; i <= k; i++)
    {
        int cnt = 0;
        while(x % i == 0)
        {
            x /= i;
            cnt++;
        }
        if(cnt & 1)
        {
            if(p == 1)
                p = i;
            else
                q = i;
        }
    }
    if(x > 1)
        q = x;
    if(p < q)
        swap(p, q);
    return make_pair(p, q);
}
int d[maxn];
bool vis[maxn];
void BFS(int s)
{
    queue<int> q;
    for(auto u:f)
    {
        d[u] = INF;
        vis[u] = false;
    }
    d[s] = 0;
    vis[s] = true;
    q.push(s);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        vis[u] = false;
        for(auto v: g[u])
        {
            if(d[v] > d[u] + 1)
            {
                d[v] = d[u] + 1;
                vis[v] = true;
                q.push(v);
            }
            else if(vis[v])
                ans = min(ans, d[u] + d[v] + 1);
        }
    }
}
int main()
{
    scanf("%d", &n);
    ans = INF;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        pair<int,int> e = split(a[i]);
        if(e.first == e.second)
            ans = min(ans, 1);
        else if(s.count(e))
            ans = min(ans, 2);
        g[e.first].push_back(e.second);
        g[e.second].push_back(e.first);
        f.push_back(e.first);
        f.push_back(e.second);
        s.insert(e);
    }
    if(ans != INF)
    {
        printf("%d\n", ans);
        return 0;
    }
    sort(f.begin(), f.end());
    unique(f.begin(), f.end());
    for(int i = 1; i <= 1000; i++)
        BFS(i);
    if(ans == INF)
        printf("-1\n");
    else
        printf("%d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int N = 1e3;
int n, a[maxn], ans;
set<pair<int,int>> s;
vector<int> g[N + 10];
pair<int,int> split(int x)
{
    int p = 1, q = 1, k = sqrt(x) + 1;
    for(int i = 2; i <= k; i++)
    {
        int cnt = 0;
        while(x % i == 0)
        {
            x /= i;
            cnt++;
        }
        if(cnt & 1)
        {
            if(p == 1)
                p = i;
            else
                q = i;
        }
    }
    if(x > 1)
        q = x;
    if(p < q)
        swap(p, q);
    return make_pair(p, q);
}
queue<int> q;
int d[N + 10];
bool vis[N + 10];
void BFS(int s)
{
    while(!q.empty())
        q.pop();
    memset(vis, false, sizeof(vis));
    d[s] = 0;
    vis[s] = true;
    q.push(s);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        for(auto v: g[u])
        {
            if(vis[v])
            {
                if(d[u] + d[v] + 1 > 2)
                    ans = min(ans, d[u] + d[v] + 1);
            }
            else
            {
                d[v] = d[u] + 1;
                vis[v] = true;
                q.push(v);
            }
        }
    }
}
int main()
{
    scanf("%d", &n);
    ans = INF;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        pair<int,int> e = split(a[i]);
        if(e.first == e.second)
            ans = min(ans, 1);
        else if(s.count(e))
            ans = min(ans, 2);
        else if(e.first <= N)
        {
            g[e.first].push_back(e.second);
            g[e.second].push_back(e.first);
        }
        s.insert(e);
    }
    if(ans != INF)
    {
        printf("%d\n", ans);
        return 0;
    }
    for(int i = 1; i <= N; i++)
        BFS(i);
    if(ans == INF)
        printf("-1\n");
    else
        printf("%d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 10;
const int N = 1e6;
int n, a[maxn], ans;
bool vis1[maxn], vis2[maxn];
struct edge
{
	int u, v;
	int next;
}e[maxn];
int head[maxn], tot;
void add_edge(int u, int v)
{
	e[tot] = edge{u, v, head[u]};
	head[u] = tot++;
	e[tot] = edge{v, u, head[v]};
	head[v] = tot++;
}
void split(int x)
{
    int u = 1, v = 1, k = sqrt(x) + 1;
    for(int i = 2; i <= k; i++)
    {
        int cnt = 0;
        while(x % i == 0)
        {
            x /= i;
            cnt++;
        }
        if(cnt & 1)
        {
            if(u == 1)
                u = i;
            else
                v = i;
        }
    }
    if(x > 1)
        v = x;
    add_edge(u, v);
}
queue<int> q;
int d[maxn], r1[maxn], t1, r2[maxn], t2;
void BFS(int s)
{
    t1 = t2 = d[s] = 0;
    vis1[s] = true;
    r1[++t1] = s;
    q.push(s);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        for(int i = head[u]; i != -1; i = e[i].next)
        {
            int v = e[i].v;
            if(vis2[i])
                continue;
            if(vis1[v])
                ans = min(ans, d[v] + d[u] + 1);
            else
            {
                vis2[i] = vis2[i^1] = true;
                r2[++t2] = i;
                d[v] = d[u] + 1;
                vis1[v] = true;
                r1[++t1] = v;
                q.push(v);
            }
        }
    }
    for(int i = 1; i <= t1; i++)
        vis1[r1[i]] = false;
    for(int i = 1; i <= t2; i++)
        vis2[r2[i]] = vis2[r2[i]^1] = false;
}
int main()
{
    memset(head, -1, sizeof(head));
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        split(a[i]);
    }
    ans  = INF;
    for(int i = 1; i <= N; i++)
        BFS(i);
    if(ans == INF)
        printf("-1\n");
    else
        printf("%d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int N = 1e3;
int n, a[maxn], ans;
set<pair<int,int>> s;
vector<int> g[N + 10];
pair<int,int> split(int x)
{
    int p = 1, q = 1, k = sqrt(x) + 1;
    for(int i = 2; i <= k; i++)
    {
        int cnt = 0;
        while(x % i == 0)
        {
            x /= i;
            cnt++;
        }
        if(cnt & 1)
        {
            if(p == 1)
                p = i;
            else
                q = i;
        }
    }
    if(x > 1)
        q = x;
    if(p < q)
        swap(p, q);
    return make_pair(p, q);
}
int d[N + 10];
bool vis[N + 10];
void BFS(int s)
{
    queue<int> q;
    memset(vis, false, sizeof(vis));
    memset(d, 0x3f, sizeof(d));
    d[s] = 0;
    vis[s] = true;
    q.push(s);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        vis[u] = false;
        for(auto v: g[u])
        {
            if(d[v] > d[u] + 1)
            {
                d[v] = d[u] + 1;
                vis[v] = true;
                q.push(v);
            }
            else if(vis[v])
                ans = min(ans, d[u] + d[v] + 1);
        }
    }
}
int main()
{
    scanf("%d", &n);
    ans = INF;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        pair<int,int> e = split(a[i]);
        if(e.first == e.second)
            ans = min(ans, 1);
        else if(s.count(e))
            ans = min(ans, 2);
        else if(e.first <= N)
        {
            g[e.first].push_back(e.second);
            g[e.second].push_back(e.first);
        }
        s.insert(e);
    }
    if(ans != INF)
    {
        printf("%d\n", ans);
        return 0;
    }
    for(int i = 1; i <= N; i++)
        BFS(i);
    if(ans == INF)
        printf("-1\n");
    else
        printf("%d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 10;
const int N = 1e6;
int n, a[maxn], ans;
bool vis1[maxn], vis2[maxn];
struct edge
{
	int u, v;
	int next;
}e[maxn];
int head[maxn], tot;
void add_edge(int u, int v)
{
	e[tot] = edge{u, v, head[u]};
	head[u] = tot++;
	e[tot] = edge{v, u, head[v]};
	head[v] = tot++;
}
void split(int x)
{
    int u = 1, v = 1, k = sqrt(x) + 1;
    for(int i = 2; i <= k; i++)
    {
        int cnt = 0;
        while(x % i == 0)
        {
            x /= i;
            cnt++;
        }
        if(cnt & 1)
        {
            if(u == 1)
                u = i;
            else
                v = i;
        }
    }
    if(x > 1)
        v = x;
    add_edge(u, v);
}
queue<int> q;
int d[maxn], r1[maxn], t1, r2[maxn], t2;
void BFS(int s)
{
    for(int i = 1; i <= t1; i++)
        vis1[r1[i]] = false;
    for(int i = 1; i <= t2; i++)
        vis2[r2[i]] = vis2[r2[i]^1] = false;
    while(!q.empty())
        q.pop();
    t1 = t2 = d[s] = 0;
    vis1[s] = true;
    r1[++t1] = s;
    q.push(s);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        for(int i = head[u]; i != -1; i = e[i].next)
        {
            int v = e[i].v;
            if(vis2[i])
                continue;
            if(vis1[v])
            {
                ans = min(ans, d[v] + d[u] + 1);
                return;
            }
            else
            {
                vis2[i] = vis2[i^1] = true;
                r2[++t2] = i;
                d[v] = d[u] + 1;
                vis1[v] = true;
                r1[++t1] = v;
                q.push(v);
            }
        }
    }
}
int main()
{
    memset(head, -1, sizeof(head));
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        split(a[i]);
    }
    ans  = INF;
    for(int i = 1; i <= N; i++)
        BFS(i);
    if(ans == INF)
        printf("-1\n");
    else
        printf("%d\n", ans);
    return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
const int N = 1e3;
int n, a[maxn], ans;
set<pair<int,int>> s;
vector<int> g[N + 10];
pair<int,int> split(int x)
{
    int p = 1, q = 1, k = sqrt(x) + 1;
    for(int i = 2; i <= k; i++)
    {
        int cnt = 0;
        while(x % i == 0)
        {
            x /= i;
            cnt++;
        }
        if(cnt & 1)
        {
            if(p == 1)
                p = i;
            else
                q = i;
        }
    }
    if(x > 1)
        q = x;
    if(p < q)
        swap(p, q);
    return make_pair(p, q);
}
int d[N + 10];
bool vis[N + 10];
void BFS(int s)
{
    queue<int> q;
    memset(vis, false, sizeof(vis));
    memset(d, 0x3f, sizeof(d));
    d[s] = 0;
    vis[s] = true;
    q.push(s);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        vis[u] = false;
        for(auto v: g[u])
        {
            if(d[v] > d[u] + 1)
            {
                d[v] = d[u] + 1;
                vis[v] = true;
                q.push(v);
            }
            else if(vis[v])
                ans = min(ans, d[u] + d[v] + 1);
        }
    }
}
int main()
{
    scanf("%d", &n);
    ans = INF;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        pair<int,int> e = split(a[i]);
        if(e.first == e.second)
            ans = min(ans, 1);
        else if(s.count(e))
            ans = min(ans, 2);
        g[e.first].push_back(e.second);
        g[e.second].push_back(e.first);
        s.insert(e);
    }
    if(ans != INF)
    {
        printf("%d\n", ans);
        return 0;
    }
    for(int i = 1; i <= N; i++)
        BFS(i);
    if(ans == INF)
        printf("-1\n");
    else
        printf("%d\n", ans);
    return 0;
}


#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

vector<int> Prime(int num) {
	vector<int>ret;
	ret.push_back(2);
	ret.push_back(3);
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i)break;
			if (i%ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i);
		flag = true;
		for (int j = 2; j < ret.size(); j++) {
			if (ret[j] * ret[j] > i + 2)break;
			if ((i + 2) % ret[j] == 0) {
				flag = false;
				break;
			}
		}
		if (flag)ret.push_back(i + 2);
	}
	return ret;
}

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

	auto P = Prime(1000000);
	vector<int>conv(1000001, -1);
	for (int i = 0; i < P.size(); i++) {
		conv[P[i]] = i;
	}
	cin >> N;
	bitset<78500>bs;
	int ans = MOD;
	unordered_map<string, int>mp;
	mp[bs.to_string()] = 0;
	for (int i = 1; i <= N; i++) {
		cin >> M;
		for (int j = 0; P[j] * P[j] <= M; j++) {
			while (M%P[j] == 0) {
				bs.flip(j);
				M /= P[j];
			}
		}
		if (M > 1) {
			bs.flip(conv[M]);
		}
		if (mp.find(bs.to_string()) != mp.end()) {
			ans = min(ans, i - mp[bs.to_string()]);
		}
		mp[bs.to_string()] = i;
	}
	if (ans == MOD)ans = -1;
	cout << ans << endl;
}