#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define sz(a) (int)(a.size())
#define all(a) a.begin(),a.end()
#define lb lower_bound
#define ub upper_bound
#define owo ios_base::sync_with_stdio(0);cin.tie(0);
#define INF (ll)(1e18)
#define debug(...) fprintf(stderr, __VA_ARGS__),fflush(stderr)
#define time__(d) for(long blockTime = 0; (blockTime == 0 ? (blockTime=clock()) != 0 : false);\
debug("%s time : %.4fs\n", d, (double)(clock() - blockTime) / CLOCKS_PER_SEC))
typedef long long int ll;
typedef long double ld;
typedef pair<ll,ll> PII;
typedef pair<int,int> pii;
typedef vector<vector<int>> vii;
typedef vector<vector<ll>> VII;
ll gcd(ll a,ll b){if(!b)return a;else return gcd(b,a%b);}
const int MAXN = 1e6;
int szz[MAXN],par[MAXN];
int n,m,k;
int find(int x){
if(par[x] == x)return x;
return par[x] = find(par[x]);
}
stack<pii>stk;
ll cur = 0;
ll eval(ll x){return (x*1LL*(x-1))/2;}
bool unite(int a,int b){
a = find(a);
b = find(b);
if(a==b)return 0;
if(szz[a] > szz[b])swap(a,b);
cur -= eval(szz[a]);
cur -= eval(szz[b]);
szz[b] += szz[a];
par[a] = b;
cur += eval(szz[b]);
stk.push({a,b});
return 1;
}
void reback(){
assert(!stk.empty());
int a = stk.top().fi;
int b = stk.top().se;
stk.pop();
cur -= eval(szz[b]);
par[a] = a;
szz[b] -= szz[a];
cur += eval(szz[a]);
cur += eval(szz[b]);
}
int ch[2][MAXNODE],nodecnt = 0;
vector<pii>edge[MAXNODE];
vector<int>ansid[MAXNODE];
ll finans[MAXN];
int newnode(){
nodecnt++;
return nodecnt;
}
void add(int v,int cur,int dep,int id){ //add queries
if(dep == -1){
ansid[v].pb(id);
return;
}
int c = (cur&(1<<dep)) > 0;
if(!ch[c][v])ch[c][v] = newnode();
add(ch[c][v],cur,dep-1,id);
}
void addedge(int v,int cur,int dep,pii ed){ //add edges
if(dep == -1)return;
if(k& (1<<dep)){ //edge can be added
int x = (cur&(1<<dep)) > 0; //edge xor with query must equal 0
if(ch[x][v])edge[ch[x][v]].pb(ed);
}
int c = ((cur^k) & (1<<dep)) > 0;
if(ch[c][v])addedge(ch[c][v],cur,dep-1,ed);
}
bool vis[MAXN];
void dfs(int v){
int cnt = 0;
for(pii e : edge[v])cnt+=unite(e.fi,e.se);
for(int id:ansid[v])finans[id] = cur;
if(ch[0][v])dfs(ch[0][v]);
if(ch[1][v])dfs(ch[1][v]);
while(cnt--)reback(); //reverse the changes
}
int main()
{
owo
cin>>n>>m>>k;
vector<array<int,3>>edges;
for(int i=0;i<m;i++){
int u,v,c;
cin>>v>>u>>c;
edges.pb({v-1,u-1,c});
}
int q;
cin>>q;
for(int i=1;i<=q;i++){
int d;
cin>>d;
add(0,d,30,i);
}
for(int i=0;i<n;i++){
par[i] = i;
szz[i] = 1;
}
for(auto e : edges)addedge(0,e[2],30,{e[0],e[1]});
dfs(0);
for(int i=1;i<=q;i++)cout<<finans[i]<<'\n';
}